// doc.h : interface of the CMUSHclientDoc class
//
/////////////////////////////////////////////////////////////////////////////

// define LUA51 in the project defines to use Lua 5.1 

#pragma once

#include "worldsock.h"
#include "chatsock.h"
#include "chatlistensock.h"
#include "ColourComboBox.h"
#include "prefspropertypages.h"
#include "TimerWnd.h"
#include "xmlparse.h"
#include "paneline.h"

#define COMPRESS_BUFFER_LENGTH 1024   // size of decompression buffer

// ============================================================================

// New versions - things to change

#define THISVERSION 430                       // Step 1.
const CString MUSHCLIENT_VERSION = "4.30";    // Step 2.
// Step 3. Don't forget VERSION resource in Resources tab
// Step 4. Remember: README.TXT 

// ============================================================================

#define MY_WEB_PAGE "http://www.gammon.com.au/mushclient/" 
#define CHANGES_WEB_PAGE "http://www.gammon.com.au/scripts/showrelnote.php" 
#define MUD_LIST "http://www.gammon.com.au/links/muds.htm" 
#define BUG_REPORT_PAGE "http://www.gammon.com.au/forum/?bbtopic_id=5"
#define FORUM_URL "http://www.gammon.com.au/forum/"
#define ORDERS_PAGE "http://www.gammon.com.au/fee.htm" 
#define REGCODE_URL "http://www.gammon.com.au/regcode.htm" 
#define MUSHCLIENT_FORUM_URL "http://www.gammon.com.au/forum/?bbsection_id=1"
#define MUSHCLIENT_FUNCTIONS_URL "http://www.gammon.com.au/mushclient/functions.htm"
#define DOCUMENTATION_PAGE "http://www.gammon.com.au/scripts/doc.php"
#define REGEXP_PAGE "http://www.gammon.com.au/mushclient/regexp.htm"
#define PLUGINS_PAGE "http://www.gammon.com.au/mushclient/plugins/"

#define MAX_LINE_WIDTH 500    // max line we will wrap to
#define MAX_RECENT_LINES 200  // maximum recent lines we can use for multi-line triggers

#pragma warning(disable: 4800) // disable warning about bool being forced to BOOL

// program constants

const int JUMP_SIZE = 100;     // how many lines we discard when we reach maximum lines
const char ENDLINE [] = "\r\n";         // line terminator
const char SIGNATURE [] = "WinMUSH";    // world file signature
const int VERSION = 15;                  // version number written to world file
#define MAX_EXECUTION_DEPTH 20          // number of nested calls to world.Execute we permit

#define MAX(arg1, arg2) (((arg1) > (arg2)) ? (arg1) : (arg2))
#define MIN(arg1, arg2) (((arg1) < (arg2)) ? (arg1) : (arg2))

// definitions for Pueblo - see:
//   http://www.chaco.com/pueblo/doc/manual/puebloPueblo_Enhancers_Guide.html

// this string identifies a Pueblo-offering server
#define PUEBLO_ID_STRING1 "This world is Pueblo 1.10 enhanced."
#define PUEBLO_ID_STRING2 "This world is Pueblo 1.0 Enhanced"
#define PUEBLO_ID_STRING3 "This world is Pueblo 2.50 enhanced."
// this string identifies that we will use Pueblo - replace %s with a 32-character hash
#define PUEBLO_REPLY1 "PUEBLOCLIENT %s md5=\"%s\""
#define PUEBLO_REPLY2 "PUEBLOCLIENT"
// this string identifies that Pueblo starts after it is received
#define PUEBLO_START "</xch_mudtext>"

#define ORIGINAL_MACRO_COUNT 60

class CSendView;
class CMUSHView;
class CChildFrame;
class CSendView;
class CTextDocument;
class UDPsocket;

#define ESC '\x1B'

// ANSI/MXP phases

enum { NONE,          // normal text
       HAVE_ESC,      // just received an escape
       DOING_CODE,    // process an ANSI escape sequence
       HAVE_IAC,      // just received a TELNET IAC (interpret as command)
       HAVE_WILL,     // just received a TELNET WILL
       HAVE_WONT,     // just received a TELNET WONT
       HAVE_DO,       // just received a TELNET DO
       HAVE_DONT,     // just received a TELNET DONT
       HAVE_SUBNEGOTIATION,  // in middle of subnegotiation
       HAVE_COMPRESSION,     // in middle of subnegotiation for compression, awaiting SE
       HAVE_MXP,             // in middle of subnegotiation for MXP, awaiting SE
       HAVE_TERMINAL_TYPE,   // in middle of subnegotiation for terminal type, awaiting SEND IAC SE
       HAVE_CHARSET_REQUEST, // in middle of subnegotiation for CHARSET, expecting delimiter character
       HAVE_CHARSET,         // in middle of subnegotiation for CHARSET, expecting character set name
       HAVE_FOREGROUND_256_START,   // received ESC[38;
       HAVE_FOREGROUND_256_FINISH,  // received ESC[38;5;
       HAVE_BACKGROUND_256_START,   // received ESC[48;
       HAVE_BACKGROUND_256_FINISH,  // received ESC[48;5;


       // mxp modes
       HAVE_MXP_ELEMENT, // collecting element, eg. < xxxxx >. Starts on <, stops on >
       HAVE_MXP_COMMENT, // collecting comment, eg. <!-- xxxxx -->. Starts on <!--, stops on -->
       HAVE_MXP_QUOTE,   // collecting quote inside element, eg. <color='red'>
       HAVE_MXP_ENTITY,  // collecting entity, eg. &gt; . Starts on &, stops on ;

       // mxp special collection modes following a special escape sequence
       HAVE_MXP_ROOM_NAME,  // the line is parsed as the name of a room.  
       HAVE_MXP_ROOM_DESCRIPTION,  // the line is parsed as a description of a room.    
       HAVE_MXP_ROOM_EXITS,  // the line is parsed as an exit line for a room.    
       HAVE_MXP_WELCOME,  // This text is sent from the MUD at the beginning of a session to welcome the user to the MUD.    
       };
        

// TELNET escape sequences  - see RFC 854

enum { WILL_END_OF_RECORD      = 0x19, // see RFC 885  */
       EOR                = 0xEF, // see RFC 885
       SE                 = 0xF0, // end of subnegotiation
       NOP                = 0xF1, // no operation
       DATA_MARK          = 0xF2, // see RFC 854
       BREAK              = 0xF3, // BRK
       INTERRUPT_PROCESS  = 0xF4, // IP
       ABORT_OUTPUT       = 0xF5, // AO
       ARE_YOU_THERE      = 0xF6, // AYT
       ERASE_CHARACTER    = 0xF7, // EC
       ERASE_LINE         = 0xF8, // EL
       GO_AHEAD           = 0xF9, // GA
       SB                 = 0xFA, // subnegotiation
       WILL               = 0xFB, 
       WONT               = 0xFC,
       DO                 = 0xFD,
       DONT               = 0xFE,
       IAC                = 0xFF
      };

// values for m_iConnectPhase - for connecting via Socks proxy or directly
//  - this is so we know what we are up to

enum {    
      eConnectNotConnected,           // 0: not connected and not attempting connection
      eConnectMudNameLookup,          // 1: finding address of MUD
      eConnectProxyNameLookup,        // 2: finding address of proxy server
      eConnectConnectingToMud,        // 3: connecting to MUD (no proxy server)
      eConnectConnectingToProxy,      // 4: connecting to proxy server
      eConnectAwaitingProxyResponse1, // 5: sent SOCKS authentication method, awaiting confirmation
      eConnectAwaitingProxyResponse2, // 6: sent SOCKS username/password, awaiting confirmation
      eConnectAwaitingProxyResponse3, // 7: sent SOCKS connect details, awaiting confirmation
      eConnectConnectedToMud,         // 8: connected, we can play now
      eConnectDisconnecting,          // 9: in process of disconnecting, don't attempt to reconnect
  };
      
// values for m_iSocksProcessing - type of proxy server

enum {
      eProxyServerNone,     // no proxy server
      eProxyServerSocks4,   // SOCKS 4
      eProxyServerSocks5,   // SOCKS 5

      // This must be last !!!

      eProxyServerLast,
  };

// values for m_iCurrentActionSource - why script is currently running

enum {
      eDontChangeAction = 999,      // leave current action alone (was -1, but must be unsigned)
      eUnknownActionSource = 0,     // no particular reason, could be plugin saving 
      eUserTyping = 1,              // user typed something in the command area and pressed <Enter>
      eUserMacro = 2,               // user typed a macro  (eg. F2)
      eUserKeypad = 3,              // user used the numeric keypad
      eUserAccelerator = 4,         // user used an accelerator key
      eUserMenuAction = 5,          // item chosen from pop-up menu
      eTriggerFired = 6,            // trigger fired
      eTimerFired = 7,              // timer fired
      eInputFromServer = 8,         // input arrived (eg. packet received)
      eWorldAction = 9,             // some sort of world action (eg. world open, connect, got focus)
      eLuaSandbox = 10,             // executing Lua sandbox
  };

// MCCP (Mud Client Compression Protocol) stuff

// NB 85 is MCCP v1, 86 is MCCP v2

#define TELOPT_ECHO     1     //just in case you want to know what 1 is :)
#define TELOPT_NAWS 31        // Negotiate About Window Size
#define TELOPT_CHARSET 42     // Negotiate About Character Set
#define TELOPT_TERMINAL_TYPE 24  // want to know terminal type
#define TELOPT_COMPRESS 85   // telet negotiation code for starting compression v1
#define TELOPT_COMPRESS2 86  // telet negotiation code for starting compression v2
#define SUPPORT_VERSIONS 0   // MCCP support-versions query
#define VERSION_IS 1         // MCCP version number
#define VERSION_NONE 0   // see web page below for details
#define VERSION_2_1 1   

// see http://www.randomly.org/projects/MCCP/protocol.html

#define SGA 3                 // suppress go-ahead

#define TELOPT_MSP 90   // telet negotiation code for MUD Sound Protocol (MSP)
#define TELOPT_MXP 91   // telet negotiation code for MUD Extension Protocol (MXP)

              
// bits for m_iFlags1

#define FLAGS1_ArrowRecallsPartial             0x0001
#define FLAGS1_CtrlZGoesToEndOfBuffer          0x0002
#define FLAGS1_CtrlPGoesToPreviousCommand      0x0004
#define FLAGS1_CtrlNGoesToNextCommand          0x0008
#define FLAGS1_HyperlinkAddsToCommandHistory   0x0010
#define FLAGS1_EchoHyperlinkInOutputWindow     0x0020
#define FLAGS1_AutoWrapWindowWidth             0x0040
#define FLAGS1_NAWS                            0x0080
#define FLAGS1_Pueblo                          0x0100
#define FLAGS1_NoEchoOff                       0x0200
#define FLAGS1_UseCustomLinkColour             0x0400
#define FLAGS1_MudCanChangeLinkColour          0x0800
#define FLAGS1_UnderlineHyperlinks             0x1000
#define FLAGS1_MudCanRemoveUnderline           0x2000
//#define FLAGS1_AssumeSecureMode                0x4000 

// bits for m_iFlags2

#define FLAGS2_AlternativeInverse              0x0001
#define FLAGS2_ShowConnectDisconnect           0x0002
#define FLAGS2_IgnoreMXPcolourChanges          0x0004
#define FLAGS2_Custom16isDefaultColour         0x0008
#define FLAGS2_LogInColour                     0x0010
#define FLAGS2_LogRaw                          0x0020


// queued commands echo and send flags - lowercase versions do not log

#define QUEUE_WITH_ECHO               'E'
#define QUEUE_WITHOUT_ECHO            'N'
#define IMMEDIATE_WITH_ECHO           'I'
#define IMMEDIATE_WITHOUT_ECHO        'W'

#define QUEUE_WITH_ECHO_NOLOG         'e'
#define QUEUE_WITHOUT_ECHO_NOLOG      'n'
#define IMMEDIATE_WITH_ECHO_NOLOG     'i'
#define IMMEDIATE_WITHOUT_ECHO_NOLOG  'w'


// reload script file options
enum {
      eReloadConfirm,
      eReloadAlways,
      eReloadNever,
  };

// used for iNotepadType

enum {
     eNotepadNormal,
     eNotepadMXPdebug,
     eNotepadTrigger,
     eNotepadRecall,
     eNotepadScript,
     eNotepadPacketDebug,
     eNotepadLineInfo,
     eNotepadWorldLoadError,
     eNotepadXMLcomments,
     eNotepadPluginInfo,
  };  

// values for auto-connect (m_connect_now)

enum
  {
  eNoAutoConnect,
  eConnectMUSH,
  eConnectDiku,
  eConnectMXP,

  eConnectTypeMax,  // this must be last!
  };  

// values for <OL> and <UL> tags
// see m_iListMode

enum
  {
  eNoList,
  eOrderedList,
  eUnorderedList,
  };

  // configuration page numbers

  enum
    {
    ePageGroup0,     // name
    ePageGeneral,
    ePageConnecting,
    ePageLogging,
    ePageTimers,
    ePageChat,
    ePageInfo,
    ePageNotes,
    ePageGroup00,    // appearance
    ePageOutput,
    ePageMXP,
    ePageANSIColours,
    ePageCustomColours,
    ePageTriggers,
//    ePageSounds,
    ePagePrinting,
    ePageGroup000,   // input
    ePageCommands,
    ePageAliases,
    ePageKeypad,
    ePageMacros,
    ePageAutosay,
//    ePageGroup0000, // paste
    ePagePaste,
    ePageSend,
    ePageGroup00000, // scripting
    ePageScripts,
    ePageVariables,
    };

