//
// The Fusion Library Interface for DOS
// Version 1.06c
// Copyright (C) 1990, 1991, 1992
// Software Dimensions
//
// Main Header File for NON window related classes, variables, and functions
//
// This file will automatically include the DEFINES.H file.
//

// ==========================================================================
// Consult the reference manual for complete function reference of all
// functions within this header file.  All variables are documented
// inside this header file, for ease of use when modifying the supplied
// source code.  For additional class information, please consult the
// Software Dimensions BBS.  Telephone numbers are included in the
// READ.ME file and in the documentation.
// ==========================================================================

#ifndef __cplusplus
#error Please switch to C++ mode before using Fusion
#endif

#ifdef __PASCAL__
#error The Pascal calling convention cannot be used with Fusion
#endif

#ifndef __Fusion__
#define __Fusion__

#ifndef __FusionDefines__
#include "defines.h"
#endif

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// Setting this variable to a non-zero value will force the computer to      //
// display shadows behind dialogs, pull down menus, and pop up menus.        //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

extern int FusionShadowing;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// Mouse handling functions                                                  //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

extern int MouseEvent;              // Event code for last queued mouse event
extern int MouseButtonStatus;       // Current button down status
extern int MouseHorizontal;         // Current X position of mouse
extern int MouseVertical;           // Current Y position of mouse

extern int MouseAvailable;          // Is mouse available?  DO NOT alter this
                                    // variable to disable the mouse -- use
                                    // MouseShutDown() instead

extern int MouseDoubleClickFactor;  // Speed required for double click
extern int MouseRepeatDelay;        // Delay until auto repeat
extern int MouseRepeatSpeed;        // Repeat speed after delay is depleated

void MouseHide();
void MouseShow();
void MouseShutDown();
void MouseReStart();
void MousePosition(int,int);
void GetMouseQueue();
void FlushMouseQueue();
void MouseLocate();

int MouseButtons();

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// FLIVideoProtect -- By Setting This Variable To 1, anywhere in your program//
// you will force the linker to include the video state saving startup and   //
// exit functions that will ensure your program is polite and will return    //
// the video characteristics to their state BEFORE your program started.     //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

extern int FLIVideoProtect;

class _FLIVideoProtect
{
  int TopCursor;                // DO NOT use this class in your own programs
  int BottomCursor;             // Consult the manual about altering the
  int DisplayMode;              // FLIVideoProtect variable
  int OtherEGAVGA;
  int Height;

public:

  _FLIVideoProtect();
  ~_FLIVideoProtect();
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// CharMask - Character Masking Class                                        //
// NumberMask - Numeric Masking Class                                        //
//                                                                           //
// Base class for Dialogs and Blaze to handle masking functions              //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class BlazeClass;

class CharMask
{
protected:

  static int MaskCheck(int,int &,int=1);
  static void MaskShow(char *,char *,BlazeClass &,int=0,int=0);
};

class NumberMask
{
protected:

  static void MaskShow(char *,char *,BlazeClass &);
  static void CountPlaces(char *,int &,int &);
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// BlazeClass - The text handling class                                      //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

extern int IsBigCursor; // Is a big cursor on the screen?

class BlazeClass : public CharMask, public NumberMask
{
private:

  static void far *VIDEO;           // Pointer to Mono or Color video RAM
  static int ScreenHeight;          // Physical screen height
  static int ScreenWidth;           // Physical screen width
  static int QuickWidth;            // Physical screen width * 2 (speeds calcs)
  static int Intense;               // Intense background colors=1
                                    // Flashing capability=0

  void far *OUTPUT;                 // Current output location in video RAM
                                    // or user specified location (UseMemory)

  int X;                            // Current X location of text output
  int Y;                            // Current Y location of text output
  int Clip;                         // Video clipping is on (1) or off (0)
  int WinX;                         // Upper X corner of window
  int WinY;                         // Upper Y corner of window
  int Color;                        // Current text output color
  int Center;                       // Centering is on (1) or off (0)
  int WinHigh;                      // Height of the window
  int WinWide;                      // Width of the window
  int Scrolling;                    // Scrolling is on (1) or off (0)
  int FlushRight;                   // Flush right is on (1) or off (0)

