/* > c.command <  */
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <stdarg.h>
#include <setjmp.h>

#include "kernel.h"
#include "aim_stdlib.h"
#include "swis.h"
#include "flex.h"
#include "os.h"
#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "event.h"
#include "baricon.h"
#include "sprite.h"
#include "werr.h"
#include "visdelay.h"
#include "magnify.h"
#include "res.h"
#include "resspr.h"
#include "template.h"
#include "txt.h"
#include "txtedit.h"
#include "dbox.h"
#include "alarm.h"
#include "menu.h"
#include "saveas.h"
#include "loadas.h"
#include "heap.h"
#include "colourtran.h"
#include "pointer.h"
#include "image.h"
#include "$.aim_kern.h.mymem"
#include "c_heap.h"
#include "command.h"
/***************************** EVENT HANDLING ******************************/

static void aim_handler(wimp_eventstr *e, void *handle)
{
  handle=handle;
     
  switch (e->e)
  {
    case wimp_ENULL:
      break;

    case wimp_EREDRAW:
      redo_wprintf(e->data.o.w);
      break;

    case wimp_EOPEN:
      wimp_open_wind(&e->data.o);
      break;

    case wimp_ECLOSE:
     /* --- window has been closed --- */
      wimpt_noerr(wimp_close_wind(e->data.o.w));
      break;

    case wimp_EBUT:
       {
  if(((e->data.but.m.bbits & wimp_BLEFT)||(e->data.but.m.bbits & wimp_BRIGHT))
      && e->data.but.m.i < 0)
      { 
         block.w=cmd_window;
         wimpt_complain(wimp_set_caret_pos(&block));      
       } 
        }
      break;

      case wimp_EMENU:
      break;

      case wimp_EPTRLEAVE:
        {
/*
         block.w=-1;
         block.i=-1;
         wimpt_complain(wimp_set_caret_pos(&block));
*/
        }
      break;

      case wimp_EPTRENTER:
        {
/*
         block.w=cmd_window;
         wimpt_complain(wimp_set_caret_pos(&block));
*/
        }
      break;

      case wimp_ESEND:
      case wimp_ESENDWANTACK:
        WimpMessage(&e->data.msg);
      break;
  
      case wimp_EUSERDRAG:
        WimpUserDragBox(&e->data.dragbox);
      break;
    
      default:
      break;
  }
}


static void WimpUserDragBox(wimp_box *drg_block)
{
   wimp_mousestr pblock;
   wimp_msgstr mblock;
   char subfilename[256];
   char stdname[80];
   int filetype;
   int estsize;
   drg_block=drg_block;                                                         

   if (strcmp(stdname,"file_004") == 0) 
      {
       filetype = AIMMACRO;
      }
   if (strcmp(stdname,"file_011") == 0) 
      {
       filetype = AIMIMAGE;
      }
   if (strcmp(stdname,"file_006") == 0) 
      {
       filetype = HAWK;
      }
  if (strcmp(stdname,"file_ff9") == 0) 
      {
       filetype = SPRITE;
      }
   if (strrchr(subfilename,0x2e) != NULL) 
      {
       strcpy(subfilename,(char *)(strrchr(subfilename,0x2e)+1));
      }
   if ((strcmp(subfilename,"") == 0) || (strcmp(subfilename,".") == 0))
      strcpy(subfilename,stdname);
   wimpt_complain(wimp_get_point_info(&pblock));
   mblock.hdr.size = 64;
   mblock.hdr.action = wimp_MDATASAVE;
   mblock.data.datasave.w = pblock.w;
   mblock.data.datasave.i = pblock.i;
   mblock.data.datasave.x           = pblock.x;
   mblock.data.datasave.y           = pblock.y;
   mblock.data.datasave.estsize     = estsize;
   mblock.data.datasave.type        = filetype;
   strncpy(mblock.data.datasave.leaf,subfilename,11);
   wimpt_complain(wimp_sendmessage(17,&mblock,0));
   save_ref = mblock.hdr.my_ref;
}

void update_wp_pal(WINDOW *w)
{
int i;
if (w->display_mode < 4)
 {
  for (i=0; i<16; i++)
   {
    w->pal.c[i].word=invert_pal.c[i].word;
   }
 }
else
 {
  for (i=0; i<16; i++)
   {
    w->pal.c[i].word=aim_pal.c[i].word;
   }
 }
}