// MXP modes - see m_iMXP_mode (based on <esc> [ x z where x is the mode)

  enum 
    {
    eMXP_open=0,   // only MXP commands in the "open" category are allowed. 
    eMXP_secure=1, // all tags and commands in MXP are allowed within the line. 
    eMXP_locked=2, // no MXP or HTML commands are allowed in the line.  The line is not parsed for any tags at all.  
    eMXP_reset=3,  // close all open tags
    eMXP_secure_once=4,  // next tag is secure only
    eMXP_perm_open=5,   // open mode until mode change 
    eMXP_perm_secure=6, // secure mode until mode change
    eMXP_perm_locked=7, // locked mode until mode change

    eMXP_room_name=10,  // the line is parsed as the name of a room.  
    eMXP_room_description=11,  // the line is parsed as a description of a room.    
    eMXP_room_exits=12,  // the line is parsed as an exit line for a room.    
    eMXP_welcome=19,  // This text is sent from the MUD at the beginning of a session to welcome the user to the MUD.    
//20 to 99 - user defined
    };

  // use mxp options  - see m_iUseMXP
enum {
     eOnCommandMXP,   // turn on after <IAC><SB><MXP><IAC><SE>
     eQueryMXP,       // turn on after option query
     eUseMXP,         // always on
     eNoMXP,          // always off
  };

// MXP debug levels
enum {
   DBG_NONE,         // no messages
   DBG_ERROR,        // only errors
   DBG_WARNING,      // errors and warnings
   DBG_INFO,         // errors, warnings and info
   DBG_ALL,          // a whole lot of useless stuff
  };

#define OPT_CUSTOM_COLOUR       0x000001    // colour number  (add 1 to colour to save, subtract 1 to load)
#define OPT_RGB_COLOUR          0x000002    // colour is RGB colour
#define OPT_DOUBLE              0x000004    // option is a double
#define OPT_UPDATE_VIEWS        0x000100    // if changed, update all views
#define OPT_UPDATE_INPUT_FONT   0x000200    // if changed, update input font
#define OPT_UPDATE_OUTPUT_FONT  0x000400    // if changed, update output font
#define OPT_FIX_OUTPUT_BUFFER   0x000800    // if changed, rework output buffer size
#define OPT_FIX_WRAP_COLUMN     0x001000    // if changed, wrap column has changed
#define OPT_FIX_SPEEDWALK_DELAY 0x002000    // if changed, speedwalk delay has changed
#define OPT_USE_MXP             0x004000    // if changed, use_mxp has changed
#define OPT_PLUGIN_CANNOT_READ  0x100000    // plugin may not read its value
#define OPT_PLUGIN_CANNOT_WRITE 0x200000    // plugin may not write its value
#define OPT_PLUGIN_CANNOT_RW    0x300000    // plugin may not read or write its value
#define OPT_CANNOT_WRITE        0x400000    // cannot be changed by any script
#define OPT_SERVER_CAN_WRITE    0x800000    // CAN be changed by <recommend_option> tag

// for debug.options and MXP <option> tag
typedef struct
  {
  char *  pName;      // name, eg. "logoutput"
  double  iDefault;   // original (default) value
  int     iOffset;    // offset in CMUSHclientDoc
  int     iLength;    // length of field (ie. 1, 2, 4, 8 bytes)
  double  iMinimum;   // minimum size it can be
  double  iMaximum;   // maximum size it can be, if both zero, assume boolean
  int     iFlags;     // colours etc, see above
  }  tConfigurationNumericOption;

// for XML load/save
typedef struct
  {
  char *  pName;      // name, eg. "server"
  char *  sDefault;   // original (default) value
  int     iOffset;    // offset in CMUSHclientDoc
  int     iFlags;     // flags, see above
  }  tConfigurationAlphaOption;


#define OPT_MULTLINE      0x000001    // multi-line option (eg. world notes)
#define OPT_KEEP_SPACES   0x000002    // preserve leading/trailing spaces
#define OPT_PASSWORD      0x000004    // use base 64 encoding
#define OPT_COMMAND_STACK 0x000008    // this is the command stack character
#define OPT_WORLD_ID      0x000010    // this is the world ID

// also can have values above: OPT_UPDATE_VIEWS, 
//                             OPT_UPDATE_INPUT_FONT, 
//                             OPT_UPDATE_OUTPUT_FONT   etc.


// for Lua tables mainly
typedef struct { const char* key; int val; } flags_pair;
typedef struct { int key; char * val; } int_flags_pair;

typedef struct 
  {
  int						iInfoType;			 // which info number it is
  const char *	sDescription;    // eg. "Server name"
  } tInfoTypeMapping;


class ScriptItem 
  {
  public:

  // constructor
  ScriptItem (CPlugin * pPlugin,
              const string sText, 
              const string sSource) :
        pWhichPlugin  (pPlugin), 
        sScriptText   (sText), 
        sScriptSource (sSource) {};

  CPlugin * pWhichPlugin;        // which plugin
  const string sScriptText;      // the script to execute
  const string sScriptSource;    // what it is, eg. "Trigger X"
  };

typedef list<ScriptItem> ScriptItemMap;

class OneShotItem 
  {
  public:

  // constructor
  OneShotItem (CPlugin * pPlugin,
              const string sKey) :
        pWhichPlugin  (pPlugin), 
        sItemKey   (sKey) {};

  CPlugin * pWhichPlugin;     // which plugin
  const string sItemKey;      // the key to delete
  };

typedef list<OneShotItem> OneShotItemMap;

// option get/set stuff

double GetBaseOptionItem (const int iItem,
                        tConfigurationNumericOption BaseOptionsTable [],
                        const int iItemCount,
                        char * pBase);

CString GetBaseAlphaOptionItem (const int iItem,
                                tConfigurationAlphaOption BaseAlphaOptionsTable [],
                                const int iItemCount,
                                char * pBase);


long SetBaseOptionItem (const int iItem,
                        tConfigurationNumericOption BaseOptionsTable [],
                        const int iItemCount,
                        char * pBase,
                        double Value,
                        bool & bChanged);

long SetBaseAlphaOptionItem (const int iItem,
                        tConfigurationAlphaOption BaseAlphaOptionsTable [],
                        const int iItemCount,
                        char * pBase,
                        CString & strValue,
                        bool & bChanged);

long FindBaseOption (LPCTSTR OptionName, 
                    tConfigurationNumericOption BaseOptionsTable [],
                    int & iItem);

long FindBaseAlphaOption (LPCTSTR OptionName, 
                    tConfigurationAlphaOption BaseAlphaOptionsTable [],
                    int & iItem);


class CNumericConfiguration : public CObject
  {
  public:

    long iValue;    // loaded value
    bool bInclude;  // true if from include file

    void Reset (void)  { iValue = 0; bInclude = false; }
    CNumericConfiguration () { Reset (); }

  }; // end of  CConfiguration

typedef CTypedPtrArray <CPtrArray, CNumericConfiguration*> CNumericConfigurationArray;

class CAlphaConfiguration : public CObject
  {
  public:

    CString sValue;   // loaded value
    bool bInclude;    // true if from include file

    void Reset (void)  { sValue.Empty (); bInclude = false; }
    CAlphaConfiguration () { Reset (); }

  }; // end of  CAlphaConfiguration

typedef CTypedPtrArray <CPtrArray, CAlphaConfiguration*> CAlphaConfigurationArray;

#ifdef PANE
  class CPaneView;
  typedef map<string, CPaneView *> CPaneMap;
  typedef map<string, CPaneView *>::iterator PaneMapIterator;
#endif // PANE

class CMUSHclientDoc : public CDocument
{
  friend class CActivityView;
  friend class CMapDlg;
  friend class CWorldSocket;
  friend class CPluginsDlg;
  friend class CSendView;
  friend class CMUSHView;
  friend class CChatSocket;
  friend class CChatListenSocket;
  friend class CChatListDlg;
  friend class CMUSHclientApp;
  friend class CScriptEngine;
  
  protected: // create from serialization only
	CMUSHclientDoc();
	DECLARE_DYNCREATE(CMUSHclientDoc)

// Attributes
public:
	CWorldSocket* m_pSocket;

// stuff saved to disk

  CString m_server;
  CString m_mush_name;
  CString m_name;
  CString m_password;
  CString m_file_postamble;
  CString m_file_preamble ;
  CString m_line_postamble;
  CString m_line_preamble ;
  CString m_notes;
  CString m_new_activity_sound;
  CString m_strScriptEditor;
  CString m_strLogFilePreamble;
  CString m_strSpeedWalkFiller;

  unsigned short m_wrap;
  unsigned short m_port;
  unsigned short m_timestamps;
  unsigned short m_connect_now;
  unsigned short m_match_width;
  unsigned short m_enable_aliases;
  unsigned short m_enable_triggers;
  unsigned short m_bEnableTimers;
  

  unsigned short m_display_my_input;    
  unsigned short m_echo_colour;
  unsigned short m_enable_beeps;
  unsigned short m_enable_trigger_sounds;
  unsigned short m_indent_paras;
  unsigned short m_bSaveWorldAutomatically;
  unsigned short m_bLineInformation;
  unsigned short m_bStartPaused;


  LONG    m_font_height;               
  CString m_font_name;   
  LONG    m_font_weight;                
  DWORD   m_font_charset;

  // normal (ANSI) colours
  COLORREF m_normalcolour [8];
  COLORREF m_boldcolour [8];

  // custom (user-defined) colours for triggers etc.
  COLORREF m_customtext [MAX_CUSTOM];
  COLORREF m_customback [MAX_CUSTOM];

//  unsigned short m_log_input;
//  unsigned short m_bLogNotes;
  unsigned short m_bEscapeDeletesInput;
  unsigned short m_bArrowsChangeHistory;
  unsigned short m_bConfirmOnPaste;

  unsigned short m_version;

  CString m_macros [MACRO_COUNT];                // for function keys
  unsigned short m_macro_type [MACRO_COUNT];     // see macro send types above
  CString m_macro_name [MACRO_COUNT];

// numeric keypad stuff
            
  CString m_keypad [eKeypad_Max_Items];  // 30 at present

  unsigned short m_keypad_enable;

// other interesting things

  unsigned short m_enable_speed_walk;
  CString m_speed_walk_prefix;

  unsigned short m_enable_command_stack;
//  unsigned char m_command_stack_character;
  CString m_strCommandStackCharacter;

  CString m_connect_text;

  CAliasMap m_AliasMap;
  CAliasArray m_AliasArray;   // array of aliases for sequencing
  CTriggerMap m_TriggerMap;
  CTriggerArray m_TriggerArray;   // array of triggers for sequencing
  CTimerMap m_TimerMap;

// new in version 7

  COLORREF m_input_text_colour;
  COLORREF m_input_background_colour;

  LONG    m_input_font_height;               
  CString m_input_font_name;   
  BYTE    m_input_font_italic;            
  LONG    m_input_font_weight;                
  DWORD   m_input_font_charset;

// new in version 8

  LONG    m_maxlines;   // maximum lines in scrollback buffer
  LONG    m_nHistoryLines;  // maximum lines in command history
  unsigned short  m_nWrapColumn;    // column to wrap at

  CString m_paste_postamble;
  CString m_paste_preamble ;
  CString m_pasteline_postamble;
  CString m_pasteline_preamble ;

	CString	m_strLanguage;              // script language
	unsigned short  m_bEnableScripts;   // enable scripting
	COLORREF m_iHyperlinkColour;        // colour for hyperlinks
	CString	m_strWorldOpen;             // handler on world open
	CString	m_strWorldClose;            // handler on world close
	CString	m_strWorldSave;             // handler on world save
	CString	m_strWorldConnect;          // handler on world connect
	CString	m_strWorldDisconnect;       // handler on world disconnect
	CString	m_strScriptFilename;        // script filename
  CString m_strScriptPrefix;          // prefix to invoke scripts from the command window


  unsigned short m_iNoteTextColour;         // colour for note 
  unsigned short m_bKeepCommandsOnSameLine; // commands stay on same line as prompt from MUD

  CVariableMap m_VariableMap;        // program variables (map)

  CString         m_strAutoSayString;
  unsigned short  m_bEnableAutoSay;
  unsigned short  m_bExcludeMacros;
  unsigned short  m_bExcludeNonAlpha;
  CString         m_strOverridePrefix;     
  unsigned short  m_bConfirmBeforeReplacingTyping;
  unsigned short  m_bReEvaluateAutoSay; // send auto-say through command interpreter

  int m_nNormalPrintStyle [8];        // when printing, whether to use bold, underline etc.
  int m_nBoldPrintStyle [8];          // when printing, whether to use bold, underline etc.

  
// new in version 9

	unsigned short  m_bShowBold;   // show bold, italic, underline in fonts
	unsigned short  m_bAltArrowRecallsPartial;     // alt+up arrow recalls partially entered command
  unsigned short  m_iPixelOffset;     // pixel offset of text from side of window
  unsigned short  m_bAutoFreeze;    // freeze if not at bottom of buffer  
  unsigned short  m_bAutoRepeat;    // auto repeat last command 
  unsigned short  m_bDisableCompression;      // don't allow compressed worlds
  unsigned short  m_bLowerCaseTabCompletion;  // tab complete words in lower case    
  unsigned short  m_bDoubleClickInserts;      // double-click inserts word into command buffer
  unsigned short  m_bConfirmOnSend;        // confirm preamble, postamble on file send
  unsigned short  m_bTranslateGerman;        // translate German character sequences


// new in version 10

  CString m_strTabCompletionDefaults;          // initial words to check for tab completion
  unsigned int m_iTabCompletionLines;          // lines to search
  unsigned short m_bTabCompletionSpace;        // insert space after word?
  CString m_strAutoLogFileName;          // name of file to log to
  CString m_strLogLinePreambleOutput;          // put at start of each log line - output
  CString m_strLogLinePreambleInput;          // put at start of each log line - input
  CString m_strLogLinePreambleNotes;          // put at start of each log line - world.note
  CString m_strWorldGetFocus;          // script called when the world gets the focus
  CString m_strWorldLoseFocus;         // script called when the world loses the focus
  CString m_strLogFilePostamble;          // written when log file closed
  CString m_strRecallLinePreamble;       // line preamble for recall window

