/* Includes */

#include "stdio.h"
#include "string.h"


/* DeskLib Includes */

#include "DeskLib:Event.h"
#include "DeskLib:EventMsg.h"
#include "DeskLib:Resource.h"
#include "DeskLib:Core.h"
#include "DeskLib:Icon.h"
#include "DeskLib:Menu.h"
#include "DeskLib:Screen.h"
#include "DeskLib:Msgs.h"
#include "DeskLib:Dialog2.h"
#include "DeskLib:Template.h"
#include "Desklib:Error.h"
#include "Desklib:Window.h"
#include "Desklib:Handler.h"
#include "Desklib:Save.h"
#include "Desklib:File.h"

/* Global Variables */
/* Reference stucture with all necessary parameters to be passed to functions.*/
struct reference
  {
    BOOL quit;
    int filetype;
    menu_ptr menuhandle;
    window_handle choice_win;
  };


/* Defines */

#define mainmenu_INFO 0
#define mainmenu_CHOICES 1
#define mainmenu_QUIT 2


/* Function Prototypes */

BOOL click(event_pollblock *event,void *ref);
BOOL drag(event_pollblock *event,void *ref);
BOOL menu_choice(event_pollblock *event, void *ref);
BOOL proginfo(event_pollblock *event, void *ref);
BOOL close_win(event_pollblock *event, void *ref);
BOOL save_file(char filename[], void *ref);
BOOL radio(event_pollblock *event, void *ref);
void task_setup(void);
void iconbar_setup(struct reference *ref);
void menu_setup(struct reference *ref);
void windows_setup(void);
void choice(struct reference *ref);


/* Main Program */

int main(void)
{
  struct reference ref;

  ref.quit = FALSE;
  ref.filetype = filetype_OBEY;
  ref.choice_win = NULL;

  task_setup();
  windows_setup();
  iconbar_setup(&ref);
  menu_setup(&ref);

/* Polling loop. *************************************************************/
  while(!ref.quit) Event_Poll();

  return(0);
}

void task_setup(void)
{
  char appname[20];
  
/* Initialise resource paths *************************************************/
  Resource_Initialise("!Choices");

/* Initialise and load Templates *********************************************/
  Template_Initialise();
  Template_LoadFile("Templates");

/* Load messages file and look up application name for initialisation.
 * The default application name is set to 'Tester'. **************************/
  Msgs_LoadFile("messages");
  Msgs_Lookup("app.name:Tester", appname, 20);

/* Initialise Task and Event processing system *******************************/
  Event_Initialise(appname);

/* Initialise User messaging system needed for Warnings **********************/
  EventMsg_Initialise();

/* This is necessary to display the menu correctly. **************************/
  Screen_CacheModeInfo();
}

void iconbar_setup(struct reference *ref)
{
  icon_handle baricon;

/* Put icon on iconbar and store the handler. ********************************/
  baricon = Icon_BarIcon("!choices", iconbar_RIGHT);

/* Check for mouse clicks on icon. *******************************************/
  Event_Claim(event_CLICK, -2, baricon, click, (void *)ref);

/* Check for files dropped on the icon. **************************************/
  EventMsg_Claim(message_DATALOAD, -2, drag, (void *)ref);
}

void menu_setup(struct reference *ref)
{
  char menu[100], menutitle[20];
  dialog2_block *info;

/* Check menu description is present. If not, report error and exit. *********/
  if(!Msgs_Lookup("menu.main", menu, 100))
  {
    Error_Report(1, "Can't find menu description.");
    ref->quit = TRUE;
  }
  
/* Look up menu title, create menu and store menu handler. *******************/
  Msgs_Lookup("menu.main", menu, 100);
  Msgs_Lookup("title.main:Main", menutitle, 20);
  ref->menuhandle = Menu_New(menutitle, menu);

/* Create Dialog box and set a warning to make it pop up when selected *******/
  info = Dialog2_CreateDialogBlock( "prog_info", -1, -1, NULL, NULL, NULL);
  Menu_Warn(ref->menuhandle, mainmenu_INFO, TRUE, proginfo, (void *)info);

/* Check for menu selections. ************************************************/
  Event_Claim(event_MENU, event_ANY, event_ANY, menu_choice, (void *)ref); 
}

void windows_setup(void)
{
/* Handle the window buttons. ************************************************/
  Event_Claim(event_OPEN, event_ANY, event_ANY, Handler_OpenWindow, NULL);

/* Uncomment the following line if the window template has the auto-redraw option switched off */
/*Event_Claim(event_REDRAW, event_ANY, event_ANY, Handler_NullRedraw, NULL);*/
}

