/* This file contains empty template routines that
 * the IDCMP handler will call uppon. Fill out these
 * routines with your code or use them as a reference
 * to create your program.
 */

#include <dos/dos.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/dos_protos.h>

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

#include "stickit.h"

#include "consts.h"
#include "structs.h"
#include "prototype.h"

extern prjptr prj;

extern struct Window *editWnd;
extern struct Window *aboutWnd;

extern struct Gadget *editGadgets[];

extern struct IntuiMessage    editMsg;

extern UWORD editTop;
extern UWORD editLeft;
extern UWORD editHeight;
extern UWORD editWidth;

struct EasyStruct andysreq =
   {
   sizeof(struct EasyStruct),
   0,
   "StickIt",
   "%s",
   "Okay|Cancel"
   };
       
int titleClicked( void )
   {
   /* routine when gadget "Title" is clicked. */

   prj->titlechanged = TRUE;
   prj->filechanged = TRUE;

   /* Place cursor in next field */

   ActivateGadget(editGadgets[GDX_note],editWnd,NULL);

   return(TRUE);
   }

int noteClicked( void )
   {
   /* routine when gadget "Note" is clicked. */

   prj->notechanged = TRUE;
   prj->filechanged = TRUE;

   /* Place cursor in next field */

   ActivateGadget(editGadgets[GDX_title],editWnd,NULL);

   return(TRUE);
   }

int notesClicked( void )
   {
   /* routine when gadget "Notes..." is clicked. */

   storenote();

   return (FALSE);
   }

int tostartClicked( void )
   {
   /* routine when gadget "Front" is clicked. */

   if (editGadgets[GDX_tostart]->Flags & GFLG_DISABLED)
      return (TRUE);

   storenote();

   prj->currnode = prj->notes_start->next;

   displaynote();
   updatebuttons();

   return(TRUE);
   }

int prevClicked( void )
   {
   /* routine when gadget "<" is clicked. */

   if (editGadgets[GDX_prev]->Flags & GFLG_DISABLED)
      return (TRUE);

   storenote();

   prj->currnode = prj->currnode->prev;

   displaynote();
   updatebuttons();

   return(TRUE);
   }

int nextClicked( void )
   {
   /* routine when gadget ">" is clicked. */

   if (editGadgets[GDX_next]->Flags & GFLG_DISABLED)
      return (TRUE);

   storenote();

   prj->currnode = prj->currnode->next;

   displaynote();
   updatebuttons();

   return(TRUE);
   }

int toendClicked( void )
   {
   /* routine when gadget "Back" is clicked. */

   if (editGadgets[GDX_toend]->Flags & GFLG_DISABLED)
      return (TRUE);

   storenote();

   prj->currnode = prj->notes_end->prev;

   displaynote();
   updatebuttons();

   return(TRUE);
   }

int addClicked( void )
   {
   nteptr newnote;

   /* routine when gadget "Add" is clicked. */

   if (!prj->currnode)
      {
      /*** Create a new note in the linked list   ***/
          
      prj->currnode = llealloc();
      prj->currnode->data = notealloc();

      newnote = prj->currnode->data;

      if (!newnote)
         error("addClicked; Can't allocate new note",ERR_MALLOC);

      /***   Add to list   ***/

      lleadd(prj->notes_start,prj->currnode);

      newnote->show = editGadgets[GDX_show]->Flags & GFLG_SELECTED;
 
      strncpy(newnote->title,GetString(editGadgets[GDX_title]),STRLEN_TITLE);
      strncpy(newnote->note,GetString(editGadgets[GDX_note]),STRLEN_NOTE);

      newnote->xpos = prj->nextx;
      newnote->ypos = prj->nexty;

      prj->nextx += INC_X;
      prj->nexty += INC_Y;

      updatebuttons();

      changeno_notes(1);

      prj->filechanged = TRUE;
      }
   else
      {
      storenote();

      prj->currnode = NULL;

      strcpy(GetString(editGadgets[GDX_title]),"");
      strcpy(GetString(editGadgets[GDX_note]),"");

      RefreshGList(editGadgets[GDX_title],editWnd,NULL,1);
      RefreshGList(editGadgets[GDX_note],editWnd,NULL,1);

      andysselectgadget(editGadgets[GDX_show],editWnd);

      updatebuttons();

      ActivateGadget(editGadgets[GDX_title],editWnd,NULL);
      }

   return(TRUE);
   }

