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

/*
*
* 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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


/* from oslib */
#include "OSLib:os.h"
#include "OSLib:osfile.h"
#include "OSLib:toolbox.h"
#include "OSLib:wimp.h"
#include "OSLib:menu.h"
#include "OSLib:messagetrans.h"
#include "OSLib:taskmanager.h"
#include "OSLib:writablefield.h"
#include "OSLib:numberrange.h"
#include "OSLib:window.h"
#include "OSLib:font.h"
#include "OSLib:fontmenu.h"
#include "OSLib:colourtrans.h"
#include "OSLib:saveas.h"
#include "OSLib:popup.h"
#include "OSLib:displayfield.h"
#include "OSLib:optionbutton.h"
#include "OSLib:stringset.h"
#include "OSLib:iconbar.h"

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

/* from CJLib */
#include "CJLib:choices.h"
#include "CJLib:etc.h"


/* from application */
#include "app.h"
#include "cjoslib.h"
#include "dpimenu.h"
#include "main.h"
#include "iconbar.h"
#include "unitconv.h"
#include "choices.h"


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

        // Preferences window
#define CHOICES_TEMPLATE        ((toolbox_id)"Prefs")
#define uevent_PREFS_ABOUT_TO_CLOSE    0x030
#define uevent_PREFS_SET               0x031
#define uevent_PREFS_SAVE              0x033
#define PREFS_DPI             ((toolbox_c)0x12)
#define PREFS_UNITS           ((toolbox_c)0x122)
#define PREFS_SELECTCLICK     ((toolbox_c)0x124)
#define PREFS_ADJUSTCLICK     ((toolbox_c)0x129)
#define PREFS_SHIFT_SELECTCLICK     ((toolbox_c)0x12b)
#define PREFS_SHIFT_ADJUSTCLICK     ((toolbox_c)0x12e)
#define PREFS_CTRL_SELECTCLICK     ((toolbox_c)0x12f)
#define PREFS_CTRL_ADJUSTCLICK     ((toolbox_c)0x132)
#define PREFS_GASMARK         ((toolbox_c)0x12A)

/* Local defines */

#define PREFS_MSG_BUFFER_SIZE 256
#define PREFS_FILENAME_LENGTH 512

#define PREFS_POPUPDPI 0x13


/************************************************************/
/* Global variables */
static toolbox_o Choices_winid;
static toolbox_o Choices_DPIMenuID;

/************************************************************/
/* Function forward references */
static osbool Choices_MainHandler ( bits event_code, toolbox_action *action,
                                    toolbox_block *id_block, void *handle );


#define USE_INDEX 1

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

static void Choices_SetUpDialogue ( void )

{
  char dpi_value [6] ;

  /* Set available options for iconbar click action string sets */
  /* All six click actions have the same set of options */
  stringset_set_available (0, Choices_winid, PREFS_SELECTCLICK, CLICK_OPTIONS);
  stringset_set_available (0, Choices_winid, PREFS_ADJUSTCLICK, CLICK_OPTIONS);
  stringset_set_available (0, Choices_winid, PREFS_SHIFT_SELECTCLICK, CLICK_OPTIONS);
  stringset_set_available (0, Choices_winid, PREFS_SHIFT_ADJUSTCLICK, CLICK_OPTIONS);
  stringset_set_available (0, Choices_winid, PREFS_CTRL_SELECTCLICK, CLICK_OPTIONS);
  stringset_set_available (0, Choices_winid, PREFS_CTRL_ADJUSTCLICK, CLICK_OPTIONS);

  sprintf (dpi_value, "%d", app.ch.dpi ) ;
  writablefield_set_value ( 0,
                            Choices_winid,
                            PREFS_DPI,
                            dpi_value ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_UNITS,
                                 app.ch.units ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_SELECTCLICK,
                                 app.ch.select_click ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_ADJUSTCLICK,
                                 app.ch.adjust_click ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_SHIFT_SELECTCLICK,
                                 app.ch.shift_select_click ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_SHIFT_ADJUSTCLICK,
                                 app.ch.shift_adjust_click ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_CTRL_SELECTCLICK,
                                 app.ch.ctrl_select_click ) ;
  stringset_set_selected_index ( USE_INDEX,
                                 Choices_winid,
                                 PREFS_CTRL_ADJUSTCLICK,
                                 app.ch.ctrl_adjust_click ) ;

  optionbutton_set_state (0, Choices_winid, PREFS_GASMARK,
                          (osbool)app.ch.show_gasmark ) ;
  return;
}




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

static void Choices_GetNewValues ( void )