#define wimp_wopen 0x00010000
void WimpMessage(wimp_msgstr *blck)
{
 int change,in,i, new_mode;
 BOOL paint,is_open;
 char cmd[80],*pntr;
 void insertstring(char *s);
 wimp_wstate state;
 wimp_redrawstr r;
 wimp_winfo      winfo;

 cmd[0]='\0';
 if (blck->hdr.your_ref != taskid) 
  {  

   switch(blck->hdr.action) 
    {
     case wimp_MPREQUIT:
       wimp_exit();
       break;
     case wimp_MMODECHANGE :    
       new_mode=wimpt_mode();
/*       change=wimpt_checkmode(); */
       if (new_mode != wimp_mode) change=TRUE;
       if (change==TRUE)
         {
         for (i=0;i<max_image;i++) 
           {
            winfo.w=wp[i]->image;
            wimpt_complain(wimp_get_wind_info(&winfo));
            r.w = wp[i]->image; 
            r.box.x0=winfo.info.ex.x0;
            r.box.x1=wimpt_dx()*WindowWidth(wp[i]);
            r.box.y0=-wimpt_dx()*WindowHeight(wp[i]);
            r.box.y1=winfo.info.ex.y1; 
            wimpt_complain(wimp_set_extent(&r));
           }
         }
       if (OSbpp !=wimpt_bpp())
        {
        grey_level=8;
        if (wimpt_bpp() == 8) grey_level=16;
        select_grey_level();
        for (i=0;i<max_image;i++)update_wp_pal(wp[i]);
        if (win_activeno() > 1)
         {     
         for (i=0;i<max_image;i++) 
           {
            wimpt_complain(wimp_get_wind_state(wp[i]->image,&state));
            is_open=state.flags & wimp_wopen;
            is_open = is_open == wimp_wopen;

            if (wp[i]->filled==1 && is_open) display(wp[i]);
            else if (is_open) 
                  display_image_window(wp[i]->image,&wp[i]->image_sprite);
           }
         }
         OSbpp=wimpt_bpp();
        }
       if (change == TRUE)
        {
         OSx=wimpt_dx();
         OSy=wimpt_dy();
         wimp_mode=wimpt_mode();
         paint=FALSE;
         wimpt_complain(wimp_get_wind_state(cmd_window,&state));
         is_open=state.flags & wimp_wopen;
         cmdwind_is_open=is_open=is_open == wimp_wopen;
         if (is_open) paint=TRUE;

 /* release handlers from old cmd_window */
         win_register_event_handler(cmd_window,(win_event_handler)0,0);
         win_claim_unknown_events(-1); 
         event_attachmenu(cmd_window,0,image_menu_proc,0);
 /* create new cmd_window */
         reinit_wprintf(wimp_mode,FALSE,paint);
 /* register and attach handlers to new cmd_window */
         win_register_event_handler(cmd_window,aim_handler,(void *)imgmenu);
         win_claim_unknown_events(cmd_window); 
         event_attachmenu(cmd_window,imgmenu,image_menu_proc,0);
        }

       break;
       case wimp_PALETTECHANGE:
        change=wimpt_checkmode();
        grey_level=8;
        if (wimpt_bpp() == 8) grey_level=16;
        select_grey_level(); 
        for (i=0;i<max_image;i++)update_wp_pal(wp[i]);
        if (win_activeno() < 2) break;
        for (i=0;i<max_image;i++)
         {
          if (wp[i]->filled==1) display(wp[i]);        
          else display_image_window(wp[i]->image,&wp[i]->image_sprite);
         }
       break;

       case wimp_MDATASAVE :
       if (blck->data.datasave.type == AIMMACRO 
           || blck->data.datasave.type == SPRITE)
        {
         blck->data.datasave.estsize = -1;
         strcpy(blck->data.datasave.leaf,"<aim$Scrap>");
         blck->hdr.size = 64;
         blck->hdr.your_ref = blck->hdr.my_ref;
         blck->hdr.action = wimp_MDATASAVEOK;
         wimpt_complain(wimp_sendmessage(17,blck,0));
         scrap_ref = blck->hdr.my_ref;
        }
       break;
     case wimp_MDATASAVEOK :
       if (blck->hdr.your_ref != save_ref) { }
       else
        {
         if (blck->data.datasaveok.type == AIMMACRO) 
          {
/*           savemac(blck->data.datasaveok.name,0); */
          }
         if (blck->data.datasaveok.type == SPRITE) 
          {
          }
        }
       blck->hdr.your_ref = blck->hdr.my_ref;
       blck->hdr.action = wimp_MDATALOAD;
       wimpt_complain(wimp_sendmessage(17,blck,0));
       save_ref = -1;
     break;
   case wimp_MDATAOPEN :
     if (blck->data.dataopen.type == AIMSETUP|| 
         blck->data.dataopen.type == AIMIMAGE|| 
         blck->data.dataopen.type == 0xFFF|| 
         blck->data.dataopen.type == SPRITE||
         blck->data.dataopen.type == GREYSPRITE||
         blck->data.dataopen.type == TCLIMAGE||
         blck->data.dataopen.type == HAWK) 
      {
       if (cmdwind_is_open ==FALSE)
          {
           wimpt_noerr(wimp_get_wind_state(cmd_window, &state));
           wimp_open_wind(&state.o);
           cmdwind_is_open=TRUE;
          }
       if (blck->data.dataopen.type == 0xFFF)
        {
        strcpy(cmd,"@"); 
        pntr=strrchr(blck->data.dataopen.name,'.');
        pntr++;
        strcat(cmd,blck->data.dataopen.name);
        }
       if (blck->data.dataopen.type == AIMSETUP)
        {       
        load_setup(blck->data.dataopen.name,TRUE);
        strcpy(setfile,blck->data.dataopen.name);
        }
       if (blck->data.dataopen.type == AIMIMAGE||
           blck->data.dataopen.type == SPRITE||
           blck->data.dataopen.type == GREYSPRITE||
           blck->data.dataopen.type == TCLIMAGE||
           blck->data.dataopen.type == HAWK)
        {
         in = -1;
         for (i=max_image-1;i>=0;i--)
          {
           if (blck->data.dataopen.w==wp[i]->image) in=i; 
          }
         load_image(blck->data.dataopen.name,in);
        }
       blck->hdr.action = wimp_MDATALOADOK;
       blck->hdr.your_ref = blck->hdr.my_ref;
       wimpt_complain(wimp_sendmessage(17,blck,0));
       if (win_activeno()-1 <=0) aim_new();
       block.w=cmd_window;
       wimpt_complain(wimp_set_caret_pos(&block));
       if (cmd[0] != '\0')insertstring(cmd); 
      }
     break;
   case wimp_MDATALOAD :
     if (blck->data.dataopen.type == AIMSETUP|| 
         blck->data.dataopen.type == AIMIMAGE|| 
         blck->data.dataopen.type == 0xFFF||
         blck->data.dataopen.type == SPRITE||
         blck->data.dataopen.type == GREYSPRITE||
         blck->data.dataopen.type == TCLIMAGE|| 
         blck->data.dataopen.type == HAWK) 
      {
       if (cmdwind_is_open ==FALSE)
          {
           wimpt_noerr(wimp_get_wind_state(cmd_window, &state));
           wimp_open_wind(&state.o);
           cmdwind_is_open=TRUE;
          }
       if (blck->data.dataopen.type == 0xFFF)
        {
        strcpy(cmd,"@"); 
        pntr=strrchr(blck->data.dataopen.name,'.');
        pntr++;
        strcat(cmd,blck->data.dataopen.name);
        }
       if (blck->data.dataopen.type == AIMSETUP)
        {          
         load_setup(blck->data.dataopen.name,TRUE);
         strcpy(setfile,blck->data.dataopen.name);
        }
       if (blck->data.dataopen.type == AIMIMAGE||
           blck->data.dataopen.type == SPRITE||
           blck->data.dataopen.type == GREYSPRITE||
           blck->data.dataopen.type == TCLIMAGE||
           blck->data.dataopen.type == HAWK)
        {
         in = -1;
         for (i=max_image-1;i>=0;i--)
          {
           if (blck->data.dataopen.w==wp[i]->image) in=i; 
          }         
         load_image(blck->data.dataopen.name,in);
        }
       if (blck->hdr.your_ref == scrap_ref)
       remove(blck->data.dataload.name);
       blck->hdr.action = wimp_MDATALOADOK;
       blck->hdr.your_ref = blck->hdr.my_ref;
       wimpt_complain(wimp_sendmessage(17,blck,0));
       if (win_activeno()-1 <=0) aim_new();
       block.w=cmd_window;
       wimpt_complain(wimp_set_caret_pos(&block));
       if (cmd[0] != '\0')insertstring(cmd); 
       scrap_ref = -1;
      }
     break;
   default:
   break;
  }
 }
}



