############################# Sample Trillian Perl Script ###############################
#
# All trillian perl scripts must include the module "TrillianPlugin".
# Once you have included this module you must call DispatchEvent to dispatch an event to
# all other plugins. This works in a similar way to a windows message loop. Once you call
# DispatchEvent, the data from the event is eventually routed through to your event handler
# subroutine (see below). If you wish you can examine TrillianPlugin.pm and TrillPerl_Link.pl
# yourself and see how these work, but they are blackboxed, and you don't really need to
# now how they work to be able to script in TrillPerl. This is just for tech-heads.
#
# NB: CRYPT SOFTWARE WILL NOT OFFER SUPPORT TO ANYONE THAT MODIFIES EITHER TRILLPERL.PM
#     OR TRILLPERL_LINK.PL - WE CANNOT SUPPORT VERSIONS WITH UNDOCUMENTED AND/OR UNTESTED
#     CHANGES!
#
use TrillianPlugin;
TrillianPlugin::DispatchEvent;
#
################################### Events go here #####################################
#

my $alias_id;
my $action_id;

# This event is called when an outgoing message is due to be sent by trillian.
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of target, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub outgoing_privateMessage
{
}

# This event is called when an incoming message has been received by trillian.
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub incoming_privateMessage
{
        my ($SELF,$medium,$cid,$sender,$body,$location) = @_;

        if ($body =~ /abcd/i)
        {
                # if you have this event enabled in your preferences, this will
                # cause the action for that event to be played.
                #
                # Bind this event to the program generated event type "An event that moos" to
                # have it trigger the callback in this script.
                # 
                TrillianPlugin::GenerateEvent("Contact List: Contact Signon",1);
        }

        if ($body =~ /qwertyuiop/i)
        {
                TrillianPlugin::SendMessage($medium,$cid,$sender,"I am cornholio!");
                TrillianPlugin::Alert("You are cornholio!","popup_callback",$SELF);
                TrillianPlugin::CreateThread("my_thread",$SELF,"optional parameter");
        }
}

sub popup_callback
{
        # we must call PopulateContacts here to ensure the %Contacts hash is up to date
        # before we mess with it.
        TrillianPlugin::PopulateContacts;
        TrillianPlugin::OutputDebug("The callback was called!");
        TrillianPlugin::OutputDebug("Az's status: ",$TrillianPlugin::Contacts{Azhrarn}{status});
}

sub my_thread
{
        $param = $_[0];
        TrillianPlugin::OutputDebug("This is my thread subroutine saying: $param!");
        for ($qq = 0; $qq < 10000; $qq++)
        {
                my $b = $qq; # do nothing here, this is a timewasting loop to prove the thread is working
        }
        TrillianPlugin::OutputDebug("The thread has done its job.");
}

sub alias_handler
{
        my($orig) = @_;
        TrillianPlugin::OutputDebug("Alias handler for $orig called!");
        TrillianPlugin::TextAliasSet("/me slaps himself about with a smelly haddock!",1);
}

# offline/online event
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] display name of user, usually different to name of sender
# [5] data about signon, signoff, in the form: "signed on at Wed Oct 15 00:33:53 2003."

sub information_standard
{
}

# IRC channel chat, or MSN/AIM etc chatroom inbound
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub incoming_groupMessage
{
}

# IRC /action and /me inbound
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub incoming_groupAction
{
}

# called when script is loaded.
# Parameters:
# [4] filename of the script

sub script_onLoad
{
        my(undef,undef,$SELF,undef,$FILE,undef) = @_;
        $alias_id = TrillianPlugin::CreateTextAlias("/haddock","alias_handler",$SELF);

        TrillianPlugin::AddContact("MSN", # medium
                                'laptop@brainbox.winbot.co.uk', # identifier
                                "LaptopBrain", # display name
                                "http://brainbox.winbot.co.uk", # uri to associate with the user
                                "Laptop Brain", # tooltip
                                "MSN"); # group
}

# called when script is unloaded (either individually, or because the plugin is shutting down
# [4] filename of the script

sub script_OnUnload
{
        TrillianPlugin::OutputDebug("The test script is being unloaded!");
        TrillianPlugin::DeleteTextAlias($alias_id);
}

# IRC channel chat, or MSN/AIM etc chatroom outbound
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub outgoing_groupMessage
{
}

