#include "Wimp.h"
#include "Desklib:Event.h"
#include "Desklib:Error.h"
#include "Desklib:Window.h"
#include "Desklib:Resource.h"
#include "Desklib:WimpSwis.h"
#include "Desklib:EventMsg.h"
#include "Desklib:icon.h"
#include "Desklib:KeyCodes.h"
#include "Desklib:screen.h"
#include "Desklib:Pointer.h"
#include "Desklib:Window.h"
#include "Desklib:Template.h"
#include "Desklib:Menu.h"
#include "Desklib:Handler.h"
#include "Desklib:SWI.h"
#include "Desklib:Mem.h"
#include "Desklib:File.h"
#include "Desklib:Sprite.h"
static sprite_area usersp;
static int next=1<<29;
static BOOL quit=FALSE;
static window_handle info_window, main_window, ctrl_window;
static menu_ptr main_menu;
sprite_area f=NULL;
static int width,height;
static int number;
static char namebuffer[256];
static int pend=0;
static mem_anchor anch;
static int mem_autocompact=mem_FULLCOMPACT;

static BOOL Close(event_pollblock *e,void *r){
  if(e->data.words[0]==main_window){
    quit=TRUE;
  }else{
    Wimp_CloseWindow(e->data.words[0]);
  }
}
static BOOL load(char *name);

static BOOL OpenCtrl(event_pollblock *e, void *r){
  drag_block g;
  switch(e->data.mouse.button.value){
    case 4 : Window_Show(ctrl_window,open_WHEREVER);break;
    case 1 : e->data.words[0]=main_window;Close(e,NULL);break;
    case 2 : g.window=main_window;g.type=drag_MOVEWINDOW;
      Wimp_DragBox(&g);break;
  }
  return 1;
}


static BOOL Update(event_pollblock *e,void *r){
   window_redrawblock g;
   int more;
     if(Icon_GetSelect(ctrl_window,0)){
       number=((number+1)%f->numsprites);
       SWI(0,1,SWI_OS_ReadMonotonicTime,&next);
     }
     SWI(5,0,SWI_OS_SpriteOp,269,f,namebuffer,256,number+1);
     if(Icon_GetSelect(ctrl_window,0)){
       if(strlen(namebuffer)<9 || namebuffer[8]<'0' || namebuffer[8]> '9') next+=8; else next+=atoi(namebuffer+8);
     }else{
       next=1<<29;
     }
     Icon_printf(ctrl_window,4,"%s\0",namebuffer);
     g.window=main_window;
     g.rect.min.x=0;
     g.rect.min.y=-height;
     g.rect.max.x=width;
     g.rect.max.y=0;
     Wimp_UpdateWindow(&g,&more);
     while(more!=0){
       Wimp_GetRectangle(&g,&more);
      }
  return 1;
}

void MakeWind(int x1,int x2, int flags,int behind){
  window_block b;
  icon_createblock i;
  int d;
  b.screenrect.min.x=x1;
  b.screenrect.min.y=x2;
  b.screenrect.max.x=width+x1;
  b.screenrect.max.y=height+x2;
  b.scroll.x=0;
  b.scroll.y=0;
  b.behind=behind;
  b.flags.value=flags;
  b.colours[0]=7;
  b.colours[1]=2;
  b.colours[2]=7;
  b.colours[3]=1;
  b.colours[4]=3;
  b.colours[5]=1;
  b.colours[6]=12;
  b.colours[7]=0;
  b.workarearect.min.x=0;
  b.workarearect.max.y=0;
  b.workarearect.min.y=-height;
  b.workarearect.max.x=width;
  b.titleflags.value=0x19;
  b.workflags.value=3<<19;
  b.spritearea=(void *) 1;
  b.minsize.x=0;
  b.minsize.y=0;
  strcpy(b.title.text,"Animation");
  b.numicons=0;
  Wimp_CreateWindow(&b,&main_window);
  i.window=main_window;
  i.icondata.workarearect.min.x=0;
  i.icondata.workarearect.min.y=-height;
  i.icondata.workarearect.max.x=width;
  i.icondata.workarearect.max.y=0;
  i.icondata.flags.value=0x311A;
  i.icondata.data.indirectsprite.name=namebuffer;
  i.icondata.data.indirectsprite.spritearea=f;
  i.icondata.data.indirectsprite.nameisname=256;
  Wimp_CreateIcon(&i,&d);
}