static void aim_leftclickproc(wimp_i i)
{
wimp_wstate state;
int j;
i=i;
if (win_activeno()-1 <=0) aim_new();
else 
 {
  wimpt_noerr(wimp_get_wind_state(cmd_window, &state));
  wimp_open_wind(&state.o);
  for (j=0;j<max_image;j++)
   {
     if (wp[j]->filled==1) display(wp[j]);
     else
       {
         display_image_window(wp[j]->image,&wp[j]->image_sprite);
         if (WindowHistElem(wp[j]) != 0 )display_histogram(wp[j]);
       }
   }
 }
cmdwind_is_open=TRUE;
}

/**************************** aim STUFF ***********************************/
BOOL get_setup(char * name, void * fl)
 { BOOL * f;
   f=(BOOL *) fl;
  load_setup(name,*f);
 return(TRUE);
 }


 WINDOW * wind_create(int Width,int Height)
{
 int i;
 unsigned long Size_image;
 WINDOW *wp;

  /* --- allocate our WINDOW area --- */
 wp = (WINDOW *)malloc(sizeof(WINDOW));
 if (wp == NULL) werr(1,"Error in wind_create: WINDOW workspace failed\r"); 
 WindowType(wp)=NULL;
 WindowWidth(wp)= Width; 
 WindowHeight(wp)=Height;
 Size_image=WindowSize(wp)=(unsigned long)WindowWidth(wp)*WindowHeight(wp);
 WindowNgrey(wp)=NGREY;
 WindowType(wp)=1;
 WindowDispM(wp)=1;
 WindowData(wp)= (PIXEL*) heap_alloc((unsigned int)Size_image*sizeof(PIXEL));
 if (WindowData(wp)==NULL) werr(1,"Failed to allocate memory for Images");
 for (i=0; i<16; i++)
  {
   wp->pal.c[i].bytes.gcol=invert_pal.c[i].bytes.gcol;
   wp->pal.c[i].bytes.red=invert_pal.c[i].bytes.red;
   wp->pal.c[i].bytes.green=invert_pal.c[i].bytes.green;
   wp->pal.c[i].bytes.blue=invert_pal.c[i].bytes.blue;
  }
 return(wp);
 }

void select_trans(wimp_palettestr *p)
{
  os_regset r;

  r.r[0]=SpriteMode;
  r.r[1]=(int)p;
  r.r[2]=-1;
  r.r[3]=-1;
  r.r[4]=(int)trans;
  wimpt_complain(os_swix(ColourTrans_SelectTable,&r));
}