                                    // These are the current characters
                                    // that are using with the Box...()
                                    // function set

  char TopLeft;                     // Top left hand corner of box
  char TopRight;                    // Top right hand corner of box
  char TopCenter;                   // Top center of box
  char CenterLeft;                  // Left hand center of box
  char CenterFill;                  // Interior of box
  char BottomLeft;                  // Bottom left of box
  char CenterRight;                 // Right hand center of box
  char BottomRight;                 // Bottom right of box
  char BottomCenter;                // Bottom center of box

public:

  BlazeClass();
  BlazeClass(BlazeClass &_Blaze);

  BlazeClass& operator -  ();
  BlazeClass& operator -- ();

  BlazeClass& operator () (int,int);
  BlazeClass& operator << (char *);
  BlazeClass& operator << (char);
  BlazeClass& operator << (int);
  BlazeClass& operator [] (int);
  BlazeClass& operator << (BlazeClass& (*_f)(BlazeClass&))
    { return ((*_f)(*this)); }

  int operator ! ();
  int operator + ();

  void far *WhatOutput();

  int WhereX();
  int WhereY();
  int WhatWinWidth();
  int WhatWinHeight();
  int QuickDisplay(int,int,int,int,char *);

  void BigCursor(int=0);
  void BlockCopyVirtualToVisual(int,int,int,int,void far *);
  void BlockCopyVisualToVirtual(int,int,int,int,void far *);
  void Box(int,int,int,int,int);
  void BoxAttribute(int,int,int,int,int);
  void BoxFilled(int,int,int,int,int);
  void ChangeForeground(int,int,int,int,int);
  void ChangeBackground(int,int,int,int,int);
  void CharacterFill(int,int,int,int,int,int);
  void CharacterRepeater(int,int,int,int,int);
  void CharacterRepeaterDown(int,int,int,int,int);
  void CopyArea(int,int,int,int,int,int);
  void CopyFromTo(int,int,int,int,void far *,void far *);
  void CopyVirtualToVirtual(void far *,void far *);
  void CopyVirtualToVisual(void far *);
  void CopyVisualToVirtual(void far *);
  void EraseArea(int,int,int,int,int);
  void FreshWorkSpace();
  void GetArea(int,int,int,int,void far *);
  void HelpLine(int,char *);
  void LineAttribute(int,int,int,int);
  void PutArea(int,int,void far *);
  void ScrollDown(int,int,int,int);
  void ScrollLeft(int,int,int,int);
  void ScrollRight(int,int,int,int);
  void ScrollUp(int,int,int,int);
  void Shadow(int,int,int,int);
  void UseMemory(void far *);
  void UseVideo();
  void UserBoxDefine(int,int,int,int,int,int,int,int,int);
  void UserBoxDefineQuick(int);
  void Window(int,int,int,int);
  void WindowGotoXY(int,int);
  void WindowInformation(int &,int &,int &,int &);

  static int ChangePalette(int,int);
  static int CheckVisible();
  static int ComputeNeededBytes(int,int);
  static int GetKey();
  static int IsBlackWhite();
  static int IsMonochrome();
  static int SeeKey();
  static int ToggleIntense();
  static int WhatHeight();
  static int WhatWidth();

  static void GetXY(int &,int &);
  static void GotoXY(int,int);
  static void InvisibleCursor();
  static void VisibleCursor();

  char * Mask(char *,char *);
  char * Mask(char *,int &);
  char * Mask(char *,long &);
  char * Mask(char *,float &);
  char * Mask(char *,double &);

  #ifdef __BCD_H
  char * Mask(char *,bcd &);
  #endif

  friend BlazeClass& Centered(BlazeClass&);
  friend BlazeClass& Flushed(BlazeClass&);
  friend BlazeClass& MoveLeft(BlazeClass&);
  friend BlazeClass& MoveRight(BlazeClass&);
  friend BlazeClass& MoveUp(BlazeClass&);
  friend BlazeClass& MoveDown(BlazeClass&);

