#include <string.h>
#include <aim_stdlib.h>

#include "wimp.h"
#include "wimpt.h"
#include "win.h"  
#include "werr.h"
#include "event.h"
#include "menu.h"
#include "heap.h"
#include "drawfobj.h"
#include "font.h"
#include "colourtran.h"
#include "image.h"
#include "drawExt.h"

#define DIAGRAM_SIZE               4096

/* Zo maar een paar kleuren definities die gebruikt kunnen worden bij     */
/* de functies: set_draw_fill_colour of set_draw_colour                   */

#define WIT                        0xffffff00
#define MED_GREY                   0xcfcfcf00
#define BLACK                      0x00000000
#define RED                        0x0000f800 
#define GREEN                      0x00f80000
#define NO_COLOUR                  0xffffffff

/* Het filtype van een drawfile is 0AFF. Deze wordt gebruikt bij saven    */

#define FILETYPE_DRAWFILE          0x0aff

/* globale definitie voor een font nummer. Dit font nummer wordt in de    */
/* draw file gebruikt i.p.v. de fontnaam. De fontnamen en fontnummers     */
/* worden in een tabel opgeslagen. PS ik weet niet of het met mijn        */
/* routines mogelijk is meerdere fonts in EEn drawfile te gebruiken. Het  */
/* is iedergeval nooit getest.                                            */

#define FONT_NUMBER                2        /* font nummer voor de drawfile */
#define FONT_SIZE                  12

/* paar globale variabelen. de variabele current_font_number is de font-  */
/* handle die je van de font manager terug krijgt.                        */
menu hsit;
static menu hent2,hent23;
BOOL plot_grid,plot_abs;
double     zoom=1.0;
char font_name[256];
int current_font_number;
extern WINDOW *wp[MAXIM];
extern int max_image;
extern void hmima(HIST *hgram, int perc, int *lmi, int *lma,int *lme, int *lva);
extern int thr(HIST *hgram);

void find_font(void)
{
   int m = 8;
   wimp_paletteword voor;
   wimp_paletteword achter;

   voor.word = 0x00000000;
   achter.word = 0xffffff00;
   wimpt_complain(font_find(font_name,FONT_SIZE * 16,FONT_SIZE * 16,0,0,&current_font_number));
   colourtran_setfontcolours(&current_font_number,&achter,&voor,&m);
}

/* routine om de 'current_font_number' vrij te geven.                   */

void lose_font(void)
{
   font_lose(current_font_number);
}


void gen_diagram(diag *diagram)
{
   int tel;
   /* zoek de font 'corpus.medium' op en maak hem 'current'. Vertel aan */
   /* de 'drawext' dat we deze font gaan gebruiken.                     */
/*
   find_font();
   font_table(diagram,FONT_NUMBER,font_name);
*/
   set_draw_fill_colour(NO_COLOUR);
   set_draw_colour(BLACK);
   
   /* teken de x en y as. Dit zijn twee aaneengesloten lijnen, dus zijn */
   /* er drie coordinaten nodig (start x,start y, midden x, midden y,   */
   /* einde x, einde y.                                                 */
                                          
     line4(diagram,20,-20,20,-400,400,-400,400,-20,20,-20);
/*   line2(diagram,20,400,20,20,400,20);*/

   /* teken de horizontale en verticale verdeling */
/*
   for (tel = 20; tel < 400; tel = tel + 20)
   {
      line1(diagram,tel,15,tel,35);
      line1(diagram,15,tel,35,tel);
   }
*/
   /* teken blokjes. Doe dit door een rectangle te tekenen met de fill  */
   /* colour op zwart        .                                          */
/*
   set_draw_fill_colour(BLACK);
   for (tel = 12; tel < 400; tel = tel + 50)
   {
      rectangle(diagram,tel,tel,tel + 5,tel + 5);
   }
   lose_font();
*/


}

#define xmin 128
#define xmax (512+xmin)
#define ymax -64
#define ymin (-400+ymax)


