# api
# $Id$

--> OpenVerse.tcl
OpenVerse client main module.  Initializes the program, does platform
specifics, and sources supporting modules.

variable (array) MV:
Catchall array for most every OpenVerse variable.
TODO: Use namespaces instead.  Use "variable" to explicitly list global
variables needed by procs.  Consider using procs instead of variables for
certain things to ensure that data is always correct.

variable (filename) MV(app):
Fully-qualified path to the OpenVerse executable.

variable (string) MV(platform):
Type of platform OpenVerse is running on.  Either Macintosh, UNIX, Winodws NT,
or Windows 9x.

variable (bool) MV(tearoff_menus):
Whether or not tearoff menus should be used.  Disabled for platforms that do
not correctly handle them.

variable (string) MV(browser_cmd):
Command line used to start a Web browser.  The url of a html redirect page is
appended to the command line before it is executed.

variable (dirname) MV(user_dir):
Path to the base of the user's personal OpenVerse installation.  User avatars,
configuration, downloads, etc. are stored here.
SUPERSEDES: MV(homedir)

variable (dirname) MV(system_dir):
Path to the base of the system OpenVerse installation.  Default configuration,
executable code, and shared images are stored here.
SUPERSEDES: MV(libbase)

variable (dirname) MV(homedir):
Path to the base of the user's personal OpenVerse installation.  User avatars,
configuration, downloads, etc. are stored here.
DEPRECATED: Use $MV(user_dir) instead.

variable (dirname) MV(libbase):
Path to the base of the system OpenVerse installation.  Default configuration,
executable code, and shared images are stored here.
DEPRECATED: Use $MV(system_dir) instead.

variable (dirname) MV(libdir):
Path to the OpenVerse library files.  Usually $MV(libbase)/lib.
DEPRECATED: Use [find_dir -lib] instead.

variable (dirname) MV(helpdir):
Path to the OpenVerse help files.  Usually $MV(libbase)/help.
DEPRECATED: Use [find_dir -help] instead.

--> lib/client/avatar.tcl
--> lib/client/object.tcl
--> lib/client/balloon.tcl
--> lib/client/nametag.tcl
--> lib/client/protocol.tcl
--> lib/client/tooltip.tcl
--> lib/client/room.tcl
--> lib/client/compat.tcl
--> lib/client/url.tcl
--> lib/client/panel.tcl
--> lib/client/misc.tcl
--> lib/client/init.tcl
--> lib/client/variable.tcl

