/************************************************************
**
** Application: TranJPEG
**
** Title:       c.status
**
*************************************************************/

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


/* headers from tasklib */
#include "TaskLib:h.os"
#include "TaskLib:h.wimp"
#include "TaskLib:h.werr"
#include "TaskLib:h.wos"
#include "TaskLib:h.err"
#include "TaskLib:h.poll"
#include "TaskLib:h.etc"
#include "TaskLib:h.pane"
#include "TaskLib:h.temp"
#include "TaskLib:h.conf"
#include "TaskLib:h.flex"



/* headers from app */
#include "h.xdeb"
#include "h.taskwindow"
#include "h.reslink"
#include "h.process"
#include "h.status"



/* gadgets in progress window */
#define STATUS_FILES        1
#define STATUS_CURRENT_FILE 3
#define STATUS_FILENAME     5
#define STATUS_STATUS       11
#define STATUS_KILL         6
#define STATUS_PAUSE        7
#define STATUS_TWMESSAGE    8





static int status_handle;
static win_position status_pos;
static int tw_paused;
int tw_killed = 0;






os_error *status_update_taskwindow_message ( wimp_msgstr * msg )
{
  os_error   *err = NULL;
  char *ptr;
  int len;

  len = msg->data.words[0];
  ptr = (char*)msg + 24;
  ptr[len] = '\0';

  if (status_handle)
    err = writeiconc ( status_handle, STATUS_TWMESSAGE, ptr );

  return (err);
}



os_error *status_update_status (char *message)
{
  os_error   *err = NULL;

  if (status_handle)
  {
    err = writeiconc ( status_handle, STATUS_STATUS, message );
  }

  return (err);
}




static os_error *status_update_status_T (int token)
{
  os_error   *err = NULL;
  os_error * msg;

  if (status_handle)
  {
    msg = geterror (token);
    err = writeiconc ( status_handle, STATUS_STATUS, msg->errmess );
  }

  return (err);
}




static os_error *status_setpause (void)
{
  os_error   *err = NULL;

  if (status_handle)
  {
    if (tw_paused)
      err = writeiconc ( status_handle, STATUS_PAUSE, "Resume" );
    else
      err = writeiconc ( status_handle, STATUS_PAUSE, "Pause" );
  }

  return (err);
}





static os_error *status_update_filenum (void)
{
  os_error   *err;
  char str[5];

  err = NULL;

  if (status_handle)
  {
    sprintf (str, "%d", num_files);
    err = writeiconc ( status_handle, STATUS_FILES, str );
  }

  return (err);
}





void status_shade_icons (void)
{
  shadeicon (status_handle, STATUS_PAUSE);
  shadeicon (status_handle, STATUS_KILL);
}




void status_updatefinished (void)
{
  if (status_handle)
  {
    status_update_status_T (SEND);
    status_shade_icons ();
  }
  return;
}




void status_updatestarted (void)
{
  /* reset flag so status opens in place of control */
  status_pos.reopen = 0;
  tw_paused = 0;
  tw_killed = 0;
  status_open ();
  status_update_filenum ();
  status_update_status_T (SSTART);
  status_setpause();
  return;
}




void status_update (char *leaf, int action, process_settings *pset)
{
  char str[128];
  int token;
  os_error * msg;
  char *p;


  if (status_handle)
  {
    /* update filename */
    if (leaf) writeiconc ( status_handle, STATUS_FILENAME, leaf );
    sprintf (str, "%d", next_file);
    writeiconc ( status_handle, STATUS_CURRENT_FILE, str );

    /* Check that ptr is not NULL, since a NULL ptr can be used to flag no output needed */
    if (pset != NULL)
    {
      /* update status message */

      /* Set the buffer for the status message to a zero length string */
      *str = 0x00;
      p = str;
      p += sprintf(p, "Process: ");

      if (pset->transform != 0)
      {
        switch (action)
        {
            case ROTATE_270:
              token = SLEFT;
              break;

            case ROTATE_90:
              token = SRIGHT;
              break;

            case ROTATE_180:
              token = S180;
              break;

            case FLIP_HOR:
              token = SHOR;
              break;

            case FLIP_VER:
              token = SVERT;
              break;

            case TRANSPOSE:
              token = STRANSP;
              break;

            case TRANSVERSE:
              token = STRANSV;
              break;

            case CROP:
              token = SCROP;
              break;

            case SKIP_FILE:
              token = SSKIP;
              break;

            case COPY_FILE:
              token = SCOPY;
              break;

            case NO_ROTATE:
              token = SNOROT;
              break;

            case NO_EXIF:
              token = SNOXIF;
              break;

            case SMARTSCALE_D:
              token = SSCALE2;
              break;

            case SMARTSCALE_H:
              token = SSCALEH;
              break;

            case SMARTSCALE_Q:
              token = SSCALEQ;
              break;

            case SMARTSCALE_E:
              token = SSCALEE;
              break;

            default:
              token = UNKNOWN;

          }
        msg = geterror (token);
        p += sprintf (p, "%s ", msg->errmess);
      }

      if (pset->optimise != 0)
      {
        p += sprintf (p, "Optimise ");
      }
      if (pset->progressive != 0)
      {
        p += sprintf (p, "Progressive");
      }
      if (pset->greyscale != 0)
      {
        p += sprintf (p, "Greyscale");
      }
    }
    writeiconc ( status_handle, STATUS_STATUS, str );
  }
  return;
}