void gen_hist_diagram(diag *diagram,HIST *hg)
{
   draw_box   box;
   draw_error err;
   int tel,i,j,j_prev,x_prev,dx;
   int thresh,lmi,lma,lme,lva;
   long max=-1;
   long *cumm;
   float hist_scale,cumm_scale;
   char ch[256];
   
   cumm=(long *) calloc(HistSize(hg),sizeof(long));

   set_draw_fill_colour(NO_COLOUR);
   set_draw_colour(BLACK);
   set_text_col(BLACK);
   set_text_background_col(WIT);
  
   box.x0 = 0;
   box.y0 = 0;
   box.x1 = 0;
   box.y1 = 0;

   /* initialiseer het diagram. 'ProgName' moet de naam van het         */
   /* programma zijn dat de drawfile gegenereerd heeft.                 */
   diagram->length = 0;
   draw_create_diag((draw_diag *)diagram,"Aim",box);
   find_font();
   font_table(diagram,FONT_NUMBER,font_name);

/* find maximum value of hist */
   cumm[0]=HistData(hg)[0];
   for (i=0; i < HistSize(hg); i++)  
    {
     if (HistData(hg)[i] > max) max=HistData(hg)[i] ;
     if (i>0) cumm[i]=cumm[i-1]+HistData(hg)[i];
    }

/* find statistics */

   thresh = thr(hg); 
   hmima(hg,2,&lmi,&lma,&lme,&lva); 
   set_draw_width(0);
   hist_scale=(float)(ymax-ymin)/(float)max;
   cumm_scale=(float)(ymax-ymin)/(float)cumm[HistSize(hg)-1];

/* teken de horizontale en verticale verdeling */
   set_draw_width(0);
   
   i=-5;
   j=5;
   if (plot_grid) { i=0; j=ymax-ymin;set_draw_colour(MED_GREY);}
   for (tel = xmin+64; tel < xmax; tel = tel + 64)
     {
      line1(diagram,tel,ymin+i,tel,ymin+j); 
     }
  i=-5;
   j=5;
   set_draw_colour(BLACK);
   if (plot_grid) { i=0; j=xmax-xmin;set_draw_colour(MED_GREY);}
   for (tel = ymin+40; tel < ymax; tel = tel + 40)
     {
      line1(diagram,xmin+i,tel,xmin+j,tel);
     }
   set_draw_colour(NO_COLOUR);
   line1(diagram,xmin,ymax,xmin,ymax);                                       
   set_draw_colour(BLACK);  
 line4(diagram,xmin,ymax, xmin,ymin, xmax,ymin, xmax,ymax, xmin,ymax);

   text(diagram,(char)FONT_NUMBER,FONT_SIZE,FONT_SIZE,xmin,ymin-32,"0");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE,FONT_SIZE,xmax-32,ymin-32,"255");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE,FONT_SIZE,xmin+200,ymin-48,"Pixel value ");  
   text(diagram,(char)FONT_NUMBER,FONT_SIZE,FONT_SIZE,xmin-32,ymin,"0");
   set_text_col(RED);
   sprintf(ch,"%d",max);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmin-96,ymax-16,ch);
   set_text_col(GREEN);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmin-96,ymax-48,"100%");
   set_text_col(BLACK);
