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

/*
*
* 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 <math.h>

/* from oslib */
#include "OSLib:menu.h"
#include "OSLib:os.h"
#include "OSLib:optionbutton.h"
#include "OSLib:popup.h"
#include "OSLib:radiobutton.h"
#include "OSLib:toolbox.h"
#include "OSLib:wimp.h"
#include "OSLib:window.h"
#include "OSLib:writablefield.h"

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

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

// from unitconv
#include "msglink.h"
#include "iconbar.h"
#include "cjoslib.h"
#include "main.h"
#include "dpimenu.h"
#include "imagesize.h"



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

/* Res related stuff - gadget ids etc */
#define IMAGESIZE_TEMPLATE      ((toolbox_id)"Images")
#define IMAGESIZE_SETPIXEL      ((toolbox_c)0x00)
#define IMAGESIZE_SETCM         ((toolbox_c)0x01)
#define IMAGESIZE_SETIN         ((toolbox_c)0x02)
#define IMAGESIZE_SETDPI        ((toolbox_c)0x11C)
#define IMAGESIZE_SETSCALE      ((toolbox_c)0x11D)
#define IMAGESIZE_DPI           ((toolbox_c)0x12)
#define IMAGESIZE_SCALE         ((toolbox_c)0x11B)
#define IMAGESIZE_PIXWIDTH      ((toolbox_c)0x09)
#define IMAGESIZE_PIXHEIGHT     ((toolbox_c)0x0A)
#define IMAGESIZE_CMWIDTH       ((toolbox_c)0x0B)
#define IMAGESIZE_CMHEIGHT      ((toolbox_c)0x0C)
#define IMAGESIZE_INWIDTH       ((toolbox_c)0x0D)
#define IMAGESIZE_INHEIGHT      ((toolbox_c)0x0E)
#define IMAGESIZE_POPUPPIX      ((toolbox_c)0x0F)
#define IMAGESIZE_POPUPCM       ((toolbox_c)0x10)
#define IMAGESIZE_POPUPIN       ((toolbox_c)0x11)
#define IMAGESIZE_POPUPDPI      ((toolbox_c)0x13)
#define IMAGESIZE_POPUPSCALE    ((toolbox_c)0x11A)
#define IMAGESIZE_ASPECTRATIO   ((toolbox_c)0x11E)
#define IMAGESIZE_ASPECTWIDTH   ((toolbox_c)0x11F)
#define IMAGESIZE_ASPECTHEIGHT  ((toolbox_c)0x121)
#define IMAGESIZE_POPUPASPECT   ((toolbox_c)0x122)


#define action_IMAGESIZE_CALCULATE   0x010
#define action_IMAGESIZE_SETPIXEL    0x011
#define action_IMAGESIZE_SETMM       0x012
#define action_IMAGESIZE_SETIN       0x013
#define action_IMAGESIZE_SETDPI      0x014
#define action_IMAGESIZE_SETSCALE    0x015
#define action_IMAGESIZE_ASPECT      0x016

        // scale menu
#define action_SCALE_100        0x280
#define action_SCALE_75         0x281
#define action_SCALE_50         0x282
#define action_SCALE_25         0x283
#define action_SCALE_20         0x284

        // cm menu
#define action_CM_A4            0x220
#define action_CM_A5            0x221

        // pixel menu
#define action_PIXEL_640        0x240
#define action_PIXEL_800        0x241
#define action_PIXEL_1280       0x242
#define action_PIXEL_1600       0x243
#define action_PIXEL_3072       0x244

        // inches menu
#define action_INCHES_6X4       0x260
#define action_INCHES_7X5       0x261
#define action_INCHES_8X6       0x262
#define action_INCHES_10X8      0x263
#define action_INCHES_12X10     0x264
#define action_INCHES_5X5       0x265
#define action_INCHES_7_5X5     0x266

        // aspect ratio menu