static BOOL load(char *name)
{
  int size,w,h,m,eg;
    size=File_Size(name)+4;
    if(size==4) return 0;
    Mem_Alloc(&anch,size);
    f = (sprite_area) anch;
    f->areasize=size;
    Sprite_Load(f,name);
    SWI(3,7,SWI_OS_SpriteOp,512+40,(int) f,((int)f)+f->firstoffset,
    NULL,NULL,NULL,&w,&h,NULL,&m);
    Icon_printf(ctrl_window,6,"%d",m);
    SWI(2,3,SWI_OS_ReadModeVariable,m,4,NULL,NULL,&eg);
    width=w<<eg;
    SWI(2,3,SWI_OS_ReadModeVariable,m,5,NULL,NULL,&eg);
    height=h<<eg;
    MakeWind(0,0,Icon_GetSelect(ctrl_window,8) ? 0x80000012 : 0xFF000012,-1);
    number=-1;
    Icon_SetSelect(ctrl_window,0,1);
    Icon_SetSelect(ctrl_window,1,0);
    Update(NULL,NULL);
    Window_Show(main_window,open_CENTERED);
  return 1;
}

static BOOL CtrlClick(event_pollblock *e, void *r){
  int x,y;
  window_state state;
  switch (e->data.mouse.icon){
    case 0 : Update(NULL,NULL);break;
    case 1 : Update(NULL,NULL);next=1<<29;break;
    case 2 :
      Icon_SetSelect(ctrl_window,0,0);
      Icon_SetSelect(ctrl_window,1,1);
      number=(number+1)%f->numsprites;
      Update(NULL,NULL);
      next=1<<29;break;
    case 3 :
      Icon_SetSelect(ctrl_window,0,0);
      Icon_SetSelect(ctrl_window,1,1);
      number=(number-1)%f->numsprites;
      Update(NULL,NULL);
      next=1<<29;break;
    case 8 :
      Wimp_GetWindowState(main_window,&state);
      Window_Delete(main_window);
      MakeWind(state.openblock.screenrect.min.x,
               state.openblock.screenrect.min.y,
               Icon_GetSelect(ctrl_window,8) ? 0x80000012 : 0xFF000012,
               state.openblock.behind);
      Wimp_GetWindowState(main_window,&state);
      Wimp_OpenWindow(&state.openblock);
  }
  return 1;
}

void main(int argc, char* argv[]){
  icon_handle baricon;
  event_pollblock event;
  event_pollmask mask;
  char appname[64] = "Animation (buffered)";
  Resource_Initialise("SESAnimate");
  usersp = Sprite_LoadFile("<SESAnimate$Dir>.Sprites");
  Event_Initialise(appname);
  EventMsg_Initialise();
  Template_LoadFile("Templates");
  Template_UseSpriteArea(usersp);
  ctrl_window=Window_Create("Control",30);
  Icon_SetSelect(ctrl_window,0,1);
  Event_Claim(event_CLICK,ctrl_window,event_ANY,CtrlClick,NULL);
  Event_Claim(event_CLICK,event_ANY,event_ANY,OpenCtrl,NULL);
  Event_Claim(event_OPEN,event_ANY,event_ANY,Handler_OpenWindow,NULL);
  Event_Claim(event_CLOSE,event_ANY,event_ANY,Close,NULL);
  Event_Claim(event_NULL,event_ANY,event_ANY,Update,NULL);
  Mem_Initialise();
  load(argv[1]);
  while(!quit){
    mask.value=0;
    Wimp_PollIdle(mask,&event,next);
    Event_Process(&event);
  }
}