# IRC /action and /me outbound
# Parameters:
# [0] internal package name (reference to self), most scripters won't need this
# [1] medium name, e.g. MSN
# [2] connection id, usually 0
# [3] name of sender, e.g. msn address or icq number
# [4] text body of actual message. May (*SHOULD!*) be html encapsulated.
# [5] location message is destined for, if event is from a group chat

sub outgoing_groupAction
{
}

# Left mouse button clicked in an edit window.
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutines
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_leftClick
{
}

# Right mouse button clicked in an edit window
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutines
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_rightClick
{
}

# Menu shown in edit window, usually follows an edit_rightClick
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutines
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_showMenu
{
}

# Menu hidden in edit window, usually follows or preceeds an edit_leftClick
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutines
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_hideMenu
{
}

# Text in an edit window was changed, called for every character that is input - *BE QUICK!*
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutine
# [1] change event type, can be one of the following strings:
# 
#       edit_insert_picture             edit_cut                edit_delete_selected
#       edit_clear                      edit_paste              edit_delete
#       edit_backspace_selected         edit_backspace_word     edit_backspace
#       edit_history                    edit_tab                edit_split
#       edit_mirc_color                 edit_format             edit_alias
#       edit_foreground                 edit_background         edit_ime_add
#       edit_character                  edit_remote_add         edit_event
#       edit_size
#       
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] text currently in the edit window
# [5] empty but defined

sub edit_changeText
{
        # This example code changes all occurances of 'shit' to 'poop' interactively
        # (basically an auto replacer)
        my ($SELF,$type,$window_id,$ev_id,$text,undef) = @_;
        if ($text =~ /shit/i)
        {
                $text =~ s/shit/poop/i;
                TrillianPlugin::SetWindowText($window_id,$text);
        }
}

# Text in an edit is about to be sent to its recipient.
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutine
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] text currently in the edit window
# [5] empty but defined

sub edit_sendText
{
}

# User has started typing a message. Occurs once at the start of every message within an edit window.
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutine
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_userIsTyping
{
}

# User has stopped typing a message. Occurs when the keyboard goes idle for a core-determined period
# Parameters:
# [0] internal package name (reference to self), used for callbacks and handler subroutine
# [1] empty but defined
# [2] window id
# [3] event id (all edit events go through the same event id, so this has little use to scripters)
# [4] empty but defined
# [5] empty but defined

sub edit_userIsNotTyping
{
}

# sub EV_* events are special in the respect that they do not pass standard parameters to @_ when called.
# TrillPerl tiggers these in response to program events which occur in trillian, which can have an undetermined
# number of variable values.
#
# When an sub EV_* sub is called, you must pass the 5th parameter to TrillianPlugin::DecodeParameters, which
# will return a hash. The contents of this hash vary from event type to event type, for example, here
# is a sample of variable names and values from an outbound message (type sub EV_im_outbound).
#
# address = 329059863
# cid = 45092604
# displayname = Blue Star
# icon = ICQ-systray-messagealert
# location = 0
# medium = ICQ
# message = <HTML><BODY BGCOLOR="#ffffff"><font lang="EN">message body</BODY></HTML>
# window_id = 45400916
#
# To access these variables, one must do so in the form: %somehash{"varname"}, this is similar to CGI in
# operation. Some examples of using sub EV_* subs follow. There are almost 70 sub EV_* type events which your
# script may handle, so for a full list of valid names for your handlers, please see the documentation.

sub EV_im_outbound
{
        my($SELF,undef,undef,undef,$data,undef) = @_;
        my %params = TrillianPlugin::DecodeParameters($data);
        TrillianPlugin::OutputDebug("You sent an outbound message to ", $params{"displayname"}, " on medium ",$params{"medium"});
}

sub EV_contactlist_signon
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_signon",$data);}


sub EV_aim_new_mail
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_aim_new_mail",$data);}

sub EV_avatar_update
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_avatar_update",$data);}


sub EV_connection_all_connected
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_connection_all_connected",$data);}


sub EV_connection_all_disconnected
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_connection_all_disconnected",$data);}


sub EV_connection_change
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_connection_change",$data);}


sub EV_connection_partially_disconnected
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_connection_partially_disconnected",$data);}


sub EV_contactlist_add
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_add",$data);}


sub EV_contactlist_bulk_signoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_bulk_signoff",$data);}