void select_grey_level(void)
{
  int i;

  wimpt_complain(wimp_readpalette(&default_pal));
  for (i=0; i<8; i++)
   {
   aim_pal.c[i].word=default_pal.c[7-i].word;
   }
  for (i=8; i<16; i++)
   {
   aim_pal.c[i].word=default_pal.c[i].word;   
   }

  if (wimpt_bpp()==8) /* 15 grey levels */
   {
    r_dit=16;r_shift=4;
    k_dit=2;k_shift=1;k_limit=31;
    l_nibble=0x0f;
    h_nibble=0xf0;
   for (i=0; i<16; i++)
    {
     c[i].bytes.gcol=invert_pal.c[i].bytes.gcol=0x10;
     c[i].bytes.red=invert_pal.c[i].bytes.red=   min(0xff,0x0+i*0x11);
     c[i].bytes.green=invert_pal.c[i].bytes.green= min(0xff,0x0+i*0x11);
     c[i].bytes.blue=invert_pal.c[i].bytes.blue=  min(0xff,0x0+i*0x11);
    }
    c[15].bytes.blue=invert_pal.c[15].bytes.blue=0;
    c[15].bytes.green=invert_pal.c[15].bytes.green=0;
   }
  else
   {
    r_dit=32;r_shift=5;
    k_dit=2;k_shift=1;k_limit=15;
    l_nibble=0x07;
    h_nibble=0x70;
   for (i=0; i<8; i++)
    {
  c[i].word=invert_pal.c[i].word=default_pal.c[7-i].word;
    }
   for (i=8; i<16; i++)
    {
     c[i].word=invert_pal.c[i].word=default_pal.c[i].word;
    }
   }
select_trans(&invert_pal);
}


BOOL aim_new(void)
{
#define AIM_VERSION "Version 2.20 "__DATE__

 wimp_wstate state;
 int i;
 change=wimpt_checkmode();
 wimp_mode=wimpt_mode();
 OSx=wimpt_dx();
 OSy=wimpt_dy();
 OSbpp=wimpt_bpp();
 if (change) 
  {
/* release handlers from old cmd_window */
    win_register_event_handler(cmd_window,(win_event_handler)0,0);
    win_claim_unknown_events(-1); 
    event_attachmenu(cmd_window,0,image_menu_proc,0);
/* create new cmd_window */
    reinit_wprintf(wimp_mode,FALSE,TRUE);
/* register and attach handlers to new cmd_window */
    win_register_event_handler(cmd_window,aim_handler,(void *)imgmenu);
    win_claim_unknown_events(cmd_window); 
    event_attachmenu(cmd_window,imgmenu,image_menu_proc,0);
  }

 wimpt_noerr(wimp_get_wind_state(cmd_window, &state));
 cmd_st.o.w=cmd_window;
 cmd_st.o.behind = -1;
 cmd_st.flags=state.flags;
 wimp_open_wind(&cmd_st.o);
 win_activeinc(); 

 for (i=max_image-1;i>=0;i--)
   {
    wimpt_noerr(wimp_get_wind_state(wp[i]->image, &state));
    image_st[i].o.w=wp[i]->image;
    image_st[i].o.behind=-1;    
    image_st[i].flags=state.flags;
    wimp_open_wind(&image_st[i].o);
    win_activeinc();
   }

 grey_level=8;
 if (OSbpp == 8) grey_level=16;
 select_grey_level();
 wprintf("%s\n",AIM_VERSION);
 return TRUE;
}

/********************** MENU AND DIALOGUE BOX HANDLING ********************/

static void aim_infoaboutprog(void)
{
  dbox d;
  d = dbox_new("ProgInfo");
  dbox_show(d);
  dbox_fillin(d);
  dbox_dispose(&d);
}


static void aim_mainmenuproc(void *handle, char *hit)
{
  handle = handle;
  switch(hit[0])
  {
    case MInfo:
      aim_infoaboutprog();
      break;
   case MQuit:
      wimp_exit();
      break;
    case MHelp:
      about_aim();
      break;
    default:
      break;
  }
}




BOOL get_tcl_image(char *name,void *in)
{
  return(TRUE);
}



BOOL get_grey_sprite(char *name,void *in)
{
  return(TRUE);
}

BOOL get_image(char *name,void *in)
{ 
  int *i;
  i= (int *) in;
  load_image(name,*i); 
  return(TRUE);
}

BOOL load_image(char *name, int in)
{
  int fromdisc(WINDOW *wp, char *filename);
  if (in <0) in=0;
  if (in > max_image-1) { wprintf("Wrong image window\n"); return(FALSE); }
  if (fromdisc(wp[in], name)!=(int)NULL) return(FALSE); 
  strncpy(WindowFile(wp[in]),name,256);
  WindowInUse(wp[in])=TRUE;
  display(wp[in]);
  return(TRUE);
}

BOOL savemac(char * name,void * handle)
{ 
  os_error err;
  FILE *fp;

  handle=handle;
  strncpy(macfile,name,256);
  if((fp=fopen(name,"w"))==NULL)
   { 
    strcpy(err.errmess,"File onbereikbaar\n --");
    strcat(err.errmess,name);
    err.errnum=3;
    wimpt_complain(&err);
    return(FALSE);
   }
  fclose(fp);
  wimpt_complain(os_swi3(OS_File,0x12,(int)name,AIMMACRO));
  return(TRUE);
}

BOOL saveimg(char * name,void * handle)
{
  int i;
  sprite_header * hoofd;
  sprite_ptr * ptr;
  PIXEL * workspace;
  int todisc(WINDOW *wp, char *filename, int file_type);
  ptr=(sprite_ptr *) handle;

  hoofd=(sprite_header *) ptr;
  for (i=0;i<max_image;i++)
   {
    if (ptr==wp[i]->image_sprite.id.s.addr)
     {
      workspace=wp[i]->beeld;
      break;
     }
   }
  strncpy(WindowFile(wp[i]),name,256);
  todisc(wp[i],name,AIMIMAGE);
  return(TRUE);
}


