/* get image colour stats */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include "wimp.h"
#include "kernel.h"
#include "swis.h"

/* Other header files. */
#include "oslib/os.h"
#include "oslib/osfile.h"
#include "oslib/osspriteop.h"

#include "debug.h"

unsigned int spriteareastart;
unsigned int firstsprite;
unsigned int *spritepointer;
unsigned int spritedata;
int height,width;
char *envpointer;
char rgbpointer;
char envstring[256];
char *charpointer;

char leafname[256];
char pathname[256];
char tempbuff[256]; 

int rhist[256];
int bhist[256];
int ghist[256];



double r,a,as,w,x,y,xo,yo,xd,yd,wd,f,w2pi;

double v,v2,w2,r2,e;

double racc,bacc,gacc;

int i,p,ncenter,n,nc,range,npixels;

int min_expanded, max_expanded;

int expanded_level[256];

double slope;

FILE *fil;

_kernel_swi_regs rin,rout;


//osspriteop_area *My_Area;
//osspriteop_header *sprite_Header;
byte *PPM_Area;
byte *ppm_Header;
// pour crire l'image ppm
//unsigned char imagnb[3000*1000];
unsigned char *imagnb;


//int LoadSprite(char* source_name);

int Loadppm(char* source_name);

int get_sprite_start(void);
void get_sprite_size(void);
/* void draw_stuff(void); */

void read_pixels(void);
void read_sprite(void);

int thispixel(int,int);


char *find_leaf(char *path)
{
  char *l;
  l = path + strlen(path);
  do { l--; } while (l >= path && l[0] != '.' && l[0] != ':');
  return l+1;
}

char *find_path(char *path)
{
  char *l,*lout;
  lout = path ;
//  l = path + strlen(path);
  //  do { l--; } while (l >= path && l[0] != '.' && l[0] != ':');
  l = path + strlen(path) - 1;
  do { l--; } while (l > path && l[0] != '.' && l[0] != ':');
   l[0]= '\0';
  //printf("lout  %s\n", lout);
  return lout;
   
 }


void read_var_val(char *var, char *varextended )
{
  // printf("var: %s \n",var);
  int len;
  int context=0;
  char par[256] ;
  #define VARTYPE_EXPANDED 3
  int vartype;
    
  if(  _swix(OS_ReadVarVal,  _INR(0,4) | _OUTR(2,4), var, par, 255 , context, VARTYPE_EXPANDED, &len, &context, &vartype)== NULL){
    //par[len] = '.';
    par[len] = '\0';
    sprintf(varextended,"%s",par);
   } else {
     printf("Not found\n");
   }

}



static void fail(char *errmsg, ...)
{
    va_list ap;

    va_start(ap, errmsg);
    vfprintf(stderr, errmsg, ap);
    va_end(ap);
    exit(1);
}


/**  Output data as PPM file type 5*/
void saveppmP5(char *filename, unsigned char *img, int width, int height){
        
        /* FILE pointer */
       // FILE *f;
        
        /* Open file for writing */
        fil = fopen(filename, "wb");
        
        /* PPM header info, including the size of the image */
        fprintf(fil, "P5\n%d %d\n%d\n", width, height, 255);
        
        /* Write the image data to the file - remember 3 byte per pixel */
        fwrite(img, 1, width*height, fil);
        
        /* Make sure you close the file */
        fclose(fil);
        
       	// set pbm type quivalent ppm ?
	osfile_set_type( filename , 0x69e );
}