static os_error *status_click (int handle, int userhandle, wimp_mousestr * m)
{
  os_error   *err;
  os_error   *warn;
  int         answer;

  err = NULL;

  switch (m->i)
  {
    case STATUS_PAUSE:
      tw_paused ^= 1;
      if (tw_paused)
      {
        taskwindow_suspend();
        status_update_status_T (SPAUSE);
      }
      else
      {
        taskwindow_resume();
        status_update_status_T (SCONT);
      }
      status_setpause();
      break;

    case STATUS_KILL:
      tw_killed = 1;
      taskwindow_kill();
      status_update_status_T (SKILL);
      if ( next_file <= num_files)
      {
        warn = geterror (QKILLALL);
        err = confirm (CONYN, &answer, warn->errmess);
        if (answer)
        {
          num_files = 0;
          status_update_status_T (SABORT);
        }
        else
        {
          tw_killed = 0;
        }
      }
      control_processfile ();
      break;


  }

  return (err);

  USE (userhandle);
  USE (handle);
}









os_error  *status_close (int w, int userhandle)
{
  os_error   *err;
  mousestr    mouse;

  err = NULL;

  if (status_handle)
  {
    wos_savewinposition (status_handle, &status_pos);
    remcloseevent (status_close, status_handle, 0);
    remclickevent (status_click, status_handle, 0);
    remhelpevent (NULL, status_handle, TSTATUS);
    remdataload (status_handle, 0, control_loadfiles);
    remdataloadtype (status_handle, 0, control_loadfiletype);

    err = closedown (&status_handle);

    if (!tw_processing)
    {
      /* If processing has completed, then if adjust used to close window, open
       * control window */
      err = getpointer (&mouse);
      if (mouse.buttons == 1)
        control_open ();
    }
  }

  return (err);

  USE (userhandle);
  USE (w);
}








os_error *status_open (void)
{
  os_error   *err;
  wimp_wstate ws;
  int x0, y1;
  int h, w;


  if (status_handle)
  {
    err = forward (status_handle, 0, NULL);
  }
  else
  {
    err = createwindow (TSTATUS, &status_handle);
    if (!err)
    {
      addcloseevent (status_close, status_handle, 0);
      addclickevent (status_click, status_handle, 0);
      addhelpevent (NULL, status_handle, TSTATUS);
      adddataload (status_handle, 0, control_loadfiles);
      adddataloadtype (status_handle, 0, control_loadfiletype);
      if (tw_processing)
      {
        /* ensure buttons are unshaded */
        unshadeicon (status_handle, STATUS_PAUSE);
        unshadeicon (status_handle, STATUS_KILL);
      }
      if (status_pos.reopen)
      {
	open (status_handle, status_pos.x0, status_pos.y0,
	      status_pos.x1, status_pos.y1, 0, 0, -1);
      }
      else
      {

        if (control_handle)
        {
          /* open status window in same place as control window */
          err = wimp_get_wind_state (control_handle, &ws);
          x0 = ws.o.box.x0;
          y1 = ws.o.box.y1;
          err = wimp_get_wind_state (status_handle, &ws);
          w = ws.o.box.x1 - ws.o.box.x0;
          h = ws.o.box.y1 - ws.o.box.y0;
          ws.o.box.x0 = x0;
          ws.o.box.y1 = y1;
          ws.o.box.x1 = ws.o.box.x0 + w;
          ws.o.box.y0 = ws.o.box.y1 - h;
          err = wimp_open_wind(&ws.o);
        }
        else

        {
          popup (status_handle, 0);
        }
	status_pos.reopen = 1;
      }
    }
  }
  return (err);
}








