/************************************************************
**
** Application: UnitConv
**
** Title:       c.main
**
*************************************************************/

/*
*
* Copyright (c) 2015, Chris Johnson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the copyright holder nor the names of their
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/* Include files */
/* from standard clib */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


/* from osLib */
#include "OSLib:os.h"
#include "OSLib:taskmanager.h"
#include "OSLib:toolbox.h"
#include "OSLib:wimp.h"



/* from support */
#include "OSLibSupport:Err.h"
#include "OSLibSupport:event.h"
#include "OSLibSupport:x.h"

/* from CJLib */
#include "CJLib:message.h"
#include "CJLib:etc.h"
#include "CJLib:wimpc.h"


/* from application */
#include "app.h"
#include "choices.h"
#include "cjoslib.h"
#include "iconbar.h"
#include "imagecrop.h"
#include "main.h"
#include "msglink.h"
#include "unitconv.h"
#include "loaddata.h"
#include "binhex.h"


/************************************************************/

/* Local defines */

#define LOWEST_WIMP_VERSION    310



/************************************************************/
/* global variables */
osspriteop_area  * SpriteArea;
wimp_block         poll_block;
toolbox_block      Id_Block;
osbool             Quit;           /* the global Quit flag  */

messagetrans_control_block   Messages_cb;	/* Messages file descriptor  */
wimp_t    TaskHandle;        /* this app's task handle  */

static os_error ErrBlock;  // static, in case we're out of memory
static osbool second_instance = FALSE;


app_globals     app;
unitconv_data   uc_data ;


/************************************************************/

/* Initialise all the global variables to sensible defaults */
static void InitialiseVariables (void)
{
  int i;


  /* initialise general globals */
  app.gv.size_diameter = TRUE ;
  app.gv.pres_flag = PRES_N ;
  app.gv.xsect_flag = XSECT_PM ;

  /* initialise number of groups */
  uc_data.no_of_groups = 0 ;
  /* setup window with first group as default */
  uc_data.current_group = 0 ;
  uc_data.current_set = 0 ;
  /* Ensure the group ptrs are NULL to start with */
  for ( i = 0; i <= MAX_UC_MENU_ENTRIES; i++ )
  {
    uc_data.group [i] = NULL;
  }

  return;
}






/****************************************************************
**      Application Message Handlers
****************************************************************/

/* Quit message received from the Wimp */
static int QuitMessage(wimp_message *message, void *handle)
{
  Quit = TRUE;
  return (TRUE);

  IGNORE (message);
  IGNORE (handle);
}







/************************************************************/

/*  Initialisation message received from the Wimp
**  this is the first thing that is called once the application
**  starts up under the WIMP.
**  It is usually best to perform all further initialisation from here,
**  as the toolbox, etc are all set up and ready.
*/

static int InitMessage (wimp_message *msg, void *handle)
{
  wimp_full_message_task_initialise *initmsg;

  initmsg = (wimp_full_message_task_initialise *)msg;
  // check the task name
  if (strncmp ( initmsg->task_name, APPNAM, strlen (APPNAM)) == 0
                && initmsg -> sender == TaskHandle)
  {
    /* Our task, our instance */
    /* If this is a second instance, then tell the user and then exit */
    if ( second_instance )
    {
      Msg_Warn (RUNNING);
      Quit = TRUE;
    }
    else
    {
      /* initialise global variables */
      InitialiseVariables ();
      /* initialise the icon bar icon */
      IconbarInit();
      if (!Loaddata_Setup ()) return (FALSE);
      Choices_Initialise ();
      Unitconv_Initialise ();
      Binhex_LoadChoices ();
      Imagecrop_SetUpAspectMenu ();
    }

  }

  return (TRUE);

  IGNORE (handle);
}








/************************************************************/

int main (void)
{
  x_exception x0;
  x_exception x1;

  int    wimp_version,
         event_code;


  int WimpMessages[] = {0};  /* list of Wimp messages to look out for; terminated by 0 */
  int ToolboxEvents[] = {0}; /* list of Toolbox events to look out for; terminated by 0 */


  x_TRY (&x0)  // top level exception catcher
  {

    x_TRY (&x1)        // set up am error TRY block
                        // if anything goes wrong, control is transferred
                        // to the corresponding CATCH block
    {
      /* we need to ensure that we don't start a second instance of the application */
      if (CJL_FindTask (APPNAM) != 0)
      {
        /* if an instance of ourself is already running, set a flag to
        ** quit after showing a message */

        second_instance = TRUE;
      }
      /* register ourselves with the Toolbox */
      TaskHandle = toolbox_initialise (0,
                                       LOWEST_WIMP_VERSION,
                                       (wimp_message_list*)WimpMessages,
                                       (toolbox_action_list*)ToolboxEvents,
                                       RESDIR,
                                       &Messages_cb,
                                       &Id_Block,
                                       &wimp_version,
                                       &SpriteArea);
    } /* end of try block x1 */

    x_CATCH (&x1)  /* the CATCH block is only entered if something goes wrong
                       within the corresponding TRY block */
    {
      /* this call is flagged fatal, and never returns */
      Err_ReportError (Err_FATAL, "There has been a serious problem during set up: %s",
                                  x1.error -> errmess);
    }   /* end of catch block x1 */

    /* Wimp Task initialisation has been successful */

    /* initialise the event library and set the event masks */
    event_initialise (&Id_Block);
    event_set_mask (    wimp_MASK_NULL
                      | wimp_MASK_LEAVING
                      | wimp_MASK_ENTERING
                      | wimp_MASK_GAIN
                      | wimp_MASK_POLLWORD
                      | wimp_GIVEN_POLLWORD
                      | wimp_POLL_HIGH_PRIORITY
                       );

    /* initialise msg and err display */
    CJL_MsgInit ( APPNAM, &Messages_cb );
    // register application message handlers
    event_register_message_handler (message_QUIT, QuitMessage, NULL);
    event_register_message_handler (message_PREQUIT, QuitMessage, NULL);
    event_register_message_handler (message_TASK_INITIALISE, InitMessage, NULL);


    x_TRY (&x1)  // we can safely re-use the exception block
    {
      /* poll loop */
      while (!Quit)
      {
        event_poll (&event_code, &poll_block, 0);
      }
    }  // end of try block x1

    // catch any exceptions encountered while handling a poll message
    x_CATCH (&x1)
    {
      Err_ReportError( 0, "%s",x1.error->errmess);
    }   // end of catch block x1
  } // end of try block x0

  // top level exception catcher - should never be required
  x_CATCH (&x0)
  {
    Err_ReportError (Err_FATAL, "Uncaught Exception: %s",
                     x0.error -> errmess);   // always fatal
  } // end of catch block x0


  return (0);
}




/************************************************************/





/*************  End of c.main  ***********************/