int main(int argc, char *argv[])
{
//  // get arguments
  if (argc != 3)
    fail("Usage: Sort <infile> <outfile>");
   // osspriteop rcupre height et width
    //LoadSprite(argv[1]);
    Loadppm(argv[1]);
    
   //espace allocation pour l'image ppm  ko si aprs avoir charger le sprite
   return 0;
#if 0
   // zeroed arrays
   //  refaire avec memset
  i=0;
  do
  {
    rhist[i]=0; ghist[i]=0;; bhist[i]=0;
    i++;
  } while (i<255);
  
  racc = 0.0; gacc = 0.0; bacc =0.0;
 
  ncenter = width*height/2 + width/2; npixels = width*height;

  read_pixels();



  // test plot the sprite on screen
  //osspriteop_put_sprite_scaled(osspriteop_USER_AREA, My_Area,  (osspriteop_id)leafname, 200, 100, 0,NULL,NULL);
  
  // sauve le sprite dans le fichier nomm arg[2]
  //printf("fichier de sortie: %s\n", argv[2]);

  // rcupre le suffixe pour l'ajouter au nom du fichier d'entre.
  sprintf(leafname,"%s/%s",leafname, find_leaf(argv[2]) );
  //printf("fichier de sortie: %s\n", leafname);
  //Se positionner dans le classeur de sortie
  sprintf(tempbuff,"dir %s",find_path(argv[2]) );
  //printf("chemin de sortie: %s\n", tempbuff);
  os_cli(tempbuff);
    

  // version sprite 32b
  //osspriteop_save_sprite_file(osspriteop_USER_AREA, My_Area, leafname);
   // printf("nom du fichier de sortie: %s\n", leafname);
   //return 0;
  // version pbm5 noir et blanc.il est dans le tableau imagnb
  saveppmP5(leafname, imagnb, width ,height );

  // retour dans  le classeur de dev

 sprintf(tempbuff,"dir <AppDir$dir>" );
 //printf("chemin de sortie: %s\n", tempbuff);
 os_cli(tempbuff);
  //free(imagnb);
 return 0;
 #endif
 
}

#if 0
void greyscale_image(void)
{

}
#endif


#if 0
void read_pixels(void)
{
  int pt;// pointer to navigate the image
  unsigned int colour;
  unsigned int xstart,xstop;

  spritepointer = (unsigned int*)spriteareastart;
  imagnb = (unsigned char *) spriteareastart;
  firstsprite = spriteareastart+spritepointer[2];  // start + offset to first sprite
 
  //printf("firstsprite offset: %d\n", spritepointer[2]);
  //printf("firstsprite ptr: %0X\n", firstsprite);
  spritepointer = (unsigned int*)firstsprite;
  spritedata = firstsprite+spritepointer[8];
  //printf("sprite data: %0X\n", spritedata);
  spritepointer = (unsigned int*)spritedata;

  //double rpc, gpc, bpc;
  unsigned int red,blue,green;
  //unsigned int greyout;
  double min, max;
  double slope;
  
  min = -1.0; max = -1.0;
  
  xstart=1; pt=0;
  xstop=width*height;
  
  pt=0;  // sprite uint32 / wordptr

// stats on all pixels: ajout de  la couleur
  do
  {
    colour=spritepointer[pt];
    
    red = (colour >> 0) & 0xffu;
    green = (colour >> 8) & 0xffu;
    blue = (colour >> 16) & 0xffu;
    
    //bhist[blue] = bhist[blue]+1;
    //ghist[green] = ghist[green]+1;
    //rhist[red] = rhist[red]+1;

    bhist[blue]  += 1;
    ghist[green] += 1;
    rhist[red]   += 1;
    /* test line follows */
    
    
    min_expanded = -1;  max_expanded = -1;
     
    pt += 1;
  } while (pt < npixels);
 
  pt=0;

  // stats on all previous tables: col hist[]: integer array
  // scaling 100.0/npixels
  do
  { 
    racc += 100.0*(rhist[pt])/npixels;
    bacc += 100.0*(bhist[pt])/npixels;
    gacc += 100.0*(ghist[pt])/npixels;
                                           
    if (min_expanded < 0)
    {
      if (bacc > 0.1)
      {
        min_expanded = pt;
        //printf ("min percent limit at %i\n", min_expanded);
      }
    }
        
    if (max_expanded < 0)
    {
      if (bacc > 50.0)
      {
        max_expanded = pt;
        //printf ("max percent limit at %i\n", max_expanded);
      }
    }
    
    pt += 1;
  } while (pt < 256);
       
  slope = 255.0/(double)(max_expanded - min_expanded);
  
  
  pt = 0;
     
  do
  {
    
    expanded_level[pt] = 0;
   
    pt += 1;
  } while (pt <= min_expanded);
     
  do
  {
    expanded_level[pt] = (int) ( slope * (double)( pt - min_expanded)   );
    
    pt += 1;
  } while (pt <= max_expanded);
     
  do
  {
    expanded_level[pt] = 255;
    pt += 1;
  } while (pt <256);
          
    
    /******  now process image (all points)*****/
    
    pt = 0; 
    
    do
    {
      colour=spritepointer[pt];
        
      blue = (colour >> 16) & 0xffu;
      
      blue = expanded_level[blue];
      
      //spritepointer[pt] = (unsigned int)( blue + blue*256 + blue*256*256);

      imagnb[pt] =  blue & 0xFF;  // image ppm
      pt += 1;
    } while (pt < width*height);
     
} 
#endif