BOOL save_tcl_img(char * name,void * handle)
{
  int i, *ptr;
  int todisc(WINDOW *wp, char *filename, int file_type);
  ptr=(int *) handle;
  i=*ptr;

  strncpy(WindowFile(wp[i]),name,256);
  todisc(wp[i],name,TCLIMAGE); 
  return(TRUE);
}

BOOL savesprite(char * name,void * handle)
{
  int i,j,*sprc;
  sprite_header * hoofd;
  sprite_ptr * ptr;
  PIXEL * workspace;

  ptr=(sprite_ptr *) handle;
  hoofd=(sprite_header *) ptr;
  for (i=0;i<max_image;i++)
   {
    if (ptr==wp[i]->image_sprite.id.s.addr)
     {
      workspace=wp[i]->beeld;
      break;
     }
   }
  sprc=(int *)&(hoofd->mode)+1;
  for (j=0;j<16;j++) sprc[2*j]=sprc[2*j+1]=wp[i]->pal.c[j].word;
  wimpt_complain(sprite_area_save(wp[i]->image_sprite.area,name));
  return(TRUE);
}

BOOL save_grey_sprite(char * name,void * handle)
{
  return(TRUE);
}

BOOL saveset(char * name,void * handle)
{
  BOOL goed;
  handle=handle;
  
  strncpy(setfile,name,256);
  goed=save_setup(name);
  if (goed) wimpt_complain(os_swi3(OS_File,0x12,(int)name,AIMSETUP));
  return(goed);
}

static menu aim_menumaker(void *handle)
{
     main_menu = menu_new("aim", ">Info,>About AIM,Quit");
  return main_menu;
}

void wimp_exit(void)
{
  char *ptrcmd;
  my_msgstr msg;
  os_regset r;
  int FSnumber;
  int i;

  r.r[0]=0;
  r.r[1]=0;
  wimpt_complain(os_swix(OS_Args,&r));
  FSnumber=r.r[0];      
  ptrcmd=getenv("Aim$dir");
  strncpy(msg.data.chars,ptrcmd,strlen(ptrcmd)-1);
  msg.data.chars[strlen(ptrcmd)-1]='\0';
  msg.data.filing_system=FSnumber;
  msg.data.zero_flag=0;
  msg.hdr.size=256;
  msg.hdr.your_ref=0;
  msg.hdr.action=wimp_FilerCloseDir;

  wimpt_complain(wimp_sendmessage(wimp_ESEND,(wimp_msgstr *)&msg,0));
  win_register_event_handler((wimp_w)cmd_window, 0, 0);
  wimpt_noerr(wimp_close_wind((wimp_w)cmd_window));
  wimpt_noerr(wimp_delete_wind((wimp_w)cmd_window));
  win_activedec(); 
  for (i=0;i<max_image;i++) win_activedec();  
  exit(0);
}


