#define INTUI_V36_NAMES_ONLY
#define __USE_SYSBASE

#include <dos.h>

#include <stdio.h>
#include <string.h>
#include <math.h>

#include <dos/dosextens.h>

#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>

#include <graphics/gfxmacros.h>
#include <graphics/text.h>
#include <graphics/modeid.h>

#include <intuition/gadgetclass.h>
#include <intuition/intuition.h>

#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <libraries/iffparse.h>

#include <prefs/palette.h>

#include <proto/asl.h>
#include <proto/commodities.h>
#include <proto/diskfont.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/icon.h>
#include <proto/iffparse.h>
#include <proto/intuition.h>
#include <proto/locale.h>
#include <proto/utility.h>

#include <clib/extras_protos.h>
#include <clib/extras/exec_protos.h>

#define MPVER "4.64"
#define VER 4
#define REV 64

#define REG register
#define ASM __asm

#define REQDEFHEIGHT (174-16)

#define SA_ModeProNode (TAG_USER | 1<<30 | 0xBADC0DE ) 

/**** GENERAL STUFF ****/
#define p(x) //printf(x);

#define FUNCCAST unsigned long (* )()
#define LIBCAST  struct Library *

#define DRIPENS 12

#define SEMAPHORES 6

// Add PrefsLeft, .Top  Active List & Node etc...

#define NUM_LISTS 4

struct MPSem
{
  struct SignalSemaphore  SharedSem,  // Shared sem to keep struct valid.
                          PrefsSem,   // Obtained by MPPrefs, only allows one Prefs open
                          ListSem,    // shared, allows shared read access to the PromotionLists
                          NodeSem,    // exclusive, allows exclusive r/w access to the PromotionLists 
                          OpenListSem,// allows access to the OpenList
                          PortSem;    // allows access to the ports
  /* NOTE TO BRAIN: NEVER EVER EVER ADD Anything between PortSem AND Version!!!!! */
  ULONG  Version,
         Revision;
  STRPTR HotKey;
  BOOL   Enabled,
         EnabledNLM,
         CatchPubScreens,
         CatchScreens,
         CatchPopup;
  struct MsgPort  *DaemonPort,
                  *PrefsPort;
  struct List OpenList;
  struct List PromotionList[NUM_LISTS];
  ULONG  Debug;     // Added in ver 4.6
  ULONG  CenterAll; // Added in ver 4.8
  BOOL   FirstPrefsOpen;
  WORD   LeftEdge,TopEdge;
  LONG   LVActive,
         CurrentList;
  WORD   WinWidth,WinHeight;
  struct MsgPort PrefsToDoPort;   // v4.27 // Things that the prefs editor must do (ForcedEdit Msgs for ex)//  (4.63.1)
  struct PalettePrefs PPrefs;
  BOOL   PPrefsSet;
/*  struct MsgPort OptionPort;
  struct SignalSemaphore OptionSem;*/
};

#define ForcedEditPort PrefsToDoPort//                                                                 (4.63.2)


/* MPSem.PromotionList[PL_?]  &  DefaultNode.Type */
#define PL_PROGRAMNAMES   0
#define PL_SCREENNAMES    1
#define PL_SCREENMODES    2
#define PL_PUBLICSCREENS  3

/* Newstyle names */
#define MPSEM_PLIST_PROGRAMNAMES    0
#define MPSEM_PLIST_SCREENNAMES     1
#define MPSEM_PLIST_SCREENMODES     2
#define MPSEM_PLIST_PUBLICSCREENS   3
#define MPSEM_PLIST_MAX             3

/*******************************/ 
/*  Messages between MP & MPP  */

struct MPMessage
{
  struct Message mp_Message;
  ULONG Command,Code;
  APTR Data;
};

struct MPScreenMessage
{
  struct Message mp_Message;
  ULONG Command,Code;
  struct DefaultNode *DN;
  struct OpenNode *ON;
};

