/*
   GDataList.mcc is a subclass of listviewclass.

   Note: Compile with SAS/C 6.1 and above.
*/

/* Includes */
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/mui.h>
#include <libraries/iffparse.h>
#include <dos/dos.h>
#include <clib/alib_protos.h>
#include <clib/alib_stdio_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>
#include <clib/muimaster_protos.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>

#include <pragmas/exec_sysbase_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/iffparse_pragmas.h>
#include <pragmas/muimaster_pragmas.h>

#include <mui/DataList_mcc.h>
#include <mui/GDataList_mcc.h>


struct DataList {
   APTR     pObj;
   ULONG    ulAttr;
   UBYTE    ubType;           // TYPE_INTEGER, TYPE_STRING or TYPE_INDEXED
   APTR    *ppValuesArray;    // array of strings (or image-
                              // strings) to index into with the
                              // data value for this object.
                              // e.g. point to the labels for an
                              //      RadioObject.
};
struct DataDL
{
   UBYTE     ubDelimeter;

   Object   *pFocusObject;

   UBYTE     szColumns[256];

   UBYTE   **ppszTitles;
   UBYTE    *pszFile;

   struct DataList   *pDL;
   UBYTE              ubDLIndex;     // index of next DataList entry
   UBYTE              ubDLLen;       // length of DL entities ( must be < 255 )

   LONG      lLastMatch;

   LONG      lSortDirection;
   LONG      lSortPrimary;
   LONG      lSortSecondary;

   LONG      lDiskTitles;
   UBYTE   **ppszDiskTitles;
   ULONG     ulMaxRecordLength;

   struct Hook  *hDestructHook;
   struct Hook  *hDisplayHook;
   struct Hook  *hSortHook;
};

struct Library *MUIMasterBase = NULL;
struct Library *UtilityBase   = NULL;
struct Library *IntuitionBase = NULL;

extern struct Library *SysBase;
extern struct Library *DOSBase;

int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}

#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif

LONG __stack = 8192;


//
//   F  U  N  C  T  I  O  N  S
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static VOID fail(APTR app, char *t)
{
   if (t) puts(t);

   if (app)             MUI_DisposeObject(app);
   if (MUIMasterBase)   CloseLibrary(MUIMasterBase);
   if (UtilityBase)     CloseLibrary(UtilityBase);
   if (IntuitionBase)   CloseLibrary(IntuitionBase);
   if (DOSBase)         CloseLibrary(DOSBase);
   exit(0);
}

