/* User interface functions for Reminder */

/* $Id: Gadfunc.c,v 1.7 93/03/06 16:30:17 Matti_Rintala Exp $ */

#include <ctype.h>

#include <exec/types.h>
#include <exec/exec.h>
#include <utility/tagitem.h>
#include <dos/dos.h>

#include <exec/libraries.h>
#include <libraries/reqtools.h>

#include <intuition/intuition.h>

#include "Globals.h"
#include "Gadutil.h"
#include "Events.h"
#include "Gadfunc.h"

#ifdef __SASC
#include <proto/dos.h>
#include <proto/reqtools.h>
#include <proto/intuition.h>
#endif

#ifdef _DCC
#include <clib/dos_protos.h>
#include <clib/reqtools_protos.h>
#include <clib/intuition_protos.h>
#endif

static int CheckGadgets(void);


void InitGadgets(void) {

  /* Try to load database from file */
  LoadEvents(filename);

  /* Initialize events */
  AttachEventlist(InitEvents());

  /* Initialize all gadgets */
  SetWDay(wday); SetDay(day); SetMonth(month); SetYear(year);
  SetBefore(before); SetAfter(after);
  SetAutodelete(autodelete);
  SetText(text);
}

void ExitGadgets(void) {

  /* Save database, if changed */
  if (changed) {
    if (SaveEvents(filename)) {
      rtEZRequestTags("Could not save database!", "OK", NULL, NULL,
		      RT_LockWindow, (Tag)TRUE, TAG_END);
    }
  }
}

/* CheckGadgets checks the contents of all event gadgets and updates values
   of globals. If some value is illegal, that gadget is activated and
   TRUE is returned */
static int CheckGadgets(void) {

  struct Gadget *gad;

  /* Check all gadgets that can be altered without event (strings) */
  gad = MainGadgets[GDX_Day];
  if (CheckInt(gad, 1, 31, &day)) {
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }
  gad = MainGadgets[GDX_Month];
  if (CheckMonth()) {
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }
  gad = MainGadgets[GDX_Year];
  if (CheckInt(gad, 0, MAXYEAR, &year) || (year > 99 && year < MINYEAR)) {
    if (year < MINYEAR)
      DisplayBeep(NULL);
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }
  /* Add missing centuries, if necessary */
  if (year <= 99 && *((struct StringInfo *)gad->SpecialInfo)->Buffer != '\0') {
    year += (year < MINYEAR%100) ? 2000 : 1900;
    SetYear(year);
  }

  gad = MainGadgets[GDX_Before];
  if (CheckInt(gad, 1, MAXBEFORE, &before)) {
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }
  gad = MainGadgets[GDX_After];
  if (CheckInt(gad, 1, MAXAFTER, &after)) {
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }
  gad = MainGadgets[GDX_Text];
  if (CheckText()) {
    ActivateGadget(gad, MainWnd, NULL);
    return TRUE;
  }

  return FALSE;
}
    

/* Functions below this are called by GadToolsBox-generated IDCMP-handler */

int YearClicked( void )
{
	/* routine when gadget "_Year" is clicked. */

  struct Gadget *gad = MainGadgets[GDX_Year];

  /* Check the new value */
  if (CheckInt(gad, 0, MAXYEAR, &year) || (year > 99 && year < MINYEAR)) {
    if (year < MINYEAR)
      DisplayBeep(NULL);
    ActivateGadget(gad, MainWnd, NULL);
  }
  /* Add missing centuries, if necessary */
  if (year <= 99 && *((struct StringInfo *)gad->SpecialInfo)->Buffer != '\0') {
    year += (year < MINYEAR%100) ? 2000 : 1900;
    SetYear(year);
  }

  return 1;
}

int MonthClicked( void )
{
	/* routine when gadget "_Month" is clicked. */

  /* Check the new value */
  if (CheckMonth())
    ActivateGadget(MainGadgets[GDX_Month], MainWnd, NULL);

  return 1;
}

int MonthListClicked( void )
{
	/* routine when gadget "" is clicked. */
  /* Set month, list starts from 0 and 12 is ANY */
  month = (MainMsg.Code != 12) ? (MainMsg.Code+1) : 0;

  return 1;
}

int DayClicked( void )
{
	/* routine when gadget "_Day" is clicked. */

  struct Gadget *gad = MainGadgets[GDX_Day];

  /* Check the new value */
  if (CheckInt(gad, 1, 31, &day))
    ActivateGadget(gad, MainWnd, NULL);

  return 1;
}

int WeekdayClicked( void )
{
	/* routine when gadget "Weekday" is clicked. */
  /* Set day of the week from IntuiMessage */
  wday = (MainMsg.Code != 7) ? (MainMsg.Code+1) : 0;

  return 1;
}

int BeforeClicked( void )
{
	/* routine when gadget "_Before" is clicked. */

  struct Gadget *gad = MainGadgets[GDX_Before];

  /* Check the new value */
  if (CheckInt(gad, 1, MAXBEFORE, &before))
    ActivateGadget(gad, MainWnd, NULL);

  return 1;
}

int AfterClicked( void )
{
	/* routine when gadget "A_fter" is clicked. */

  struct Gadget *gad = MainGadgets[GDX_After];

  /* Check the new value */
  if (CheckInt(gad, 1, MAXAFTER, &after))
    ActivateGadget(gad, MainWnd, NULL);

  return 1;
}

int AutodeleteClicked( void )
{
	/* routine when gadget "_Delete event when expired" is clicked. */

  autodelete = !autodelete;	/* Toggle Autodelete setting */
  SetAutodelete(autodelete);	/* Refresh gadget state (needed if keypressed) */
  
  return 1;
}