BOOL menu_choice(event_pollblock *event, void *ref)
{
  struct reference *ptr;

/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;

/* Check which menu point was selected ***************************************/
  switch(event->data.selection[0])
  {
/* If 'Quit' was selected, close the task down and end polling loop. *********/
    case(mainmenu_CHOICES):
      choice(ref);
      break;
    case(mainmenu_QUIT):
      Event_CloseDown();
      ptr->quit = TRUE;
      break;
  }
  return(TRUE);  
}

BOOL proginfo(event_pollblock *event, void *ref)
{
  Dialog2_OpenDialogMenuLeaf(event, (dialog2_block *)ref);

  return(TRUE);
}

BOOL click(event_pollblock *event, void *ref)
{
  struct reference *ptr;

/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;

/* Check if click was the menu button. ***************************************/
  if(event->data.mouse.button.data.menu)
  {
/* Show the menu at the position of the mouse pointer but on top the icon bar.*/
    Menu_Show(ptr->menuhandle, event->data.mouse.pos.x, -1);
  }
  return(TRUE);  
}

BOOL drag(event_pollblock *event, void *ref)
{
  struct reference *ptr;
  static window_handle window;
  char outfile[212];
   
/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;

/* Create window when function is first called.  This works because
   static variables are initialised to 0. ************************************/
  if(window == NULL)window = Window_Create("save", 20);

/* Construct output file name.  It's got an _x appended to prevent ************/
/* Accidental overwriting of an important file...******************************/
  strncpy(outfile, event->data.message.data.dataload.filename, 200);
  strcat(outfile, "_x"); 

/* Set text for indirected icon. *********************************************/
  Icon_SetText(window, 1, outfile);

/* Display window in the centre of the desktop every time a file is dropped. */
  Window_Show(window, open_CENTERED);

/* Saving the test file. *****************************************************/
  Save_InitSaveWindowHandler(window, FALSE, TRUE, TRUE, 2, 3, 0, 1, save_file, NULL, NULL, 20, ptr->filetype, NULL);    

  return(TRUE);
}

BOOL save_file(char filename[], void *ref)
{
  FILE *fp;
  BOOL status = TRUE;

/* Open the output file and write a little message. ***************************/  fp = fopen(filename, "w");
  if(fp == NULL)
  {
    fprintf(stderr, "Unable to open file %s.\n", filename);
    status = FALSE;
  }
  else
  {
    fprintf(fp, "This file was created by !Save.\n");
    fprintf(fp, "The full filename was:\n");
    fprintf(fp, "%s\n", filename);
    fprintf(fp, "with a total length of %d characters\n", strlen(filename));
    fclose(fp);
  }
  return(status);
}

void choice(struct reference *ref)
{
  struct reference *ptr;
   
/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;
  
/* Open choices window and set necessary flags ********************************/
  if(ptr->choice_win == NULL) ptr->choice_win = Window_Create("choices", 20);
  Icon_SetRadios(ptr->choice_win, 4, 7, 4);
  Window_Show(ptr->choice_win, open_CENTERED);
  
/* Check for close button. ***************************************************/
  Event_Claim(event_CLOSE, ptr->choice_win, event_ANY, close_win, ref);
  
/* Check for other clicks. ***************************************************/
  Event_Claim(event_CLICK, ptr->choice_win, event_ANY, radio, ref);
}

BOOL close_win(event_pollblock *event, void *ref)
{
  struct reference *ptr;
   
/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;

/* Delete window and set hanlde back to NULL. ********************************/
  Window_Delete(ptr->choice_win);
  ptr->choice_win = NULL;
  
  return(TRUE);
}


BOOL radio(event_pollblock *event, void *ref)
{
  struct reference *ptr;
  int type;
   
/* Cast reference structure back from VOID. **********************************/
  ptr = (struct reference *)ref;
  type = Icon_WhichRadio(ptr->choice_win, 4, 7);

  switch(type)
  {
    case 4:  ptr->filetype = filetype_TEXT;
             break;
    case 5:  ptr->filetype = filetype_DATA;
             break;
    case 6:  ptr->filetype = filetype_COMMAND;
             break;
    case 7:  ptr->filetype = filetype_OBEY;
             break;
  }
  return(TRUE);
}
/* EOF. */
