/* User interface functions for Reminder */

/* $Id: Gadfunc.c,v 1.12 1993/04/18 21:52:14 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 */
  NewEvent();
  SetEvent();
}

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);
  }

  ShowWDay();			/* Check ShowWDay gadget */

  edited = TRUE;			/* Event has been edited */

  return 1;
}

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

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

  ShowWDay();			/* Check ShowWDay gadget */

  edited = TRUE;		/* Event has been edited */

  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;

  ShowWDay();			/* Check ShowWDay gadget */

  edited = TRUE;		/* Event has been edited */

  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);

  ShowWDay();			/* Check ShowWDay gadget */

  edited = TRUE;		/* Event has been edited */

  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;

  ShowWDay();			/* Check ShowWDay gadget */

  edited = TRUE;		/* Event has been edited */

  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);

  edited = TRUE;		/* Event has been edited */

  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);

  edited = TRUE;		/* Event has been edited */

  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) */
  
  edited = TRUE;		/* Event has been edited */

  return 1;
}

int GroupedClicked( void )
{
	/* routine when gadget "_Grouped" is clicked. */

  grouped = !grouped;		/* Toggle Grouped setting */
  SetGrouped(grouped);		/* Refresh gadget state (needed if keypressed) */

  edited = TRUE;		/* Event has been edited */

  return 1;
}

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

  edited = TRUE;		/* Event has been edited */

  return 1;
}

int EventlistClicked( void )
{
	/* routine when gadget "Events in memory:" is clicked. */

  int oldevent = event;		/* Backup of the current event */

  event = MainMsg.Code;
  if (!GetEvent()) {
    event = oldevent;		/* If event wasn't changed */
    SetEventlist(event);	/* Reselect the old event */
  }
  else
    SetEvent();			/* Otherwise update event gadgets */

  return 1;
}

int NewClicked( void )
{
	/* routine when gadget "_New" is clicked. */
  NewEvent();			/* Make new event */
  if (event == ~0) {
    /* If event was reset, update gadgets */
    SetEvent();			/* Update gadgets */
    ResetEvent();		/* Deselect event in Eventlist */
  }

  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());
    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 event in gadgets has been edited */
  if (edited) {
    if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
			 "_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
			 RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
			 TAG_END)) {
      /* If user does not want to abandon changes */
      return 1;
    }
  }

  /* 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. */

  /* Ask for confirmation if event in gadgets has been edited */
  if (edited) {
    if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
			 "_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
			 RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
			 TAG_END)) {
      /* If user does not want to abandon changes */
      return 1;
    }
  }

  return 0;
}

int ARexxComClicked( void )
{
	/* routine when gadget "C_omm/Script" is clicked. */
  if (CheckCom())
    ActivateGadget(MainGadgets[GDX_ARexxCom], MainWnd, NULL);

  edited = TRUE;		/* Event has been edited */

  return 1;
}

int ARexxModeClicked( void )
{
	/* routine when gadget "" is clicked. */
  mode = MainMsg.Code;		/* Get new mode */
  /* Disable or enable ARexxPort gadget depending on new mode */
  SetAMode(mode);		/* (De)select other ARexx gadgets */

  edited = TRUE;

  return 1;
}

int ARexxPortClicked( void )
{
	/* routine when gadget "_Port" is clicked. */
  if (CheckPort())
    ActivateGadget(MainGadgets[GDX_ARexxPort], MainWnd, NULL);

  edited = TRUE;		/* Event has been edited */

  return 1;
}

int MainCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */

  /* Ask for confirmation if event in gadgets has been edited */
  if (edited) {
    if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
			 "_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
			 RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
			 TAG_END)) {
      /* If user does not want to abandon changes */
      return 1;
    }
  }

  /* 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". */
  BOOL shifted;			/* Is the letter shifted? */

  /* Parse keyboard shortcuts */

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

  /* Notice shifted letters A-Z */
  shifted = (MainMsg.Code >= 'A' && MainMsg.Code <= 'Z');

  /* Parse lowercase key */
  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 'n':
    PressButton(MainGadgets[GDX_New]);
    return NewClicked();
  case 'e':
    return AutodeleteClicked();
  case 'g':
    return GroupedClicked();

    /* Radio buttons */
  case 'c':
    mode = AREXXCMODE;
    SetAMode(mode);
    break;
  case 'i':
    mode = AREXXSMODE;
    SetAMode(mode);
    break;
  case 'h':
    mode = AREXXNMODE;
    SetAMode(mode);
    break;

    /* 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;
  case 'p':
    if (mode == AREXXCMODE) {
      /* Only allow activation of Port gagdet in ARexxCommand mode */
      ActivateGadget(MainGadgets[GDX_ARexxPort], MainWnd, NULL);
    }
    break;
  case 'o':
    if (mode != AREXXNMODE) {
      /* Do not allow activation in No ARexx mode */
      ActivateGadget(MainGadgets[GDX_ARexxCom], MainWnd, NULL);
    }
    break;

  /* ListView gadgets */
  case 'w':
    /* Weekday, direction depends on shift */
    if (shifted) {
      /* Select previous weekday */
      if (wday == 0)
	wday = 7;
      else
	wday--;
    }
    else {
      /* Select next event */
      if (wday == 7)
	wday = 0;
      else
	wday++;
    }
    SetWDay(wday);
    ShowWDay();			/* Check showed weekday */
    break;
    
  case 'v':
    /* Event, direction depends on shift */
    if (eventno != 0) {		/* Only if events available */
      if (shifted) {
	/* Select previous event */
	if (event == ~0 || event == 0)
	  event = eventno-1;	/* Last event */
	else
	  event--;
      }
      else {
	/* Select next event */
	if (event == ~0 || event == eventno-1)
	  event = 0;	/* Last event */
	else
	  event++;
      }
      SetEventlist(event);
      GetEvent();
      SetEvent();
    }
    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;
}