#define action_ASPECT_1X1       0x290
#define action_ASPECT_2X1       0x291
#define action_ASPECT_3X2       0x292
#define action_ASPECT_4X3       0x293

/* Local defines */

#define STATE_ON    1
#define STATE_OFF   0

#define MM_TO_INCH 25.4
#define DPI_TO_SCALE 9000.0


/************************************************************/
/* global variables */
static toolbox_o Imagesize_winid;
static wimp_w    Imagesize_winhandle;
static toolbox_position Imagesize_win_pos;
static toolbox_o Imagesize_PixelMenuID;
static toolbox_o Imagesize_CmMenuID;
static toolbox_o Imagesize_InchMenuID;
static toolbox_o Imagesize_DPIMenuID;
static toolbox_o Imagesize_ScaleMenuID;
static toolbox_o Imagesize_AspectMenuID;
static osbool Imagesize_fix_aspect;

/* ========================================================================== */


/**********************
**
** Calculate image size
**
***********************/

#define TEXT_BUF_SIZE 15

/* ========================================================================== */

static void Imagesize_calculate (void)
{
  /* for get value */
  char txbuf [TEXT_BUF_SIZE] ;
  int used ;
  double dpi = 90.0, scale ;
  int pixels ;
  double aspect_height = 1.0, aspect_width = 1.0;

  double pixel_width ;
  double pixel_height ;
  double inch_width, inch_height ;
  double cm_width, cm_height ;

  osbool state ;
  toolbox_c on_button ;


  /* Find which radio icon dpi/scale is selected */
  state = radiobutton_get_state ( 0, Imagesize_winid,
                                  IMAGESIZE_SETDPI, &on_button ) ;
  switch ( on_button )
  {
    case IMAGESIZE_SETDPI:
      /* read dpi value */
      used = writablefield_get_value ( 0, Imagesize_winid,
                                       IMAGESIZE_DPI, txbuf, TEXT_BUF_SIZE ) ;
      dpi = atof ( txbuf ) ;
      /* and write the corresponding scale value */
      scale = DPI_TO_SCALE / dpi ;
      sprintf ( txbuf, "%.2f", scale ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_SCALE, txbuf ) ;
      break ;

    case IMAGESIZE_SETSCALE:
      /* read scale value */
      used = writablefield_get_value ( 0, Imagesize_winid,
                                       IMAGESIZE_SCALE, txbuf, TEXT_BUF_SIZE ) ;
      scale = atof ( txbuf ) ;
      /* calculate and write the corresponding dpi value */
      dpi = DPI_TO_SCALE / scale ;
      sprintf ( txbuf, "%.0f", dpi ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_DPI, txbuf ) ;
      break ;
  }

  if ( Imagesize_fix_aspect == TRUE )
  {
    /* get the aspect ratio */
    used = writablefield_get_value ( 0, Imagesize_winid,
                                     IMAGESIZE_ASPECTWIDTH, txbuf, TEXT_BUF_SIZE ) ;
    aspect_width = atof ( txbuf ) ;
    used = writablefield_get_value ( 0, Imagesize_winid,
                                     IMAGESIZE_ASPECTHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
    aspect_height = atof ( txbuf ) ;
  }

  state = radiobutton_get_state ( 0, Imagesize_winid,
                                  IMAGESIZE_SETPIXEL, &on_button ) ;
  switch ( on_button )
  {
    case IMAGESIZE_SETPIXEL:
      /* Read values to use */
      /* get width and height */

      if ( Imagesize_fix_aspect == TRUE )
      {
        /* get the width */
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_PIXWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        if (used > 1)
        {
          /* field contains a value */
          pixel_width = atof ( txbuf ) ;
          /* calculate corresponding height */
          pixel_height = pixel_width * aspect_height / aspect_width ;
          sprintf ( txbuf, "%.0f", pixel_height ) ;
          writablefield_set_value ( 0, Imagesize_winid,
                                    IMAGESIZE_PIXHEIGHT , txbuf );
        }
        else
        {
          /* get the height */
          used = writablefield_get_value ( 0, Imagesize_winid,
                                           IMAGESIZE_PIXHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
          pixel_height = atof ( txbuf ) ;
          pixel_width = pixel_height * aspect_width / aspect_height ;
          sprintf ( txbuf, "%.0f", pixel_width ) ;
          writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_PIXWIDTH, txbuf );
        }

      }
      else
      {
        /* just read the width and height */
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_PIXWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        pixel_width = atof ( txbuf ) ;
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_PIXHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
        pixel_height = atof ( txbuf ) ;
      }
      /* convert to inches at given dpi */
      inch_width = pixel_width / dpi ;
      sprintf ( txbuf , "%.2f" , inch_width ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INWIDTH, txbuf );
      inch_height = pixel_height / dpi ;
      sprintf ( txbuf , "%.2f" , inch_height ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INHEIGHT, txbuf );
      /* now do the cm/mm */
      inch_width *= MM_TO_INCH ;
      sprintf ( txbuf , "%.1f" , inch_width ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMWIDTH, txbuf );
      inch_height *= MM_TO_INCH ;
      sprintf ( txbuf , "%.1f" , inch_height ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMHEIGHT, txbuf );
      break ;

    case IMAGESIZE_SETCM:
      /* Read values to use */
      /* get width and height */
      if ( Imagesize_fix_aspect == TRUE )
      {
        /* get the width */
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_CMWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        if (used > 1)
        {
          /* field contains a value */
          cm_width = atof ( txbuf ) ;
          /* calculate corresponding height */
          cm_height = cm_width * aspect_height / aspect_width ;
          sprintf ( txbuf, "%.1f", cm_height ) ;
          writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMHEIGHT, txbuf );
        }
        else
        {
          /* get the height */
          used = writablefield_get_value ( 0, Imagesize_winid,
                                           IMAGESIZE_CMHEIGHT, txbuf, TEXT_BUF_SIZE );
          cm_height = atof ( txbuf ) ;
          cm_width = cm_height * aspect_width / aspect_height ;
          sprintf ( txbuf, "%.1f", cm_width ) ;
          writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMWIDTH, txbuf );
        }

      }
      else
      {
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_CMWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        cm_width = atof ( txbuf ) ;
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_CMHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
        cm_height = atof ( txbuf ) ;
      }

      /* convert to inches at given dpi */
      inch_width = cm_width / MM_TO_INCH ;
      sprintf ( txbuf , "%.2f" , inch_width ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INWIDTH, txbuf );
      inch_height = cm_height / MM_TO_INCH ;
      sprintf ( txbuf , "%.2f" , inch_height ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INHEIGHT, txbuf );
      /* now do the pixels */
      inch_width *= dpi ;
      pixels = (int) floor ( inch_width + 0.5 ) ;
      sprintf ( txbuf , "%d" , pixels ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_PIXWIDTH, txbuf );
      inch_height *= dpi ;
      pixels = (int) floor ( inch_height + 0.5 ) ;
      sprintf ( txbuf , "%d" , pixels ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_PIXHEIGHT, txbuf );
      break ;

    case IMAGESIZE_SETIN:
      /* Read values to use */
      /* get width and height */
      if ( Imagesize_fix_aspect == TRUE )
      {
        /* get the width */
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_INWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        if (used > 1)
        {
          /* field contains a value */
          inch_width = atof ( txbuf ) ;
          /* calculate corresponding height */
          inch_height = inch_width * aspect_height / aspect_width ;
          sprintf ( txbuf, "%.2f", inch_height ) ;
          writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INHEIGHT, txbuf );
        }
        else
        {
          /* get the height */
          used = writablefield_get_value ( 0, Imagesize_winid,
                                        IMAGESIZE_INHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
          inch_height = atof ( txbuf ) ;
          inch_width = inch_height * aspect_width / aspect_height ;
          sprintf ( txbuf, "%.2f", inch_width ) ;
          writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_INWIDTH, txbuf );
        }

      }
      else
      {
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_INWIDTH, txbuf, TEXT_BUF_SIZE ) ;
        inch_width = atof ( txbuf ) ;
        used = writablefield_get_value ( 0, Imagesize_winid,
                                         IMAGESIZE_INHEIGHT, txbuf, TEXT_BUF_SIZE ) ;
        inch_height = atof ( txbuf ) ;
      }

      /* convert to inches at given dpi */
      pixel_width = inch_width * dpi ;
      pixels = (int) floor ( pixel_width + 0.5 ) ;
      sprintf ( txbuf , "%d" , pixels ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_PIXWIDTH, txbuf );
      pixel_height = inch_height * dpi ;
      pixels = (int) floor ( pixel_height + 0.5 ) ;
      sprintf ( txbuf , "%d" , pixels ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_PIXHEIGHT, txbuf );
      /* now do the cm/mm */
      cm_width = inch_width * MM_TO_INCH ;
      sprintf ( txbuf , "%.1f" , cm_width ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMWIDTH, txbuf );
      cm_height = inch_height * MM_TO_INCH ;
      sprintf ( txbuf , "%.1f" , cm_height ) ;
      writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_CMHEIGHT, txbuf );
      break ;

  }

  return ;
}




