/*
**
** Copyright © 1996 Kai Hofmann. All rights reserved.
** Registered MUI custom class!
**
** $VER: TimeString-Demo.c 12.2 (29.12.96)
**
*/

 #define __MakeLib

 #include "system.h"
 #include "Time_mcc.h"
 #include "TimeString_mcc.h"
 #include <clib/alib_protos.h>
 #include <exec/libraries.h>
 #include <proto/exec.h>
 #include <proto/muimaster.h>
 #include <libraries/mui.h>
 #include <stdio.h>


 #ifdef DEBUG
   void kprintf(UBYTE *fmt,...);
   #define debug(x)	kprintf(x "\n");
 #else
   #define debug(x)
 #endif


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


 struct MUI_CustomClass *App_CC,*Win_CC,*Str_CC;


 struct Library *MUIMasterBase;
 static Object *App;


 struct Win_Data {
                  Object *TimeString;
                 };


 struct App_Data {
                  Object *win1;
                 };

 /* ------------------------------------------------------------------------ */

 static ULONG STACKARGS DoSuperNew(struct IClass *cl, Object *obj, ULONG tags, ...)
  {
   return(DoSuperMethod(cl,obj,OM_NEW,&tags,NULL));
  }

 /* --- String ------------------------------------------------------------- */

 static ULONG Str_New(struct IClass *cl, Object *obj, struct opSet *msg)
  {
   obj = (Object *)DoSuperNew(cl,obj,
                              MUIA_String_Format,	MUIV_String_Format_Left,
                              MUIA_String_MaxLen,	30,
                              MUIA_Frame,		MUIV_Frame_String,
                              MUIA_Background,		MUII_TextBack,
                              TAG_MORE, msg->ops_AttrList
                             );
   return((ULONG)obj);
  }


 static ULONG Str_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragQuery *msg)
  {
   /*struct Str_Data *data = (struct Str_Data *)INST_DATA(cl,obj);*/
   /*ULONG result;*/
   ULONG Hour,Min,Sec;

   if (get(msg->obj,MUIA_Time_Hour,&Hour) && get(msg->obj,MUIA_Time_Minute,&Min) && get(msg->obj,MUIA_Time_Second,&Sec))
    {
     return(MUIV_DragQuery_Accept);
    }
   return(MUIV_DragQuery_Refuse);
  }


 static ULONG Str_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  {
   /*struct Str_Data *data = (struct Str_Data *)INST_DATA(cl,obj);*/
   /*ULONG result;*/
   char str[30];
   ULONG Hour,Min,Sec;

   /*result =*/ get(msg->obj,MUIA_Time_Hour,&Hour);
   /*result =*/ get(msg->obj,MUIA_Time_Minute,&Min);
   /*result =*/ get(msg->obj,MUIA_Time_Second,&Sec);
   sprintf(str,"%lu:%lu:%lu",Hour,Min,Sec);
   /*result =*/ set(obj,MUIA_String_Contents,(ULONG)str);
   return(0);
  }


 static ULONG SAVEDS_ASM Str_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  {
   switch (msg->MethodID)
    {
     case OM_NEW			: return(Str_New(cl,obj,(struct opSet *)msg));
     case MUIM_DragQuery		: return(Str_DragQuery(cl,obj,(struct MUIP_DragQuery *)msg));
     case MUIM_DragDrop			: return(Str_DragDrop(cl,obj,(struct MUIP_DragDrop *)msg));
     default				: return(DoSuperMethodA(cl,obj,msg));
    }
  }

 /* --- Window ------------------------------------------------------------- */

 static ULONG Win_New(struct IClass *cl, Object *obj, struct opSet *msg)
  {
   Object *TimeString,*Hour,*Min,*Sec,*saveobj,*loadobj,*format;

   obj = (Object *)DoSuperNew(cl,obj,
                              MUIA_Window_ID,			MAKE_ID('D','E','M','O'),
                              MUIA_Window_Title,		"TimeString-Demo",
                              MUIA_Window_ScreenTitle,		"TimeString-Demo V1.3",
                              MUIA_Window_RootObject,		VGroup,
                                MUIA_Group_SameWidth,		TRUE,
                                MUIA_Group_Child,		TimeString = TimeStringObject,
                                  MUIA_Frame,			MUIV_Frame_String,
                                  MUIA_FrameTitle,		"TimeString.mcc",
                                  MUIA_CycleChain,		1,
                                  MUIA_Draggable,		TRUE,
                                  /*MUIA_Dropable,		FALSE,*/
                                  MUIA_Time_Hour,		17,
                                  MUIA_Time_Minute,		0,
                                  MUIA_Time_Second,		0,
                                  /*MUIA_Time_ZoneMinute,	60,*/
                                  /*MUIA_Time_DaylightSaving,	FALSE,*/
                                  /*MUIA_Time_ChangeDay,	MUIV_Time_ChangeDay_SummerToWinter,*/
                                  /*MUIA_TimeString_TimeFormat,	"%H:%M:%S",*/
                                  MUIA_String_AdvanceOnCR,	TRUE,
                                  MUIA_ObjectID,		1,
                                End,
                                MUIA_Group_Child,		HGroup,
                                  MUIA_Group_SameHeight,	TRUE,
                                  MUIA_Frame,			MUIV_Frame_Group,
                                  MUIA_Group_Child,		RectangleObject,
                                  End,
                                  MUIA_Group_Child,		Hour = NumericbuttonObject,
                                    MUIA_Numeric_Format,	"%lu",
                                    MUIA_Numeric_Min,		0,
                                    MUIA_Numeric_Max,		23,
                                    MUIA_Numeric_Default,	0,
                                    /*MUIA_Numeric_Value,	21,*/
                                    MUIA_CycleChain,		1,
                                    MUIA_Font,			MUIV_Font_Button,
                                  End,
                                  MUIA_Group_Child,		Min = NumericbuttonObject,
                                    MUIA_Numeric_Format,	"%lu",
                                    MUIA_Numeric_Min,		0,
                                    MUIA_Numeric_Max,		59,
                                    MUIA_Numeric_Default,	0,
                                    /*MUIA_Numeric_Value,	0,*/
                                    MUIA_CycleChain,		1,
                                    MUIA_Font,			MUIV_Font_Button,
                                  End,
                                  MUIA_Group_Child,		Sec = NumericbuttonObject,
                                    MUIA_Numeric_Format,	"%lu",
                                    MUIA_Numeric_Min,		0,
                                    MUIA_Numeric_Max,		59,
                                    MUIA_Numeric_Default,	0,
                                    /*MUIA_Numeric_Value,	0,*/
                                    MUIA_CycleChain,		1,
                                    MUIA_Font,			MUIV_Font_Button,
                                  End,
                                  MUIA_Group_Child,		RectangleObject,
                                  End,
                                End,
                                MUIA_Group_Child,		HGroup,
                                  MUIA_Frame,			MUIV_Frame_Group,
                                  MUIA_Background,		MUII_GroupBack,
                                  MUIA_Group_SameHeight,	TRUE,
                                  MUIA_Group_Child,		Label2("Format:"),
                                  MUIA_Group_Child,		format = StringObject,
                                    MUIA_Frame,			MUIV_Frame_String,
                                    MUIA_Background,		MUII_TextBack,
                                    MUIA_String_Accept,		"%:., qHQIpMSRTXrhms0123fvloujzc",
                                    MUIA_String_Format,		MUIV_String_Format_Left,
                                    MUIA_String_MaxLen,		25,
                                    MUIA_CycleChain,		1,
                                  End,
                                End,
                                MUIA_Group_Child,		HGroup,
                                  MUIA_Frame,			MUIV_Frame_Group,
                                  MUIA_Background,		MUII_GroupBack,
                                  MUIA_Group_SameHeight,	TRUE,
                                  MUIA_Group_Child,		Label2("Drop here:"),
                                  MUIA_Group_Child,		NewObject(Str_CC->mcc_Class,NULL,MUIA_Dropable,TRUE,TAG_DONE),
                                End,
                                MUIA_Group_Child,		HGroup,
                                  MUIA_Frame,			MUIV_Frame_Group,
                                  MUIA_Background,		MUII_GroupBack,
                                  MUIA_Group_SameHeight,	TRUE,
                                  MUIA_Group_Child,		loadobj = TextObject,
                                    MUIA_Frame,			MUIV_Frame_Button,
                                    MUIA_Background,		MUII_ButtonBack,
                                    MUIA_Font,			MUIV_Font_Button,
                                    MUIA_Text_PreParse,		"\33c",
                                    MUIA_InputMode,		MUIV_InputMode_RelVerify,
                                    MUIA_Text_Contents,		"Load",
                                    MUIA_Text_HiChar,		'L',
                                    MUIA_ControlChar,		'l',
                                    MUIA_CycleChain,		1,
                                  End,
                                  MUIA_Group_Child,		saveobj = TextObject,
                                    MUIA_Frame,			MUIV_Frame_Button,
                                    MUIA_Background,		MUII_ButtonBack,
                                    MUIA_Font,			MUIV_Font_Button,
                                    MUIA_Text_PreParse,		"\33c",
                                    MUIA_InputMode,		MUIV_InputMode_RelVerify,
                                    MUIA_Text_Contents,		"Save",
                                    MUIA_Text_HiChar,		'S',
                                    MUIA_ControlChar,		's',
                                    MUIA_CycleChain,		1,
                                  End,
                                End,
                              End,
                              TAG_MORE, msg->ops_AttrList
                             );
   if (obj != NULL)
    {
     struct Win_Data *data = (struct Win_Data *)INST_DATA(cl,obj);
     /*ULONG result;*/
     ULONG hour,min,sec;
     STRPTR timeformat;

     data->TimeString = TimeString;

     /*result =*/ get(TimeString,MUIA_Time_Hour,&hour);
     /*result =*/ get(TimeString,MUIA_Time_Minute,&min);
     /*result =*/ get(TimeString,MUIA_Time_Second,&sec);
     /*result =*/ set(Hour,MUIA_Numeric_Value,hour);
     /*result =*/ set(Min,MUIA_Numeric_Value,min);
     /*result =*/ set(Sec,MUIA_Numeric_Value,sec);

     /*result =*/ get(TimeString,MUIA_TimeString_TimeFormat,&timeformat);
     /*result =*/ set(format,MUIA_String_Contents,timeformat);

     /*result =*/ DoMethod(TimeString,MUIM_Notify,MUIA_Time_Hour,MUIV_EveryTime,Hour,3,MUIM_Set,MUIA_Numeric_Value,MUIV_TriggerValue);
     /*result =*/ DoMethod(TimeString,MUIM_Notify,MUIA_Time_Minute,MUIV_EveryTime,Min,3,MUIM_Set,MUIA_Numeric_Value,MUIV_TriggerValue);
     /*result =*/ DoMethod(TimeString,MUIM_Notify,MUIA_Time_Second,MUIV_EveryTime,Sec,3,MUIM_Set,MUIA_Numeric_Value,MUIV_TriggerValue);

     /*result =*/ DoMethod(Hour,MUIM_Notify,MUIA_Numeric_Value,MUIV_EveryTime,TimeString,3,MUIM_Set,MUIA_Time_Hour,MUIV_TriggerValue);
     /*result =*/ DoMethod(Min,MUIM_Notify,MUIA_Numeric_Value,MUIV_EveryTime,TimeString,3,MUIM_Set,MUIA_Time_Minute,MUIV_TriggerValue);
     /*result =*/ DoMethod(Sec,MUIM_Notify,MUIA_Numeric_Value,MUIV_EveryTime,TimeString,3,MUIM_Set,MUIA_Time_Second,MUIV_TriggerValue);

     /*result =*/ DoMethod(format,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,TimeString,3,MUIM_Set,MUIA_TimeString_TimeFormat,MUIV_TriggerValue);

     /*result =*/ DoMethod(loadobj,MUIM_Notify,MUIA_Pressed,FALSE,MUIV_Notify_Application,2,MUIM_Application_Load,MUIV_Application_Load_ENV);
     /*result =*/ DoMethod(saveobj,MUIM_Notify,MUIA_Pressed,FALSE,MUIV_Notify_Application,2,MUIM_Application_Save,MUIV_Application_Save_ENV);
    }
   return((ULONG)obj);
  }


 static ULONG SAVEDS_ASM Win_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  {
   switch (msg->MethodID)
    {
     case OM_NEW			: return(Win_New(cl,obj,(struct opSet *)msg));
     default				: return(DoSuperMethodA(cl,obj,msg));
    }
  }

 /* --- Application -------------------------------------------------------- */

 static ULONG App_New(struct IClass *cl, Object *obj, struct opSet *msg)
  {
   Object *win1;

   obj = (Object *)DoSuperNew(cl,obj,
                              MUIA_Application_Title,           "TimeString-Demo",
                              MUIA_Application_Author,          "Kai Hofmann",
                              MUIA_Application_Copyright,       "© 1996 Kai Hofmann",
                              MUIA_Application_Version,         "$VER: TimeString-Demo 1.3 " __AMIGADATE__,
                              MUIA_Application_Description,     "TimeString demonstration program",
                              MUIA_Application_Base,            "TSDEMO",
                              MUIA_Application_SingleTask,      TRUE,
                              MUIA_Application_Active,          TRUE,
                              MUIA_Application_Window,		win1 = NewObject(Win_CC->mcc_Class,NULL,TAG_DONE),
                              TAG_MORE, msg->ops_AttrList
                             );
   if (obj != NULL)
    {
     struct App_Data *data = (struct App_Data *)INST_DATA(cl,obj);
     /*ULONG result;*/

     data->win1 = win1;

     /*result =*/ DoMethod(win1,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,MUIV_Notify_Application,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
     set(win1,MUIA_Window_Open,TRUE);
    }
   return((ULONG)obj);
  }


 static ULONG SAVEDS_ASM App_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  {
   switch (msg->MethodID)
    {
     case OM_NEW			: return(App_New(cl,obj,(struct opSet *)msg));
     default				: return(DoSuperMethodA(cl,obj,msg));
    }
  }

 /* ------------------------------------------------------------------------ */

 int muiclasses_Init(void)
  {
   int retstat = RETURN_OK;

   App_CC = MUI_CreateCustomClass(NULL,MUIC_Application,NULL,sizeof(struct App_Data),App_Dispatcher);
   if (App_CC == NULL)
    {
     printf("Can not create 'App' privat custom class!\n");
     retstat = RETURN_ERROR;
    }
   else
    {
     Win_CC = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct Win_Data),Win_Dispatcher);
     if (Win_CC == NULL)
      {
       printf("Can not create 'Win' privat custom class!\n");
       retstat = RETURN_ERROR;
      }
     else
      {
       Str_CC = MUI_CreateCustomClass(NULL,MUIC_String,NULL,NULL,Str_Dispatcher);
       if (Str_CC == NULL)
        {
         printf("Can not create 'Str' privat custom class!\n");
         retstat = RETURN_ERROR;
        }
      }
    }

   return(retstat);
  }


 int muiclasses_Cleanup(void)
  {
   int retstat = RETURN_OK;

   if (Str_CC != NULL)
    {
     if (!MUI_DeleteCustomClass(Str_CC))
      {
       printf("Can not delete 'Str' privat custom class!\n");
       retstat = RETURN_ERROR;
      }
    }
   if (Win_CC != NULL)
    {
     if (!MUI_DeleteCustomClass(Win_CC))
      {
       printf("Can not delete 'Win' privat custom class!\n");
       retstat = RETURN_ERROR;
      }
    }
   if (App_CC != NULL)
    {
     if (!MUI_DeleteCustomClass(App_CC))
      {
       printf("Can not delete 'App' privat custom class!\n");
       retstat = RETURN_ERROR;
      }
    }

   return(retstat);
  }

 /* ------------------------------------------------------------------------ */

 int gui_Init(void)
  {
   int retstat;

   MUIMasterBase = OpenLibrary((UBYTE *)MUIMASTER_NAME,(unsigned long)MUIMASTER_VMIN);
   if (MUIMasterBase != NULL)
    {
     retstat = muiclasses_Init();
     if (retstat == RETURN_OK)
      {
       Object *ts;

       ts = MUI_NewObject(MUIC_TimeString,
                          TAG_DONE
                         );
       if (ts != NULL)
        {
         MUI_DisposeObject(ts);
         App = NewObject(App_CC->mcc_Class,NULL,TAG_DONE);
         if (App == NULL)
          {
           printf("Can not create application object!\n");
           retstat = RETURN_FAIL;
          }
        }
       else
        {
         printf("Missing TimeString.mcc!\n");
         retstat = RETURN_FAIL;
        }
      }
    }
   else
    {
     printf("Can not open muimaster.library V%lu!\n",(ULONG)MUIMASTER_VMIN);
     retstat = RETURN_FAIL;
    }
   return(retstat);
  }


 int gui_Cleanup(void)
  {
   int retstat = RETURN_OK;

   if (MUIMasterBase != NULL)
    {
     if (App != NULL)
      {
       MUI_DisposeObject(App);
      }
     retstat = muiclasses_Cleanup();
     if (retstat == RETURN_OK)
      {
       CloseLibrary(MUIMasterBase);
      }
     else
      {
       printf("Can not close muimaster.library!\n");
       retstat = RETURN_FAIL;
      }
    }
   return(retstat);
  }


 void gui_MainLoop(void)
  {
   if (App != NULL)
    {
     ULONG signals=0;

     while (DoMethod(App,(unsigned long)MUIM_Application_NewInput,&signals) != MUIV_Application_ReturnID_Quit)
      {
       if (signals)
        {
         signals = Wait(signals | SIGBREAKF_CTRL_C);
         if (signals & SIGBREAKF_CTRL_C)
          {
           /*ULONG result;*/

           /*result =*/ DoMethod(App,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
          }
        }
      }
    }
  }

 /* ------------------------------------------------------------------------ */

 void main(void)
  {
   if (gui_Init() == RETURN_OK)
    {
     gui_MainLoop();
     /*result =*/ gui_Cleanup();
    }
  }