  unsigned short  m_bPasteCommentedSoftcode;   // are we pasting commented softcode?
  unsigned short  m_bFileCommentedSoftcode;    // are we sending commented softcode?
  unsigned short  m_bShowItalic;     // italic text to be shown in italic?
  unsigned short  m_bShowUnderline;     // underlined text to be underlined?
  unsigned short  m_bFlashIcon;     // flash icon on taskbar for new activity?
  unsigned short  m_bArrowKeysWrap;     // arrow keys wrap command history?
  unsigned short  m_bSpellCheckOnSend;        // spell check when you send something

  LONG  m_nPasteDelay;           // delay in milliseconds before pasting each line
  LONG  m_nFileDelay;            // delay in milliseconds before sending each line
  LONG  m_nReloadOption;      // option for reloading changed script file
  LONG  m_bUseDefaultOutputFont;            // Default output font overrides
  LONG  m_bSaveDeletedCommand;            // save deleted command in command history on <esc>
  LONG  m_bTranslateBackslashSequences;            // interpret \n \r etc. on a send
  LONG  m_bEditScriptWithNotepad;            // use inbuilt notepad for editing scripts
  LONG  m_bWarnIfScriptingInactive;       // warn if we can't invoke a script
  LONG  m_nPasteDelayPerLines;            // how many lines to send before the delay
  LONG  m_nFileDelayPerLines;            // how many lines to send before the delay

  // new in version 11

	unsigned short m_bDoubleClickSends;   // double-click sends to MUD
	unsigned short m_bWriteWorldNameToLog;    // write world name to log file
	unsigned short m_bSendEcho;
	unsigned short m_bPasteEcho;
	unsigned short m_bUseDefaultColours;
	unsigned short m_bUseDefaultTriggers;
	unsigned short m_bUseDefaultAliases;
	unsigned short m_bUseDefaultMacros;
	unsigned short m_bUseDefaultTimers;
	unsigned short m_bUseDefaultInputFont;

  CString m_strCustomColourName [255];    // custom colour names
  CString m_strTerminalIdentification;    // for telnet negotiation, defaults to ANSI

  // new in version 14

  CString m_strLogLinePostambleOutput;      // put at end of each log line - output
  CString m_strLogLinePostambleInput;       // put at end of each log line - input
  CString m_strLogLinePostambleNotes;       // put at end of each log line - world.note
  CString m_strMappingFailure;              // message for mapping failure

// callback routines for MXP
  CString m_strOnMXP_Start;                 // MXP starting up
  CString m_strOnMXP_Stop;                  // MXP closing down
  CString m_strOnMXP_Error;                 // MXP error
  CString m_strOnMXP_OpenTag;               // MXP tag open
  CString m_strOnMXP_CloseTag;              // MXP tag close
  CString m_strOnMXP_SetVariable;           // MXP variable set

  CString m_strBeepSound;                   // sound to play for beeps

	unsigned short m_bLogHTML;    // convert special HTML sequences (eg. < and > )
	unsigned short m_bUnpauseOnSend;    // cancel pause on next send to MUD
	unsigned short m_iSpeedWalkDelay;    // delay in ms for speed walking
	unsigned short m_bMapFailureRegexp;    // for expansion
	unsigned short m_iFlags1;       // various flags, see below
	unsigned short m_iFlags2;       // more flags
	unsigned short m_iUseMXP;       // whether to use MXP - see enum above
	unsigned short m_iMXPdebugLevel;     // level of MXP debugging


  CString m_strWorldID;           // unique ID for this world

  // new in version 15 

  unsigned short m_bAlwaysRecordCommandHistory; // record command history even if echo off
  unsigned short m_bCopySelectionToClipboard;   // automatically copy selection
  unsigned short m_bCarriageReturnClearsLine;   // \r character empties current line
  unsigned short m_bSendMXP_AFK_Response;       // reply to <afk> query?
  unsigned short m_bMudCanChangeOptions;        // server may recommend options
//  unsigned short m_bShowGridLinesInListViews;   // list views show grid
  unsigned short m_bEnableSpamPrevention;       // send spam filler every x lines
  unsigned short m_iSpamLineCount;              // send spam filler after this many lines the same
  CString        m_strSpamMessage;              // what spam filler to send

  unsigned short m_bDoNotShowOutstandingLines;  // don't show outstanding lines in tabbed windows
  unsigned short m_bDoNotTranslateIACtoIACIAC;  // don't translate outgoing IAC to IAC/IAC

  // new in 3.36

  CString m_strProxyServerName;     // name/IP address of proxy server
  unsigned short m_iProxyServerPort;  // proxy server port
  unsigned short m_iSocksProcessing;  // 0 = none, 1 = Socks 4, 2 = Socks 5
  CString m_strProxyUserName;     // user name for proxy authentication
  CString m_strProxyPassword;     // password for proxy authentication

  // more new stuff

  unsigned short m_bAutoCopyInHTML;     // auto-copy to clipboard in HTML
  unsigned short m_iLineSpacing;        // line spacing, 0 to use font height
  unsigned short m_bUTF_8;              // want UTF-8 support
  unsigned short m_bConvertGAtoNewline; // convert IAC/GA or IAC/EOR to a newline
  unsigned short m_iCurrentActionSource;// what caused the current script to run

  CString m_strTriggersFilter;          // Lua code to filter triggers
  CString m_strAliasesFilter;           // Lua code to filter aliases
  CString m_strTimersFilter;            // Lua code to filter timers
  CString m_strVariablesFilter;         // Lua code to filter variables


  unsigned short m_bScriptErrorsToOutputWindow;     // write script errors in window

  unsigned short m_bAutoResizeCommandWindow;   // change command window height automatically
  CString m_strEditorWindowName;               // What window to bring to the front after editing a text file
  unsigned short m_iAutoResizeMinimumLines;    // command window minimum number of lines
  unsigned short m_iAutoResizeMaximumLines;    // command window maximum number of lines
  unsigned short m_bDoNotAddMacrosToCommandHistory;    // macros not into command history

  // end of stuff saved to disk **************************************************************

  // stuff from pre version 11, read from disk but not saved

  unsigned short m_page_colour;
  unsigned short m_whisper_colour;
  unsigned short m_mail_colour;
  unsigned short m_game_colour;
  unsigned short m_chat_colour;         

  unsigned short m_remove_channels1;
  unsigned short m_remove_channels2;
  unsigned short m_remove_pages;
  unsigned short m_remove_whispers;
  unsigned short m_remove_set;
  unsigned short m_remove_mail;
  unsigned short m_remove_game;

  // end of pre version 11 stuff


  // from m_iFlags1;

  BOOL m_bArrowRecallsPartial;    // arrow key (without ALT) recalls partial command
  BOOL m_bCtrlZGoesToEndOfBuffer;       // Ctrl+Z goes to end of output buffer
  BOOL m_bCtrlPGoesToPreviousCommand;   // Ctrl+P gets previous command
  BOOL m_bCtrlNGoesToNextCommand;       // Ctrl+N gets next command
  BOOL m_bHyperlinkAddsToCommandHistory;  // MXP hyperlink goes into history
  BOOL m_bEchoHyperlinkInOutputWindow;    // MXP hyperlink is echoed
  BOOL m_bAutoWrapWindowWidth;          // auto wrap to current window width
  BOOL m_bNAWS;                         // Negotiate About Window Size
  BOOL m_bPueblo;                       // Allow Pueblo worlds
  BOOL m_bNoEchoOff;                    // ignore attempts to stop command echoing
  BOOL m_bUseCustomLinkColour       ;    // use our custom link colour
  BOOL m_bMudCanChangeLinkColour    ;    // however MUD can override it
  BOOL m_bUnderlineHyperlinks       ;    // underline our hyperlinks
  BOOL m_bMudCanRemoveUnderline     ;    // however MUD can remove the underline


  // end of m_iFlags1


  // from m_iFlags2;

  BOOL m_bAlternativeInverse;     // alternative way of displaying bold inverse
  BOOL m_bShowConnectDisconnect;  // show message in output window on connect/disconnect
  BOOL m_bIgnoreMXPcolourChanges; // don't let MXP/Pueblo change output colours
  BOOL m_bCustom16isDefaultColour;  // user custom colour 16 after ANSI reset
  BOOL m_bLogInColour;            // HTML logging is in colour
  BOOL m_bLogRaw;                 // write raw input from mud to log file

  // end of m_iFlags2

  BOOL m_bNAWS_wanted;     // server wants NAWS messages
  BOOL m_bCHARSET_wanted;  // server wants CHARSET messages
  bool m_bLoaded;          // true if we have loaded from disk
  bool m_bSelected;        // true if selected in Send To All Worlds
  bool m_bVariablesChanged; // true if variables have changed

  bool m_bNoEcho; // set if we get IAC WILL ECHO
                  // cleared if we get IAC WONT ECHO
  bool m_bDebugIncomingPackets;   // set if we want to display all incoming text

  __int64 m_iInputPacketCount;   // count of packets received
  __int64 m_iOutputPacketCount;   // count of packets sent
  long m_iUTF8ErrorCount;      // count of lines with bad UTF8

  long m_iTriggersEvaluatedCount;    // how many triggers we evaluated
  long m_iTriggersMatchedCount;      // how many triggers matched
  long m_iAliasesEvaluatedCount;     // how many aliases we evaluated 
  long m_iAliasesMatchedCount;       // how many aliases matched      
  long m_iTimersFiredCount;          // how many timers fired

  int m_last_prefs_page;
  unsigned short m_bConfigEnableTimers;   // used when doing world config

  CSendView * m_pActiveCommandView;
  CMUSHView * m_pActiveOutputView;

// list of output buffer lines

  CLineList m_LineList;

  CLine * m_pCurrentLine;   // the line we are currently receiving

  CString m_strCurrentLine;   // line currently received from MUD (excluding control codes)

// list of actions for style runs

  CActionList m_ActionList;

// we will record the position of each JUMP_SIZE lines, to speed up lookups

  POSITION * m_pLinePositions;  // array of line positions

  long m_total_lines;
  long m_new_lines;   // lines they haven't read yet (if not active view)
  long m_nTotalLinesSent;   // lines sent this connection
  
  CTime m_tConnectTime;       // time we connected to the world
  CTime m_tLastPlayerInput;   // time the player last typed something (for <afk> )
  CTimeSpan m_tsConnectDuration;  // timespan we have been connected

  CTime m_tStatusTime;    // time of line that mouse was over

  int m_view_number;  // sequence in activity view

  int m_phase;        // telnet negotiation phase
  int m_subnegotiation_type;    // what type of subnegotiation to turn on/off

  char m_charset_delimiter;  // what character set delimiter for telnet CHARSET negotiation
  CString m_charset_name;    // requested character set name

  // MCCP (MUD Client Compression Protocol) stuff
  z_stream m_zCompress;         // compression structure
  bool m_bCompress;             // true if decompressing
  bool m_bCompressInitOK;       // true if OK to decompress
  Bytef * m_CompressInput;        // input buffer for decompresion
  Bytef * m_CompressOutput;       // output buffer for decompresion
  __int64 m_nTotalUncompressed;
  __int64 m_nTotalCompressed;
  LONGLONG m_iCompressionTimeTaken;   // time taken to decompress


  int m_iMCCP_type;   // MCCP protocol type in use: 0 = none, 1 = v1, 2 = v2
  bool m_bSupports_MCCP_2;    // if true we have agreed to support MCCP v 2

  // end MCCP stuff

  // MSP (MUD Sound Protocol) stuff
  bool m_bMSP;  // true if using MSP

  // end MSP stuff

  // MXP (MUD Extension Protocol) stuff

  bool m_bMXP;       // true if using MXP at present
  bool m_bPuebloActive;    // Pueblo mode :)
  CString  m_iPuebloLevel;    // ie. 1.0, 1.10
  bool m_bPreMode;    // <PRE> tag active
  int m_iMXP_mode;   // current tag security (eg. eMXP_open)
  int m_iMXP_defaultMode; // default tag mode (after newline)
  int m_iMXP_previousMode; // previous mode before mode 4 (secure-once mode)
  bool m_bInParagraph; // discard newlines (wrap)
  bool m_bMXP_script;   // in script collection mode
  bool m_bSuppressNewline;        // newline does NOT start a new line

  // NB - lists are being done in a hurry - I should really allow for nesting them
  int m_iListMode;      // see enum above - what sort of list we are displaying
  int m_iListCount;     // for ordered list - how far we are through

  CString m_strMXPstring;         // string we are currently collecting, eg. <bol...
  CString m_strMXPtagcontents;    // stuff *inside* a tag, for use with &text;
  char    m_cMXPquoteTerminator;  // ' or "

  // These two are defined with !ELEMENT and !ENTITY
  CElementMap         m_CustomElementMap;   // Custom MXP elements 
  CMapStringToString  m_CustomEntityMap;    // Custom MXP entities

  CActiveTagList  m_ActiveTagList;  // MXP elements currently active (eg. <bold> )

  char m_cLastChar;   // last incoming character (for <p> stuff)

  CString m_strLastDebugWorldInput;

  int m_iLastOutstandingTagCount;

  CString m_strPuebloMD5; // Pueblo hash string

  // MXP stats

  __int64 m_iMXPerrors;
  __int64 m_iMXPtags;
  __int64 m_iMXPentities;

  // end MXP stuff

  int m_code;             // current ANSI code (colour, hilite etc.)

  int m_lastGoTo;         // last line we went to

  bool  m_bWorldClosing;    // true if world is closing

// we save the current style here on any style change *from the mud*
// we don't want to mix up notes/user input with mud-set styles

  // these values are set by RememberStyle

  // current style
  unsigned short m_iFlags;      // see define in othertypes.h
  COLORREF       m_iForeColour; // RGB foreground colour, or ANSI/custom colour number
  COLORREF       m_iBackColour; // RGB background colour, or ANSI/custom colour number

  bool      m_bNotesInRGB;         // are notes in RGB mode?  (ie. world.note, world.tell)
  COLORREF  m_iNoteColourFore;     // RGB notes text colour
  COLORREF  m_iNoteColourBack;     // RGB notes background colour
  unsigned short  m_iNoteStyle;    // notes style: HILITE, UNDERLINE, BLINK, INVERSE       