/* arrows indicate which ways messages can travel */
#define MP_QUIT            1  // Mp <-  MPP
#define MP_PREFSTOFRONT    2  // MP  -> MPP
#define MP_PREFSCLOSE      3  // MP  -> MPP
#define MP_NEWNODE         4  // MP  -> MPP, Code = listnumber; Data = Node
#define MP_REMNODE         5  // A node was removed & freed, used to be a &Data, NOT USED
#define MP_LISTSTATUS      6  // MP  -> MPP,
#define MP_REFRESH         7  // MP  -> MPP, currently for refreshing Menu settings from MPSem
#define MP_CDTYSTATUS      8  // NOT USED.

#define MP_SAVE           10  // MP  -> MPP, Instruct MPPrefs to save.
#define MP_SHOWGUI        11  // Patch -> MP, show gui, Code = Success
//??????????????????????????????????

#define MP_PUBSCREEN      12  // Patch -> MP, open a public screen.
                              // Code 0:Open/Lock 1:Close/Unlock
                              // Data is Name 

#define MP_SCREENOPENED   13  // Patch -> MP, Data = OpenNode * 
#define MP_SCREENCLOSING  14  // Patch -> MP, Data = OpenNode *

// ToDo messages
#define MPTD_IMPORT         15
#define MPTD_FORCEDEDIT     9 
#define MP_FORCEDEDIT       MPTD_FORCEDEDIT 
                              // MP  -> MPP, Sets prefs to forced edit mode. Data is DNode ptr. 
                              // Only sent to MPSem->PrefsToDoPort
                              // Prefs ReplyMsg Code values: 
                              // 0 - Cancel 1-Permant Ignore, 2-Use&Delete 3-Save&Use

// MP_LISTSTATUS Codes
#define MPLS_NORMAL        0  // ModePro is in normal mode.  ModeProPrefs can access lists
#define MPLS_UPDATING      1  // ModePro is in updating the list(s).  ModeProPrefs cannot access lists

// MP_CDTYSTATUS Codes
#define MPCS_DISABLED    0
#define MPCS_ENABLED     1

// MP_FORCEDEDIT return Codes
#define MPFE_CANCEL      0
#define MPFE_NEVER       1
#define MPFE_USEDELETE   2
#define MPFE_SAVEUSE     3

/*** STRUCTURES ***/




/* Data Nodes for OpenNode.DataList */
struct BackdropNode
{
  struct Node bn_Node; //ln_Type = MPDN_Backdrop
  struct Window *bn_Window;
  struct DTObject *bn_DTObject;
};

struct QuickPicNode
{
  struct Node qn_Node; //ln_Type = MPDN_QuickPic
  struct Window *qn_Window;
};



struct RGB
{
  ULONG Red,Green,Blue;
};

struct DefaultNode
{
  struct  Node Def_Node; // 14
  UWORD   Type;  // see PL_types  //2
  ULONG   ModeSelect; //4
  ULONG   ModeID; //4
  WORD    Width, //2
          Height; //2
  ULONG   OverscanType;//4
  UBYTE   AutoScroll;//1
  UBYTE   Look3D; //1
  ULONG   Flags; //4
  WORD    Pens[DRIPENS]; //24
  UBYTE   FontType; //1 + 1
  struct  TTextAttr Font; //12
  ULONG   PubOptions; //4
  UBYTE   *PubName; //4
  UWORD   Depth; //2
  UBYTE   *LockedPens; //4
  UBYTE   *HotKey;//4
  ULONG   OrigDisplayID; //4
  UBYTE   ODFlags; //1
  UBYTE   CenterFlags; //1
  LONG    Colors; //4
  struct  RGB *Palette; //4
  BYTE    BackdropType; //1
  BYTE    BackdropFlags; //1
  STRPTR  BackdropFile; //4
  struct  RGB BackdropRGB; //12
  
}; //126

/* DefaultNode.ModeSelect */
#define MS_DONT_PROMOTE         0
#define MS_PROMOTE_MONITOR      1
#define MS_PROMOTE_SCREENMODE   2
#define MS_PROMOTE_REQUESTER    3
#define MS_PROMOTE_BEST_MODE    4

#define MS_PROMOTE_MAX          4