  friend _FLIVideoProtect::~_FLIVideoProtect();
};

BlazeClass& Centered(BlazeClass&);
BlazeClass& Flushed(BlazeClass&);
BlazeClass& MoveLeft(BlazeClass&);
BlazeClass& MoveRight(BlazeClass&);
BlazeClass& MoveUp(BlazeClass&);
BlazeClass& MoveDown(BlazeClass&);

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// FusionHelp - The Fusion Help controller system                            //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

extern int HelpSystemAvailable; // Is help available (i.e. the help file)
extern int DisabledHelp; // Was the help system shut off by the programmer?

class FusionHelp
{
public:

  int HelpId;                       // Id of the current help screen

  static int DefineHelp(char *);
  static void DisableHelp();

protected:

  void EngageHelp();
  void RequestHelp(int);

  FusionHelp();
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// EventClass - The event handling class                                     //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class Event : virtual public FusionHelp
{
private:

  static int EventTimer;            // Number of timer ticks between each
                                    // live function call

  void (**ActionQueue)();           // Pointers to live functions
  int ActionCount;                  // The total number of live functions

  long ActionTimer;                 // Contains timer that determines when
                                    // the live functions should be called

  BlazeClass Blaze;                 // Definition of BlazeClass

protected:

  int X;                            // X location of the event controlled area
  int Y;                            // Y location of the event controlled area
  int XShadow;                      // Is there a shadow?
  int YShadow;                      // Is there a shadow?
  int Shadowing;                    // Shadow status when class constructed
  int Width;                        // Width of the event controlled area
  int Height;                       // Height of the event controlled area
  int CloseIcon;                    // Region has close icon (1) or not (0)

  char *ScreenSave;                 // Saved portion of the screen

public:

  Event();
  ~Event();

  int GetEvent(int=0);

  void NotClosable();
  void RestoreWindow();
  void LocalLive(void (*Action)());
  void SpecifyWindow(int X,int Y,int Width,int Height);

  static void SetLiveTime(int Timer) { EventTimer=Timer; }
  static void GlobalLive(void (*GlobalAction)());

private:

  int JustEvent();
  void MoveWindow();
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// DialogElement - An abstract class for defining elements                   //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class DialogElement
{
public:

  int X;                            // X coordinate of this element
  int Y;                            // Y coordinate of this element
  int LocX;                         // X coordinate of element locator
  int LocY;                         // Y coordinate of element locator
  int Width;                        // Width of this element
  int Height;                       // Height of this element
  int QuickKey;                     // Quick key used to jump to this element
  int GroupCode;                    // Which group owns this element?
  int FusionHelp;                   // What help screen goes with this element?

  int *Avail;                       // Quick availability checker

  char *Help;                       // Help text for the bottom of the screen
  char *LocatorText;                // The text displayed for the locator

  BlazeClass *Blaze;                // A pointer to BlazeClass within the
                                    // DialogClass that is using this
                                    // element

  DialogElement *Last;              // Pointer to the last element
  DialogElement *Next;              // Pointer to the next element

  DialogElement();
  virtual ~DialogElement();

  virtual int Action();
  virtual int Arrival();
  virtual int Available();
  virtual int Departure();
  virtual int Validation();

  virtual void operator+ (char *);

  virtual void Show() = 0;
  virtual void HighLight() = 0;
  virtual int EventHandler(int) = 0;
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// DialogClass - The main handler for the dialog elements                    //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class DialogClass : public Event
{
private:

  static int DialogTimer;           // Number of ticks between each action
                                    // event call

  DialogElement *Last;              // Pointer to the last element
  DialogElement *First;             // Pointer to the very first element
  DialogElement *Current;           // Pointer to the current element (init)
  DialogElement *Present;           // Pointer to the present element (usage)

  DialogElement *LastPresent;       // Pointer to the last, present element

  char *TopTitle;                   // Title of the dialog

  int XSave;                        // Saved X cursor location
  int YSave;                        // Saved Y cursor location
  int Grouped;                      // Current group number (if there is one)
  int MultiTask;                    // Is mutitasking in use (1) or not (0)
  int UseAction;                    // Action functions in use (1) or not (0)
  int LocatedFirst;                 // What is the first group?

  int PreXSave;                     // Save X and Y at dialog powerup
  int PreYSave;

  int AlreadyShown;                 // The dialog has been shown, so do
                                    // not redraw the locators and stuff
  int GroupLock;                    // Used to lock into a group

  int CheckBigCursor;               // Is big cursor on screen?
  int CheckVisible;                 // Is cursor visible on screen?

  int NoDefaults;                   // Are default keys overriden

  void *BottomSave;                 // Storage for bottom line of display

  long ActionTimer;                 // Timer storage for multitasking and
                                    // action functions

  struct _GroupHeadings             // Storage for group headings
  {
    int X;                             // X coordinate of this group heading
    int Y;                             // Y coordinate of this group heading
    int GroupCode;                     // Code for this group
    int HotKey;                        // Hotkey that jumps to this group
    char *Heading;                     // Heading for this group
  } *HeadingStorage;

  int HeadingCount;                 // Number of group headings

  int Valid();
  int NextGroup();
  int NextElement();
  int PreviousGroup();
  int NextWithinGroup();
  int PreviousElement();
  int PreviousWithinGroup();
  int Depart(DialogElement &);
  int Arrive(DialogElement &);

  int CallAllActions();
  void ShowElements(int=0);
  void ShowDialogBox();
  void ShowLocator(int=1);
  void ShowHeading(int);

public:

  BlazeClass Blaze;

  DialogClass();
  DialogClass(int,int,char *,int=1);
  DialogClass(int,int,int,int,char *,int=1);
  virtual ~DialogClass();

  int UseDialog();
  int RePosition(DialogElement *);

  void Help(char *);
  void FusionHelp(int);
  void Available(int &);
  void UtilizeMultiTasking();
  void UtilizeActionFunctions();
  void Element(DialogElement *);
  void HotKey(int,int,char *,int=0);
  void GroupElement(int,DialogElement *);
  void GroupHeading(int,int,int,char *,int=0);
  void NoDefaultKeys() { NoDefaults=1; }

  static void SetActionTime(int Timer) { DialogTimer=Timer; }

  DialogClass& operator +(char *);

  virtual int EventHandler(int) = 0;
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// PopUpMenu - The main popup menu class                                     //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class PopUpMenu : public Event
{
private:

  char *TitleOfMenu;                // Title of this menu
  char **HelpStorage;               // Storage for prompt line help
  char **OptionStorage;             // Storage for all menu options

  int AutoSeek;                     // Is menu automatically placed?
  int AllocationError;              // Error in allocation (1) or not (0)
  int NumberOfOptions;              // Number of menu options
  int *QuickKeyStorage;             // Option single-key quick-key storage
  int **OptionAvailable;            // Option availability pointers
  int *FusionHelpStorage;           // Fusion help for options

  BlazeClass Blaze;

public:

  PopUpMenu();
  virtual ~PopUpMenu();

  int UseMenu();
  void Title(char *);
  void NoCloseIcon();
  void Available(int &);
  void Location(int,int);
  void Option(char *,char *,int);

  virtual int EventHandler(int) = 0;
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//
//                                                                           //
// InfoBox - Class to handle information boxes                               //
//                                                                           //
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//

class InfoBox
{
private:

  int AllocationError;              // An allocation error occured
  int NumberOfInfoLines;            // Number of lines in this InfoBox
  int CloseIcon;                    // Is there a close icon on this info box?

  char *TitleOfInfoBox;             // Title of the InfoBox
  char **MessageLineStorage;        // Storage for all InfoBox lines

public:

  InfoBox();
  ~InfoBox();

  int UseInfoBox ();
  void Title(char *);
  void NoCloseIcon();
  InfoBox& operator+ (char *);
};

#endif