void image_menu_proc(void *handle,char * hit)
{
  char cmdstr[256],*ptrcmd;
  wimp_eventstr e;
  my_msgstr msg;
  os_regset r;
  int FSnumber;
  BOOL test, flag;
  int i;
  void insertstring(char *s);

  handle=handle;
  switch(hit[0])
   {
    case IMACDIR:
      r.r[0]=0;
      r.r[1]=0;
      wimpt_complain(os_swix(OS_Args,&r));
      FSnumber=r.r[0];      
      strncpy(msg.data.chars,macro_file,strlen(macro_file)-1);
      msg.data.chars[strlen(macro_file)-1]='\0';
      msg.data.filing_system=FSnumber;
      msg.data.zero_flag=0;
      msg.hdr.size=256;
      msg.hdr.your_ref=0;
      msg.hdr.action=wimp_FilerOpenDir;
      wimpt_complain(wimp_sendmessage(wimp_ESEND,(wimp_msgstr *)&msg,0));
      break;
    case IIMGDIR:
      r.r[0]=0;
      r.r[1]=0;
      wimpt_complain(os_swix(OS_Args,&r));
      FSnumber=r.r[0]; 
      strncpy(msg.data.chars,image_file,strlen(image_file)-1);
      msg.data.chars[strlen(image_file)-1]='\0';
      msg.hdr.size=256;
      msg.hdr.your_ref=FSnumber;
      msg.hdr.action=wimp_FilerOpenDir;
      wimpt_complain(wimp_sendmessage(wimp_ESEND,(wimp_msgstr *)&msg,0));
      break;
    case IHIDE:
      txt_hide(helpwnd);
      dbox_hide(d);
      wimpt_noerr(wimp_close_wind(cmd_window));
      for (i=0; i<max_image;i++)
       {
        wimpt_noerr(wimp_close_wind(wp[i]->image));
        wimpt_noerr(wimp_close_wind(WindowHistHandle(wp[i])));
       } 
      cmdwind_is_open=FALSE;
      break;
    case IMEM:
 
      break;
    case IQUIT:
      if (alloc_ptr >0) emergency_free();
      visdelay_end();
      pointer_reset_shape();
      wimp_exit();
      break;
    case ITRACE:
      trace_on=!trace_on;
      if (trace_on) menu_setflags(imgmenu,ITRACE,1,0);
      else menu_setflags(imgmenu,ITRACE,0,0);
      break;      
    case ICMPRS:
      compress=!compress;
      if (compress) menu_setflags(imgmenu,ICMPRS,1,0);
      else menu_setflags(imgmenu,ICMPRS,0,0);
      for (i=0;i<max_image;i++)display_image_window(wp[i]->image,&wp[i]->image_sprite);
      break;
    case ILOAD:
      i=strlen(setfile);
      if (i==0 || setfile[i-1] == 0x2e)
       {
        strncpy(setfile,setup_file,99);
        strcat(setfile,"default");
       }
      test=TRUE;
      if (hit[1]==L1SET)loadas(AIMSETUP,setfile,512,get_setup,0,0,(void *)&test);
      if (hit[1]==L1IMG)
       {
        i=strlen(imagefile);
        if (i==0 || imagefile[i-1] == 0x2e)
         {
           strncpy(imagefile,image_file,99);
           strcat(imagefile,"trui");
         }
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;       
        loadas(AIMIMAGE,imagefile,65535,get_image,0,0,(void *)&i);  
       }
      if (hit[1]==L1TCL)
       {
        i=strlen(imagefile);
        if (i==0 || imagefile[i-1] == 0x2e)
         {
           strncpy(imagefile,image_file,99);
           strcat(imagefile,"trui");
         }
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;       
        loadas(TCLIMAGE,imagefile,65535,get_tcl_image,0,0,(void *)&i);  
     }
      if (hit[1]==L1GREY)
       {
        i=strlen(imagefile);
        if (i==0 || imagefile[i-1] == 0x2e)
         {
           strncpy(imagefile,image_file,99);
           strcat(imagefile,"trui");
         }
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;       
        loadas(GREYSPRITE,imagefile,65535,get_grey_sprite,0,0,(void *)&i);  
     }
      break;
    case ISAVE:
      if (hit[1]==C1MAC) saveas(AIMMACRO,macfile,55,savemac,0,0,0);
      if (hit[1]==C1IMG)
       {
        strncpy(imagefile,image_file,99);
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;
        saveas(AIMIMAGE,imagefile,65535,saveimg,0,0,wp[i]->image_sprite.id.s.addr);
       }
      if (hit[1]==C1TCL)
       {
        strncpy(imagefile,image_file,99);
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;
        saveas(TCLIMAGE,imagefile,65535,save_tcl_img,0,0,(void *) &i);
       }

      if (hit[1]==C1GREY)
       {
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;
        saveas(GREYSPRITE,"sprite3",65535,save_grey_sprite,0,0,wp[i]->image_sprite.id.s.addr);
       }
      if (hit[1]==C1SPR)
       {
        if (hit[2]==IMGA) i=0;
        if (hit[2]==IMGB) i=1;
        if (hit[2]==IMGC) i=2;
        if (hit[2]==IMGD) i=3;
        saveas(SPRITE,"sprite3",65535,savesprite,0,0,wp[i]->image_sprite.id.s.addr);
       }

      if (hit[1]==C1SET) 
        {
         strncpy(setfile,setup_file,99);
         saveas(AIMSETUP,setfile,55,saveset,0,0,0);
        }
           
      break;
/*
      magnify_select(&magnmult,&magndiv,20,20,image_magnify,(void*)whandle); 
*/
    
    default:
    for (i=0;i<10;i++)
         { 
           if ( (int)hit[i] == 0 ) break;
         }

/* A work around to adopt second level leafnames as commands */    
    flag=FALSE;
    if (i < 3 && hit[0]==6 && hit[1]==1) flag=TRUE;
    if (i < 3 && hit[0]==3 && hit[1] >2) flag=TRUE;
    
    if (i < 3 && flag == FALSE) break; /* Not a leafname */

/* Process leafname as a command */
    for (i=0;i<10;i++) e.data.menu[i]=(int)hit[i]-1;
    for (i=0;i<256;i++)cmdstr[i]='\0';   
    ptrcmd=get_cmd(cmdstr, &e);
    block.w=cmd_window;
    wimpt_complain(wimp_set_caret_pos(&block));
    insertstring(ptrcmd); 
    break;
  }

}

void image_magnify(void *handle)
 {
   int *whnd;
   whnd=(int *)handle;
  
   if (magndiv > magnmult) magndiv=magnmult;
   wprintf("mul=%d div=%d\n",magnmult,magndiv);  
   image_redraw_window((wimp_w) (*whnd)); 
 }