{
  char value [16] ;
  int size = 15 ;
  int used ;

  /* read dpi value */
  used = writablefield_get_value ( 0,
                                   Choices_winid,
                                   PREFS_DPI,
                                   value,
                                   size ) ;
  app.ch.dpi = atoi ( value ) ;

  /* Get image size units */
  app.ch.units = stringset_get_selected_index ( USE_INDEX,
                                                Choices_winid,
                                                PREFS_UNITS ) ;
  /* Get the iconbar icon click actions */
  app.ch.select_click = stringset_get_selected_index ( USE_INDEX,
                                                       Choices_winid,
                                                       PREFS_SELECTCLICK ) ;
  app.ch.adjust_click = stringset_get_selected_index ( USE_INDEX,
                                                       Choices_winid,
                                                       PREFS_ADJUSTCLICK ) ;
  app.ch.shift_select_click = stringset_get_selected_index ( USE_INDEX,
                                                             Choices_winid,
                                                             PREFS_SHIFT_SELECTCLICK ) ;
  app.ch.shift_adjust_click = stringset_get_selected_index ( USE_INDEX,
                                                             Choices_winid,
                                                             PREFS_SHIFT_ADJUSTCLICK ) ;
  app.ch.ctrl_select_click = stringset_get_selected_index ( USE_INDEX,
                                                            Choices_winid,
                                                            PREFS_CTRL_SELECTCLICK ) ;
  app.ch.ctrl_adjust_click = stringset_get_selected_index ( USE_INDEX,
                                                            Choices_winid,
                                                            PREFS_CTRL_ADJUSTCLICK ) ;
  /* Include gas mark? */
  app.ch.show_gasmark = (osbool) optionbutton_get_state (0,
                           Choices_winid, PREFS_GASMARK ) ;

  if (app.ch.show_gasmark)
  {
    uc_data.group[uc_data.no_of_groups-1]->set[0].no_of_items = 4;
  }
  else
  {
    uc_data.group[uc_data.no_of_groups-1]->set[0].no_of_items = 3;
  }
  if (uc_data.current_group == uc_data.no_of_groups-1)
  {
    if (uc_data.current_set == 0)
    {
      /* we must be showing temperature */
      /* set up window again */
      UnitconvSetupItems ();
    }
  }

  return;
}


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

                  load_prefs

  Function to read the application prefs from the
  choices file located in the new boot structure

  If the new boot structure is absent, then it will default
  to looking in the app directory

  The choices file is loaded into memory and messagetrans
  used to look up the values

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





/* Routines to load and save choices files */
/* Make them available to other source files */



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

static CJL_choices_tag  tag_table[] =
{
  "DefaultDPI", TAGINT, &app.ch.dpi, 0,
  "DefaultImageSizeUnit", TAGINT, &app.ch.units, 0,
  "DefaultSelectClick", TAGINT, &app.ch.select_click, 0,
  "DefaultAdjustClick", TAGINT, &app.ch.adjust_click, 0,
  "DefaultShiftSelectClick", TAGINT, &app.ch.shift_select_click, 0,
  "DefaultShiftAdjustClick", TAGINT, &app.ch.shift_adjust_click, 0,
  "DefaultCtrlSelectClick", TAGINT, &app.ch.ctrl_select_click, 0,
  "DefaultCtrlAdjustClick", TAGINT, &app.ch.ctrl_adjust_click, 0,
  "ShowGasMark", TAGINT, &app.ch.show_gasmark, 0,

  NULL,0,NULL
};






#define LEAF "Choices"
#define FILE_ID "UnitConv choices"


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

void Choices_DoLoad (void)
{
  CJL_choices_loadsavedata d;

  d.leafname = LEAF;
  d.file_id = FILE_ID;
  d.app_name = APPNAM;
  d.author_dir = AUTHOR_DIR;
  d.save = FALSE;
  d.use_flex = FALSE;
////  d.data.load.not_found = "PREFnotfound";
  d.data.load.no_read = "PREFnomalloc";
  d.data.load.malloc_fail = "PREFnoread";

  CJL_ChoicesLoad (&d, tag_table);

  return;
}




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

void Choices_DoSave (void)
{
  CJL_choices_loadsavedata d;

  /* now do the save */

  d.leafname = LEAF;
  d.file_id = FILE_ID;
  d.app_name = APPNAM;
  d.author_dir = AUTHOR_DIR;
  d.save = TRUE;
  d.use_flex = FALSE;
  d.data.save.write_err = "PREFnosave";

  CJL_ChoicesSave (&d, tag_table);

  return;
}







/* Choices dialogue event handlers */



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

static void Choices_SetDPI ( char *dpi )
{
  writablefield_set_value (0, Choices_winid, PREFS_DPI, dpi );
  return;
}




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