int Loadppm(char* source_name)
{
  //debug_printf(" %s",__func__);
  fileswitch_object_type  fileswitch;
  os_dynamic_area_no area_no;
  int size;
  int da_size ;

  os_error *error;
  // DA cration : DetoxPPM avec la taille du fichier.
  // info sur fichier.  source_name
  //get leaf name
  // ncessaire pour crire le fichier aprs traitement dans un autre classeur.
  //  printf("source name = %s\n",source_name);
  sprintf(leafname,"%s", find_leaf(source_name));
  //printf("leaf filename = %s\n", leafname );  
  // ** Get path name  , pas forcement ncessaire **
  //sprintf(pathname,"%s", find_path(source_name));
  //printf("path name in= %s\n", pathname );

  fileswitch = osfile_read_stamped(source_name ,NULL,NULL,&size,NULL,NULL);
  if( fileswitch == fileswitch_NOT_FOUND) printf("sprite not found\n",size);
  printf("%s: ppm size= %d\n",__func__, size);

  area_no = osdynamicarea_create( os_DYNAMIC_AREA_APPLICATION_SPACE, 4096, PPM_Area, 0x58, NULL, 0 , 0, "PPM-DA" , &PPM_Area, &da_size);

  printf("%s: area_num, ppm size= %d\n",__func__, area_no, size);
  osdynamicarea_delete (area_no);

  return 0;


}


#if 0
int LoadSprite(char* source_name)
{
  //Find size of sprite file
  fileswitch_object_type  fileswitch;
  int size;


  //get leaf name
  sprintf(leafname,"%s", find_leaf(source_name));
//  printf("leaf filename = %s\n", leafname );
//  printf("source name = %s\n",source_name);
  // Get path name
  sprintf(pathname,"%s", find_path(source_name));
  //printf("path name in= %s\n", pathname );

  // positionnement dans le classeur images
  sprintf(tempbuff,"dir %s", pathname);   //pathname
  os_cli(tempbuff);

  fileswitch = osfile_read_stamped_no_path(leafname ,NULL,NULL,&size,NULL,NULL);
  if( fileswitch == fileswitch_NOT_FOUND) printf("sprite not found\n",size);
   
  //Reserve memory for user sprite area,  Size of area should be size of file + 4 bytes for length
  My_Area = malloc(size +32);

  //Initialise area with size...
  My_Area->size = size +4; 
  My_Area->first = 16;
  //Finish initialising with this sprite op  initialise sprite area
  //osspriteop_verify_area(osspriteop_USER_AREA, My_Area);   //KO

  // load sprite
  //osspriteop_load_sprite_file(osspriteop_USER_AREA, My_Area, source_name);
  osspriteop_load_sprite_file(osspriteop_USER_AREA, My_Area,leafname );

  //osspriteop_read_sprite_info( osspriteop_USER_AREA, My_Area, (osspriteop_id) source_name, & width, &height, false, NULL);
  osspriteop_read_sprite_info( osspriteop_USER_AREA, My_Area, (osspriteop_id) leafname , & width, &height, false, NULL);

 //printf("width: %d\n",width);
 //printf("heigth: %d\n\n",height);
 spriteareastart = (int)My_Area;//  + My_Area->first;


 // test plot the sprite on screen
 //osspriteop_put_sprite_scaled(osspriteop_USER_AREA, My_Area,  (osspriteop_id)source_name, 200, 100, 0,NULL,NULL);


  return 1;
}
#endif

//Fin