static menu image_menumaker(void *handle)
{
  static menu ent1,ent11,ent12,ent13,ent14,ent15,ent16,ent17,ent18;
  static menu ent2,ent21,ent22,ent23;
  static menu ent3,ent31,ent33; 
  static menu ent4,ent41,ent42,ent43,ent44;
  static menu ent5,ent51,ent52,ent53;
  static menu ent6;
  handle=handle;
  /* --- only remake the menu stucture if it is not already there --- */

    if(event_is_menu_being_recreated() == FALSE)
    { 

    /* --- create a menu for this aim window --- */
/* ------------------------ level 3 and 2 ---------------------------------- */
      if (max_image < MAXIM) {
      ent1 = menu_new("Grey ops","Point Ops,Arit Ops,Sgn Arit Ops,Non-Arit Ops,Lin Filters,N-Lin Filt 1,~N-Lin Filt 2,Adapt Filt"); }
      else {
      ent1 = menu_new("Grey ops","Point Ops,Arit Ops,Sgn Arit Ops,Non-Arit Ops,Lin Filters,N-Lin Filt 1,N-Lin Filt 2,Adapt Filt");  }

      ent11=menu_new("Point Ops","equal[ization],table,thresh[olding],mcopy");
      ent12=menu_new("Arit Ops","copy|clear,ginv,cabs,cadd,cmul,cdiv,assign|abs,add,sub,mul,div|mud");
      ent13=menu_new("Sgn Arit Ops","sginv,scabs,scmul,scdiv|sabs,sadd,ssub,smul,sdiv|smud");
      ent14=menu_new("Non-Arit Ops","minimum,maximum,sminimum,smaximum,ssminimum|mindev");
      ent15=menu_new("Lin Filters","gauss,gradx,grady,enhance,nlaplace,dog,roberts,filter|uniform,lgauss,adneighbour,adrecursive,ggradient,lgradient,suneighbour,surecursive,parabola,separable");
      ent16=menu_new("N-Lin Filt 1","median,peak,hara,have|lmin,lmax|lower,upper");
      ent17=menu_new("N-Lin Filt 2","dythresh,tethresh,dygist,tegist,ragist,dyledge,teledge,raledge,dysharp,tesharp,rasharp,dyfront,tefront,rafront,dyrange,terange,rarange");
      ent18=menu_new("Adapt Filt","edgps,kuwahara");

      menu_submenu(ent1,1,ent11);
      menu_submenu(ent1,2,ent12);
      menu_submenu(ent1,3,ent13);
      menu_submenu(ent1,4,ent14);
      menu_submenu(ent1,5,ent15);
      menu_submenu(ent1,6,ent16);
      menu_submenu(ent1,7,ent17);
      menu_submenu(ent1,8,ent18);
/* ------------------------ level 3 and 2 ---------------------------------- */ 
      ent2=menu_new("Bin Ops","Morph Ops,Bit Ops,Meas Ops");
      ent21=menu_new("Morph Ops","erosion,dilation,propag[ation]|skelet,-skelet,contour,majority,remove[noise]|sinpix[els],endpix[els],linkpix[els],vertices");
      ent22=menu_new("Bit Ops","bcopy,and,or,exor,invert,set,reset");
      ent23=menu_new("Meas Ops","measure,label,distance");

      menu_submenu(ent2,1,ent21);
      menu_submenu(ent2,2,ent22);
      menu_submenu(ent2,3,ent23);
/* ------------------------ level 3 and 2 ---------------------------------- */
      ent3=menu_new("Utils","Display,Timer,histogram,printval,shad");
      ent31=menu_new("Display","don,doff,gdisplay,bdisplay");
      ent33=menu_new("Timer","ton,toff");

      menu_submenu(ent3,1,ent31);
      menu_submenu(ent3,2,ent33);                                        

/* ------------------------- level 4 and 3 --------------------------------- */
      ent4 = menu_new("Save as","AIM image,TCL image,Grey sprite,Display,>Setup");
      if (max_image==2) ent41 = menu_new("AIM image",",>A,>B,~C,~D");
      if (max_image==3) ent41 = menu_new("AIM image",",>A,>B,>C,~D");
      if (max_image==4) ent41 = menu_new("AIM image",",>A,>B,>C,>D");

      if (max_image==2) ent42 = menu_new("TCL image",",>A,>B,~C,~D");
      if (max_image==3) ent42 = menu_new("TCL image",",>A,>B,>C,~D");
      if (max_image==4) ent42 = menu_new("TCL image",",>A,>B,>C,>D");

      if (max_image==2) ent43 = menu_new("Grey sprite",",>A,>B,~C,~D");
      if (max_image==3) ent43 = menu_new("Grey sprite",",>A,>B,>C,~D");
      if (max_image==4) ent43 = menu_new("Grey sprite",",>A,>B,>C,>D");


      if (max_image==2) ent44 = menu_new("Display",",>A,>B,~C,~D");
      if (max_image==3) ent44 = menu_new("Display",",>A,>B,>C,~D");
      if (max_image==4) ent44 = menu_new("Display",",>A,>B,>C,>D");

      menu_submenu(ent4,1,ent41);
      menu_submenu(ent4,2,ent42);
      menu_submenu(ent4,3,ent43);
      menu_submenu(ent4,4,ent44);

/* ------------------------- level 5 and 3 --------------------------------- */
      ent5 = menu_new("Load","AIM image,TCL image,Grey sprite,>Setup");
      if (max_image==2) ent51 = menu_new("AIM image",",>A,>B,~C,~D");
      if (max_image==3) ent51 = menu_new("AIM image",",>A,>B,>C,~D");
      if (max_image==4) ent51 = menu_new("AIM image",",>A,>B,>C,>D");

      if (max_image==2) ent52 = menu_new("TCL image",",>A,>B,~C,~D");
      if (max_image==3) ent52 = menu_new("TCL image",",>A,>B,>C,~D");
      if (max_image==4) ent52 = menu_new("TCL image",",>A,>B,>C,>D");

      if (max_image==2) ent53 = menu_new("Grey sprite",",>A,>B,~C,~D");
      if (max_image==3) ent53 = menu_new("Grey sprite",",>A,>B,>C,~D");
      if (max_image==4) ent53 = menu_new("Grey sprite",",>A,>B,>C,>D");

      menu_submenu(ent5,1,ent51);  
      menu_submenu(ent5,2,ent52);  
      menu_submenu(ent5,3,ent53);  

/*-------------------------- level 6 and 3 -------------------------------- */
      ent6=menu_new("Digitise","grab,~scan");

/* ------------------------- level 2 and 1 -------------------------------- */
      imgmenu = menu_new("Aim","Grey Ops,Bin Ops,Utils|Load,Save,Digitise,Image Dir,Macro Dir,Trace On,Scaled,Hide,Quit");
      menu_submenu(imgmenu,1,ent1);
      menu_submenu(imgmenu,2,ent2);
      menu_submenu(imgmenu,3,ent3);
  
/* Changed 'save' and 'load' entry conform Atari layout. Ed 15-02-91 */
      menu_submenu(imgmenu,4,ent5);
      menu_submenu(imgmenu,5,ent4);
      menu_submenu(imgmenu,6,ent6);
    } 
    

  return imgmenu;
}