/* Set base size units and fading and unfading gadgets */


/* ========================================================================== */

static void Imagesize_fade_pixel ( void )
{
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_PIXWIDTH ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_PIXHEIGHT ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPPIX ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_unfade_pixel ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_PIXWIDTH ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_PIXHEIGHT ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPPIX ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_fade_cm ( void )
{
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_CMWIDTH ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_CMHEIGHT ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPCM ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_unfade_cm ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_CMWIDTH ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_CMHEIGHT ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPCM ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_fade_inch ( void )
{
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_INWIDTH ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_INHEIGHT ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPIN ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_unfade_inch ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_INWIDTH ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_INHEIGHT ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPIN ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_fade_aspect ( void )
{
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_ASPECTWIDTH ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_ASPECTHEIGHT ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPASPECT ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_unfade_aspect ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_ASPECTWIDTH ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_ASPECTHEIGHT ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPASPECT ) ;
  return ;
}

/* ========================================================================== */

static void Imagesize_set_to_pixels ( void )
{
  Imagesize_unfade_pixel ( ) ;
  Imagesize_fade_cm ( ) ;
  Imagesize_fade_inch ( ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_set_to_cm ( void )
{
  Imagesize_unfade_cm ( ) ;
  Imagesize_fade_pixel ( ) ;
  Imagesize_fade_inch ( ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_set_to_inch ( void )
{
  Imagesize_unfade_inch ( ) ;
  Imagesize_fade_pixel ( ) ;
  Imagesize_fade_cm ( ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_set_to_dpi ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_DPI ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPDPI ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_SCALE ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPSCALE ) ;
  return ;
}


/* ========================================================================== */

static void Imagesize_set_to_scale ( void )
{
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_SCALE ) ;
  CJL_GadgetUnfade ( Imagesize_winid, IMAGESIZE_POPUPSCALE ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_DPI ) ;
  CJL_GadgetFade ( Imagesize_winid, IMAGESIZE_POPUPDPI ) ;
  return ;
}



/* ========================================================================== */

static void Imagesize_SetPixel (char *wid, char *ht)
{
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_PIXWIDTH , wid );
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_PIXHEIGHT , ht );
  Imagesize_calculate ( ) ;
  return;
}




/* ========================================================================== */

static osbool Imagesize_PixelMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_PIXEL_640:
      Imagesize_SetPixel ( "640", "480" );
      break;

    case action_PIXEL_800:
      Imagesize_SetPixel ( "800", "600" );
      break;

    case action_PIXEL_1280:
      Imagesize_SetPixel ( "1280", "1024" );
      break;

    case action_PIXEL_1600:
      Imagesize_SetPixel ( "1600", "1200" );
      break;

    case action_PIXEL_3072:
      Imagesize_SetPixel ( "3072", "2048" );
      break;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_PixelMenuID,
                                         action_ANY,
                                         Imagesize_PixelMenuHandler,
                                         NULL );
      break;
  }

  return (TRUE);

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




/* ========================================================================== */

static void Imagesize_SetCm (char *width, char *height)
{
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_CMWIDTH , width );
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_CMHEIGHT, height );
  Imagesize_calculate ( ) ;
  return;
}