sub EV_contactlist_bulk_signon
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_bulk_signon",$data);}


sub EV_contactlist_signoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_signoff",$data);}


sub EV_contactlist_statuschange
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_statuschange",$data);}


sub EV_metacontact_signoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_metacontact_signoff",$data);}


sub EV_metacontact_signon
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_metacontact_signon",$data);}


sub EV_metacontact_statuschange
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_metacontact_statuschange",$data);}


sub EV_contactlist_remove
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_contactlist_remove",$data);}


sub EV_subcontact_bulk_signoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_subcontact_bulk_signoff",$data);}


sub EV_subcontact_bulk_signon
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_subcontact_bulk_signon",$data);}


sub EV_subcontact_signoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_subcontact_signoff",$data);}


sub EV_subcontact_signon
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_subcontact_signon",$data);}


sub EV_subcontact_statuschange
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_subcontact_statuschange",$data);}


sub EV_status_set_away
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_status_set_away",$data);}


sub EV_status_set_back
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_status_set_back",$data);}


sub EV_status_idle_back
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_status_idle_back",$data);}


sub EV_screensaver_end
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_screensaver_end",$data);}


sub EV_screensaver_start
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_screensaver_start",$data);}


sub EV_pending_file_transfer
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_pending_file_transfer",$data);}


sub EV_inbound_dcc_chat
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_inbound_dcc_chat",$data);}


sub EV_pending_dcc
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_pending_dcc",$data);}


sub EV_new_mail
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_new_mail",$data);}


sub EV_chat_inbound_focused
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_inbound_focused",$data);}


sub EV_chat_inbound_focused_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_inbound_focused_unmutable",$data);}


sub EV_chat_inbound_unfocused
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_inbound",$data);}


sub EV_chat_inbound_unfocused_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_inbound_unfocused_unmutable",$data);}


sub EV_chat_outbound
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_outbound",$data);}


sub EV_chat_outbound_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_chat_outbound_unmuteable",$data);}


sub EV_im_inbound_focused
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_inbound_focused",$data);}


sub EV_im_inbound_focused_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_inbound_focused_unmutable",$data);}


sub EV_im_inbound_unfocused
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_inbound_unfocused",$data);}


sub EV_im_inbound_unfocused_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_inbound_unfocused_unmutable",$data);}


sub EV_im_outbound
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_outbound",$data);}


sub EV_im_outbound_unmutable
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_outbound_unmuteable",$data);}


sub EV_im_window_created
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_window_created",$data);}


sub EV_im_window_destroyed
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_window_destroyed",$data);}


sub EV_im_window_initial_view
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_im_window_initial_view",$data);}


sub EV_message_pending_event
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_message_pending_event",$data);}


sub EV_message_url
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_message_url",$data);}


sub EV_msn_new_mail
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_msn_new_mail",$data);}


sub EV_plugin_finalunload
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_finalunload",$data);}


sub EV_plugin_initialload
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_initialload",$data);}


sub EV_plugin_load
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_load",$data);}


sub EV_plugin_start
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_start",$data);}


sub EV_plugin_stop
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_stop",$data);}


sub EV_plugin_unload
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_plugin_unload",$data);}


sub EV_exit_program
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_exit_program",$data);}


sub EV_load_program
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_load_program",$data);}


sub EV_default_message_send
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_default_message_send",$data);}


sub EV_windows_console_connect
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_console_connect",$data);}


sub EV_windows_console_disconnect
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_console_disconnect",$data);}


sub EV_windows_remote_connect
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_remote_connect",$data);}


sub EV_windows_remote_disconnect
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_remote_disconnect",$data);}


sub EV_windows_logoff
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_logoff",$data);}


sub EV_windows_userswitch
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_userswitch",$data);}


sub EV_windows_switchback
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_windows_switchback",$data);}


sub EV_yahoo_new_mail
{my($SELF,undef,undef,undef,$data,undef) = @_;Display("sub EV_yahoo_new_mail",$data);}

sub Display
{
        my($name,$data) = @_;
        my %par = TrillianPlugin::DecodeParameters($data);
        open(FH,">>c:\\events.txt") or die "BLERGHHH!\n";
        print FH "\n--- $name\n\n";
        foreach $key (sort keys %par)
        {
                print FH "$key = '". $par{"$key"} ."'\n";
        }
        close(FH);
}