  FILE * m_logfile;
  CString m_logfile_name;
  CTime m_LastFlushTime;

  CFont * m_font [8];     // 8 fonts - normal, bold, italic, bold-normal etc.
  int m_FontHeight,
      m_FontWidth; 

  CFont * m_input_font;
  int m_InputFontHeight,
      m_InputFontWidth; 

  __int64 m_nBytesIn;
  __int64 m_nBytesOut;

// telnet negotiation stuff

  bool m_bSent_WILL_SGA;
  bool m_bSent_WILL_TELOPT_TERMINAL_TYPE;
  bool m_bSent_WILL_TELOPT_ECHO;

// sockets stuff

	SOCKADDR_IN m_sockAddr;       // MUD address/port
	SOCKADDR_IN m_ProxyAddr;      // Proxy address/port

  HANDLE      m_hNameLookup;
  char *      m_pGetHostStruct;
  int         m_iConnectPhase;    // see enum above


// chatting

  CChatSocketList m_ChatList;           // list of chat calls
  CString         m_strOurChatName;     // who we are on chat lists
  unsigned  short m_IncomingChatPort;   // default 4050
  unsigned  short m_bAcceptIncomingChatConnections;   // do we listen for incoming chats?
  unsigned  short m_bIgnoreChatColours;   // throw away incoming ANSI colours
  unsigned  short m_bValidateIncomingCalls; // ask before accepting chat connections
  unsigned  short m_bAutoAllowSnooping;   // once snooping is permitted don't ask again
  unsigned  short m_bAutoAllowFiles;      // don't query if we can send a particular file
//  unsigned  short m_bChatSumchecksToSender;  // tell sender sumchecks too
  COLORREF        m_cChatForegroundColour;  // default colour for chats
  COLORREF        m_cChatBackgroundColour;  //  - background for above
  CChatListenSocket * m_pChatListenSocket;  // for listening for chat connections
  long            m_iNextChatID;            // next available chat session ID
  CString         m_strLastMessageSent;   // the last message we sent to everybody
  CTime           m_tLastMessageTime;     // time we sent it
  CString         m_strLastGroupMessageSent;   // the last message we sent to a group
  CTime           m_tLastGroupMessageTime;     // time we sent it
  CString         m_strChatMessagePrefix;   // <CHAT> or whatever
  CString         m_strChatSaveDirectory;     // where to save files
  long            m_iMaxChatLinesPerMessage;   // max lines per chat message
  long            m_iMaxChatBytesPerMessage;   // max bytes per chat message


  unsigned short  m_iLastOutgoingChatPort;
  CString         m_strLastOutgoingChatAddress;

  set<string>     m_ExtraShiftTabCompleteItems;  // for Shift+Tab completion
  bool            m_bTabCompleteFunctions;

// scripting

  CScriptEngine * m_ScriptEngine;

  bool m_bSyntaxErrorOnly;
  bool m_bDisconnectOK;
  bool m_bTrace;
  bool m_bInSendToScript;
  LONGLONG m_iScriptTimeTaken;        // time taken to execute scripts

  CString m_strLastImmediateExpression;

	HANDLE	m_pThread;			// Notification thread
	CEvent  m_eventScriptFileChanged;		// script file changed thread event
  bool m_bInScriptFileChanged;
  CTime m_timeScriptFileMod;

  CString m_strStatusMessage;   // "ready" or user-supplied message
  CTime m_tStatusDisplayed; // when we last displayed the status line

  CString m_strScript;    // script as read from file

  // Lua note - for Lua the DISPID is a flag indicating whether or not
  // the routine exists. It is set to DISPID_UNKNOWN if the last call caused an error
  // For Lua, it will be 1 for "routine exists" and DISPID_UNKNOWN if not.

	DISPID	m_dispidWorldOpen;             // handler on world open
	DISPID	m_dispidWorldClose;            // handler on world close
	DISPID	m_dispidWorldSave;             // handler on world save
	DISPID	m_dispidWorldConnect;          // handler on world connect
	DISPID	m_dispidWorldDisconnect;       // handler on world disconnect
	DISPID	m_dispidWorldGetFocus;         // handler on world getting focus
	DISPID	m_dispidWorldLoseFocus;        // handler on world losing focus
	DISPID	m_dispidOnMXP_Start;           // handler on MXP startup
	DISPID	m_dispidOnMXP_Stop;            // handler on MXP shutdown
	DISPID	m_dispidOnMXP_OpenTag;         // handler on MXP opening tag, eg. <send>           
  DISPID	m_dispidOnMXP_CloseTag;        // handler on MXP closing tag, eg. </send>
	DISPID	m_dispidOnMXP_SetVariable;     // handler on MXP set variable, eg. set hp
	DISPID	m_dispidOnMXP_Error;           // handler on MXP error (parse etc.)

  bool    m_bPluginProcessesOpenTag;     // does a plugin handle the open tag?
  bool    m_bPluginProcessesCloseTag;    // does a plugin handle the close tag?
  bool    m_bPluginProcessesSetVariable; // does a plugin handle set variable?
  bool    m_bPluginProcessesSetEntity;   // does a plugin handle set entity?
  bool    m_bPluginProcessesError;       // does a plugin handle the error?

  // listening for UDP packets

  map<int, UDPsocket *> m_UDPsocketMap;

// stuff for finding in the output buffer

  CFindInfo m_DisplayFindInfo;

// other find info stuff

  CFindInfo m_RecallFindInfo;
  CFindInfo m_TriggersFindInfo;
  CFindInfo m_AliasesFindInfo;
  CFindInfo m_MacrosFindInfo;
  CFindInfo m_TimersFindInfo;
  CFindInfo m_VariablesFindInfo;
  CFindInfo m_NotesFindInfo;

  // flags for recall window
  bool m_bRecallCommands;
  bool m_bRecallOutput;
  bool m_bRecallNotes; 

  __int64 m_iUniqueDocumentNumber;

  CStringList m_strMapList;
  t_regexp * m_MapFailureRegexp;
  CString m_strSpecialForwards;
  CString m_strSpecialBackwards;

  CTimerWnd * m_pTimerWnd;    // for speed walk delays
	CStringList m_QueuedCommandsList;  // queue of delayed commands (for speed walking)
  bool m_bShowingMapperStatus;  // if set, don't change status line for 5 seconds
  CStringList m_strIncludeFileList;         // list of root level include files
  CStringList m_strCurrentIncludeFileList;  // list of current tree of include files

  CNumericConfigurationArray m_NumericConfiguration;
  CAlphaConfigurationArray m_AlphaConfiguration;

  CPluginList m_PluginList;     // plugins
  CPlugin *   m_CurrentPlugin;  // plugin currently active, NULL if none
  bool        m_bPluginProcessingCommand; // plugin is doing ON_PLUGIN_COMMAND
  bool        m_bPluginProcessingSend; // plugin is doing ON_PLUGIN_SEND
  bool        m_bPluginProcessingSent; // plugin is doing ON_PLUGIN_SENT

  CString     m_strLastCommandSent;   // for spam prevention
  int         m_iLastCommandCount;    // number of times last command sent
  int         m_iExecutionDepth;      // count of nested calls to world.Execute
  bool        m_bOmitFromCommandHistory;  // alias wants to omit from command history?

  tStringMapOfMaps m_Arrays;    // map of arrays (for scripting)

  deque<string> m_sRecentLines; // for multi-line triggers

  /*
  // background image
  CPalette m_pal;
  CBitmap m_bitmap;

  */

  // for DirectSound
  LPDIRECTSOUNDBUFFER m_pDirectSoundSecondaryBuffer [MAX_SOUND_BUFFERS];


  WORD m_nextAcceleratorCommand;  // next free command
  map<long, WORD> m_AcceleratorToCommandMap;  // command to send for accelerator
  map<WORD, string> m_CommandToMacroMap;      // what that command does
  map<WORD, short> m_CommandToSendToMap;      // where it goes (eg. 0 = world, 1 = command etc.)
  HACCEL m_accelerator;

  // for mapping colours to colours
  map<COLORREF, COLORREF> m_ColourTranslationMap;

#ifdef PANE
  // for pane windows

  CPaneMap m_PaneMap;
#endif // PANE

  protected:

// Operations
public:
	BOOL ConnectSocket(void);
	void ProcessPendingRead();
	void DoSendMsg(const CString& strText, 
                 const bool bEchoIt,
                 const bool bLogIt);
	void SendMsg(CString strText, 
               const bool bEchoIt,
               const bool bQueueIt,
               const bool bLogIt);
	void ReceiveMsg();
	void DisplayMsg(LPCTSTR lpszText, int size, const int flags);
  void AddToLine (LPCTSTR lpszText, const int flags);
  void StartNewLine_KeepPreviousStyle (const int flags);
  void Phase_ESC (const unsigned char c);            
  void Phase_ANSI (const unsigned char c);           
  void Phase_IAC (unsigned char & c);            
  void Phase_WILL (const unsigned char c);           
  void Phase_WONT (const unsigned char c);           
  void Phase_DO (const unsigned char c);             
  void Phase_DONT (const unsigned char c);           
  void Phase_SUBNEGOTIATION (const unsigned char c); 
  int Phase_COMPRESSION (const unsigned char c, CString & strMessage);    
  void Phase_MXP (const unsigned char c);    
  void Phase_CHARSET_REQUEST (const unsigned char c);    
  void Phase_CHARSET (const unsigned char c);    

  // mxp collection phases
  void Phase_MXP_ELEMENT (const unsigned char c);            
  void Phase_MXP_COMMENT (const unsigned char c);            
  void Phase_MXP_QUOTE (const unsigned char c);           
  void Phase_MXP_ENTITY (const unsigned char c);            
  void Phase_MXP_COLLECT_SPECIAL (const unsigned char c);           

  // other MXP processing

  void MXP_unterminated_element (const char * pReason);
  void MXP_mode_change (int iNewMode);
  void MXP_collected_element (void);
  void MXP_collected_entity (void);
  void MXP_error (const int iLevel, const long iMessageNumber, CString strMessage);
  void MXP_Definition (CString strTag);
  void MXP_Element (CString strName, CString strTag);
  void MXP_Entity  (CString strName, CString strTag);
  void MXP_Attlist (CString strName, CString strTag);
  void MXP_StartTag (CString strTag);
  void MXP_EndTag (CString strTag);
  void MXP_CloseTag (CString strTag, const bool bOpen = false);
  void MXP_CloseOpenTags (void);
  void MXP_CloseAllTags (void);
  void MXP_On (const bool bPueblo = false, const bool bManual = false);     // turning MXP/Pueblo on
  void MXP_Off (const bool bCompletely = false);  // turning MXP off
  void MXP_OpenAtomicTag (const CString strTag,   // name
                          int iAction,            // action code
                          CStyle * pStyle,        // style it should modify
                          CString & strAction,    // new action
                          CString & strHint,      // new hint
                          CString & strVariable,  // new variable
                          CArgumentList & ArgumentList);  // args
  void MXP_CloseAtomicTag (const int iAction, 
                           const CString & strText,
                           const POSITION firstlinepos,
                           const POSITION firststylepos);
  CString MXP_GetEntity (CString & strName);
  bool BuildArgumentList (CArgumentList & ArgumentList, 
                          CString strTag);

  void CheckArgumentsUsed (const CString strTag, CArgumentList & ArgumentList);
  bool MXP_StartTagScript (const CString & strName, 
                           const CString & strArguments,
                           CArgumentList & ArgumentList);

  void AddToCommandHistory (LPCTSTR Message);

  // simple test to see if we are in secure mode right now
  inline bool MXP_Secure (void)
    { 
    return m_iMXP_mode == eMXP_secure ||
           m_iMXP_mode == eMXP_secure_once ||
           m_iMXP_mode == eMXP_perm_secure;
    }

  // simple test to see if we are in open mode right now
  inline bool MXP_Open (void)
    { 
    return m_iMXP_mode == eMXP_open ||
           m_iMXP_mode == eMXP_perm_open;
    }
  
  // cancels secure-once mode
  inline void MXP_Restore_Mode (void)
    {
    if (m_iMXP_mode == eMXP_secure_once)
      m_iMXP_mode = m_iMXP_previousMode; 
    }

  void Debug_MUD (const char * sCaption, const char * sData);
  void Debug_Packets (LPCTSTR sCaption, LPCTSTR lpszText, int size, const __int64 iNumber);
  void SendPacket (const char * lpBuf, const int nBufLen);   // low-level send
  void SendPacket (const unsigned char * lpBuf, const int nBufLen);   // low-level send

  // finds an action, adding it if necessary
  CAction * GetAction (const CString & strAction,
                       const CString & strHint,
                       const CString & strVariable);

  bool CheckConnected (void);
  bool FindStyle (const CLine * pLine,         // which line
                  const int iWantedCol,  // which column we want
                  int & iCol,            // which column style goes up to
                  CStyle * & pStyle,     // return style pointer
                  POSITION & foundpos) const;  // and its position

  void GetStyleRGB (CStyle * pStyle, COLORREF & colour1, COLORREF & colour2) const;

  CStyle * AddStyle (const unsigned short iFlags,
                     const COLORREF       iForeColour,
                     const COLORREF       iBackColour,
                     const int            iLength = 0,
                     CString              strAction = "",
                     CString              strHint = "",
                     CString              strVariable = "",
                     CLine *              pLine = NULL);

  CStyle * AddStyle (const unsigned short iFlags,
                     const COLORREF       iForeColour,
                     const COLORREF       iBackColour,
                     const int            iLength = 0,
                     CAction *            pAction = NULL,
                     CLine *              pLine = NULL);

  void RememberStyle (const CStyle * pStyle); 

  void StartNewLine (const bool hard_break, const int flags);
  bool ProcessPreviousLine (void);
  void SendLineToPlugin (void);
  void SetNewLineColour (const int flags);

  void ProcessOneTriggerSequence (CString & strCurrentLine,
//                            CPaneLine & StyledLine,
                            CString & strResponse,
                            const POSITION prevpos,
                            bool & bNoLog,
                            bool & bNoOutput,
                            bool & bChangedColour,
                            CTriggerList & triggerList,
                            CString & strExtraOutput,
                            ScriptItemMap & mapDeferredScripts,
                            OneShotItemMap & mapOneShotItems);