/* Print text */
   j=16;
   i=64;
   dx=32;
   sprintf(ch,"Threshold");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"Minimum (.2 %%)");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"Maximum (.2 %%)");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"Mean");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"Variance");
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch); 
/* print = */
   j=16;
   i=64;
   dx=dx+176;
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,"=");
   i=i+2*j;
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,"=");
   i=i+2*j;
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,"=");
   i=i+2*j;
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,"=");
   i=i+2*j;
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,"=");
/* print getallen */
   j=16;
   i=64;
   dx=dx+24;
   sprintf(ch,"%-d",thresh);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"%-d",lmi);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"%-d",lma);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"%-d",lme);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch);
   i=i+2*j;
   sprintf(ch,"%-d",lva);
   text(diagram,(char)FONT_NUMBER,FONT_SIZE-2,FONT_SIZE-2,xmax+dx,ymax-i,ch); 


    set_draw_colour(NO_COLOUR);
    line1(diagram,xmin,ymin,xmin,ymin);
 
    j_prev=(int)(hist_scale*(float)HistData(hg)[0]);
    x_prev=xmin;
   for (tel = 0; tel <  HistSize(hg); tel++)
   { 
      set_draw_colour(RED);
      j=(int)(hist_scale*(float)HistData(hg)[tel]);
      line1(diagram,x_prev,ymin,x_prev,ymin+j);
      line1(diagram,x_prev,ymin,x_prev,ymin);
      x_prev=xmin+2*tel;
      set_draw_colour(BLACK);
      line1(diagram,x_prev,ymin,x_prev,ymin);
      j_prev=j;        
   }
 
   set_draw_colour(GREEN);
   j_prev=(int)(cumm_scale*(float)cumm[0]);
   x_prev=xmin;
   for (tel = 0; tel <  HistSize(hg); tel++)
   { 
      j=(int)(cumm_scale*(float)cumm[tel]);
      line1(diagram,x_prev,ymin+j_prev,xmin+2*tel,ymin+j);
      x_prev=xmin+2*tel;
      j_prev=j;        
   }
  free(cumm);
  lose_font();

   if (!draw_verify_diag((draw_diag *)diagram,&err))
   {
      draw_show_error("gen_hist",&err);
   }
}

void save_drawfile(char *filename,void *handle)
{
   os_filestr file;
   draw_diag *diagram; 
   WINDOW * wp;
   /* Save the entire file */
   wp=(WINDOW *)handle;
   diagram=(draw_diag *)&WindowDiag(wp);
   draw_shift_diag((draw_diag*)diagram,0,draw_screenToDraw(1024));  

   file.action   = 0x0a;                   /* Save block and date stamp file */
   file.name     = filename;
   file.loadaddr = FILETYPE_DRAWFILE;       /* File type */
   file.start    = (int)diagram->data;
   file.end      = (int)(diagram->data + diagram->length);
   os_file(&file);
   draw_shift_diag((draw_diag*)diagram,0,draw_screenToDraw(-1024));  
}

/* routine om een bepaalde font 'current' te maken. De fontnaam staat   */
/* in de globale variabele 'font_name'. De fonthandle wordt in de       */
/* variabele 'current_font_number' terug gezet. Voorgrondkleur is zwart */
/* achtergrond kleur is wit.                                            */


void init_Histdraw(WINDOW *wp)
{
   draw_box   box;

   /* zet de te gebruiken fontnaam op 'corpus.medium'.                  */
   plot_grid=TRUE;
   plot_abs=FALSE;
   strcpy(font_name,"Trinity.Medium");

   /* vraag voor de eerste keer geheugen aan voor het diagram           */
   if (WindowDiag(wp).data == NULL)
   {
      WindowDiag(wp).data   = heap_alloc(DIAGRAM_SIZE);
      if (WindowDiag(wp).data ==NULL) werr(TRUE,"Diagram alloc failed");
      WindowDiag(wp).length = 0;
      WindowDiag(wp).size   = DIAGRAM_SIZE;
   }

   /* zet de omtrek van het diagram op 0,0 - 0,0. Bij het toevoegen van */
   /* lijnen wordt deze omtrek automatisch aangepast.                   */

   box.x0 = 0;
   box.y0 = 0;
   box.x1 = 0;
   box.y1 = 0;

   /* initialiseer het diagram. 'ProgName' moet de naam van het         */
   /* programma zijn dat de drawfile gegenereerd heeft.                 */
   draw_create_diag((draw_diag *)&WindowDiag(wp),"ProgName",box);

   /* tijdens het aanmaken van een diagram mogen er geen fout meldingen */
   /* gegeven worden, omdat anders het scherm weer 'verstoord' wordt en */
   /* dan moet hij weer een 'redraw' gaan doen -> weer drawfile aan-    */
   /* maken -> crash. Doe dit dan ook aan het einde.                    */


}