/* ========================================================================== */

static osbool Imagesize_CmMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_CM_A4:
      Imagesize_SetCm ( "297", "210" ) ;
      break;

    case action_CM_A5:
      Imagesize_SetCm ( "210", "148.5" ) ;
      break;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_CmMenuID,
                                         action_ANY,
                                         Imagesize_CmMenuHandler,
                                         NULL );
      break;
  }

  return (TRUE);

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




/* ========================================================================== */

static void Imagesize_SetInch (char *width, char *height)
{
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_INWIDTH , width );
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_INHEIGHT, height );
  Imagesize_calculate ( ) ;
  return;
}



/* ========================================================================== */

static osbool Imagesize_InchMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_INCHES_6X4:
      Imagesize_SetInch ( "6", "4" ) ;
      break;

    case action_INCHES_7X5:
      Imagesize_SetInch ( "7", "5" ) ;
      break;

    case action_INCHES_8X6:
      Imagesize_SetInch ( "8", "6" ) ;
      break;

    case action_INCHES_10X8:
      Imagesize_SetInch ( "10", "8" ) ;
      break;

    case action_INCHES_12X10:
      Imagesize_SetInch ( "12", "10" ) ;
      break;

    case action_INCHES_5X5:
      Imagesize_SetInch ( "5", "5" ) ;
      break;

    case action_INCHES_7_5X5:
      Imagesize_SetInch ( "7.5", "5" ) ;
      break;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_InchMenuID,
                                         action_ANY,
                                         Imagesize_InchMenuHandler,
                                         NULL );
      break;
  }

  return (TRUE);

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




