/** @page tcl-howto Tcl Scripting HOWTO

@section Intoduction

NOTA BENE: This documentation is badly out of date for 2.x.

The libpurple Tcl interface provides a Tcl API for many useful libpurple
functions.  Like the perl API, the Tcl API does not provide access to
every corner of libpurple exposed by the @e C interface.  It does,
however, provide a very powerful interface to many of libpurple's
functions through a simple to learn and extend scripting language.

If you are not familiar with Tcl, you will probably find it somewhat
different from what you are used to.  Despite being somewhat unique
(more akin to shell programming than other traditional scripting
languages such as @e perl or @e python), it is simple to learn for
beginners and experienced programmers alike.  There are numerous books
on the subject; we will not discuss it any further here.

@section start Getting Started

The only requirement placed on a purple Tcl script by libpurple is the
existence of a procedure called @c plugin_init.  This procedure has
some limitations placed upon it; it will be parsed and evaluated before
the rest of the Tcl script, so it cannot reference any other variables
or procedures declared in the script.  In practice this is not a
problem, as the only thing this procedure should do is return a simple
list containing five items: the @b name of the script, its @b version
number, a @b summary (just a few words) of its function, a short (longer
than the summary, but no more than a couple of sentences if possible)
@b description, the @b author, and a @b URL to web page.  For example:

@code
proc plugin_init { } {
  return [ list "Example Plugin" \
                "1.0" \
		"Example plugin registration" \
		"Example of how to register a plugin for the Tcl HOWTO" \
		"Ethan Blanton <eblanton@cs.purdue.edu>" \
		"http://pidgin.im/" ]
}
@endcode

The rest of the script will generally be registration to recieve
notification of various purple (or Pidgin, or finch, or ...) signals
(more about this below) and definitions of procedures to be executed
when those signals occur.

@section details Interpreter Details

libpurple initializes and drives the Tcl event loop (similar to Tk),
meaning that commands like @c fileevent and @c after are available and
do not require @c vwait etc.  The @c vwait actually seems to be somewhat
broken due to a bug somewhere in the Tcl/Glib event loop glue, and it
should not be used for now.

The purple-specific functions are provided in a statically-linked
package called @c purple; this means that if you spawn a child
interpreter and wish to use the purple-specific functions, you will need
to execute <tt>load {} purple</tt> in that interpreter.

@section internals purple Internal Procedures and Variables

All of the information provided for your use by purple will be in the @c
::purple namespace.  This means that in order to access it you will either
have to import the purple namespace (e.g. via the command <tt>namespace
import purple::*</tt>) or reference it explicitly.  The following
descriptions will reference it explicitly for clarity.

@li Variables

@code
purple::version
@endcode

  This contains the version of the libpurple library which loaded the
  script.

@li Commands

@code
purple::account alias account
purple::account connect account
purple::account connection account
purple::account disconnect account
purple::account find username protocol
purple::account handle
purple::account isconnected account
purple::account list ?option?
purple::account protocol account
purple::account username account
@endcode

  The @c purple::account command consists of a set of subcommands
  pertaining to purple accounts.

  @c alias returns the alias for the account @c account.  If there is no
  alias for the given account, it returns the empty string.

  The subcommand @c connect connects the named account if it is not
  connected, and does nothing if it is.  In either case, it returns
  the @c gc for the account.

  @c connection returns the @c gc of the given account if it is connected,
  or 0 if it is not.  This @c gc is the gc used by purple::connection and
  other functions.

  @c disconnect disconnects the given @c account if it is connected, or
  does nothing if it is.

  @c find finds an account by its @c username and @c protocol (as returned by
  <tt>purple::account username</tt> and <tt>purple::account protocol</tt>) and 
  returns the account if found, or 0 otherwise.

  @c handle returns the instance handle required to connect to account
  signals.  (See <tt>purple::signal connect</tt>).

  The @c isconnected query returns true if the given account is
  connected and false otherwise.

  The @c list subcommand returns a list of all of the accounts known to
  libpurple.  The elements of this lists are accounts appropriate for the
  @c account argument of the other subcommands.  The @c -all option
  (default) returns all accounts, while the @c -online option returns
  only those accounts which are online.

  The @c protocol subcommand returns the protocol ID (e.g. "prpl-msn")
  for the given account.

  The @c username subcommand returns the username for the account
  @c account.

@code
purple::buddy alias buddy
purple::buddy handle
purple::buddy info ( buddy | account username )
purple::buddy list
@endcode

  @c purple::buddy is a set of commands for retrieving information about
  buddies and manipulating the buddy list.  For the purposes of Tcl,
  a "buddy" is currently a list of several elements, the first of
  which being the type.  The currently recognized types are "group",
  "buddy", and "chat".  A group node looks like:
@code
	{ group name { buddies } }
@endcode
  A buddy node is:
@code
	{ buddy name account }
@endcode
  And a chat node is:
@code
	{ chat alias account }
@endcode

  The @c alias subcommand returns the alias for the given buddy if it
  exists, or the empty string if it does not.

  @c handle returns the blist handle for the purposes of connecting
  signals to buddy list events.  (See <tt>purple::signal connect</tt>).

  @c info causes the purple-using UI to display the info dialog for the
  given buddy.  Since it is possible to request user info for a buddy
  not in your buddy list, you may also specify a buddy by his or her
  username and the account through which you wish to retrieve info.

  @c list returns a list of @c group structures, filled out with buddies
  and chats as described above.

@code
purple::connection account gc
purple::connection displayname gc
purple::connection handle
purple::connection list
@endcode

  @c purple::connection is a collection of subcommands pertaining to
  account connections.

  @c account returns the purple account associated with @c gc.  This
  account is the same account used by @c purple::account and other
  commands.

  @c displayname returns the display name (duh) of @c gc as reported by
  <tt>purple_connection_get_display_name(gc)</tt>.

  @c handle returns the purple connections instance handle.  (See
  <tt>purple::signal connect</tt>).

  @c list returns a list of all known connections.  The elements of
  this list are appropriate as @c gc arguments to the other
  @c purple::connection subcommands or other commands requiring a gc.

@code
purple::conv_send account who text
@endcode

  @c purple::conv is simply a convenience wrapper for @c purple::send_im and
  <tt>purple::conversation write</tt>.  It sends the IM, determines the from
  and to arguments for <tt>purple::conversation write</tt>, and prints the text
  sent to the conversation as one would expect.  For the curious, you
  may view the source for it by typing <tt>info body purple::conv_send</tt> at
  a Purple Commander prompt.

  Note that an error in either @c purple::send_im or <tt>purple::conversation
  write</tt> will not be caught by this procedure, and will be propagated
  to the caller.

@code
purple::conversation find ?-account account? name
purple::conversation handle
purple::conversation list
purple::conversation new ?-chat? ?-im? account name
purple::conversation write conversation style from to text
@endcode

  @c purple::conversation provides an API for dealing with
  conversations.  Given that libpurple clients are instant messenger
  programs, you'll probably spend a lot of time here.

  The command @c find attempts to find an existing conversation with
  username @c name.  If the @c -account option is given, it refines its
  search to include only conversations on that account.

  @c handle returns the conversations instance handle for the purposes
  of signal connection.  (See <tt>purple::signal connect</tt>).

  @c list returns a list of all currently open conversations.

  The @c new subcommand can be used to create a new conversation with
  a specified user on a specified account if one does not exist, or
  retrieve the existing conversation if it does.  The @c -chat and
  @c -im options specify whether the created conversation should be a
  chat or a standard IM, respectively.

  @c write is used to write to the specified conversation.  The @c style
  argument specifies how the text should be printed -- as text coming
  from the purple user (style @c send), being sent to the purple user
  (style @c recv), or as a system message (such as "so-and-so has
  signed off", style @c system).  From is the name to whom the text
  should be attributed -- you probably want to check for aliases here,
  lest you confuse the user.  @c text is the text to print.

@code
purple::core handle
purple::core quit
@endcode

  This command exposes functionality provided by the purple core API.

  <tt>purple::core handle</tt> returns a handle to the purple core for signal
  connection.  (See <tt>purple::signal connect</tt>).

  @c quit exits the libpurple client cleanly, and should be used in
  preference to the tcl @c exit command.  (Note that @c exit has not
  been removed, however.)

@code
purple::debug level category message
@endcode

  Equivalent to the C purple_debug function, this command outputs
  debugging information to the libpurple UI's debug window (or,
  typically, stdout if that UI is invoked with -d|--debug).  The valid
  levels are, in increasing level of severity, @c -misc, @c -info, @c
  -warning, and, or @c -error.  @c category is a short (a few characters
  ... for instance, "tcl" or "tcl plugin") "topic" type name for this
  message, and @c message is the text of the message. In the style of
  Tcl @e puts (and differing from @e purple_debug), no trailing \\n is
  required.  (However, embedded newlines may be generated with \\n).

@code
purple::notify ?type? title primary secondary
@endcode

  Also a direct equivalent to a C function, purple_notify, this command
  causes libpurple to present the provided notification information to
  the user via some appropriate UI method.  The @c type argument, if
  present, must be one of @c -error, @c -warning, or @c -info. The
  following three arguments' absolute meanings may vary with the purple
  UI being used, but @c title should generally be the title of the
  window, and @c primary and @c secondary text within that window; in
  the Pidgin UI, @c primary is slightly larger than @c secondary and
  displayed in a @b boldface font.

@code
purple::send_im gc who text
@endcode

  This sends an IM in the fashion of serv_send_im.  @c gc is the GC of
  the connection on which you wish to send (as returned by most event
  handlers), @c who is the nick of the buddy to which you wish to send,
  and @c text is the text of the message.

@code
purple::signal connect instance signal args proc
purple::signal disconnect instance signal
@endcode

  @c purple::signal is a set of subcommands for dealing with purple
  signals.

  The @c connect subcommand registers the procedure @c proc as a handler
  for the signal @c signal on the instance @c instance.  @c instance
  should be an instance handle as returned by one of the @c handle
  commands from the various parts of libpurple. @c args and @ proc are
  as in the Tcl @e proc command; note that the number of arguments in @c
  args must match the number of arguments emitted by the signal exactly,
  although you need not use them all.  The procedure @c proc may be
  either a simple command or a procedure in curly brackets.  Note that
  only one procedure may be associated with each signal; an attempt to
  connect a second procedure to the same signal will remove the existing
  binding and replace it with the new procedure.  <tt>purple::signal
  connect</tt> returns 0 on success and 1 on failure.

  @c disconnect removes any existing signal handler for the named
  signal and instance.

@code
purple::unload
@endcode

  This unloads the current plugin.  Note that preferences will not be
  updated (yet).

@section Signals

Check the signals documentation for the meaning of these signals; this is
intended to be a list only of their arguments.  Signal callbacks will
be made in their own namespace, and arguments to those signal
callbacks will live in the namespace @c event underneath that
namespace.  To briefly illustrate, the signal @c receiving-im-msg is
provided with three arguments; the account on which the IM was
received, the screen name of the user sending the IM, and the text of
the IM.  These arguments live in the variables @c event::account,
@c event::sender, and @c event::buffer, respectively.  Therefore a callback
which notifies the user of an incoming IM containing the word 'shizzle'
might look like this:

@code
purple::signal connect [purple::conversation handle] receiving-im-msg {
	if {[ string match "*shizzle*" $event::buffer ]} {
		purple::notify -info "tcl plugin" "Fo' shizzle" \
			"$event::sender is down with the shizzle"
	}
}
@endcode

Note that for some signals (notably @c receiving-im-msg, @c sending-im-msg,
and their chat counterparts), changes to the event arguments will
change the message itself from libpurple's vantage.  For those signals
whose return value is meaningful, returning a value from the Tcl event
will return that value as it would in C.

*/

// vim: syntax=c tw=72 et
