#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "kernel.h"
#include "swis.h"
#include "toolbox.h"
#include "colourdbox.h"
#include "fontdbox.h"
#include "saveas.h"
#include "scale.h"
#include "event.h"
#include "window.h"
#include "wimp.h"
#include "wimplib.h"
#include "flex.h"
#include "drawfile.h"

#include "main.h"
#include "msgtrans.h"
#include "defines.h"
#include "settings.h"
#include "watermark.h"
#include "ui.h"

int *watermark_file=NULL;
int watermark_length=0;
ObjectId watermark_window=0;

static int watermark_redraw(int event_code,WimpPollBlock *poll,IdBlock *id,void *handle)
{
  int more;
  WimpRedrawWindowBlock block;
  Transform transform;
  int x,y;
  BBox extent;
  settings *s=(settings *)handle;

  transform[0][0]=s->wm_scale_x;
  transform[0][1]=0;
  transform[1][0]=0;
  transform[1][1]=s->wm_scale_y;

  block.window_handle=poll->redraw_window_request.window_handle;
  wimp_redraw_window(&block,&more);

  while (more) {
    if (watermark_file) {
      x=block.visible_area.xmin-block.xscroll;
      y=block.visible_area.ymax-block.yscroll;
      transform[2][0]=256*x;//-extent.xmin;
      transform[2][1]=256*y;//-extent.ymin;

      drawfile_render(0,watermark_file,watermark_length,(Transform *)&transform,&block.redraw_area,0);
    }
    _swix(Wimp_GetRectangle,_IN(1)|_OUT(0),&block,&more);
//    wimp_get_rectangle(&block,&more);
  }

  return 1;
}

void watermark_init(settings *s)
{
  error(toolbox_create_object(0,"WMpreview",&watermark_window),TRUE);

  event_register_wimp_handler(watermark_window,Wimp_ERedrawWindow,watermark_redraw,s);
}

void pager_callback(ComponentId button, ObjectId child)
{
  WindowShowObjectBlock show;
  WimpGetWindowStateBlock state;
  BBox extent;

  if (button!=Page_Watermark) return;

  // add watermark window to this one

  gadget_get_bbox(0,child,WM_Preview,&extent);

  window_get_wimp_handle(0,child,&state.window_handle);
  wimp_get_window_state(&state);

  show.visible_area.xmin=extent.xmin + state.visible_area.xmin - state.xscroll;
  show.visible_area.xmax=show.visible_area.xmin+ (extent.xmax-extent.xmin);
  show.visible_area.ymax=state.visible_area.ymax - state.yscroll + extent.ymax;
  show.visible_area.ymin=show.visible_area.ymax- (extent.ymax-extent.ymin);
  show.xscroll=0;
  show.yscroll=0;
  show.behind=-1;
  show.window_flags=0;
  show.parent_window_handle=state.window_handle;
  show.alignment_flags=0;

  toolbox_show_object(Toolbox_ShowObject_AsSubWindow,watermark_window,Toolbox_ShowObject_FullSpec,&show,child,0);
}

static void watermark_force_redraw(void)
{
  BBox redraw;
  window_get_extent(0,watermark_window,&redraw);
  window_force_redraw(0,watermark_window,&redraw);
}

void watermark_set_extents(ObjectId parent, settings *s)
{
  BBox extent,minsize;
  int w,h;
  Transform transform;

  transform[0][0]=s->wm_scale_x;
  transform[0][1]=0;
  transform[1][0]=0;
  transform[1][1]=s->wm_scale_y;
  transform[2][0]=0;
  transform[2][1]=0;

  gadget_get_bbox(0,parent,WM_Preview,&minsize);
  w=minsize.xmax-minsize.xmin;
  h=minsize.ymax-minsize.ymin;

  drawfile_bbox(0,watermark_file,watermark_length,&transform,&extent);
  minsize.xmin=extent.xmin/256;
  minsize.xmax=extent.xmax/256;
  minsize.ymin=extent.ymin/256;
  minsize.ymax=extent.ymax/256;
  if ((minsize.xmax-minsize.xmin)<w) minsize.xmax=minsize.xmin+w;
  if ((minsize.ymax-minsize.ymin)<h) minsize.ymax=minsize.ymin+h;
  window_set_extent(0,watermark_window,&minsize);
}

