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

#include "kernel.h"
#include "swis.h"
#include "flex.h"
#include "os.h"
#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "event.h"
#include "filetype.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 "c_heap.h"*/
#include "command.h"

extern menu hsit;

/***************************** 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=wprintf_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=wprintf_window;
         wimpt_complain(wimp_set_caret_pos(&block));
*/
        }
      break;

      case wimp_ESEND:
      case wimp_ESENDWANTACK:
        WimpMessage(&e->data.msg);
      break;
  
      case wimp_EUSERDRAG:
        
      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 = AIM;
      }
   if (strcmp(stdname,"file_011") == 0) 
      {
       filetype = ASMF;
      }
   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 = 64000;
   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;
}


#define wimp_wopen 0x00010000    
void WimpMessage(wimp_msgstr *blck)
{
 int change, new_mode;
 BOOL paint,is_open;
 char cmd[80];
 wimp_wstate state;
 
 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 (OSbpp !=wimpt_bpp())
         {
           OSbpp=wimpt_bpp();
         }
       if (change == TRUE)
        {
         OSx=wimpt_dx();
         OSy=wimpt_dy();
         wimp_mode=wimpt_mode();
         paint=FALSE;
         wimpt_complain(wimp_get_wind_state(wprintf_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 wprintf_window */
         win_register_event_handler(wprintf_window,(win_event_handler)0,0);
         win_claim_unknown_events(-1); 
         event_attachmenu(wprintf_window,0,image_menu_proc,0);
 /* create new wprintf_window */
         reinit_wprintf(wimp_mode,FALSE,paint);
 /* register and attach handlers to new wprintf_window */
         win_register_event_handler(wprintf_window,aim_handler,(void *)imgmenu);
         win_claim_unknown_events(wprintf_window); 
         event_attachmenu(wprintf_window,imgmenu,image_menu_proc,0);
        }

       break;
     case wimp_PALETTECHANGE:
       
       break;

     case wimp_MDATASAVE :
       
       break;
     case wimp_MDATASAVEOK :

       break;
     case wimp_MDATAOPEN :
     
       break;
     case wimp_MDATALOAD :
    
       break;
     default:
       break;
  }
 }
}

static void aim_leftclickproc(wimp_i i)
{
wimp_wstate state;
int j;

i=i;
if (win_activeno()-1 <=0) aim_new();              /* eerste keer click op bar icon */
else 
  {
  wimpt_noerr(wimp_get_wind_state(wprintf_window, &state));
  wimp_open_wind(&state.o);                                 /* open textwindow */

  for (j = 0;j<number_of_signals;j++)
      display_signal_plot(vp[j]);                             /* open de displaywindows */
     
   } 
cmdwind_is_open=TRUE;
}

/**************************** aim STUFF ***********************************/



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));
}






BOOL aim_new(void)
{
#define ASM_VERSION "ASM Version 1.00 "__DATE__

 wimp_wstate state;

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

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



 wprintf("%s\n",ASM_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:
      break;
    default:
      break;
  }
}




static menu aim_menumaker(void *handle)
{
  main_menu = menu_new("asm", ">Info,>About ASM,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("ASM$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)wprintf_window, 0, 0);
  wimpt_noerr(wimp_close_wind((wimp_w)wprintf_window));
  wimpt_noerr(wimp_delete_wind((wimp_w)wprintf_window));
  win_activedec(); 
  for (i=0;i<number_of_signals;i++) win_activedec();  
  exit(0);
}


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


BOOL save_asm_signal(char * name,void * handle)
{
  int i, *ptr;
  int todisc(VENSTER *vp, char *filename, int file_type);


  ptr=(int *) handle;
  i=*ptr;
  strncpy(Window_File(vp[i]),name,256);
  wprintf("save as asm signal %s \n",name);
  todisc(vp[i],name,TCL);
  return(TRUE);
} 