/* ========================================================================== */

static void Imagesize_SetDPI ( char *dpi )
{
  double scale ;
  double dpif ;
  char sc[10];

  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_DPI, dpi );
  dpif = atof ( dpi ) ;
  scale = DPI_TO_SCALE / dpif ;
  /* now set the corresponding scale factor */
  sprintf ( sc, "%.2f", scale ) ;
  writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_SCALE, sc ) ;
  Imagesize_calculate ( ) ;
  return;
}



/* ========================================================================== */

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

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

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

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

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

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

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

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

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

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

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

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_DPIMenuID,
                                         action_ANY,
                                         Imagesize_DPIMenuHandler,
                                         NULL );
      break;
  }

  return (TRUE);

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




/* ========================================================================== */

static void Imagesize_SetScale (char *scale)
{
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_SCALE, scale );
  Imagesize_calculate ( ) ;
  return;
}



/* ========================================================================== */

static osbool Imagesize_ScaleMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_SCALE_100:
      Imagesize_SetScale ( "100" ) ;
      break;

    case action_SCALE_75:
      Imagesize_SetScale ( "75" ) ;
      break;

    case action_SCALE_50:
      Imagesize_SetScale ( "50" ) ;
      break;

    case action_SCALE_25:
      Imagesize_SetScale ( "25" ) ;
      break;

    case action_SCALE_20:
      Imagesize_SetScale ( "20" ) ;
      break;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_ScaleMenuID,
                                         action_ANY,
                                         Imagesize_ScaleMenuHandler,
                                         NULL );
      break;
  }


  return (TRUE);

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