void watermark_load_file(char *filename,settings *s,ObjectId parent,BOOL force_enabled)
{   
  int len,type;
  _kernel_oserror *e;
  WimpGetWindowStateBlock winstate;
  
  e=_swix(OS_File,_INR(0,1)|_OUT(0)|_OUT(4),5,filename,&type,&len);
  if (e) {
    error(e,FALSE);
    return;
  }
  if (type!=1) return;

  if (watermark_file) {
    flex_free((flex_ptr)&watermark_file);
    watermark_file=NULL;
    watermark_length=0;
  }

  if (!flex_alloc((flex_ptr)&watermark_file,len)) {
    msgtrans_error("NoMem");
    watermark_force_redraw();
    return;
  }

  if (filename!=s->watermark_filename) {
    if (s->watermark_filename) {
      flex_free((flex_ptr)&s->watermark_filename);
      s->watermark_filename=NULL;
    }
    
    if (!flex_alloc((flex_ptr)&s->watermark_filename,1+strlen(filename))) {
      msgtrans_error("NoMem");
      flex_free((flex_ptr)&watermark_file);
      watermark_file=NULL;
      watermark_length=0;
      return;
    }
    
    strcpy(s->watermark_filename,filename);
  }

  e=_swix(OS_File,_INR(0,3),255,filename,watermark_file,0);
  if (e) {
    error(e,FALSE);
    flex_free((flex_ptr)&watermark_file);
    watermark_file=NULL;
    watermark_length=0;
    flex_free((flex_ptr)&s->watermark_filename);
    s->watermark_filename=NULL;
  } else {
    // set window extent to drawfile bounds
    watermark_length=len;
    watermark_set_extents(parent,s);
  }

  // reopen window
  window_get_wimp_handle(0,watermark_window,&winstate.window_handle);
  wimp_get_window_state(&winstate);

  if (winstate.flags & WimpWindow_Open) {
    winstate.xscroll=0;
    winstate.yscroll=0;
    wimp_open_window((WimpOpenWindowBlock *)&winstate);

    // redraw window
    watermark_force_redraw();
  }

  if (force_enabled) {
    optionbutton_set_state(0,parent,WM_Enable,1);
    s->watermark_enabled=TRUE;
  }
  window_set_fades(Page_Watermark,parent,s);
}

int wmscale_show(int event_code,ToolboxEvent *event,IdBlock *id,void *handle)
{
  settings *s=(settings *)handle;

  scale_set_value(0,id->self_id,s->wm_display_scale);

  return 1;
}

int wmscale_set(int event_code,ToolboxEvent *event,IdBlock *id,void *handle)
{
  settings *s=(settings *)handle;
  ScaleApplyFactorEvent *e=(ScaleApplyFactorEvent *)event;
  char scale_text[8];
  WimpGetWindowStateBlock winstate;

  s->wm_scale_x=s->wm_scale_y=(e->factor*65536)/100;
  s->wm_display_scale=e->factor;

  sprintf(scale_text,"%d %%",e->factor);
  displayfield_set_value(0,id->parent_id,WM_ScalePerc,scale_text);

  watermark_set_extents(id->parent_id,s);

  // reopen window with updated scroll positions as may now be invalid
  window_get_wimp_handle(0,watermark_window,&winstate.window_handle);
  wimp_get_window_state(&winstate);

  winstate.xscroll=0;
  winstate.yscroll=0;
  wimp_open_window((WimpOpenWindowBlock *)&winstate);

  // redraw window
  watermark_force_redraw();

  return 1;
}