void image_menu_proc(void *handle,char * hit)
{        
  
  extern char signal_dir[],macro_dir[],setup_file[];

  char setfile[100],signalfile[100];
  my_msgstr msg;
  os_regset r;
  int FSnumber,i;
  handle=handle;
  

  switch(hit[0])
   {
    case 1:
      break; 
    
    case 2:
      break; 
    case 3:
      break;
   
    case 4:                /* Load      */
      i=strlen(setfile);
      if (i==0 || setfile[i-1] == 0x2E)
          {
          strncpy(setfile,setup_file,99);
          strcat(setfile,"default");
          }
      if (hit[1] == 1)              /* ASM Signal */
          {
          i=strlen(signalfile);
          if (i==0 || signalfile[i-1] == 0x2e);
              { 
              strncpy(signalfile,signal_dir,99);
              strcat(signalfile,"signal");
              }
          if (hit[2] == 1)   i=0;             /* Signal A */
          if (hit[2] == 2)   i=1;             /* Signal B */
          if (hit[2] == 3)   i=2;             /* Signal C */
          if (hit[2] == 4)   i=3;             /* Signal D */  
          /*  loadas(TCL,signalfile,65535,get_asm_signal,0,0,(void *)&i); */
          break;
          }
       if (hit[1] == 2)            /* SetupFile */
       /*   loadas(AIMSETUP,setfile,512,get_setup,0,0,(void *)&test);*/
       break;
    
    case 5:                /*  SAVE  */
      if (hit[1]==1)             /* ASM Signal  */
          {
          strncpy(signalfile,signal_dir,99);
          strncat(signalfile,"signal",99); 
          if (hit[2] == 1)   i=0;             /* Signal A */
          if (hit[2] == 2)   i=1;             /* Signal B */
          if (hit[2] == 3)   i=2;             /* Signal C */
          if (hit[2] == 4)   i=3;             /* Signal D */ 
          /* saveas(TCL,signalfile,65535,save_asm_signal,0,0,handle); */   
          }
      break;
    case 7:                /* SignalDir */
      r.r[0]=0;
      r.r[1]=0;
      wimpt_complain(os_swix(OS_Args,&r));
      FSnumber=r.r[0];
      strncpy(msg.data.chars,signal_dir,strlen(signal_dir)-1); 
      msg.data.chars[strlen(signal_dir)-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 8:               /* MacroDir   */
      r.r[0]=0;
      r.r[1]=0;
      wimpt_complain(os_swix(OS_Args,&r));
      FSnumber=r.r[0];
      strncpy(msg.data.chars,macro_dir,strlen(macro_dir)-1);
      msg.data.chars[strlen(macro_dir)-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 9:                /* display on/off  */
      don=!don;
      menu_setflags(imgmenu,9,don,0);
      /* Deze flag wordt ook gezet in c.plotcomm (in DoffCi en DonCi) */
      break;      

   case 10:                /* bargraph on/off */
      bon=!bon;
      menu_setflags(imgmenu,10,bon,0);
      /* Deze flag wordt ook gezet in c.plotcomm (in BoffCi en BonCi) */
      break;      

     case 11:              /* QUIT    */
      visdelay_end();
      pointer_reset_shape();
      wimp_exit();
      break;

    default:
      break;
 }
}


static menu image_menumaker(void *handle)
{
/* Creating menu tree for mainwindow */
  static menu ops_menu,functions_menu,utilsmenu,loadmenu,savemenu;
  static menu point_ops_menu,arit_ops_menu,nonarit_ops_menu,lin_filters_menu;
  static menu nonlin_filters_menu,transf_menu,window_menu;
  static menu loadsignalmenu,savesignalmenu;

if (event_is_menu_being_recreated() == FALSE)
  {
 
      imgmenu = menu_new("ASM", "Operations,Functions,Utils|Load,Save,Digitise,Signal Dir,Macro Dir,Display On,Bargraph On,Quit");

      ops_menu = menu_new("Operations", "Point Ops,Arit Ops,Non-Arit Ops,Lin Filters,N-Lin Filt,Transf,Convolution,Correlation");           
      functions_menu = menu_new("Functions","windows|fdelta,fconstant,fstep,fsquarewave,framp,ftriangle,fsine,fsinc,fcosine,fexp,fnoise"); 
      utilsmenu = menu_new("Utils","display,real,imag,rename,list,info,print,xscale|histogram");
      loadmenu = menu_new("Load","ASM signal,Setup");
      
      savemenu = menu_new("Save","ASM signal,Setup");

             point_ops_menu = menu_new("Point Ops","rotate,shift,clip,zeropad");
             arit_ops_menu = menu_new("Arit Ops","copy|clear,assign,inv,conjugate,cabs,cmul,cdiv|abs,add,sub,mul|sine,cosine,ln,log,epow,tenpow");
             nonarit_ops_menu = menu_new("Non-Arit Ops","maximum,minimum");
             lin_filters_menu = menu_new("Lin Filters","derivate,integrate");
             nonlin_filters_menu = menu_new("N-Lin Filters","median");
             transf_menu = menu_new("Transf","fft|ifft|magnitude,phase");
             window_menu = menu_new("Windows","wblock,whanning,whamming,wgauss,wblackman,wkaiser,wtriangle");
             loadsignalmenu = menu_new("ASM signal",">A,>B,>C,>D");
             savesignalmenu = menu_new("ASM signal",">A,>B,>C,>D");
             
     

          menu_submenu(ops_menu,1,point_ops_menu); 
          menu_submenu(ops_menu,2,arit_ops_menu);
          menu_submenu(ops_menu,3,nonarit_ops_menu);
          menu_submenu(ops_menu,4,lin_filters_menu);
          menu_submenu(ops_menu,5,nonlin_filters_menu);
          menu_submenu(ops_menu,6,transf_menu);
          menu_submenu(functions_menu,1,window_menu);
          menu_submenu(loadmenu,1,loadsignalmenu);
          menu_submenu(savemenu,1,savesignalmenu);
          


      menu_submenu(imgmenu,1,ops_menu);
      menu_submenu(imgmenu,2,functions_menu);
      menu_submenu(imgmenu,3,utilsmenu);
      menu_submenu(imgmenu,4,loadmenu);
      menu_submenu(imgmenu,5,savemenu);
 }

  return imgmenu;
}

/***************************** INITIALISATION ******************************/

void config(void)
{
  char * window_col, *window_row, *image;
  char *pntr, *max_sig, *max_length, *sample_rate;
  
  max_sig=getenv("Max_signals"); 
  max_signals = atoi(max_sig);    /* Het maximale aantal signalen */  

  max_length=getenv("Max_Length");
  MAX_LENGTH=(unsigned short)atoi(max_length);


  sample_rate=getenv("Sample_Rate");
  SAMPLE_RATE=(unsigned short)atoi(sample_rate);

  number_of_signals = 0;          /* Het aantal momentele signalen in gebruik */

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

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

  image=getenv("ASM$image");
  if (image==NULL) image="3";
 

/* 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=600;


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



void aim_initialise(void)
{
  wimp_i bar_icon;
  int spr_area, i;

    wimpt_init("ASM"); 
    taskid=wimpt_task();
    flex_init();
    heap_init(TRUE);
    _kernel_register_slotextend(flex_dont_budge); 
    visdelay_init();
    res_init("ASM");
    resspr_init();
    template_init();
    dbox_init();
    alarm_init();
   
  /* --- put Aim icon on the icon bar --- */
    spr_area=(int)resspr_area();
    bar_icon=baricon("!asm", (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);
    signal_menu_maker((void *)&hsit);
 
    win_register_event_handler(wprintf_window,aim_handler,(void *)imgmenu);
/*    win_claim_idle_events(wprintf_window); */
    win_claim_unknown_events(wprintf_window); 
    event_attachmenu(wprintf_window,imgmenu,image_menu_proc,0);
    grey_level=8;
    if (OSbpp == 8) grey_level=16;
/*  select_grey_level();  */

    for (i=0;i<MAXSIG;i++) 
        vp[i]=NULL;  

    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 ");
    don=TRUE;       /* display = on */
    if (don) menu_setflags(imgmenu,9,1,0);
    bon = FALSE;
    if (bon) menu_setflags(imgmenu,10,1,0);
    compress=FALSE;
    if (compress) menu_setflags(imgmenu,ICMPRS,1,0);
}

/***********************************************************************
 * int Find_Signal_Venster(char *signalname)                           *
 * -Input:   Naam van een signaal.                                     *
 * -Returns: Het bijbehorende vensternummer                            *
 *           -1 als signaal niet bestaat.                              *
 ***********************************************************************/

int Find_Signal_Venster(char *signalname)
{ 
  int i;                               


/* Kijk of het signaal bestaat */

  for (i=0; (i < number_of_signals) && ((strcmp(DataSignalName(vp[i]),signalname)) != 0) ; i++);


  if (strcmp(DataSignalName(vp[i]),signalname) == 0)
  {
     return i;                        /* Het signaal bestaat, return vensternummer */ 
  }
    else      
    return -1;                        /* Het signaal bestaat niet */
 }
                                                                      
/****************************************************************************
 * int Create_Venster(char *signalname,unsigned int Alloc_Size)                                     *
 * Input:   Naam nieuw te creeren signaal.                                  *
 * Output:  Maakt een nieuw venster voor het nieuwe signaal aan.            *
 * Returns: Het nieuwe vensternummer;                                       *
 *          -1 als het aantal displaywindows al het maximale is             *
 ****************************************************************************/

int Create_Venster(char *signalname,unsigned int Alloc_Size)
{

  /* Alloc_Size is de ruimte die voor de data gereserveerd moet worden. */

  int i,y_res;
  wimp_wstate state;
  wimp_winfo winfo;

    i = number_of_signals;

    y_res = mode_y_res();   /* Verticale resolutie beeldscherm */

     if (number_of_signals < max_signals)
    { 
      /* Maak een nieuw window aan */
      vp[i]=Create_ImagePool(Alloc_Size,signalname);


/* Vindt de grootte van de window template */

   winfo.w = Window_Handle(vp[i]);
   wimpt_complain(wimp_get_wind_info(&winfo));

   Window_Height(vp[i]) = -winfo.info.ex.y0;
   Window_Width(vp[i]) = winfo.info.ex.x1;
 
   
/* Open het eerste displaywindow linksboven in het scherm en
   de volgenden steeds iets naar rechtsonder verschuiven. */

      signal_st[i].o.box.x0=(i*40);
      signal_st[i].o.box.y0=(y_res - Window_Height(vp[i]) - (i+1)*40);
      signal_st[i].o.box.x1=(Window_Width(vp[i]) + i*40);
      signal_st[i].o.box.y1=(y_res-(i+1)*40);

     
      wimpt_noerr(wimp_get_wind_state(Window_Handle(vp[i]), &state));
      signal_st[i].o.w=Window_Handle(vp[i]);
      signal_st[i].o.behind=-1;    
      signal_st[i].flags=state.flags;
      if (don) wimp_open_wind(&signal_st[i].o);
      win_activeinc(); 

      Window_Mode(vp[i]) = REAL_M;       /* Display real data */
      Window_Log(vp[i]) = 0;          /* Geen log as   */
      Window_InUse(vp[i]) = FALSE;     /* Geen signaal */ 
      Window_HScale(vp[i]) = 1;
      Window_VScale(vp[i]) = 1;

      number_of_signals++;
      return i;
    }
    else
      return -1;                  /* Te veel displaywindows */
} 

/******************************* 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();
   alloc_bottom=alloc_ptr;
   aim_kern(); 
}