  bool ProcessOneAliasSequence (const CString strCurrentLine,
                            const bool bCountThem,
                            bool & bOmitFromLog,
                            bool & bEchoAlias,
                            CAliasList & AliasList,
                            OneShotItemMap & mapOneShotItems);

  void WriteToLog (const char * text, size_t len);
  void WriteToLog (const CString & strText);
  void LogLineInHTMLcolour (POSITION startpos);
  void LogCommand (const char * text);

  BOOL OpenSession (void);
  void SetUpOutputWindow (void);

  bool m_bInPlaySoundFilePlugin;
  bool m_bInCancelSoundFilePlugin;
  bool PlaySoundFile (CString strSound);
  void CancelSound (void);

  CChildFrame * GetChildFrame (void);

  void ChangeFont ( const int nHeight, 
                    const char * lpszFacename,
                    const int nWeight, 
                    const DWORD iFontCharset,
                    const BOOL bShowBold,
                    const BOOL bShowItalic,
                    const BOOL bShowUnderline,
                    const unsigned short iLineSpacing);
  void ChangeInputFont ( const int nHeight, 
                         const char * lpszFacename,
                         const int nWeight, 
                         const DWORD iCharset,
                         const BYTE bItalic);

  void setupstrings (void);

  void Serialize_World_XML (CArchive& ar);

// bits for world saving mask
#define XML_GENERAL    0x0001
#define XML_TRIGGERS   0x0002
#define XML_ALIASES    0x0004
#define XML_TIMERS     0x0008
#define XML_MACROS     0x0010
#define XML_VARIABLES  0x0020
#define XML_COLOURS    0x0040
#define XML_KEYPAD     0x0080
#define XML_PRINTING   0x0100
#define XML_INCLUDES   0x0200
#define XML_PLUGINS    0x0400
#define XML_NO_PLUGINS 0x0800
#define XML_OVERWRITE  0x1000

  // XML saving
  void Save_World_XML (CArchive& ar, 
                       const unsigned long iMask,
                       CString strComment = "");

  void Save_Header_XML (CArchive& ar, const char * sName, const bool bShowVersion = true);
  void Save_Footer_XML (CArchive& ar, const char * sName);
  void Save_General_XML (CArchive& ar);
  void Save_Triggers_XML (CArchive& ar);
  void Save_One_Trigger_XML (CArchive& ar, CTrigger * t);
  void Save_Aliases_XML (CArchive& ar);
  void Save_One_Alias_XML (CArchive& ar, CAlias * a);
  void Save_Variables_XML (CArchive& ar);
  void Save_One_Variable_XML (CArchive& ar, CVariable * v);
  void Save_Timers_XML (CArchive& ar);
  void Save_One_Timer_XML (CArchive& ar, CTimer * t);
  void Save_Macros_XML (CArchive& ar);
  void Save_One_Macro_XML (CArchive& ar, const int iIndex);
  void Save_Colours_XML (CArchive& ar);
  void Save_Keypad_XML (CArchive& ar);
  void Save_One_Keypad_XML (CArchive& ar, const int iIndex);
  void Save_Printing_XML (CArchive& ar);
  void Save_Version_And_Date_XML (CArchive& ar);
  void Save_Includes_XML (CArchive& ar);
  void Save_Plugins_XML (CArchive& ar);
  void Save_World_Numeric_Options_XML (CArchive& ar);
  void Save_World_Single_Line_Alpha_Options_XML (CArchive& ar);
  void Save_World_Multi_Line_Alpha_Options_XML (CArchive& ar);

#define LOAD_INCLUDE        0x01    // loading an include file
#define LOAD_OVERWRITE      0x02    // overwrites existing values (triggers, etc.)
#define LOAD_KEEP           0x04    // use include file in preference to non-include
#define LOAD_WARN           0x08    // warn if clash

  // XML loading
  UINT Load_World_XML (CArchive& ar, 
                       const unsigned long iMask,
                       const unsigned long iFlags = 0,
                        UINT * piTriggers = NULL,
                        UINT * piAliases = NULL,
                        UINT * piTimers = NULL,
                        UINT * piMacros = NULL,
                        UINT * piVariables = NULL,
                        UINT * piColours = NULL,
                        UINT * piKeypad = NULL,
                        UINT * piPrinting = NULL);

  void LoadError (const char * sType, const char * sMessage, UINT iLine = 0);
  void CheckUsed (CXMLelement & node);
  void HandleLoadException (const char * sComment, CException* e);

  void Load_Includes_XML (CXMLelement & parent,
                      const unsigned long iMask,
                      const unsigned long iFlags,
                      const bool bPlugins,  // only if plugin="y"
                      UINT * piTriggers,
                      UINT * piAliases,
                      UINT * piTimers,
                      UINT * piMacros,
                      UINT * piVariables,
                      UINT * piColours,
                      UINT * piKeypad,
                      UINT * piPrinting);
  void Load_One_Include_XML (CXMLelement & node,
                      const unsigned long iMask,
                      const unsigned long iFlags,
                      const bool bPlugins,  // only if plugin="y"
                      UINT * piTriggers,
                      UINT * piAliases,
                      UINT * piTimers,
                      UINT * piMacros,
                      UINT * piVariables,
                      UINT * piColours,
                      UINT * piKeypad,
                      UINT * piPrinting);