/* ========================================================================== */

static void Imagesize_SetAspect (char *width, char *height)
{
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_ASPECTWIDTH , width );
  writablefield_set_value (0, Imagesize_winid, IMAGESIZE_ASPECTHEIGHT, height );
  return;
}



/* ========================================================================== */

static osbool Imagesize_AspectMenuHandler ( bits event_code,
                                           toolbox_action *action,
                                           toolbox_block *id_block,
                                           void *handle )
{
  switch (event_code)
  {
    case action_ASPECT_1X1:
      Imagesize_SetAspect ( "1", "1" ) ;
      break;

    case action_ASPECT_2X1:
      Imagesize_SetAspect ( "2", "1" ) ;
      break;

    case action_ASPECT_3X2:
      Imagesize_SetAspect ( "3", "2" ) ;
      break;

    case action_ASPECT_4X3:
      Imagesize_SetAspect ( "4", "3" ) ;
      break;

    case action_MENU_DIALOGUE_COMPLETED:
      event_deregister_toolbox_handler ( Imagesize_AspectMenuID,
                                         action_ANY,
                                         Imagesize_AspectMenuHandler,
                                         NULL );
      break;
  }

  return (TRUE);

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





/* ========================================================================== */

static osbool Imagesize_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 osbool Imagesize_Handler ( bits event_code,
                                  toolbox_action *action,
                                  toolbox_block *id_block,
                                  void *handle )
{
  PopUpAboutToBeShownBlock *popupblk;


  switch (event_code)
  {
    case action_IMAGESIZE_CALCULATE:
      Imagesize_calculate ( ) ;
      break ;

    case action_IMAGESIZE_SETPIXEL:
      Imagesize_set_to_pixels ();
      break ;

    case action_IMAGESIZE_SETMM:
      Imagesize_set_to_cm ();
      break ;

    case action_IMAGESIZE_SETIN:
      Imagesize_set_to_inch ();
      break ;

    case action_IMAGESIZE_SETDPI:
      Imagesize_set_to_dpi ( ) ;
      break ;

    case action_IMAGESIZE_SETSCALE:
      Imagesize_set_to_scale ( ) ;
      break ;

    case action_IMAGESIZE_ASPECT:
      Imagesize_fix_aspect = optionbutton_get_state (0,
                      Imagesize_winid, IMAGESIZE_ASPECTRATIO ) ;
      if ( Imagesize_fix_aspect == TRUE )
      {
        Imagesize_unfade_aspect ();
      }
      else
      {
        Imagesize_fade_aspect ();
      }
      break ;

    case action_POP_UP_ABOUT_TO_BE_SHOWN:
      popupblk = (PopUpAboutToBeShownBlock *)action;

      switch (id_block->this_cmp)
      {
        case IMAGESIZE_POPUPPIX:
          Imagesize_PixelMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_PixelMenuID,
                                           action_ANY,
                                           Imagesize_PixelMenuHandler,
                                           NULL );
          break;

        case IMAGESIZE_POPUPCM:
          Imagesize_CmMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_CmMenuID,
                                           action_ANY,
                                           Imagesize_CmMenuHandler,
                                           NULL );
          break;

        case IMAGESIZE_POPUPIN:
          Imagesize_InchMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_InchMenuID,
                                           action_ANY,
                                           Imagesize_InchMenuHandler,
                                           NULL );
          break;

        case IMAGESIZE_POPUPDPI:
          Imagesize_DPIMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_DPIMenuID,
                                           action_ANY,
                                           Imagesize_DPIMenuHandler,
                                           NULL );
          break;

        case IMAGESIZE_POPUPSCALE:
          Imagesize_ScaleMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_ScaleMenuID,
                                           action_ANY,
                                           Imagesize_ScaleMenuHandler,
                                           NULL );
          break;

        case IMAGESIZE_POPUPASPECT:
          Imagesize_AspectMenuID = popupblk->menu_id;
          event_register_toolbox_handler ( Imagesize_AspectMenuID,
                                           action_ANY,
                                           Imagesize_AspectMenuHandler,
                                           NULL );
          break;

      }

      break;

    case action_WINDOW_DIALOGUE_COMPLETED:
      /* get current position of Imagesize window */
      CJL_GetTopLeftWinPos ( Imagesize_winhandle, &Imagesize_win_pos );

      event_deregister_toolbox_handler ( Imagesize_winid,
                                      action_ANY,
                                      Imagesize_Handler,
                                      NULL);
      event_deregister_wimp_handler ( Imagesize_winid,
                                      wimp_KEY_PRESSED,
                                      Imagesize_KeyPress,
                                      NULL );
      toolbox_delete_object ( 0, Imagesize_winid );
      Imagesize_winid = toolbox_NULL_OBJECT;
      break;
  }

  return(TRUE);

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