static osbool Choices_DPIMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_DPI_72:
      Choices_SetDPI ( "72" ) ;
      break ;

    case action_DPI_90:
      Choices_SetDPI ( "90" ) ;
      break ;

    case action_DPI_150:
      Choices_SetDPI ( "150" ) ;
      break ;

    case action_DPI_180:
      Choices_SetDPI ( "180" ) ;
      break ;

    case action_DPI_200:
      Choices_SetDPI ( "200" ) ;
      break ;

    case action_DPI_270:
      Choices_SetDPI ( "270" ) ;
      break ;

    case action_DPI_300:
      Choices_SetDPI ( "300" ) ;
      break ;

    case action_DPI_360:
      Choices_SetDPI ( "360" ) ;
      break ;

    case action_DPI_400:
      Choices_SetDPI ( "400" ) ;
      break ;

    case action_DPI_600:
      Choices_SetDPI ( "600" ) ;
      break ;

    case action_DPI_720:
      Choices_SetDPI ( "720" ) ;
      break ;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Choices_DPIMenuID,
                                         action_ANY,
                                         Choices_DPIMenuHandler,
                                         NULL );
      break;
  }
  return (TRUE);
}



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

static osbool Choices_KeyPress ( wimp_event_no event,
                                  wimp_block * blk,
                                  toolbox_block * id_block,
                                  void * handle )
{
  wimp_key *wkey;

  wkey = (wimp_key*)blk;
  if (wkey->c == wimp_KEY_F1)
    IconbarShowHelp();
  else
  if (( wkey->c < 32 ) || ( wkey->c > 126 ))
    wimp_process_key (wkey->c);

  return (TRUE);

  /* for compiler */
  IGNORE (handle);
  IGNORE (id_block);
  IGNORE (event);
}





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

static void Choices_CloseDown (void)
{
  event_deregister_toolbox_handler (Choices_winid,
                                    action_ANY,
                                    Choices_MainHandler,
                                    NULL);
  event_deregister_wimp_handler ( Choices_winid,
                                  wimp_KEY_PRESSED,
                                  Choices_KeyPress,
                                  NULL );
  toolbox_delete_object (0, Choices_winid);
  Choices_winid = toolbox_NULL_OBJECT ;
  return;
}



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

static osbool Choices_MainHandler (bits event_code,
                                 toolbox_action *action,
                                 toolbox_block *id_block,
                                 void *handle )
{
  PopUpAboutToBeShownBlock *popupblk;


  switch (event_code)
  {
    case uevent_PREFS_ABOUT_TO_CLOSE:
      Choices_CloseDown ();
      break;

    case uevent_PREFS_SET:
      Choices_GetNewValues ();
      break;

    case uevent_PREFS_SAVE:
      Choices_GetNewValues ();
      Choices_DoSave ();
      break;

    case action_POP_UP_ABOUT_TO_BE_SHOWN:
      popupblk = (PopUpAboutToBeShownBlock *)action;
      if (id_block->this_cmp == PREFS_POPUPDPI)
      {
          Choices_DPIMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Choices_DPIMenuID,
                                           action_ANY,
                                           Choices_DPIMenuHandler,
                                           NULL );
      }
      break;

  }


  return(TRUE);

  /* for compiler */
  IGNORE (handle);
  IGNORE (id_block);
  IGNORE (action);
}



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

void  Choices_OpenDialogue (void)
{
  if ( Choices_winid == toolbox_NULL_OBJECT)
  {
    Choices_winid = toolbox_create_object (0, CHOICES_TEMPLATE);
    /* now register the event handlers */
    event_register_toolbox_handler ( Choices_winid,
                                    action_ANY,
                                    Choices_MainHandler,
                                    NULL);
    event_register_wimp_handler ( Choices_winid,
                                  wimp_KEY_PRESSED,
                                  Choices_KeyPress,
                                  NULL );
    Choices_SetUpDialogue ();

    toolbox_show_object (0,
                        Choices_winid,
                        toolbox_POSITION_CENTRED,
                        0,
                        toolbox_NULL_OBJECT,
                        toolbox_NULL_COMPONENT ) ;
  }
  else
  {
    toolbox_show_object (0,
                        Choices_winid,
                        toolbox_POSITION_DEFAULT,
                        0,
                        toolbox_NULL_OBJECT,
                        toolbox_NULL_COMPONENT ) ;
  }

  return;
}



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

void Choices_Initialise (void)
{
  /* initialise prefs */
  app.ch.dpi = 180 ;
  app.ch.units = PREFS_IMAGESIZE_CM ;
  app.ch.select_click = PREFS_CLICK_UNITS ;
  app.ch.adjust_click = PREFS_CLICK_BINHEX ;
  app.ch.shift_select_click = PREFS_CLICK_NONE ;
  app.ch.shift_adjust_click = PREFS_CLICK_CHOICES ;
  app.ch.ctrl_select_click = PREFS_CLICK_NONE ;
  app.ch.ctrl_adjust_click = PREFS_CLICK_NONE ;
  app.ch.show_gasmark = FALSE;

  Choices_DoLoad ();

  /* do we need to show gas mark */
  if (!app.ch.show_gasmark)
  {
    uc_data.group[uc_data.no_of_groups-1]->set[0].no_of_items = 3;
  }

  return;
}



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





/*************  End of c.choices  ***********************/