void redo_histogram(wimp_redrawstr r,BOOL more)
{
  draw_error err;
  BOOL more_to_do=more;
  wimp_redrawstr  new_r = r;
  int i,j;

  j=0;
  for (i=0;i<max_image;i++)
   {
     if (new_r.w == WindowHistHandle(wp[i])) { j=i; break; }
   }
/*
   draw_rebind_diag((draw_diag*)&WindowDiag(wp[j]));
  if (!draw_verify_diag((draw_diag *)&WindowDiag(wp[j]),&err))
   {
      draw_show_error("gen_hist",&err);
   }
*/

  while (more_to_do)
   {
      draw_render_diag((draw_diag *)&WindowDiag(wp[j]),
                       (draw_redrawstr *)&new_r,zoom,&err);
      wimp_get_rectangle(&new_r,&more_to_do);
   }
}

 void histogram_redraw_window(wimp_w handle)
{
  BOOL  more;
  wimp_redrawstr r;
  wimp_winfo      winfo;
  
  winfo.w = handle;
  wimp_get_wind_info(&winfo);
  r.w = handle; 
  wimp_redraw_wind(&r, &more);
  if (more)
    redo_histogram(r, more);

}



 void histogram_update_window(wimp_w handle)
{
  BOOL  more;
  wimp_redrawstr r;
  wimp_winfo      winfo;
  
  winfo.w = handle;
  wimp_get_wind_info(&winfo);
  r.w = handle; 
  wimp_update_wind(&r, &more);
  if (more)
    redo_histogram(r, more);

}


  

 void histogram_open_window(wimp_openstr *o)
{
  static int old_x, old_y;
  
  /* --- force scroll offsets to 0, since the window always --- */
  /* --- represents the whole display                       --- */


  wimp_open_wind(o);

  /* --- only do a redraw if the size of the window has changed --- */

    if (old_x != (o->box.x1 - o->box.x0) || old_y != (o->box.y1 - o->box.y0))
    {
      old_x = o->box.x1 - o->box.x0;
      old_y = o->box.y1 - o->box.y0;
      histogram_update_window(o->w);
    }
}  

void display_histogram(WINDOW *wp)
 {  
   wimp_wstate state;
   wimpt_noerr(wimp_get_wind_state(WindowHistHandle(wp),&state));
   state.o.behind=-1;
   wimp_open_wind(&state.o);
   histogram_redraw_window(state.o.w);
 }

#define HSAVE 2
#define HOPT 1
#define GRID 1
#define Y_AXIS 2
#define Y_ABS 1
#define Y_REL 2

void histogram_menu_proc(void *handle,char *hit)
 {
  switch(hit[0])
   {
    case HSAVE:
         saveas(0xAFF,"Hist",65535,save_drawfile,0,0,handle);
         break;
    case HOPT:
          if (hit[1]== GRID)
            {
             plot_grid=!plot_grid;
             if (plot_grid) menu_setflags(hent2,GRID,1,0);
             else           menu_setflags(hent2,GRID,0,0);
            }
           else
            {
              if (hit[2]==Y_ABS)
               {
                plot_abs=TRUE;
                menu_setflags(hent23,Y_ABS,1,0);
                menu_setflags(hent23,Y_REL,0,0);
               }
              else
               {
                menu_setflags(hent23,Y_REL,1,0);
                menu_setflags(hent23,Y_ABS,0,0);
               }
             }
         break;
    default:
         break;
   }
}

void histogram_menu_maker(void *handle)
 {


  if (event_is_menu_being_recreated()==FALSE)
    {
     hent2=menu_new("Options","~Chart,~Y-axis");
     hent23=menu_new("Y-axis","Absolute,!Relative");
     menu_submenu(hent2,2,hent23);
     hsit=menu_new("Aim","Options,>Save");
    menu_submenu(hsit,1,hent2);   
    }
 }