int showClicked( void )
   {
   /* routine when gadget "Show" is clicked. */

   ((nteptr)prj->currnode->data)->show = 
                              editGadgets[GDX_show]->Flags & GFLG_SELECTED;

   return (TRUE);
   }

int editopen( void )
   {
   LONG reqreply;

   /* routine when (sub)item "Open" is selected. */

   storenote();

   /***   If data has changed, ask if continue else do nothing   ***/

   if (prj->filechanged)
      {
      /***   If data has changed, ask if continue else open anyway   ***/

      andysoffgadget(editGadgets[GDX_title],editWnd);
      andysoffgadget(editGadgets[GDX_note],editWnd);

      reqreply = EasyRequest(editWnd,&andysreq,NULL,
            "Data has been changed, continue with open ?"); /* 1 = Ok */

      /***   Clear any stray messages   ***/

      andysstripintuimessages(editWnd->UserPort,editWnd);

      if (aboutWnd)
         andysstripintuimessages(aboutWnd->UserPort,aboutWnd);

      if (reqreply)  /* If user has clicked on Okay */
         {
         /***   Free old notes   ***/

         llfreemid(prj->notes_start->next);

         readnotefile();

         if (prj->no_notes == 0)
            {
            prj->currnode = NULL;
            addClicked();
            }
         else
            prj->currnode = prj->notes_start->next;
         }

      /***   Re-draw text (may have been altered)   ***/

      if (prj->currnode)
         {
         displaynote();
         updatebuttons();
         }

      andysongadget(editGadgets[GDX_title],editWnd);
      andysongadget(editGadgets[GDX_note],editWnd);
      }

   return(TRUE);
   }

int editsave( void )
   {
   /* routine when (sub)item "Save" is selected. */

   storenote();
   writenotefile();

   return(TRUE);
   }

int editabout( void )
   {
   /* routine when (sub)item "About" is selected. */

   if (!aboutWnd)
      openabout();
   else
      WindowToFront(aboutWnd);

   return (TRUE);
   }

int editquit( void )
   {
   /* routine when (sub)item "Quit" is selected. */

   return(editCloseWindow());
   }

int editcut( void )
   {
   /* routine when (sub)item "Cut" is selected. */

   if (prj->currnode)
      {
      editcopy();
      editdelete();

      prj->nextx -= INC_X;
      prj->nexty -= INC_Y;
      }

   return (TRUE);
   }

int editcopy( void )
   {
   /* routine when (sub)item "Copy" is selected. */

   if (prj->currnode)
      {
      if (!prj->copybuffernode)
         createcopybuffernode();

      strncpy(((nteptr)prj->copybuffernode->data)->title,GetString(
                                        editGadgets[GDX_title]),STRLEN_TITLE);
      strncpy(((nteptr)prj->copybuffernode->data)->note,GetString(
                                        editGadgets[GDX_note]),STRLEN_NOTE);

      prj->nextx = ((nteptr)prj->currnode->data)->xpos;
      prj->nexty = ((nteptr)prj->currnode->data)->ypos;

      prj->nextx += INC_X;
      prj->nexty += INC_Y;

      ((nteptr)prj->copybuffernode->data)->xpos =
                                       ((nteptr)prj->currnode->data)->xpos;
      ((nteptr)prj->copybuffernode->data)->ypos =
                                       ((nteptr)prj->currnode->data)->ypos;

      ((nteptr)prj->copybuffernode->data)->show =
                                 editGadgets[GDX_show]->Flags & GFLG_SELECTED;

      }

   return(TRUE);
   }

int editpaste( void )
   {
   struct ndnode *ndptr;

   /* routine when (sub)item "Paste" is selected. */

   if ((prj->copybuffernode) && (prj->currnode))
      {
      /***   Only do it if there is something in the buffer   ***/

      storenote();

      ndptr = llealloc();
      ndptr->data = notealloc();

      if (!ndptr->data)
         error("editpaste; Can't alloc note",ERR_MALLOC);

      strncpy(((nteptr)ndptr->data)->title,
                     ((nteptr)prj->copybuffernode->data)->title,STRLEN_TITLE);
      strncpy(((nteptr)ndptr->data)->note,
                     ((nteptr)prj->copybuffernode->data)->note,STRLEN_NOTE);
      ((nteptr)ndptr->data)->show = ((nteptr)prj->copybuffernode->data)->show;
      ((nteptr)ndptr->data)->win = NULL;

      ((nteptr)ndptr->data)->xpos = prj->nextx;
      ((nteptr)ndptr->data)->ypos = prj->nexty;

      prj->nextx += INC_X;
      prj->nexty += INC_Y;

      /***   Add to list   ***/

      lleadd(prj->currnode->prev,ndptr);

      prj->currnode = ndptr;

      displaynote();

      updatebuttons();

      changeno_notes(1);

      prj->filechanged = TRUE;
      }

   return(TRUE);
   }