/* ========================================================================== */

/* Set up the imagesize window as per defaults */

static void Imagesize_Setup ( void )
{
  char buf [6];
  double scale ;


  sprintf ( buf, "%d", app.ch.dpi ) ;
  writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_DPI, buf ) ;
  scale = DPI_TO_SCALE / ( double ) app.ch.dpi ;
  sprintf ( buf, "%.2f", scale ) ;
  writablefield_set_value ( 0, Imagesize_winid, IMAGESIZE_SCALE, buf ) ;

  switch ( app.ch.units )
  {
    case PREFS_IMAGESIZE_PIX:
      radiobutton_set_state ( 0, Imagesize_winid, IMAGESIZE_SETPIXEL, STATE_ON ) ;
      Imagesize_set_to_pixels ();
      break ;

    case PREFS_IMAGESIZE_CM:
      radiobutton_set_state ( 0, Imagesize_winid, IMAGESIZE_SETCM, STATE_ON ) ;
      Imagesize_set_to_cm ();
      break ;

    case PREFS_IMAGESIZE_INCH:
      radiobutton_set_state ( 0, Imagesize_winid, IMAGESIZE_SETIN, STATE_ON ) ;
      Imagesize_set_to_inch ();
      break ;
  }

  return;
}



/* ========================================================================== */

void Imagesize_Open (void)
{

  if (Imagesize_winid == toolbox_NULL_OBJECT)
  {
    Imagesize_winid = toolbox_create_object ( 0, IMAGESIZE_TEMPLATE);
    Imagesize_winhandle = window_get_wimp_handle (0, Imagesize_winid);
    event_register_toolbox_handler ( Imagesize_winid,
                                     action_ANY,
                                     Imagesize_Handler,
                                     NULL);
    event_register_wimp_handler ( Imagesize_winid,
                                  wimp_KEY_PRESSED,
                                  Imagesize_KeyPress,
                                  NULL );
    Imagesize_Setup ();

    if (Imagesize_win_pos.top_left.x == 0)
    {
      toolbox_show_object ( 0,
                            Imagesize_winid,
                            toolbox_POSITION_CENTRED,
                            0,
                            toolbox_NULL_OBJECT,
                            toolbox_NULL_COMPONENT ) ;
    }
    else
    {
      toolbox_show_object (0,
                          Imagesize_winid,
                          toolbox_POSITION_TOP_LEFT,
                          &Imagesize_win_pos,
                          toolbox_NULL_OBJECT,
                          toolbox_NULL_COMPONENT ) ;
    }
  }
  else
  {
    toolbox_show_object (0,
                        Imagesize_winid,
                        toolbox_POSITION_DEFAULT,
                        NULL,
                        toolbox_NULL_OBJECT,
                        toolbox_NULL_COMPONENT ) ;
  }
  return;
}




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







/*************  End of c.imagesize  ***********************/

