/*****************************************************************************
 *
 * Filename              : main.c
 * Desc.                 : The main part of the style prog (init+save/load)
 *
 * version               : 1.1
 * created               :    07-99
 * last change           : 05-08-99
 *
 * history
 * 1.0                   : initial version
 * 1.1                   : some bugs removed (clear)
 *
 *****************************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <libraries/gadtools.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/rtracker_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/gadtools_protos.h>
#include <pragmas/rtracker_pragmas.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <dos/dos.h>

#include <libraries/pm.h>
#include <proto/pm.h>

#include "main.h"
#include "nodes.h"
#include "hchoice.h"
#include "graph.h"
#include "menu.h"


/* the base libraries
 */
struct Library        * RTrackerBase ;
struct Library        * GadToolsBase ;
struct PopupMenuBase  * PopupMenuBase;

void ProcessWin(struct Window *) ;                   /* handle window events */
void SaveFile(char * filename) ;            /* save a file to env: & envarc: */
void SavePoints(void) ;

SPoint * ipoint,                                        /* the initial point */
       * current ;                      /* the current point (for inserting) */

char * version = VER ;                                    /* the $VER string */

/*
 * defintion of the gadget
 * should be cleaned for future version
 *
 */
struct NewGadget savgad = {
  0,0,WIDTH, 20, "Save", NULL, ID_SAVE, PLACETEXT_IN, NULL, NULL
} ;
struct NewGadget clrgad = {
  0,0,WIDTH, 20, "Clear", NULL, ID_CLEAR, PLACETEXT_IN, NULL, NULL
} ;

/* The MAIN part :)
 */
void main() {
  APTR VI ;                                               /* the visual info */
  struct Screen * scr ;                                     /* the wb screen */
  struct Window * wing ;                                  /* the main window */
  struct Gadget * gad,                                        /* the gadgets */
                * glist ;

  /* initialisation
   */
  if ((RTrackerBase = OpenLibrary("rtracker.library",10)) == NULL) {
    /* what no rtracker:
     * should quit safely
     */
    printf("Couldn't open rtracker.library version 1\n") ;
    exit(20) ;                                                      /* fatal */
  }
  /* initialize the library
   */
  InitResource() ;
  if ((GadToolsBase = NewOpenLibrary("gadtools.library",37)) == NULL) {
    /* what no gadtools
     * how do i display my gadgets then ?
     */
    printf("Couldn't open gadtools.library version 37\n") ;
    CloseResource() ;
    CloseLibrary(RTrackerBase) ;
    exit(20) ;
  }
  if ((PopupMenuBase=(struct PopupMenuBase *)NewOpenLibrary(POPUPMENU_NAME,
                                                            POPUPMENU_VERSION)) == NULL) {
    /* the popup library is inexistant
     * so -> quit
     */
    printf("Couldn't open %s version %ld\n", POPUPMENU_NAME,
                                             POPUPMENU_VERSION) ;
    CloseResource() ;
    /* i know i did not close GadTools
     * but rtracker did it for me (just before)
     */
    CloseLibrary(RTrackerBase) ;
    exit(20) ;
  }
  if (scr = LockPubScreen("Workbench")) {
    /* pub screen found (normaly the wb)
     */
    if (VI = NewGetVisualInfo(scr, TAG_DONE)) {
      /* got the vi for the gadgets
       */
      if (gad = NewCreateContext(&glist)) {
        /* creating gadgets
         * this will cleaned in the future
         */
        savgad.ng_LeftEdge = scr->WBorLeft ;
        savgad.ng_TopEdge  = scr->RastPort.TxHeight + scr->WBorTop + 4 + HEIGHT ;
        savgad.ng_VisualInfo = VI ;
        gad = CreateGadgetA(BUTTON_KIND, gad, &savgad, TAG_DONE) ;
        clrgad.ng_LeftEdge = scr->WBorLeft ;
        clrgad.ng_TopEdge  = scr->RastPort.TxHeight + scr->WBorTop + 8 + HEIGHT + GADHEIGHT ;
        clrgad.ng_VisualInfo = VI ;
        gad = CreateGadgetA(BUTTON_KIND, gad, &clrgad, TAG_DONE) ;
        /* open the window
         * note that default values will be #define'd in the future
         */
        wing = OpenWindowTags(NULL,WA_Left, 50,
                                   WA_Top,  50,
                                   WA_InnerWidth, WIDTH,
                                   WA_InnerHeight, HEIGHT+50,
                                   WA_IDCMP, IDCMP,
                                   WA_Flags, FLAGS,
                                   WA_Title, TITLE,
                                   WA_Gadgets, glist,
                                   WA_RMBTrap, TRUE,
                                   WA_ScreenTitle, STITLE, TAG_DONE) ;

        if (wing) {
          /* window opened
           * initialize the first point (which is not a point)
           */
          ipoint = NewAllocVec(sizeof(SPoint), MEMF_PUBLIC|MEMF_CLEAR) ;
          ipoint->next = NULL ;                       /* the fist & the last */
          current = ipoint ;                        /* set the current point */
          DrawGrid(wing) ;                                  /* draw the grid */
          ProcessWin(wing) ;                      /* & handles window events */
          CloseWindow(wing) ;
        }else
          /* something goes wrong ?
           */
          printf("Can't open window\n") ;
        NewFreeGadgets(glist) ;                     /* this free all gadgets */
      }else
        printf("Can't create context\n") ;
      NewFreeVisualInfo(VI) ;
    }else
      printf("Can't get visual info\n") ;
    UnlockPubScreen(NULL, scr) ;
  }else
    printf("Can't lock public screen Workbench\n") ;
  CloseResource() ;                          /* clear all forgotten resource */
  CloseLibrary(RTrackerBase) ;
}