/***************************** INITIALISATION ******************************/
void config(void)
{
  int i;
  char * window_col, *window_row, *image, *width, *height;
  char *pntr;

  window_col=getenv("Aim$window_col");
  if (window_col==NULL) window_col="60";

  max_col=min(80,abs(atoi(window_col)));
  window_row=getenv("Aim$window_row");
  if (window_row==NULL) window_row="30";
  max_row=min(99,abs(atoi(window_row)));

  image=getenv("Aim$image");
  if (image==NULL) image="3";
  max_image=min(4,abs(atoi(image)));
  if (max_image < 2) max_image=2;

  width=getenv("Aim$default_image_width");
  if (image==NULL) width="256";
  Init_Image_Width=min(512,abs(atoi(image)));
                                             
  height=getenv("Aim$default_image_height");
  if (image==NULL) height="256";
  Init_Image_Height=min(512,abs(atoi(image)));

/* Default settings */
  cmd_st.o.box.x0=0;
  cmd_st.o.box.y0=200;
  cmd_st.o.box.x1=960;
  cmd_st.o.box.y1=1024;

  for (i=0; i<4; i++)
   {
    image_st[i].o.box.x0=100;
    image_st[i].o.box.y0=100;
    image_st[i].o.box.x1=612;
    image_st[i].o.box.y1=612;
   }

  pntr=getenv("Aim$Dir");
  strcpy(father_dir,pntr); 
  strcat(father_dir,".");
  strcpy(setupfile,pntr);
  strcat(setupfile,".resources.");
  pntr=getenv("Aim$setup_file");
  strcat(setupfile,pntr); 
}



void aim_initialise(void)
{
  wimp_i bar_icon;
  int spr_area,i;
  /* --- initialise RISCOS library modules --- */
    wimpt_init("aim");
    taskid=wimpt_task();
    flex_init();
    heap_init(TRUE);
    _kernel_register_slotextend(flex_dont_budge); 
    visdelay_init();
    res_init("aim");
    resspr_init();
    template_init();
    dbox_init();
    alarm_init();
    helpwnd=txt_new("Help for command's");
  /* --- put Aim icon on the icon bar --- */
    spr_area=(int)resspr_area();
    bar_icon=baricon("!aim", (int)resspr_area(), aim_leftclickproc); 
    change=wimpt_checkmode();
    OSx=wimpt_dx();
    OSy=wimpt_dy();
    OSbpp=wimpt_bpp();
    wimp_mode=wimpt_mode();
    wimp_save_fp_state_on_poll();
    config();
    wprintf_init();
    load_setup(setupfile,FALSE);
    image_menumaker((void *) &imgmenu); 
    histogram_menu_maker((void *)&hsit);
    win_register_event_handler(cmd_window,aim_handler,(void *)imgmenu);
/*    win_claim_idle_events(cmd_window); */
    win_claim_unknown_events(cmd_window); 
    event_attachmenu(cmd_window,imgmenu,image_menu_proc,0);
    grey_level=8;
    if (OSbpp == 8) grey_level=16;
    select_grey_level();
    imname[0]="Image A";
    imname[1]="Image B";
    imname[2]="Image C";
    imname[3]="Image D";
    for (i=0;i<MAXIM;i++)wp[i]=NULL;
    for (i=0; i<max_image;i++)
     {
      wp[i]=Create_ImagePool(Init_Image_Width,Init_Image_Height,imname[i]);
     }
    event_attachmenumaker(win_ICONBAR, aim_menumaker, aim_mainmenuproc, 0);
    magnmult=1;magndiv=1;
    if((d = dbox_new("newdiag")) == 0)
    werr(TRUE, "No space for dialogue boxes ");
    trace_on=FALSE;
    compress=FALSE;
    if (compress) menu_setflags(imgmenu,ICMPRS,1,0);
}

/******************************* MAIN PROGRAM ******************************/

int main()
{
  int i;
  
/* Initialize AIM heap manager */
  for (i=0;i<200;i++)alloc[i]=0;
  alloc_top=200;
  alloc_bottom=0;
  alloc_ptr=0;
/* Allocate Image pools, reset AIM and WIMP */
  aim_initialise();
/* Make Image pools read/write only */
  alloc_bottom=alloc_ptr;
/* Start the interperter */
  aim_kern(); 
}