int TextClicked( void )
{
	/* routine when gadget "_Text" is clicked. */
  if (CheckText())
    ActivateGadget(MainGadgets[GDX_Text], MainWnd, NULL);

  return 1;
}

int EventlistClicked( void )
{
	/* routine when gadget "Events in memory:" is clicked. */
  event = MainMsg.Code;
  GetEvent();
  SetEvent();

  return 1;
}

int AddClicked( void )
{
	/* routine when gadget "_Add" is clicked. */
  /* Add event if gadgets are valid */
  if (!CheckGadgets()) {
    DetachEventlist();		/* Detach the event list from gadget */
    /* Add new event and attach list back to gadget */
    AttachEventlist(AddEvent());
    event = eventno-1;		/* Last event is now selected */
    SetEventlist(event);	/* Select the new event */
  }

  return 1;
}

int RemoveClicked( void )
{
	/* routine when gadget "_Remove" is clicked. */
  if (event != ~0) {
    /* If event is selected */
    DetachEventlist();		/* Detach the event list from gadget */
    /* Remove event and attach list back */
    AttachEventlist(RemoveEvent());
    event = ~0;			/* No event selected now */
  }
  else {
    rtEZRequestTags("No event selected!","OK", NULL, NULL,
		    RT_LockWindow, (Tag)TRUE, TAG_END);
  }

  return 1;
}

int UpdateClicked( void )
{
	/* routine when gadget "_Update" is clicked. */
  if (event != ~0) {
    /* If event selected, update if gadgets valid */
    if (!CheckGadgets()) {
      DetachEventlist();		/* Detach the event list from gadget */
      /* Update event and attach list back */
      AttachEventlist(UpdateEvent());
      SetEventlist(event);	/* Select the new event */
    }
  }
  else {
    rtEZRequestTags("No event selected!","OK", NULL, NULL,
		    RT_LockWindow, (Tag)TRUE, TAG_END);
  }

  return 1;
}

int CancelClicked( void )
{
	/* routine when gadget "_Quit, no save" is clicked. */
  /* Ask for confirmation if database was changed */
  if (changed == 1) {
    if (!rtEZRequestTags("Really quit and\nabandon changes?", "_Yes!|_No way", NULL,
			NULL, RT_LockWindow, (Tag)TRUE, RT_Underscore, (Tag)'_',
			RTEZ_DefaultResponse, (Tag)0, TAG_END)) {
      /* If user does not want to exit */
      return 1;
    }
    changed = 0;		/* User did not wish to save changes */
  }

  return 0;
}

int QuitClicked( void )
{
	/* routine when gadget "Quit and _save" is clicked. */
  return 0;
}

int MainCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */
  /* Ask whether user wants to save changes (if any) */
  if (changed == 1) {
    if (!rtEZRequestTags("Save changes\nbefore quitting?", "_Yes|_No!", NULL, NULL,
		    RT_LockWindow, (Tag)TRUE, RT_Underscore, (Tag)'_', TAG_END)) {
      /* If user does not want to save changes */
      changed = 0;
    }
  }

  return 0;
}

int MainVanillaKey( void )
{
	/* routine for "IDCMP_VANILLAKEY". */

  /* Parse keyboard shortcuts (currently qualifier insensitive) */

  /* Keys from '0' to '7' are weekdays */
  if (MainMsg.Code >= '0' && MainMsg.Code <= '7') {
    wday = MainMsg.Code - '0';
    SetWDay(wday);
    return 1;
  }

  switch (tolower(MainMsg.Code)) {

    /* Boolean and check gadgets: */
  case 'a':
    PressButton(MainGadgets[GDX_Add]);
    return AddClicked();
  case 'r':
    PressButton(MainGadgets[GDX_Remove]);
    return RemoveClicked();
  case 'u':
    PressButton(MainGadgets[GDX_Update]);
    return UpdateClicked();
  case 'q':
    PressButton(MainGadgets[GDX_Cancel]);
    return CancelClicked();
  case 's':
    PressButton(MainGadgets[GDX_Quit]);
    return QuitClicked();
  case 'e':
    return AutodeleteClicked();

    /* String and integer gadgets */
  case 'b':
    ActivateGadget(MainGadgets[GDX_Before], MainWnd, NULL);
    break;
  case 'f':
    ActivateGadget(MainGadgets[GDX_After], MainWnd, NULL);
    break;
  case 'd':
    ActivateGadget(MainGadgets[GDX_Day], MainWnd, NULL);
    break;
  case 'm':
    ActivateGadget(MainGadgets[GDX_Month], MainWnd, NULL);
    break;
  case 'y':
    ActivateGadget(MainGadgets[GDX_Year], MainWnd, NULL);
    break;
  case 't':
    ActivateGadget(MainGadgets[GDX_Text], MainWnd, NULL);
    break;
  }

  return 1;
}

int MainRawKey( void )
{
	/* routine for "IDCMP_RAWKEY". */

  /* Check rawkeys */

  switch (MainMsg.Code) {

  case CURSORUP:
    /* Select previous event */
    if (eventno != 0) {
      if (event == ~0 || event == 0)
	event = eventno-1;	/* Last event */
      else
	event--;
      SetEventlist(event);
      GetEvent();
      SetEvent();
    }
    break;

  case CURSORDOWN:
    /* Select next event */
    if (eventno != 0) {
      if (event == ~0 || event == eventno-1)
	event = 0;	/* Last event */
      else
	event++;
      SetEventlist(event);
      GetEvent();
      SetEvent();
    }
    break;
  }

  return 1;
}