/*
 * this opens the choice window &
 * ask the type of arrow
 * then save it to disk
 */
void SavePoints() {
  LONG type ;                                                   /* h | m | s */

  type = choice() ;                             /* ask for the type of arrow */

  switch (type) {
    case ASECONDS :
      SaveFile("env:backclock.s") ;
      SaveFile("envarc:backclock.s") ;
      break ;

    case AMINUTES :
      SaveFile("env:backclock.m") ;
      SaveFile("envarc:backclock.m") ;
      break ;

    case AHOURS :
      SaveFile("env:backclock.h") ;
      SaveFile("envarc:backclock.h") ;
      break ;

    default :
      break ;
  }

   /*
  }   */

}

/*
 * this save a single file to disk
 */
void SaveFile(char * filename) {
  BPTR file ;                                    /* the file, null if failed */
  SPoint * cp ;                                     /* the point to be saved */
  file = NewOpen(filename, MODE_NEWFILE) ;                  /* open the file */
  if (file) {
    /* the file is opened
     */
    cp = ipoint->next ;                              /* skip the first point */
    while(cp) {
      /* write datas to disk
       */
      Write(file, &(cp->x), 4) ;
      Write(file, &(cp->y), 4) ;
      cp = cp->next ;
    }
    NewClose(file) ;
  }
}


void ProcessWin(struct Window * win) {
  /* handle events
   */
  BOOL stop = FALSE ;                                         /* TRUE = QUIT */
  struct IntuiMessage * imsg ;                          /* the intui message */
  ULONG class ;                                                  /* for temp */
  UWORD code ;
  WORD mx, my ;                         /* coords of the mouse in the window */
  struct Gadget * gad ;                          /* gadget currently pressed */
  ULONG r ;                          /* choice of the user for the popupmenu */
  BOOL draw = NULL ;                      /* if !NULL then redraw the window */

  while(!stop) {
    /* the user didn't choose the close button
     */
    WaitPort(win->UserPort) ;                          /* wait for a message */
    while (imsg = (struct IntuiMessage*)GetMsg(win->UserPort)) {

      /* extract datas from the message
       */
      class = imsg->Class ;
      code  = imsg->Code ;
      mx = imsg->MouseX ;
      my = imsg->MouseY ;
      gad = (struct Gadget*)imsg->IAddress ;
      if (imsg) {
        ReplyMsg((struct Message*)imsg) ;
        switch (class) {
          case IDCMP_CLOSEWINDOW :
            /* close gadget selected
             */
            stop=TRUE ;
            break ;
          case IDCMP_MOUSEBUTTONS :
            /* boutons actived
             */
            switch (code) {
              case 104 : /* 232 = released */
                /* lbutton pressed
                 */
                AddPoint(win, mx, my) ;
                draw = TRUE ;
                break ;

              case 105 :
                /* rbutton pressed
                 */
                r = OpenMenu(win, code) ;
                switch (r) {
                  case ID_MDELETE:
                  /* delete this point
                   */
                    RemPoint(win, mx, my) ;
                    draw = TRUE ;
                    break;
                  case ID_MBECURRENT:
                  /* be the current point
                   */
                    SetCurPoint(win, mx, my) ;
                    draw = TRUE ;
                    break;
                  case ID_MQUIT:
                  /* quit
                   */
                    stop = TRUE ;
                    break ;

                  default:
                    break ;
                }
                break ;

              default :
                break ;
            }
            if (draw) {
              DrawArrow(win) ;
              draw = NULL ;
            }
            break ;
          case IDCMP_GADGETUP :
            /* gadget pressed
             */
            switch (gad->GadgetID) {
              case ID_SAVE:
                /* Save the file
                 */
                SavePoints() ;
                break;
              case ID_CLEAR:
                /* clear all the points
                 */
                ClearPoints() ;
                DrawGrid(win) ;
                break;
            }
            break ;
          default:
            break ;
        }
      }
    }
  }
}