  void Load_General_XML (CXMLelement & parent, 
    const unsigned long iFlags);
  UINT Load_Triggers_XML (CXMLelement & parent, 
    const unsigned long iMask,
    const unsigned long iFlags);
  void Load_One_Trigger_XML (CXMLelement & node, 
    const unsigned long iMask,
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Aliases_XML (CXMLelement & parent, 
    const unsigned long iMask,
    const unsigned long iFlags);
  void Load_One_Alias_XML (CXMLelement & node, 
    const unsigned long iMask,
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Variables_XML (CXMLelement & parent, 
    const unsigned long iMask,
    const unsigned long iFlags);
  void Load_One_Variable_XML (CXMLelement & node, 
    const unsigned long iMask,
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Timers_XML (CXMLelement & parent, 
    const unsigned long iMask,
    const unsigned long iFlags);
  void Load_One_Timer_XML (CXMLelement & node, 
    const unsigned long iMask,
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Macros_XML (CXMLelement & parent, 
    const unsigned long iFlags);
  void Load_One_Macro_XML (CXMLelement & node, 
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Colours_XML (CXMLelement & parent, 
    const unsigned long iFlags);
  void Load_One_Colour_XML (CXMLelement & node, 
    const long iVersion, 
    const int iGroup, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Keypad_XML (CXMLelement & parent, 
    const unsigned long iFlags);
  void Load_One_Key_XML (CXMLelement & node, 
    const long iVersion, 
    bool bUseDefault, 
    const unsigned long iFlags);
  UINT Load_Printing_XML (CXMLelement & parent, 
    const unsigned long iFlags);
  void Load_One_Print_Colour_XML (CXMLelement & node, 
    const long iVersion, 
    const int iGroup, 
    bool bUseDefault, 
    const unsigned long iFlags);
  void Load_Version_And_Date_XML (CXMLelement & parent);
  void Load_Comments_XML (CXMLelement & parent);
  void Load_Plugin_XML (CXMLelement & parent);
  void Load_Scripts_XML (CXMLelement & parent);
  void Load_World_Numeric_Options_XML (CXMLelement & parent, 
                              bool bUseDefault,
                              const unsigned long iFlags);
  void Load_World_Single_Line_Alpha_Options_XML (CXMLelement & parent, 
                              bool bUseDefault,
                              const unsigned long iFlags);
  void Load_World_Multi_Line_Alpha_Options_XML (CXMLelement & parent, 
                              bool bUseDefault,
                              const unsigned long iFlags);

  void InternalLoadPlugin (const CString & strName);

  // set up trigger array after adding a trigger or two
  void SortTriggers (void);
  // set up alias array after adding an alias or two
  void SortAliases (void);


  BOOL Load_Set (const int set_type, 
                 CString strFileName,
                 CWnd * parent_window);  
  BOOL Save_Set (const int set_type, 
                 CWnd * parent_window);  
  
  BOOL EvaluateCommand (const CString & input, 
                        const bool bCountThem,
                        bool & bOmitFromLog,
                        const bool bTest = false);

  CTrigger * EvaluateTrigger (const CString & input, 
                              CString & output, 
                              int & iItem,
                              int & iStartCol,
                              int & iEndCol);

  CString FixSendText (const CString strSource, 
                            const int iSendTo,
                            const t_regexp * regexp,    // regular expression (for triggers, aliases)
                            const char * sLanguage, // language for send-to-script
                            const bool bMakeWildcardsLower,
                            const bool bExpandVariables,
                            const bool bExpandWildcards,
                            const bool bFixRegexps, // convert \ to \\ for instance
                            const bool bIsRegexp,   // true = regexp trigger
                            const bool bThrowExceptions);   // throw exception on error

#ifdef PANE

  void SendToPane (const CString strSource,      // what to send (eg. %1 = %2)
                   const CPaneLine & StyledLine, // the styled text to be sent
                   const string sPaneName,       // which pane
                   const t_regexp * regexp,      // regular expression (for triggers, aliases)
                   const bool bMakeWildcardsLower, // force wildcards to lower-case?
                   const bool bExpandVariables); // expand variables (eg. @foo)

  void TriggerToPane (CTrigger * pTrigger, CPaneLine & StyledLine);

  CPaneView * GetPane (LPCTSTR Name);

#endif // PANE

  const COLORREF TranslateColour (const COLORREF & source) const;

  void OnConnect(int nErrorCode);
  void HostNameResolved (WPARAM wParam, LPARAM lParam);
  const char * GetSocketError (int nError);
  bool LookupHostName (LPCTSTR sName);
  void InitiateConnection (void);
  void ConnectionEstablished (void);

  int ProcessProxyResponse1 (char * buff, const int count);
  int ProcessProxyResponse2 (char * buff, const int count);
  int ProcessProxyResponse3 (char * buff, const int count);
  bool CheckExpectedProxyResponse (const char cExpected, const char cReceived);
  void SendProxyConnectSequence (void);
  bool SendProxyUserNameAndPassword (void);

  BOOL FixUpOutputBuffer (int nNewBufferSize);
  bool SendToMushHelper (CFile * f, 
                         CString & strPreamble,
                         CString & strLinePreamble,
                         CString & strLinePostamble,
                         CString & strPostamble,
                         const BOOL bCommentedSoftcode,
                         const long nLineDelay,
                         const long nPerLines,
                         const BOOL bConfirm,
                         const BOOL bEcho);

  POSITION GetLinePosition (long nLine);
  long GetLastLine (void);
  void RemoveChunk (void);

  void InterpretANSIcode (const int iCode);
  void Interpret256ANSIcode (const int iCode);
  void ResetOneTimer (CTimer * timer_item);
  void ResetAllTimers (CTimerMap & TimerMap);
  void CheckTimerList (CTimerMap & TimerMap);
  void CheckTimers (void);

  virtual BOOL DoSave(LPCTSTR lpszPathName, BOOL bReplace);

  virtual HACCEL GetDefaultAccelerator();

  void SendWindowSizes (const int iNewWidth);
//  void ShowHyperlink (const CString strLink);
  CString DelayedSend(const CString strMessage, const bool bEchoIt);
  void SendTo (const unsigned short iWhere, 
               const CString strSendText,
               const bool bOmitFromOutput,
               const bool bOmitFromLog,
               const CString strDescription,
               const CString strVariable,
               CString & strOutput);

  // send a chat message to all connections
  int SendChatMessageToAll 
              (const int iMessage,         // message type (see enum)
               const CString strMessage,   // the message
               const bool bUnlessIgnoring, // don't send if we are ignoring them
               const bool bServed,         // if true, to incoming only
               const bool bNotServed ,      // if true, to outgoing only
               const long nExceptID,           // not to this ID
               const CString strGroup,        // group to send to
               const long iStamp);                 // zChat stamp to use, 0 = our connection
  
  CChatSocket * GetChatSocket (const long nID) const; // find a chat socket
  long ChatCallGeneral (LPCTSTR Server, long Port, const bool zChat);

// scripting support

  bool CreateScriptEngine();
  void DisableScripting (void);
  void CreateMonitoringThread();
	static void ThreadFunc(LPVOID pParam);
  void OnScriptFileChanged(const bool bForce = false);
  DISPID GetProcedureDispid (const CString & strName, 
                             const CString & strType,
                             const CString & strLabel,
                             CString & strErrorMessage);
  DISPID GetProcedureDispidHelper (const CString & strName, 
                             const CString & strType,
                             const CString & strLabel,
                             CString & strErrorMessage);
  bool SeeIfHandlerCanExecute (const CString & strName);
  bool FindAllEntryPoints (void);
  void FindGlobalEntryPoints (CString & strErrorMessage);

  void SetUpVariantString (VARIANT & tVariant, const CString & strContents);
  void SetUpVariantShort  (VARIANT & tVariant, const short iContents);
  void SetUpVariantBool   (VARIANT & tVariant, const BOOL iContents);
  void SetUpVariantLong   (VARIANT & tVariant, const long iContents);
  void SetUpVariantDate   (VARIANT & tVariant, const COleDateTime iContents);
  void SetUpVariantDouble (VARIANT & tVariant, const double dContents);
  long CheckObjectName    (CString & strObjectName, const bool bConform = true);

  const bool CheckScriptingAvailable (const char * sWhat,
                                      const DISPID dispid,
                                      const char * sScript);

  bool ExecuteScript (DISPID & dispid,  // dispatch ID, will be set to DISPID_UNKNOWN on an error
                      LPCTSTR szProcedure,  // eg. ON_TRIGGER_XYZ
                      const unsigned short iReason,  // value for m_iCurrentActionSource
                      LPCTSTR szType,   // eg. trigger, alias
                      LPCTSTR szReason, // eg. invoking trigger subroutine XXX
                      DISPPARAMS & params,  // parameters
                      long & nInvocationCount,  // count of invocations
                      COleVariant * result = NULL   // result from function call
                      );

  void ExecuteTriggerScript (CTrigger * trigger_item,
                             const CString strCurrentLine,
                             CPaneLine & StyledLine);

  bool ExecuteAliasScript (CAlias * alias_item,
                             const CString strCurrentLine);
                               
  void ShowErrorLines (const int iLine);  // show script file around the error point

  void ShowStatusLine (const bool bNow = false); // update the status line

  void ShowOptions (void);
  void ShowAlphaOptions (void);

  CPlugin * GetPlugin (LPCTSTR PluginID);

  // load from document into property page

  void LoadPrefsP1  (CPrefsP1  &page1);
  void LoadPrefsP2  (CPrefsP2  &page2);
  void LoadPrefsP3  (CPrefsP3  &page3);
  void LoadPrefsP4  (CPrefsP4  &page4);
  void LoadPrefsP5  (CPrefsP5  &page5);
  void LoadPrefsP6  (CPrefsP6  &page6);
  void LoadPrefsP7  (CPrefsP7  &page7);
  void LoadPrefsP8  (CPrefsP8  &page8);
  void LoadPrefsP9  (CPrefsP9  &page9);
  void LoadPrefsP10 (CPrefsP10 &page10);
  void LoadPrefsP11 (CPrefsP11 &page11);
  void LoadPrefsP12 (CPrefsP12 &page12);
  void LoadPrefsP13 (CPrefsP13 &page13);
  void LoadPrefsP14 (CPrefsP14 &page14);
  void LoadPrefsP15 (CPrefsP15 &page15);
  void LoadPrefsP16 (CPrefsP16 &page16);
  void LoadPrefsP17 (CPrefsP17 &page17);
  void LoadPrefsP18 (CPrefsP18 &page18);
  void LoadPrefsP19 (CPrefsP19 &page19);
  void LoadPrefsP20 (CPrefsP20 &page20);
  void LoadPrefsP21 (CPrefsP21 &page21);
  void LoadPrefsP22 (CPrefsP22 &page22);
  void LoadPrefsP23 (CPrefsP23 &page23);

  // check if document has changed by comparing to property page

  bool ChangedPrefsP1  (CPrefsP1  &page1);
  bool ChangedPrefsP2  (CPrefsP2  &page2);
  bool ChangedPrefsP3  (CPrefsP3  &page3);
  bool ChangedPrefsP4  (CPrefsP4  &page4);
  bool ChangedPrefsP5  (CPrefsP5  &page5);
  bool ChangedPrefsP6  (CPrefsP6  &page6);
  bool ChangedPrefsP7  (CPrefsP7  &page7);
  bool ChangedPrefsP8  (CPrefsP8  &page8);
  bool ChangedPrefsP9  (CPrefsP9  &page9);
  bool ChangedPrefsP10 (CPrefsP10 &page10);
  bool ChangedPrefsP11 (CPrefsP11 &page11);
  bool ChangedPrefsP12 (CPrefsP12 &page12);
  bool ChangedPrefsP13 (CPrefsP13 &page13);
  bool ChangedPrefsP14 (CPrefsP14 &page14);
  bool ChangedPrefsP15 (CPrefsP15 &page15);
  bool ChangedPrefsP16 (CPrefsP16 &page16);
  bool ChangedPrefsP17 (CPrefsP17 &page17);
  bool ChangedPrefsP18 (CPrefsP18 &page18);
  bool ChangedPrefsP19 (CPrefsP19 &page19);
  bool ChangedPrefsP20 (CPrefsP20 &page20);
  bool ChangedPrefsP21 (CPrefsP21 &page21);
  bool ChangedPrefsP22 (CPrefsP22 &page22);
  bool ChangedPrefsP23 (CPrefsP23 &page23);

  // unload from property page into document

  void SavePrefsP1  (CPrefsP1  &page1);
  void SavePrefsP2  (CPrefsP2  &page2);
  void SavePrefsP3  (CPrefsP3  &page3);
  void SavePrefsP4  (CPrefsP4  &page4);
  void SavePrefsP5  (CPrefsP5  &page5);
  void SavePrefsP6  (CPrefsP6  &page6);
  void SavePrefsP7  (CPrefsP7  &page7);
  void SavePrefsP8  (CPrefsP8  &page8);
  void SavePrefsP9  (CPrefsP9  &page9);
  void SavePrefsP10 (CPrefsP10 &page10);
  void SavePrefsP11 (CPrefsP11 &page11);
  void SavePrefsP12 (CPrefsP12 &page12);
  void SavePrefsP13 (CPrefsP13 &page13);
  void SavePrefsP14 (CPrefsP14 &page14);
  void SavePrefsP15 (CPrefsP15 &page15);
  void SavePrefsP16 (CPrefsP16 &page16);
  void SavePrefsP17 (CPrefsP17 &page17);
  void SavePrefsP18 (CPrefsP18 &page18);
  void SavePrefsP19 (CPrefsP19 &page19);
  void SavePrefsP20 (CPrefsP20 &page20);
  void SavePrefsP21 (CPrefsP21 &page21);
  void SavePrefsP22 (CPrefsP22 &page22);
  void SavePrefsP23 (CPrefsP23 &page23);

  CString AppendMUDName (const CString strName);

  bool GamePreferences (const int iPage); 

  bool LoggingInput (void) { return m_log_input; };

  long DoSetVariable (LPCTSTR VariableName, LPCTSTR Contents)
    { return SetVariable (VariableName, Contents); };

  void Trace (LPCTSTR lpszFormat, ...);

  void Screendraw  (const long iType,
                    const long iLog,
                    const char * sText);

  CString RecallText (const CString strSearchString,   // what to search for
                      const bool bMatchCase,
                      const bool bRegexp,          // and other params
                      const bool bCommands,
                      const bool bOutput,
                      const bool bNotes,
                      const int  iLines,
                      const CString strRecallLinePreamble);

  bool SwitchToNotepad (void);
  bool AppendToTheNotepad (const CString strTitle,
                           const CString strText,
                           const bool bReplace = false,
                           const int  iNotepadType = eNotepadNormal);

  CTextDocument * FindNotepad (const CString strTitle);

  void DoRecallText (void);
  CString DoEvaluateSpeedwalk(LPCTSTR SpeedWalkString);
  static CString DoReverseSpeedwalk(LPCTSTR SpeedWalkString);

  void AddToMap (CString str);
  void ShowQueuedCommands (void);
  CString CalculateSpeedWalkString (const bool bOmitComments = false);
  void DrawMappingStatusLine (void);
  
  void ClearOutput (void);
  CString FormatTime (const CTime theTime, 
                      LPCTSTR pFormat, 
                      const bool bFixHTML = false);

  long GetOptionIndex (LPCTSTR OptionName);
  long GetOptionItem (const int iItem);
  long SetOptionItem (const int iItem, 
                      long Value, 
                      const bool bDoSpecial,
                      const bool bInclude);
  void SetDefaults (const bool bDoSpecial);

  long GetAlphaOptionIndex (LPCTSTR OptionName);
  CString GetAlphaOptionItem (const int iItem);
  long SetAlphaOptionItem (const int iItem, 
                          LPCTSTR sValue, 
                          const bool bDoSpecial,
                          const bool bInclude);
  void SetAlphaDefaults (const bool bDoSpecial);

  void AllocateConfigurationArrays (void);
  void DeleteConfigurationArrays (void);
  void ResetConfigurationArrays (void);

  // helper routines to get the appropriate map
  CTriggerMap & GetTriggerMap (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_TriggerMap;
    else
      return m_TriggerMap;
    };

  CTriggerArray & GetTriggerArray (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_TriggerArray;
    else
      return m_TriggerArray;
    };

  CAliasMap & GetAliasMap (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_AliasMap;
    else
      return m_AliasMap;
    };

  CAliasArray & GetAliasArray (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_AliasArray;
    else
      return m_AliasArray;
    };

  CTimerMap & GetTimerMap (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_TimerMap;
    else
      return m_TimerMap;
    };

  CVariableMap & GetVariableMap (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_VariableMap;
    else
      return m_VariableMap;
    };

  CScriptEngine * GetScriptEngine (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_ScriptEngine;
    else
      return m_ScriptEngine;
    };

  tStringMapOfMaps & GetArrayMap (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_Arrays;
    else
      return m_Arrays;
    };

  CString GetLanguage (void)
    {
    if (m_CurrentPlugin)
      return m_CurrentPlugin->m_strLanguage;
    else
      return m_strLanguage;
    };

  void DoFixMenus(CCmdUI* pCmdUI);

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMUSHclientDoc)
	public:
	virtual BOOL OnNewDocument();
	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
	protected:
	virtual BOOL SaveModified();
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CMUSHclientDoc();
	virtual void Serialize(CArchive& ar);   // overridden for document i/o
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

public:
	short m_bLogNotes;
	short m_log_input;
	short m_bLogOutput;

protected:

// Generated message map functions
protected:
	//{{AFX_MSG(CMUSHclientDoc)
	afx_msg void OnFileLogsession();
	afx_msg void OnUpdateFileLogsession(CCmdUI* pCmdUI);
	afx_msg void OnUpdateStatuslineLines(CCmdUI* pCmdUI);
	afx_msg void OnUpdateStatuslineMushname(CCmdUI* pCmdUI);
	afx_msg void OnGameWraplines();
	afx_msg void OnUpdateGameWraplines(CCmdUI* pCmdUI);
	afx_msg void OnUpdateStatuslineTime(CCmdUI* pCmdUI);
	afx_msg void OnUpdateStatuslineLog(CCmdUI* pCmdUI);
	afx_msg void OnGamePreferences();
	afx_msg void OnGameTestcommand();
	afx_msg void OnGamePastefile();
	afx_msg void OnConnectionConnect();
	afx_msg void OnUpdateConnectionConnect(CCmdUI* pCmdUI);
	afx_msg void OnConnectionDisconnect();
	afx_msg void OnUpdateConnectionDisconnect(CCmdUI* pCmdUI);
	afx_msg void OnEditPastetomush();
	afx_msg void OnUpdateSessionOpen(CCmdUI* pCmdUI);
	afx_msg void OnUpdateEditPastetomush(CCmdUI* pCmdUI);
	afx_msg void OnUpdateGamePreferences(CCmdUI* pCmdUI);
	afx_msg void OnGameImmediate();
	afx_msg void OnUpdateGameImmediate(CCmdUI* pCmdUI);
	afx_msg void OnGameAutosay();
	afx_msg void OnUpdateGameAutosay(CCmdUI* pCmdUI);
	afx_msg void OnConnectDisconnect();
	afx_msg void OnUpdateConnectDisconnect(CCmdUI* pCmdUI);
	afx_msg void OnGameReloadScriptFile();
	afx_msg void OnUpdateGameReloadScriptFile(CCmdUI* pCmdUI);
	afx_msg void OnDisplayClearOutput();
	afx_msg void OnGameConfigureMudaddress();
	afx_msg void OnGameConfigureNameAndPassword();
	afx_msg void OnGameConfigureLogging();
	afx_msg void OnGameConfigureInfo();
	afx_msg void OnGameConfigureNotes();
	afx_msg void OnGameConfigureColours();
	afx_msg void OnGameConfigurePrinting();
	afx_msg void OnGameConfigureOutput();
	afx_msg void OnGameConfigureHighlighting();
	afx_msg void OnGameConfigureCommands();
	afx_msg void OnGameConfigureKeypad();
	afx_msg void OnGameConfigureMacros();
	afx_msg void OnGameConfigureAutosay();
	afx_msg void OnGameConfigurePastetoworld();
	afx_msg void OnGameConfigureSendfile();
	afx_msg void OnGameConfigureScripting();
	afx_msg void OnGameConfigureVariables();
	afx_msg void OnGameConfigureTriggers();
	afx_msg void OnGameConfigureAliases();
	afx_msg void OnGameConfigureTimers();
	afx_msg void OnGameResetalltimers();
	afx_msg void OnUpdateGameResetalltimers(CCmdUI* pCmdUI);
	afx_msg void OnGameEditscriptfile();
	afx_msg void OnUpdateGameEditscriptfile(CCmdUI* pCmdUI);
	afx_msg void OnUpdateGameConfigureMudaddress(CCmdUI* pCmdUI);
	afx_msg void OnDisplayRecalltext();
	afx_msg void OnGameConfigureCustomColours();
	afx_msg void OnFileReloaddefaults();
	afx_msg void OnUpdateFileReloaddefaults(CCmdUI* pCmdUI);
	afx_msg void OnGameTrace();
	afx_msg void OnUpdateGameTrace(CCmdUI* pCmdUI);
	afx_msg void OnEditFliptonotepad();
	afx_msg void OnFileOpen();
	afx_msg void OnFileSave();
	afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI);
	afx_msg void OnFileSaveAs();
	afx_msg void OnUpdateFileSaveAs(CCmdUI* pCmdUI);
	afx_msg void OnGameMapper();
	afx_msg void OnUpdateGameMapper(CCmdUI* pCmdUI);
	afx_msg void OnInputDiscardqueuedcommands();
	afx_msg void OnUpdateInputDiscardqueuedcommands(CCmdUI* pCmdUI);
	afx_msg void OnGameDomapperspecial();
	afx_msg void OnUpdateGameDomapperspecial(CCmdUI* pCmdUI);
	afx_msg void OnFilePreferences();
	afx_msg void OnDebugWorldInput();
	afx_msg void OnDisplayNocommandecho();
	afx_msg void OnUpdateDisplayNocommandecho(CCmdUI* pCmdUI);
	afx_msg void OnEditDebugincomingpackets();
	afx_msg void OnUpdateEditDebugincomingpackets(CCmdUI* pCmdUI);
	afx_msg void OnGameConfigureMxppueblo();
	afx_msg void OnFileImport();
	afx_msg void OnFilePlugins();
	afx_msg void OnFilePluginwizard();
	afx_msg void OnGameDomappercomment();
	afx_msg void OnUpdateGameDomappercomment(CCmdUI* pCmdUI);
	afx_msg void OnGameChatsessions();
	afx_msg void OnGameConfigureChat();
	afx_msg void OnGameResetconnectedtime();
	afx_msg void OnDisplayStopsoundplaying();
	afx_msg void OnInputKeyname();
	afx_msg void OnEditConvertclipboardforumcodes();
	//}}AFX_MSG
	afx_msg void OnFixMenus(CCmdUI* pCmdUI);
  DECLARE_MESSAGE_MAP()

// if you get a compile error:
//    C2371: 'm_display_my_input' : redefinition; different basic types
// delete the lines below:   short m_display_my_input; 
//	                         short m_log_input;
//	                         short m_bLogOutput;

// ======================================================================
// When adding script functions, see the comments at the end of methods.cpp
//   - these relate to updating the Lua glue routines, and the list of available functions.
// ======================================================================

public:

// This will probably occur after adding new methods or properties.

    // Generated OLE dispatch map functions
	//{{AFX_DISPATCH(CMUSHclientDoc)
	afx_msg void OnLogNotesChanged();
	afx_msg void OnLogInputChanged();
	afx_msg void OnLogOutputChanged();
	BOOL m_bMapping;
	afx_msg void OnMappingChanged();
	BOOL m_bRemoveMapReverses;
	afx_msg void OnRemoveMapReversesChanged();
	afx_msg short GetNoteColour();
	afx_msg void SetNoteColour(short nNewValue);
	afx_msg BOOL GetTrace();
	afx_msg void SetTrace(BOOL bNewValue);
	afx_msg short GetSpeedWalkDelay();
	afx_msg void SetSpeedWalkDelay(short nNewValue);
	afx_msg long GetNoteColourFore();
	afx_msg void SetNoteColourFore(long nNewValue);
	afx_msg long GetNoteColourBack();
	afx_msg void SetNoteColourBack(long nNewValue);
	afx_msg BOOL GetEchoInput();
	afx_msg void SetEchoInput(BOOL bNewValue);
	afx_msg long GetLineCount();
	afx_msg BOOL IsConnected();
	afx_msg BSTR WorldName();
	afx_msg void Note(LPCTSTR Message);
	afx_msg long Send(LPCTSTR Message);
	afx_msg long Sound(LPCTSTR SoundFileName);
	afx_msg long DeleteTrigger(LPCTSTR TriggerName);
	afx_msg long AddTrigger(LPCTSTR TriggerName, LPCTSTR MatchText, LPCTSTR ResponseText, long Flags, short Colour, short Wildcard, LPCTSTR SoundFileName, LPCTSTR ScriptName);
	afx_msg long EnableTrigger(LPCTSTR TriggerName, BOOL Enabled);
	afx_msg long GetTrigger(LPCTSTR TriggerName, VARIANT FAR* MatchText, VARIANT FAR* ResponseText, VARIANT FAR* Flags, VARIANT FAR* Colour, VARIANT FAR* Wildcard, VARIANT FAR* SoundFileName, VARIANT FAR* ScriptName);
	afx_msg long IsTrigger(LPCTSTR TriggerName);
	afx_msg VARIANT GetTriggerList();
	afx_msg VARIANT GetVariable(LPCTSTR VariableName);
	afx_msg long SetVariable(LPCTSTR VariableName, LPCTSTR Contents);
	afx_msg VARIANT GetVariableList();
	afx_msg BOOL Save(LPCTSTR Name);
	afx_msg long Connect();
	afx_msg long Disconnect();
	afx_msg long DeleteAlias(LPCTSTR AliasName);
	afx_msg long EnableAlias(LPCTSTR AliasName, BOOL Enabled);
	afx_msg long GetAlias(LPCTSTR AliasName, VARIANT FAR* MatchText, VARIANT FAR* ResponseText, VARIANT FAR* Parameter, VARIANT FAR* Flags, VARIANT FAR* ScriptName);
	afx_msg VARIANT GetAliasList();
	afx_msg long IsAlias(LPCTSTR AliasName);
	afx_msg long CloseLog();
	afx_msg long OpenLog(LPCTSTR LogFileName, BOOL Append);
	afx_msg long WriteLog(LPCTSTR Message);
	afx_msg BOOL IsLogOpen();
	afx_msg long EnableTimer(LPCTSTR TimerName, BOOL Enabled);
	afx_msg long AddAlias(LPCTSTR AliasName, LPCTSTR MatchText, LPCTSTR ResponseText, long Flags, LPCTSTR ScriptName);
	afx_msg long DeleteVariable(LPCTSTR VariableName);
	afx_msg void ResetTimers();
	afx_msg void SetStatus(LPCTSTR Message);
	afx_msg long SetCommand(LPCTSTR Message);
	afx_msg BSTR GetNotes();
	afx_msg void SetNotes(LPCTSTR Message);
	afx_msg void Redraw();
	afx_msg long ResetTimer(LPCTSTR TimerName);
	afx_msg void SetOutputFont(LPCTSTR FontName, short PointSize);
	afx_msg void SetInputFont(LPCTSTR FontName, short PointSize, short Weight, BOOL Italic);
	afx_msg BOOL SendToNotepad(LPCTSTR Title, LPCTSTR Contents);
	afx_msg BOOL AppendToNotepad(LPCTSTR Title, LPCTSTR Contents);
	afx_msg BOOL ActivateNotepad(LPCTSTR Title);
	afx_msg void Activate();
	afx_msg LPDISPATCH GetWorld(LPCTSTR WorldName);
	afx_msg VARIANT GetWorldList();
	afx_msg BSTR FixupHTML(LPCTSTR StringToConvert);
	afx_msg BSTR Replace(LPCTSTR Source, LPCTSTR SearchFor, LPCTSTR ReplaceWith, BOOL Multiple);
	afx_msg BSTR FixupEscapeSequences(LPCTSTR Source);
	afx_msg BSTR Trim(LPCTSTR Source);
	afx_msg BOOL ReplaceNotepad(LPCTSTR Title, LPCTSTR Contents);
	afx_msg VARIANT GetAliasInfo(LPCTSTR AliasName, short InfoType);
	afx_msg VARIANT GetTriggerInfo(LPCTSTR TriggerName, short InfoType);
	afx_msg BSTR EvaluateSpeedwalk(LPCTSTR SpeedWalkString);
	afx_msg BSTR ReverseSpeedwalk(LPCTSTR SpeedWalkString);
	afx_msg long DeleteTimer(LPCTSTR TimerName);
	afx_msg long IsTimer(LPCTSTR TimerName);
	afx_msg VARIANT GetTimerList();
	afx_msg long GetTimer(LPCTSTR TimerName, VARIANT FAR* Hour, VARIANT FAR* Minute, VARIANT FAR* Second, VARIANT FAR* ResponseText, VARIANT FAR* Flags, VARIANT FAR* ScriptName);
	afx_msg VARIANT GetTimerInfo(LPCTSTR TimerName, short InfoType);
	afx_msg long GetUniqueNumber();
	afx_msg long Queue(LPCTSTR Message, BOOL Echo);
	afx_msg long DiscardQueue();
	afx_msg VARIANT GenerateName();
	afx_msg long ReadNamesFile(LPCTSTR FileName);
	afx_msg long AddToMapper(LPCTSTR Direction, LPCTSTR Reverse);
	afx_msg long GetMappingCount();
	afx_msg VARIANT GetMappingItem(long Item);
	afx_msg VARIANT GetMappingString();
	afx_msg long DeleteLastMapItem();
	afx_msg long DeleteAllMapItems();
	afx_msg long GetSentBytes();
	afx_msg long GetReceivedBytes();
	afx_msg long GetConnectDuration();
	afx_msg double GetScriptTime();
	afx_msg BSTR WorldAddress();
	afx_msg long WorldPort();
	afx_msg void DeleteCommandHistory();
	afx_msg void DeleteOutput();
	afx_msg void Tell(LPCTSTR Message);
	afx_msg void NoteColourRGB(long Foreground, long Background);
	afx_msg void NoteColourName(LPCTSTR Foreground, LPCTSTR Background);
	afx_msg BSTR Version();
	afx_msg void Reset();
	afx_msg long GetOption(LPCTSTR OptionName);
	afx_msg VARIANT GetOptionList();
	afx_msg long SetOption(LPCTSTR OptionName, long Value);
	afx_msg VARIANT Debug(LPCTSTR Command);
	afx_msg void Pause(BOOL Flag);
	afx_msg LPDISPATCH Open(LPCTSTR FileName);
	afx_msg VARIANT GetLineInfo(long LineNumber, short InfoType);
	afx_msg long GetLinesInBufferCount();
	afx_msg VARIANT GetStyleInfo(long LineNumber, long StyleNumber, short InfoType);
	afx_msg long GetSelectionStartLine();
	afx_msg long GetSelectionEndLine();
	afx_msg long GetSelectionStartColumn();
	afx_msg long GetSelectionEndColumn();
	afx_msg VARIANT GetCommandList(long Count);
	afx_msg BSTR PushCommand();
	afx_msg void SelectCommand();
	afx_msg BSTR GetCommand();
	afx_msg long AddTriggerEx(LPCTSTR TriggerName, LPCTSTR MatchText, LPCTSTR ResponseText, long Flags, short Colour, short Wildcard, LPCTSTR SoundFileName, LPCTSTR ScriptName, short SendTo, short Sequence);
	afx_msg VARIANT GetQueue();
	afx_msg long DeleteTemporaryTriggers();
	afx_msg long DeleteTemporaryAliases();
	afx_msg long DeleteTemporaryTimers();
	afx_msg VARIANT GetInfo(long InfoType);
	afx_msg VARIANT GetAlphaOptionList();
	afx_msg long SetAlphaOption(LPCTSTR OptionName, LPCTSTR Value);
	afx_msg VARIANT GetAlphaOption(LPCTSTR OptionName);
	afx_msg long ColourNameToRGB(LPCTSTR Name);
	afx_msg BSTR RGBColourToName(long Colour);
	afx_msg VARIANT Base64Decode(LPCTSTR Text);
	afx_msg VARIANT Base64Encode(LPCTSTR Text, BOOL MultiLine);
	afx_msg VARIANT GetLoadedValue(LPCTSTR OptionName);
	afx_msg VARIANT GetDefaultValue(LPCTSTR OptionName);
	afx_msg VARIANT GetCurrentValue(LPCTSTR OptionName);
	afx_msg void ColourNote(LPCTSTR TextColour, LPCTSTR BackgroundColour, LPCTSTR Text);
	afx_msg void ColourTell(LPCTSTR TextColour, LPCTSTR BackgroundColour, LPCTSTR Text);
	afx_msg BSTR CreateGUID();
	afx_msg BSTR Hash(LPCTSTR Text);
	afx_msg BSTR GetUniqueID();
	afx_msg VARIANT GetPluginVariable(LPCTSTR PluginID, LPCTSTR VariableName);
	afx_msg BSTR GetPluginID();
	afx_msg VARIANT GetPluginList();
	afx_msg VARIANT GetPluginInfo(LPCTSTR PluginID, short InfoType);
	afx_msg long LoadPlugin(LPCTSTR FileName);
	afx_msg VARIANT GetPluginVariableList(LPCTSTR PluginID);
	afx_msg VARIANT GetPluginTriggerList(LPCTSTR PluginID);
	afx_msg VARIANT GetPluginAliasList(LPCTSTR PluginID);
	afx_msg VARIANT GetPluginTimerList(LPCTSTR PluginID);
	afx_msg VARIANT GetPluginTriggerInfo(LPCTSTR PluginID, LPCTSTR TriggerName, short InfoType);
	afx_msg VARIANT GetPluginAliasInfo(LPCTSTR PluginID, LPCTSTR AliasName, short InfoType);
	afx_msg VARIANT GetPluginTimerInfo(LPCTSTR PluginID, LPCTSTR TimerName, short InfoType);
	afx_msg BOOL IsPluginInstalled(LPCTSTR PluginID);
	afx_msg long SaveState();
	afx_msg long CallPlugin(LPCTSTR PluginID, LPCTSTR Routine, LPCTSTR Argument);
	afx_msg long PluginSupports(LPCTSTR PluginID, LPCTSTR Routine);
	afx_msg long EnablePlugin(LPCTSTR PluginID, BOOL Enabled);
	afx_msg BSTR GetPluginName();
	afx_msg long LogSend(LPCTSTR Message);
	afx_msg long AddMapperComment(LPCTSTR Comment);
	afx_msg long SendPush(LPCTSTR Message);
	afx_msg long EnableGroup(LPCTSTR GroupName, BOOL Enabled);
	afx_msg long EnableTriggerGroup(LPCTSTR GroupName, BOOL Enabled);
	afx_msg long EnableAliasGroup(LPCTSTR GroupName, BOOL Enabled);
	afx_msg long EnableTimerGroup(LPCTSTR GroupName, BOOL Enabled);
	afx_msg void ShowInfoBar(BOOL Visible);
	afx_msg void Info(LPCTSTR Message);
	afx_msg void InfoFont(LPCTSTR FontName, short Size, short Style);
	afx_msg long DeleteGroup(LPCTSTR GroupName);
	afx_msg long DeleteTriggerGroup(LPCTSTR GroupName);
	afx_msg long DeleteAliasGroup(LPCTSTR GroupName);
	afx_msg long DeleteTimerGroup(LPCTSTR GroupName);
	afx_msg void InfoClear();
	afx_msg void InfoColour(LPCTSTR Name);
	afx_msg void InfoBackground(LPCTSTR Name);
	afx_msg VARIANT GetTriggerOption(LPCTSTR TriggerName, LPCTSTR OptionName);
	afx_msg long SetTriggerOption(LPCTSTR TriggerName, LPCTSTR OptionName, LPCTSTR Value);
	afx_msg VARIANT GetAliasOption(LPCTSTR AliasName, LPCTSTR OptionName);
	afx_msg VARIANT GetTimerOption(LPCTSTR TimerName, LPCTSTR OptionName);
	afx_msg long SetAliasOption(LPCTSTR AliasName, LPCTSTR OptionName, LPCTSTR Value);
	afx_msg long SetTimerOption(LPCTSTR TimerName, LPCTSTR OptionName, LPCTSTR Value);
	afx_msg long SaveNotepad(LPCTSTR Title, LPCTSTR FileName, BOOL ReplaceExisting);
	afx_msg long CloseNotepad(LPCTSTR Title, BOOL QuerySave);
	afx_msg BSTR GetEntity(LPCTSTR Name);
	afx_msg long Execute(LPCTSTR Command);
	afx_msg long ChatCall(LPCTSTR Server, long Port);
	afx_msg void AnsiNote(LPCTSTR Text);
	afx_msg long ChatNameChange(LPCTSTR NewName);
	afx_msg long ChatAcceptCalls(short Port);
	afx_msg void ChatStopAcceptingCalls();
	afx_msg VARIANT GetChatList();
	afx_msg VARIANT GetChatInfo(long ChatID, short InfoType);
	afx_msg long ChatEverybody(LPCTSTR Message, BOOL Emote);
	afx_msg long ChatPersonal(LPCTSTR Who, LPCTSTR Message, BOOL Emote);
	afx_msg long ChatID(long ID, LPCTSTR Message, BOOL Emote);
	afx_msg long ChatGroup(LPCTSTR Group, LPCTSTR Message, BOOL Emote);
	afx_msg long ChatPing(long ID);
	afx_msg long ChatPeekConnections(long ID);
	afx_msg long ChatRequestConnections(long ID);
	afx_msg long ChatDisconnect(long ID);
	afx_msg long ChatMessage(long ID, short Message, LPCTSTR Text);
	afx_msg BSTR ANSI(short Code);
	afx_msg BSTR StripANSI(LPCTSTR Message);
	afx_msg VARIANT GetChatOption(long ID, LPCTSTR OptionName);
	afx_msg long SetChatOption(long ID, LPCTSTR OptionName, LPCTSTR Value);
	afx_msg void ChatNote(short NoteType, LPCTSTR Message);
	afx_msg long ChatGetID(LPCTSTR Who);
	afx_msg long ChatDisconnectAll();
	afx_msg long ChatPasteText(long ID);
	afx_msg long ChatSendFile(long ID, LPCTSTR FileName);
	afx_msg long ChatStopFileTransfer(long ID);
	afx_msg long ChatPasteEverybody();
	afx_msg VARIANT GetWorldIdList();
	afx_msg LPDISPATCH GetWorldById(LPCTSTR WorldID);
	afx_msg BSTR GetHostName(LPCTSTR IPaddress);
	afx_msg VARIANT GetHostAddress(LPCTSTR HostName);
	afx_msg BSTR GetClipboard();
	afx_msg long ImportXML(LPCTSTR XML);
	afx_msg long DoCommand(LPCTSTR Command);
	afx_msg VARIANT GetInternalCommandsList();
	afx_msg long ChatCallzChat(LPCTSTR Server, long Port);
	afx_msg long GetNotepadLength(LPCTSTR Title);
	afx_msg BSTR GetNotepadText(LPCTSTR Title);
	afx_msg long SendImmediate(LPCTSTR Message);
	afx_msg long AdjustColour(long Colour, short Method);
	afx_msg long SendNoEcho(LPCTSTR Message);
	afx_msg BSTR ExportXML(short Type, LPCTSTR Name);
	afx_msg void Hyperlink(LPCTSTR Action, LPCTSTR Text, LPCTSTR Hint, LPCTSTR TextColour, LPCTSTR BackColour, BOOL URL);
	afx_msg void NoteStyle(short Style);
	afx_msg short GetNoteStyle();
	afx_msg long GetFrame();
	afx_msg long ArrayCreate(LPCTSTR Name);
	afx_msg long ArrayDelete(LPCTSTR Name);
	afx_msg VARIANT ArrayListAll();
	afx_msg long ArrayImport(LPCTSTR Name, LPCTSTR Values, LPCTSTR Delimiter);
	afx_msg VARIANT ArrayGet(LPCTSTR Name, LPCTSTR Key);
	afx_msg long ArraySet(LPCTSTR Name, LPCTSTR Key, LPCTSTR Value);
	afx_msg VARIANT ArrayExport(LPCTSTR Name, LPCTSTR Delimiter);
	afx_msg VARIANT ArrayListKeys(LPCTSTR Name);
	afx_msg long ArrayClear(LPCTSTR Name);
	afx_msg long ArrayDeleteKey(LPCTSTR Name, LPCTSTR Key);
	afx_msg BOOL ArrayExists(LPCTSTR Name);
	afx_msg BOOL ArrayKeyExists(LPCTSTR Name, LPCTSTR Key);
	afx_msg VARIANT ArrayExportKeys(LPCTSTR Name, LPCTSTR Delimiter);
	afx_msg long ArrayCount();
	afx_msg long ArraySize(LPCTSTR Name);
	afx_msg VARIANT ArrayGetFirstKey(LPCTSTR Name);
	afx_msg VARIANT ArrayGetLastKey(LPCTSTR Name);
	afx_msg VARIANT ArrayListValues(LPCTSTR Name);
	afx_msg void ResetStatusTime();
	afx_msg void EnableMapping(BOOL Enabled);
	afx_msg void ActivateClient();
	afx_msg BSTR RemoveBacktracks(LPCTSTR Path);
	afx_msg VARIANT GetTriggerWildcard(LPCTSTR TriggerName, LPCTSTR WildcardName);
	afx_msg BSTR GetRecentLines(long Count);
	afx_msg VARIANT GetAliasWildcard(LPCTSTR AliasName, LPCTSTR WildcardName);
	afx_msg long ReloadPlugin(LPCTSTR PluginID);
	afx_msg BSTR TranslateGerman(LPCTSTR Text);
	afx_msg BSTR GetWorldID();
	afx_msg long Accelerator(LPCTSTR Key, LPCTSTR Send);
	afx_msg VARIANT AcceleratorList();
	afx_msg void MapColour(long Original, long Replacement);
	afx_msg VARIANT SpellCheck(LPCTSTR Text);
	afx_msg long GetMapColour(long Which);
	afx_msg VARIANT MapColourList();
	afx_msg BSTR MakeRegularExpression(LPCTSTR Text);
	afx_msg long SpellCheckCommand(long StartCol, long EndCol);
	afx_msg void MoveMainWindow(long Left, long Top, long Width, long Height);
	afx_msg void MoveWorldWindow(long Left, long Top, long Width, long Height);
	afx_msg long MoveNotepadWindow(LPCTSTR Title, long Left, long Top, long Width, long Height);
	afx_msg long GetSysColor(long Index);
	afx_msg long GetSystemMetrics(long Index);
	afx_msg BSTR GetMainWindowPosition();
	afx_msg BSTR GetWorldWindowPosition();
	afx_msg BSTR GetNotepadWindowPosition(LPCTSTR Title);
	afx_msg long UdpSend(LPCTSTR IP, short Port, LPCTSTR Text);
	afx_msg long UdpListen(LPCTSTR IP, short Port, LPCTSTR Script);
	afx_msg long NotepadColour(LPCTSTR Title, LPCTSTR TextColour, LPCTSTR BackgroundColour);
	afx_msg long NotepadFont(LPCTSTR Title, LPCTSTR FontName, short Size, short Style, short Charset);
	afx_msg void MtSrand(long Seed);
	afx_msg double MtRand();
	afx_msg void SetChanged(BOOL ChangedFlag);
	afx_msg VARIANT UdpPortList();
	afx_msg long AddTimer(LPCTSTR TimerName, short Hour, short Minute, double Second, LPCTSTR ResponseText, long Flags, LPCTSTR ScriptName);
	afx_msg long DoAfter(double Seconds, LPCTSTR SendText);
	afx_msg long DoAfterNote(double Seconds, LPCTSTR NoteText);
	afx_msg long DoAfterSpeedWalk(double Seconds, LPCTSTR SendText);
	afx_msg long DoAfterSpecial(double Seconds, LPCTSTR SendText, short SendTo);
	afx_msg void NoteHr();
	afx_msg void MoveWorldWindowX(long Left, long Top, long Width, long Height, short Which);
	afx_msg BSTR GetWorldWindowPositionX(short Which);
	afx_msg void SetEntity(LPCTSTR Name, LPCTSTR Contents);
	afx_msg BSTR GetXMLEntity(LPCTSTR Entity);
	afx_msg long GetUdpPort(long First, long Last);
	afx_msg void SetClipboard(LPCTSTR Text);
	afx_msg long BroadcastPlugin(long Message, LPCTSTR Text);
	afx_msg long PickColour(long Suggested);
	afx_msg void TraceOut(LPCTSTR Message);
	afx_msg BSTR ErrorDesc(long Code);
	afx_msg BSTR PasteCommand(LPCTSTR Text);
	afx_msg void Help(LPCTSTR Name);
	afx_msg void Simulate(LPCTSTR Text);
	afx_msg void ResetIP();
	afx_msg long AddSpellCheckWord(LPCTSTR OriginalWord, LPCTSTR ActionCode, LPCTSTR ReplacementWord);
	afx_msg long OpenBrowser(LPCTSTR URL);
	afx_msg void DeleteLines(long Count);
	afx_msg BOOL NotepadSaveMethod(LPCTSTR Title, short Method);
	afx_msg long ChangeDir(LPCTSTR Path);
	afx_msg long SendPkt(LPCTSTR Packet);
	afx_msg BSTR Metaphone(LPCTSTR Word, short Length);
	afx_msg long EditDistance(LPCTSTR Source, LPCTSTR Target);
	afx_msg long FlushLog();
	afx_msg BOOL Transparency(long Key, short Amount);
	afx_msg VARIANT SpellCheckDlg(LPCTSTR Text);
	afx_msg void SetWorldWindowStatus(short Parameter);
	afx_msg BSTR GetCustomColourName(short WhichColour);
	afx_msg long SetCustomColourName(short WhichColour, LPCTSTR Name);
	afx_msg VARIANT GetNotepadList(BOOL All);
	afx_msg long TranslateDebug(LPCTSTR Message);
	afx_msg long SendSpecial(LPCTSTR Message, BOOL Echo, BOOL Queue, BOOL Log, BOOL History);
	afx_msg VARIANT GetGlobalOption(LPCTSTR Name);
	afx_msg VARIANT GetGlobalOptionList();
	afx_msg VARIANT GetPluginTriggerOption(LPCTSTR PluginID, LPCTSTR TriggerName, LPCTSTR OptionName);
	afx_msg VARIANT GetPluginAliasOption(LPCTSTR PluginID, LPCTSTR AliasName, LPCTSTR OptionName);
	afx_msg VARIANT GetPluginTimerOption(LPCTSTR PluginID, LPCTSTR TimerName, LPCTSTR OptionName);
	afx_msg long AcceleratorTo(LPCTSTR Key, LPCTSTR Send, short SendTo);
	afx_msg long StopSound(short Buffer);
	afx_msg long GetSoundStatus(short Buffer);
	afx_msg long PlaySound(short Buffer, LPCTSTR FileName, BOOL Loop, double Volume, double Pan);
	afx_msg long SetCommandWindowHeight(short Height);
	afx_msg long SetToolBarPosition(short Which, BOOL Float, short Side, long Top, long Left);
	afx_msg long ShiftTabCompleteItem(LPCTSTR Item);
	afx_msg long NotepadReadOnly(LPCTSTR Title, BOOL ReadOnly);
	afx_msg long GetNormalColour(short WhichColour);
	afx_msg void SetNormalColour(short WhichColour, long nNewValue);
	afx_msg long GetBoldColour(short WhichColour);
	afx_msg void SetBoldColour(short WhichColour, long nNewValue);
	afx_msg long GetCustomColourText(short WhichColour);
	afx_msg void SetCustomColourText(short WhichColour, long nNewValue);
	afx_msg long GetCustomColourBackground(short WhichColour);
	afx_msg void SetCustomColourBackground(short WhichColour, long nNewValue);
	//}}AFX_DISPATCH
	DECLARE_DISPATCH_MAP()
	DECLARE_INTERFACE_MAP()

};

/////////////////////////////////////////////////////////////////////////////


// MXP-oriented utilities

bool GetWord (CString & strResult, CString & str);
CString GetArgument (const CArgumentList & ArgumentList, 
                     CString strName, 
                     const int iPosition, 
                     const bool bLowerCase = false);
bool GetKeyword (CArgumentList & ArgumentList, 
                     CString strName);
bool IsNumeric (const CString & str);
bool IsValidName (const CString & str);
bool SetColour (const CString & strName, COLORREF & iColour);
CString GetAction (const CString & str);
CString GetHint (const CString & str);
void StringToList (const CString str, const char * delim, CStringList & thelist);
void ListToString (const CStringList & thelist, const char * delim, CString & str);


#define MAKE_STRING(msg) \
   (((ostringstream&) (ostringstream() << boolalpha << msg)).str())

// for timing things

class timer
  {
  LARGE_INTEGER start;
  LONGLONG iCounterFrequency;

  const string sReason;

  public:

    // constructor remembers time it was constructed
    timer (const string s) : sReason (s)
      {
      LARGE_INTEGER large_int_frequency;  
      QueryPerformanceFrequency (&large_int_frequency);
      iCounterFrequency = large_int_frequency.QuadPart;
      QueryPerformanceCounter (&start);
      TRACE (MAKE_STRING ("Start     : " << left << sReason << endl).c_str ());
      };

    // destructor gets current time, displays difference
    ~timer ()
      {
      LARGE_INTEGER finish;
      LONGLONG iTimeTaken;    
      QueryPerformanceCounter (&finish);  
      iTimeTaken = finish.QuadPart - start.QuadPart; 
      double fTime = ((double) iTimeTaken) /      
                     ((double) iCounterFrequency);    

      // TRACE or ::AfxMessageBox (for release builds)

      TRACE (MAKE_STRING ( "Time taken: " << left << sReason << " = "
           << fixed << fTime << " seconds." << endl ).c_str ());

      }
  };    // end of class timer