/***************************************************/
/**                MAIN PROGRAM                   **/
/***************************************************/
int main(int argc,char *argv[])
{
   Object *app,*win,*list,*str,*cyc,*rad,*load,*save,*addrec,*fabrec,*reprec;
   ULONG signals;
   BOOL running = TRUE;
   BPTR fh;

   static char *titles[]   = { "\33bName","\33bCycler","\33bFM Dude", NULL };
   static char *cycarray[] = { "Cyc1","Cyc2","Cyc3", NULL };
   static char *radarray[] = { "Rad1","Rad2","Rad3", NULL };
   static char *buttons[]  = { "_Upsy","_Downsy","_Topsy", "_Butt", NULL };

   // pre-fab record to use with AddRecordFromArray
   static APTR *recarray[] = { (APTR)"String!", (APTR)1, (APTR)0 };

   // array of default values for use when New button is clicked
   static APTR *defarray[] = { (APTR)"(new)", (APTR)0, (APTR)1 };


   //
   // open libraries
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   if (!(DOSBase = OpenLibrary( "dos.library", 37L )))
      fail(NULL,"Cannot open dos.library 37+");

   if (!(IntuitionBase = OpenLibrary("intuition.library",37L)))
      fail(NULL,"Cannot open intuition.library 37+");

   if (!(UtilityBase = (struct Library *)OpenLibrary("utility.library",37L)))
      fail(NULL,"Couldn't open utility.library.");

   if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
      fail(NULL,"Couldn't open muimaster.library.");

   app = ApplicationObject,
      MUIA_Application_Title      , "ShowGDataList",
      MUIA_Application_Version    , "ShowGDataList 1.0 (13.11.95)",
      MUIA_Application_Copyright  , "(C) 1995  by John Haubrich",
      MUIA_Application_Author     , "John Haubrich",
      MUIA_Application_Description, "Show the GDataList custom class.",
      MUIA_Application_Base       , "SHOWDATALIST",

      SubWindow, win = WindowObject,
         MUIA_Window_Title, "Show the GDataList public custom class",
         MUIA_Window_ID   , MAKE_ID('S','A','S','G'),

         WindowContents, VGroup,
            Child, list   = GDataListObject,
               MUIA_GDataList_DefaultValues   , defarray,
               MUIA_GDataList_DelButton       , "_Zap!",
               MUIA_GDataList_DelConfirm      , "Are you sure you want me to delete this stuff?",
               MUIA_GDataList_DelResponse     , "*Yes!|No, sir.",
               MUIA_GDataList_DelVerify       , TRUE,
               MUIA_GDataList_InsertPosition  , MUIV_List_Insert_Sorted,
               MUIA_GDataList_MoveButtons     , buttons,
               MUIA_GDataList_NewButton       , "_Nuevo",
               MUIA_GDataList_NumSelected     , "Selected = %-.3ld",

               MUIA_DataList_AttachCount     , 3,
               MUIA_DataList_Delimeter       , '&',
               MUIA_DataList_DiskTitles      , MUIV_DataList_DiskTitles_On,
               MUIA_DataList_MaxRecordLength , 2048,
               MUIA_DataList_Sort            , MUIV_DataList_Sort_Ascending,
               MUIA_DataList_SortPrimary     , 0,
               MUIA_DataList_SortSecondary   , 2,
               MUIA_DataList_Titles          , titles,
               End,
            Child, str = StringObject, StringFrame,
               End,
            Child, HGroup,
               Child, HSpace(0),
               Child, KeyLabel1("Cycler",'c'),
               Child, cyc = KeyCycle(cycarray,'c'),
               Child, HSpace(0),
               End,
            Child, HGroup,
               Child, HSpace(0),
               Child, VGroup, GroupFrameT("FM Dude"),
                  Child, rad = RadioObject,
                     MUIA_Radio_Entries, radarray,
                     End,
                  End,
               Child, HSpace(0),
               End,
            Child, addrec = KeyButton("Add",'a'),
            Child, fabrec = KeyButton("Add Pre-Fab",'f'),
            Child, reprec = KeyButton("Replace",'r'),
            Child, load   = KeyButton("Load",'l'),
            Child, save   = KeyButton("Save",'s'),
            End,
         End,
      End;

   if (!app)
      fail(app,"Couldn't create app object.");

   set( list, MUIA_GDataList_FocusObject, rad );

/*
** Attach objects to datalist...
*/
   DoMethod(list, MUIM_DataList_Attach, str, MUIA_String_Contents, TYPE_STRING , NULL     );
   DoMethod(list, MUIM_DataList_Attach, cyc, MUIA_Cycle_Active   , TYPE_INDEXED, cycarray );
   DoMethod(list, MUIM_DataList_Attach, rad, MUIA_Radio_Active   , TYPE_INDEXED, radarray );

/*
** Install notification events...
*/
   DoMethod(win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
            app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
   DoMethod(load  , MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 101 );
   DoMethod(save  , MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 102 );
   DoMethod(addrec, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 103 );
   DoMethod(fabrec, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 104 );
   DoMethod(reprec, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 105 );


/*
** Input loop...
*/

   set(win,MUIA_Window_Open,TRUE);

   while (running)
   {
      switch (DoMethod(app,MUIM_Application_Input,&signals))
      {
         case MUIV_Application_ReturnID_Quit:
            running = FALSE;
            break;
         case 101:   // load data
            fh = Open("datalist.data",MODE_OLDFILE);
            DoMethod( list, MUIM_DataList_Load, fh );
            if ( fh )   Close( fh );
            break;
         case 102:   // save data
            fh = Open("datalist.data",MODE_READWRITE);
            DoMethod( list, MUIM_DataList_Save, fh );
            if ( fh )   Close( fh );
            break;
         case 103:   // add data to list
            DoMethod( list, MUIM_DataList_AddRecord, MUIV_DataList_AddRecord_ReplaceNone, 0 );
            break;
         case 104:   // add pre-fab data to list
            DoMethod( list, MUIM_DataList_AddRecordFromArray, recarray, MUIV_DataList_AddRecord_ReplaceNone, 0 );
            break;
         case 105:   // replace current selection with new data
            DoMethod( list, MUIM_DataList_AddRecord, MUIV_DataList_AddRecord_ReplaceActive, 0 );
            break;
      }

      if (running && signals) Wait(signals);
   }

   set(win,MUIA_Window_Open,FALSE);


/*
** Shut down...
*/

   fail(app,NULL);
}