int editdelete( void )
   {
   struct ndnode *new;

   if (prj->currnode)    /* 'cos I can't ghost the menu out yet */
      {
      /* routine when (sub)item "Delete" is selected. */

      strcpy(GetString(editGadgets[GDX_title]),"");
      strcpy(GetString(editGadgets[GDX_note]),"");

      new = prj->currnode->prev;

      lleremove(prj->currnode);

      changeno_notes(-1);

      prj->currnode = new->next;

      if (prj->currnode->next == NULL)    /* If we're at the end, move back */
         prj->currnode = new;

      if (prj->no_notes != 0)
         {
         displaynote();
         updatebuttons();
         }
      else
         {
         RefreshGList(editGadgets[GDX_title],editWnd,NULL,1);
         RefreshGList(editGadgets[GDX_note],editWnd,NULL,1);

         prj->currnode = NULL;

         updatebuttons();
         }

      prj->filechanged = TRUE;
      }

   return (TRUE);
   }

int editshownotes( void )
   {
   /* routine when (sub)item "Show notes..." is selected. */

   storenote();

   return (FALSE);
   }

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

   LONG reqreply;

   storenote();

   if (prj->filechanged)
      {
      /***   If data has changed, ask if continue else open anyway   ***/

      andysoffgadget(editGadgets[GDX_title],editWnd);
      andysoffgadget(editGadgets[GDX_note],editWnd);

      reqreply = EasyRequest(editWnd,&andysreq,NULL,
            "Data has been changed, continue with quit ?"); /* 1 = Ok */

      /***   Clear any stray messages   ***/

      andysstripintuimessages(editWnd->UserPort,editWnd);

      if (aboutWnd)
         andysstripintuimessages(aboutWnd->UserPort,aboutWnd);

      if (reqreply)  /* If user has clicked on Okay */
         {
         prj->quit = TRUE;
         return(FALSE);
         }

      andysongadget(editGadgets[GDX_title],editWnd);
      andysongadget(editGadgets[GDX_note],editWnd);

      return(TRUE);
      }

   prj->quit = TRUE;
   return(FALSE);
   }

int editChangeWindow( void )
   {
   /* routine for "IDCMP_CHANGEWINDOW". */

   editLeft   = editWnd->LeftEdge;
   editTop    = editWnd->TopEdge;
   editWidth  = editWnd->Width;
   editHeight = editWnd->Height - editWnd->BorderTop;

   return (TRUE);
   }

int aboutMouseButtons( void )
   {
   /* routine for "IDCMP_MOUSEBUTTONS". */

   if (aboutWnd)
      prj->abouttoclose = TRUE;

   return (TRUE);
   }
           
int dummynoteMouseButtons( void )
   {
   /* routine for "IDCMP_MOUSEBUTTONS". */

   return(TRUE);
   }
               
int dummynoteChangeWindow( void )
   {
   /* routine for "IDCMP_CHANGEWINDOW". */

   return(TRUE);
   }
	   
int gadeditbutdelClicked( void )
   {
   /* routine when gadget "Del" is clicked. */

   return(TRUE);
   }

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

   switch (editMsg.Code)
      {
      case 'f':
      case 'F':
         tostartClicked();
         break;
      case 'b':
      case 'B':
         toendClicked();
         break;
      case ',':
      case '<':
         prevClicked();
         break;
      case '.':
      case '>':
         nextClicked();
         break;

      case 'a':
      case 'A':
         addClicked();
         break;

      case 't':
      case 'T':
         ActivateGadget(editGadgets[GDX_title],editWnd,NULL);
         break;

      case 'n':
      case 'N':
         ActivateGadget(editGadgets[GDX_note],editWnd,NULL);
         break;

      case 's':
      case 'S':
         editGadgets[GDX_show]->Flags ^= GFLG_SELECTED;

         if (editGadgets[GDX_show]->Flags & GFLG_SELECTED)
            GT_SetGadgetAttrs(editGadgets[GDX_show],editWnd,NULL,
               GTCB_Checked,TRUE);
         else
            GT_SetGadgetAttrs(editGadgets[GDX_show],editWnd,NULL,
               GTCB_Checked,FALSE);         
         break;

      default:
         break;
      }
   return (TRUE);
   }
           
