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

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

/* from oslib */
#include "OSLib:menu.h"
#include "OSLib:optionbutton.h"
#include "OSLib:writablefield.h"
#include "OSLib:window.h"

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

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

/* from application */
#include "imagecrop.h"
#include "msglink.h"



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

/* Local defines */

#define IMAGECROP_TEMPLATE ((toolbox_id)"ImgSize")
#define IMAGECROP_ASPECTMENU_TEMPLATE ((toolbox_id)"aspcropM")


#define action_IMAGECROP_CALCULATE 0x400
#define action_IMAGECROP_CLEAR     0x401

#define IMAGECROP_ASPECT_X      ((toolbox_c)0x01)
#define IMAGECROP_ASPECT_Y      ((toolbox_c)0x03)
#define IMAGECROP_NEW_X         ((toolbox_c)0x05)
#define IMAGECROP_NEW_Y         ((toolbox_c)0x07)
#define IMAGECROP_USE_PERCENT   ((toolbox_c)0x0B)
#define IMAGECROP_PERCENT_VALUE ((toolbox_c)0x0C)

/* Calculation flags */
#define IMAGECROP_CHECK_FIELDS 0
#define IMAGECROP_X_GIVEN      1
#define IMAGECROP_Y_GIVEN      2
#define IMAGECROP_CALC_PERCENT 3

#define TEXT_BUF_SIZE 15

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

/* exported variables */


/************************************************************/
/* global variables */

typedef struct imagesize_values
{
  int aspect_x;
  int aspect_y;
  int calc_x;
  int calc_y;
} imagesize_values;

static toolbox_o Imagecrop_winid;
static wimp_w    Imagecrop_winhandle;
static toolbox_position Imagecrop_win_pos;
static imagesize_values size;
static toolbox_o Imagecrop_AspectMenuID;
static osbool find_percent;

typedef struct aspect_values
{
  char * xval;
  char * yval;
} aspect_values;

static aspect_values aspect[] = { "3", "2",
                                  "4", "3",
                                  "16", "9",
                                  "16", "10",
                                  "640", "480",
                                  "1280", "1024",
                                  "1600", "1200",
                                  "1880", "1040",
                                  "1920", "1080",

                                  "0", "0"
                                };


/************************************************************/
/* forward function declarations */


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


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





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

static void Imagecrop_clear (void)

{
  char txbuf[2];

  txbuf[0] = 0x00;
  writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_ASPECT_X, txbuf );
  writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_ASPECT_Y, txbuf );
  writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_X, txbuf );
  writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_Y, txbuf );
  writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_PERCENT_VALUE, txbuf );

  return;
}




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

static void Imagecrop_calculate (int method)

{
  int used ;
  char txbuf [TEXT_BUF_SIZE] ;
  int percent;
  double ratio;
  int scale;


  used = writablefield_get_value ( 0, Imagecrop_winid,
                                   IMAGECROP_ASPECT_X, txbuf, TEXT_BUF_SIZE ) ;
  if (used > 1)
  {
    size.aspect_x = atoi(txbuf);
  }
  else
  {
    Msg_Warn ( NOASPECTX );
    return;
  }
  used = writablefield_get_value ( 0, Imagecrop_winid,
                                   IMAGECROP_ASPECT_Y, txbuf, TEXT_BUF_SIZE ) ;
  if (used > 1)
  {
    size.aspect_y = atoi(txbuf);
  }
  else
  {
    Msg_Warn ( NOASPECTY );
    return;
  }
  /* Now do the calculation */
  used = 0;

  if (find_percent)
  {
      used = writablefield_get_value ( 0, Imagecrop_winid,
                                       IMAGECROP_PERCENT_VALUE, txbuf, TEXT_BUF_SIZE ) ;
      percent = atoi(txbuf);
      ratio = 100.0 / (double)percent;
      size.calc_x = (double)size.aspect_x * ratio;
      size.calc_y = (double)size.aspect_y * ratio;
      sprintf ( txbuf, "%d", size.calc_x ) ;
      writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_X, txbuf );
      sprintf ( txbuf, "%d", size.calc_y ) ;
      writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_Y, txbuf );
  }
  else
  {

    if ((method == IMAGECROP_X_GIVEN) || (method == IMAGECROP_CHECK_FIELDS))
    {
      used = writablefield_get_value ( 0, Imagecrop_winid,
                                       IMAGECROP_NEW_X, txbuf, TEXT_BUF_SIZE ) ;
      if (used > 1)
      {
        size.calc_x = atoi(txbuf);
        size.calc_y = size.calc_x * size.aspect_y / size.aspect_x;
        sprintf ( txbuf, "%d", size.calc_y ) ;
        writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_Y, txbuf );
        scale = (int)((100.0 * (double)size.aspect_x) / (double)size.calc_x);
        sprintf ( txbuf, "%d", scale ) ;
        writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_PERCENT_VALUE, txbuf );
      }
    }
    if ((method == IMAGECROP_Y_GIVEN) || (used < 2))
    {
      used = writablefield_get_value ( 0, Imagecrop_winid,
                                       IMAGECROP_NEW_Y, txbuf, TEXT_BUF_SIZE ) ;
      if (used > 1)
      {
        size.calc_y = atoi(txbuf);
        size.calc_x = size.calc_y * size.aspect_x / size.aspect_y;
        sprintf ( txbuf, "%d", size.calc_x ) ;
        writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_NEW_X, txbuf );
        scale = (int)((100.0 * (double)size.aspect_y) / (double)size.calc_y);
        sprintf ( txbuf, "%d", scale ) ;
        writablefield_set_value ( 0, Imagecrop_winid, IMAGECROP_PERCENT_VALUE, txbuf );
      }
      else
      {
        return;
      }
    }
  }

  return;
}





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