--> lib/common/dcc.tcl
proc (sock_id) new_dcc {host port type file_name position version block_size} {
Initiate either end of a DCC connection.
host: Name or ip address of opposite end of connection.
port: Port to open locally to connect to remotely.
type: Type of DCC connection; one of ar, as, pr, ps.
file_name: Name of file to send or receive.
position: Position in file to start transfer at.
version: Version of protocol to use.
block_size: Amount of data to be sent as an individual block.

--> lib/common/debug.tcl
proc bgerror {code}:
Routes bgerrors through the message system.  Elsewhere some proc should probably
pop up error windows, print red text, go feep, send email, or do something
alarming whenever messages come across the debug/warn channel.
NOTE: Probably should not be directly called.

--> lib/common/socket.tcl
Network connection functions.  The new_socket proc accepts a protocol parameter.
A protocol is a key/value list, as generated by array get, defining the
following parameters.  See the fconfigure man page for more information on some
of these options.
(bool) protocol(server): A server socket is opened for others to connect to.
(bool) protocol(want_peername): Record the peer's network address, hostname, and
port.
(bool) protocol(want_sockname): Record the local socket's network address,
hostname, and port.
(proc) protocol(on_connect): Handler for a successful connection.
(proc) protocol(on_readable): Handler for available data.
(proc) protocol(on_writable): Handler for the socket being open for further
writing.
(proc) protocol(on_disconnect): Handler for the socket being closed by either
the local program or the peer.
(bool) protocol(blocking): Have port block on read and write access.
(string) protocol(buffering): Full, line, or none.
(int) protocol(buffersize): Size of the transmit and receive buffers.
(string) protocol(encoding): Encoding for the channel.
(string) protocol(eofchar): End-of-file character or characters.
(string) protocol(translation): Translation mode or modes.
NOTE: Where appropriate, use the procs in this module to manipulate sockets.
For instance, the on_disconnect handler won't be properly called if the socket
is closed using Tcl's builtin close command.

proc (sock_id) new_socket {protocol host port {extra {}}}:
Opens a tcp/ip network connection to 'host':'port' and returns a socket ID (same
as the socket handle that can be used with gets, fconfigure, etc).  For server
sockets, 'host' is ignored.  'Protocol' defines the connection parameters and
the procedures to call for various events.  'extra', if specified, is a
key/value list of extra data to store in the socket information array, including
some procs.  The proc fields may be blank.  The procs receive one parameter, the
name of the socket, which is good both as a parameter to the socket functions in
this file and as a parameter to Tcl's gets, puts, fconfigure, and other builtin
file and network commands.

proc del_socket {sock}:
Closes and deletes a network connection.

proc (list[sock_id]) get_sockets {}:
Returns a list of all open sockets.

proc (time) get_socket_time {sock}:
Returns the creation time of a socket.

proc (string) get_socket_extra {sock}:
Returns the creation time of a socket.

--> lib/common/message.tcl
Messaging functions.  These procs accept multiple channels of messages and
dispatch them to registered listeners.  For example, the main room canvas and
the text chat window ask to receive the 'chat' channel so they can display or
log the conversation, and the debug window asks to see the 'protocol' channel
so it can display the low-level network communications.  These procs are also
useful to the server.  Listener procs take two arguments: channel and message.
'channel' is the channel that the message occurred on; passing it explicitly
allows a single listener proc to handle multiple channels.  'message' is the
actual message passed; encode extra data (such as SCHATs) by making 'message' a
list with multiple fields.

proc new_listener {listener channel {index "end"}}:
Registers 'listener' to handle messages in 'channel'.
listener: Name of the proc to handle messages.  Listeners should accept three
 parameters: channel and message.  Listeners can exit with error to cancel
further message processing.
index: The index at which to register the listener.  Defaults to 'end'.

proc del_listener {listener {channel ""}}:
Removes 'listener' from the listener lists.  If 'channel' is supplied,
'listener' is only removed from the listener list for 'channel'.

proc new_channel {channel}:
Creates a channel for listeners to listen to.  Normally not needed because
channels are automatically created by registering listeners on them.

proc del_channel {channel};
Deletes a channel.  Normally not needed because it's simpler to unregister all
listeners on a channel; empty channels are usually treated as if they didn't
exist.

proc (list[proc]) get_listeners {{channel ""}}:
Returns a list of listeners.  If 'channel' is supplied, only listeners
listening to 'channel' are returned.

proc (list[string]) get_channels {{listener ""}}:
Returns a list of channels.  If 'listener' is supplied, only channels to which
'listener' is listening are returned.

proc (bool) send_message {channel msg args}:
Sends 'msg' to all listeners to 'channel'.  Messages are normally sent as part
of an idle callback.
args: -sync: Don't send messages as an idle callback; return false if a cancel
request occurred.  -cancel: Honor cancel requests (i.e. errors in listeners).

--> lib/common/plugin.tcl
Plugin functions.  New-style plugins are supported as well as old-style plugins
(PlugInit.tcl), panels (through panel.tcl files), and server objects (*.obj).

proc identify_plugins {}:
Gathers information about all plugins in the system.
TODO: Generalize to work with the server as well.  Clean up this code.  Handle
plugins that are already loaded but have disappeared from disk.

proc load_plugin {plugins}:
Load specified plugins.
TODO: Provide warnings about unloadable plugins.

proc unload_plugin {plugins args}:
Unload specified plugins.  Plugins dependent on the listed plugins are not
unloaded unless '-force' is specified.
args: -force: Recursively unload plugins dependent on those listed.
TODO: Provide warnings about plugins that can't be unloaded.

proc (bool) plugin_requires {plug1 plug2}:
Returns true if 'plug1' immediately depends on 'plug2'.

proc (bool) plugin_conflicts {plug1 plug2}:
Returns true if 'plug1' and 'plug2' conflicts.

proc (list) get_plugin_info {plugin}:
Returns an array-formatted list describing a plugin.
app: Client or server.
app_version: Version of main app plugin was written for.
version: Plugin version (major.minor.revision).
date: Revision date (yyyy-mm-dd).
name: Long name.
description: Long description.
contact: Contact email address (Author <user@host.net>).
url: Website URL.
provides: Services the plugin provides (e.g. setup).
requires: List of required plugins.
conflicts: List of conflicting plugins.
tags: [lunion 'provides' 'name'].
info_file: Filename of the plugin_info.tcl file.
load_file: Filename of the plugin_load.tcl file.
unload_file: Filename of the plugin_unload.tcl file.

--> lib/common/file.tcl
Functions for locating files and directories.  This file contains stuff for
locating files and directories in the system and user installations of
OpenVerse.  It also contains functions for installing and upgrading the user
installation.
TODO: Move the install/ugprade stuff to its own module.  Throw an error when a
file can't be found.

proc (dirname) find_dir {args}:
Returns the indicated directory, or "" if it does not exist.
args: [{-client | -server}] [{-user | -system}] {-config [<server-name>] |
-plugin [<plugin-name>] | -lib | -log [<server-name>] | -cache
[{avatars|rooms|objects}] | -download | -tmp | -avatars | -help [<plugin-name>]
| -icons [<plugin-name>] | -lang [<plugin-name] | -toplevel}

proc (filename) find_help {args}:
Returns the indicated help file, or "" if it does not exist.
args: [-plugin <plugin-name>] <help-filename>
TODO: Add language support

proc (filename) find_lang {args}:
Returns the indicated language file, or "" if it does not exist.
args: [{-client|-server}] [-plugin <plugin-name>] <language-name>

proc (filename) find_icon {args}:
Returns the indicated icon file, or "" if it does not exist.
args: [{-client|-server}] [-plugin <plugin-name>] <language-name>

proc (filename) find_avatar {args}:
Returns the indicated avatar file (.av or .gif), or "" if it does not exist.
args: [{-client|-server}] [{-personal|-cache}] <avatar-filename>

proc (filename) find_room {name}:
Returns the indicated cached room image file, if it exists.  If it does not,
then "" is returned.

proc (filename) find_object {name}:
Returns the indicated cached server object file, if it exists.  If it does not,
then "" is returned.

proc check_user_installation {}:
Checks to see if the user has OpenVerse installed in his home directory.  If
not, the user stuff is installed.  If the user has an older version of
OpenVerse installed in his home, its layout is upgraded, and the user is given
the option to make backups and compatibility symlinks.
TODO: Move this to another module.  Move install and upgrade functions to their
own procs.  Handle plugin upgrades.

--> lib/common/tcl_compat.tcl
Tcl 8.0 compatibility functions.  Provides 8.0-compatible implementations of
post-8.0 functions used by OpenVerse.

proc (bool) string_equal {args}:
Duplicates 'string equal'.

proc (string) string_map {args}:
Duplicates 'string map'.

proc (string) string_replace {args}:
Duplicates 'string replace'.

proc (string) string_totitle {args}:
Duplicates 'string totitle'.

proc (int) string_first {s1 s2 args}:
Duplicates 'string first ... ?startindex?'.

proc (bool) string_match {args}:
Duplicates 'string match -nocase ...'.

proc (bool) string_is {class args}:
Duplicates 'string is'.
NOTE: This proc does not provide a full implementation of 'string is'.

proc (string) string_repeat {str count}:
Duplicates 'string repeat'.

proc array_unset {ar args}:
Duplicates 'array unset'.

--> lib/common/misc.tcl
Miscellaneous functions.  These procs aren't specific to OpenVerse and can
probably be used anywhere.

proc (bool) lcontains {a b}:
Returns true if 'b' is an element of 'a'.
EXAMPLE: [lcontains {1 2 3} 2] == 1 ;# Because 2 is in {1 2 3}

proc (bool) lsubset {a b}:
Returns true if every element of 'a' is present in 'b'.
EXAMPLE: [lsubset {1 2 3} {2 3 4}] == 0 ;# Because 1 isn't in {2 3 4}

proc (list) lsubtract {a b}:
Returns 'a' minus every element from 'b'.
EXAMPLE: [lsubtract {1 2 3} {2 3 4}] == {1}

proc (list) lunion {args}:
Returns all lists merged, sans duplicate elements.
EXAMPLE: [lunion {1 2 3} {2 3 4}] == {1 2 3 4}

proc (list) lintersect {a b}:
Returns a list containing every element common to 'a' and 'b'.
EXAMPLE: [lintersect {1 2 3} {2 3 4}] == {2 3}

proc (list) ldifference {a b}:
Returns a list containing all elements exclusive to 'a' or 'b'.
EXAMPLE: [ldifference {1 2 3} {2 3 4}] == {1 4}

proc (bool) arg_pop {out in}:
Pops elements off 'in' and stores them in the variables whose names are listed
in 'out'.  Useful for processing variadic arguments.  Returns true on success.
EXAMPLE: if ![arg_pop next_arg args] break

proc swap {a b}:
Swaps variables 'a' and 'b'.

proc (number) min {args}:
Returns the minimal argument.

proc (number) max {args}:
Returns the maximal argument.

proc (number) mid {a b c}:
Returns the argument numerically between the other two arguments.

proc (color) interp_color {a b f}:
Interpolates colors 'a' and 'b' according to 'f'.  'f' ranges from 0.0 to 1.0;
'a' and 'b' range from 0 to 65535.  An 'f' of 0.0 means return 'a'; 'f' equal
to 1.0 means return 'b'.  An 'f' of 0.5 means return the average color.

proc (string) tcl_escape {a args}:
Returns an escape-protected string formed from 'a'.  If '-space' is given as an
extra argument, spaces are escaped.

proc (int) unique_id {}:
Returns a unique value.  Unique values start at 0 and increase from there.

--> server.tcl

# vim:syntax=ov_api:

# EOF