/* DefaultNode.Flags */
#define INTERLEAVE        (1<<0)
#define CENTER            (1<<2)  // obsolete as of 4.6
#define FIXASPECT         (1<<3)  // for the font
#define DEPTH             (1<<4) 
#define SHAREPENS         (1<<5)
#define SCRHOTKEY         (1<<6)
/* newstyle names */
#define DNF_PALETTE       (1<<7)
#define DNF_FORCEPLANAR   (1<<8) 
#define DNF_IGNORE_WH     (1<<9)  // Ignore Width & Height settings.  (4.19)
#define DNF_BLANK_BORDER  (1<<10)
#define DNF_BEHIND        (1<<11)
#define DNF_3D_DEFAULT    (1<<12) // Use system defaults for 3d pens
#define DNF_NEVER_PROMOTE (1<<13)
#define DNF_UNAPPROVED    (1<<14)

#define DNODE_OSCANTYPE_MIN 1
#define DNODE_OSCANTYPE_MAX 4

#define BF_ON      (1<<0) /* obsolete */
#define BF_CENTER  (1<<1)
#define BF_TILE    (1<<2)

/* DNode.BackdropType */
#define DNODE_BACKDROPTYPE_OFF    0
#define DNODE_BACKDROPTYPE_IMAGE  1
#define DNODE_BACKDROPTYPE_COLOR  2
#define DNODE_BACKDROPTYPE_MAX    2

/* DefaultNode.FontType */
#define SFONT_PROG      0
#define SFONT_SYS       1
#define SFONT_MP        2


/* The OpenNode structure is allocated when certain screens 
 *   are promoted and require certain resources to be allocated 
 ***************************************************************/

#define MAX_ONPENS 256

struct OpenNode
{
  struct Node on_Node; // 14
  struct Screen *Screen; // 4
  ULONG  Flags; // 4
  struct TTextAttr TA; // 12
  UBYTE  PubName[MAXPUBSCREENNAME+1]; // 140
  CxObj  *Cx; // 4
  UBYTE  *HotKey; // 4
  UBYTE  *ScreenTitle; // 4
  struct BitMap *BitMap; // 4
  UBYTE  ObtainedPens[MAX_ONPENS]; // 256
  struct DefaultNode *DN;  // 4 Copy of the defaultnode that promoted this screen.
  struct Screen *PubScreenLock;
/*  struct MsgPort MPort;
  struct SignalSemaphore SS;
  struct List *MPData;*/
};

/* OpenNode.Flags */
#define ON_FONT         (1<<0)  /* If the font was specified by MP .TA is set */
#define ON_PUBLIC       (1<<1)  /* Is a public screen */
#define ON_OPEN         (1<<2)  /* This flag is set until the screen owner calls CloseScreen() */ 
#define ON_WORKBENCH    (1<<4)  /* This OpenNode belongs to the Workbench screen. */
#define ON_SCANNED      (1<<7)  /* When MP knows that this node exists, it sets this bit */
#define ON_CLOSEME      (1<<8)  /* Try to close this screens */

// 4.53 (UNUSED) #define ON_HOTKEY       (1<<3)  /* This OpenNode has a hotkey assigned to it, .CX .HotKey .ScreenTitle are set */  
// 4.53 (UNUSED) #define ON_BITMAP       (1<<5)  /* If forced planar .BitMap is set */
// 4.53 (UNUSED) #define ON_QUICKWIN     (1<<6)  /* Never used! Has a quickwindow ??, .QuickWindow is set */

//833 1072





#define ALL_MODES (~MONITOR_ID_MASK)
#define BADMODES (DIPF_IS_HAM | DIPF_IS_DUALPF | DIPF_IS_PF2PRI | DIPF_IS_EXTRAHALFBRITE)

BOOL    LoadFile(struct List *List, UBYTE *fname);
void    FreeDNode(struct DefaultNode *dn);
void    FreeDefList(struct List *);
void    FreeAllDefLists(struct List *);
struct DefaultNode *AllocDefaultNode(STRPTR Name);
struct DefaultNode *DupDNode(struct DefaultNode *Src);