static osbool Imagecrop_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_RETURN)
  {
    if (id_block->this_cmp == IMAGECROP_NEW_X)
    {
      Imagecrop_calculate (IMAGECROP_X_GIVEN);
    }
    else
    {
      if (id_block->this_cmp == IMAGECROP_NEW_Y)
      {
        Imagecrop_calculate (IMAGECROP_Y_GIVEN);
      }
      else
      {
        Imagecrop_calculate (IMAGECROP_CHECK_FIELDS);
      }
    }
  }

  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 Imagecrop_SetAspect (char *w, char *h)
{
  writablefield_set_value (0, Imagecrop_winid, IMAGECROP_ASPECT_X, w );
  writablefield_set_value (0, Imagecrop_winid, IMAGECROP_ASPECT_Y, h );
  return;
}



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

static void Imagecrop_setup (void)

{
  CJL_GadgetSetFade (Imagecrop_winid, IMAGECROP_PERCENT_VALUE, !find_percent);
  CJL_GadgetSetFade (Imagecrop_winid, IMAGECROP_NEW_X, find_percent);
  CJL_GadgetSetFade (Imagecrop_winid, IMAGECROP_NEW_Y, find_percent);
  return;
}





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

static osbool Imagecrop_AspectMenuHandler ( bits event_code,
                                            toolbox_action *action,
                                            toolbox_block *id_block,
                                            void *handle )
{
  int cmp;

  if  (event_code == action_MENU_SELECTION)
  {
    cmp = (int)id_block->this_cmp;
    Imagecrop_SetAspect ( aspect[cmp].xval, aspect[cmp].yval );
  }

  return (TRUE);

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




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

#define MENU_ITEM_TEXT_LENGTH 16

void Imagecrop_SetUpAspectMenu (void)

{
  menu_entry_object entry;
  char mtext[MENU_ITEM_TEXT_LENGTH];
  int i;


  /* set up the unchanging parts of the menu entry object */
  entry.flags = 0;
  entry.text_limit = MENU_ITEM_TEXT_LENGTH;
  entry.click_object_name = NULL;
  entry.sub_menu_object_name = NULL;
  entry.sub_menu_action = 0;
  entry.click_action = 0;
  entry.help = NULL;
  entry.help_limit = 0;

  /* create the menu - the res template has only a title bar */
  if (Imagecrop_AspectMenuID == toolbox_NULL_OBJECT)
    Imagecrop_AspectMenuID = toolbox_create_object ( 0, IMAGECROP_ASPECTMENU_TEMPLATE );
  i = 0;
  do
  {
    entry.text = mtext;
    entry.cmp = (toolbox_c)i;
    sprintf(mtext, "%s  %s", aspect[i].xval, aspect[i].yval);
    menu_add_entry (0, Imagecrop_AspectMenuID, menu_ADD_AT_END, &entry);
    i++;
  } while (strcmp (aspect[i].xval, "0"));
  return;
}




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

static osbool Imagecrop_Handler ( bits event_code,
                                  toolbox_action *action,
                                  toolbox_block *id_block,
                                  void *handle )
{
  optionbutton_action_state_changed_block *obblk;

  switch (event_code)
  {
    case action_IMAGECROP_CALCULATE:
      Imagecrop_calculate (IMAGECROP_CHECK_FIELDS);
      break;


    case action_IMAGECROP_CLEAR:
      Imagecrop_clear ();
      break;

    case action_OPTION_BUTTON_STATE_CHANGED:
      obblk = (optionbutton_action_state_changed_block *)action;
      find_percent = obblk->on;
      Imagecrop_setup ();
      break;

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

      event_deregister_toolbox_handler ( Imagecrop_winid,
                                         action_ANY,
                                         Imagecrop_Handler,
                                         NULL);

      event_deregister_toolbox_handler ( Imagecrop_AspectMenuID,
                                         action_ANY,
                                         Imagecrop_AspectMenuHandler,
                                         NULL);

      event_deregister_wimp_handler ( Imagecrop_winid,
                                      wimp_KEY_PRESSED,
                                      Imagecrop_KeyPress,
                                      NULL );

      toolbox_delete_object ( 0, Imagecrop_winid );
      Imagecrop_winid = toolbox_NULL_OBJECT;
      break;
  }

  return (TRUE);

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




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

void Imagecrop_Open (void)

{
  if (Imagecrop_winid == toolbox_NULL_OBJECT)
  {
    Imagecrop_winid = toolbox_create_object ( 0, IMAGECROP_TEMPLATE);
    Imagecrop_winhandle = window_get_wimp_handle (0, Imagecrop_winid);
    event_register_toolbox_handler ( Imagecrop_winid,
                                     action_ANY,
                                     Imagecrop_Handler,
                                     NULL);
    event_register_toolbox_handler ( Imagecrop_AspectMenuID,
                                     action_ANY,
                                     Imagecrop_AspectMenuHandler,
                                     NULL);
    event_register_wimp_handler ( Imagecrop_winid,
                                  wimp_KEY_PRESSED,
                                  Imagecrop_KeyPress,
                                  NULL );

    Imagecrop_setup ();

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

  return;
}




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





/*************  End of c.imagecrop  ***********************/

