#include "defs.h"
#include <stdio.h>
#include <stdlib.h>
#include "imageio.h"
#include "patternlist.h"
#ifdef USE_DEBUG
#include "time.h"
#endif
#ifdef USE_CLUSTER
#include "cluster.h"
#endif


struct patternfield {
   int width;
   int height;
   int *pattern;
};

struct patternfield pattern(	ImagePtr* dest, ImagePtr imsource,
				int patternwidth, int patternheight,
				int xwidth, int ywidth,  struct patternlist* list) {
/*Does a pattern search in imsource, saves a pattern in imdest
  and gives back a struct patternfield (uses patternlist list of course*/

   ImagePtr imdest;			/*VarPointers to the Image Data*/
   int t,tt,i,ii,tx,ty,sx,sy,x,y,actual,sum;	/*Several integers*/
   int color[256];			/*Some sort of Color Map*/
   struct pattern *icon;		/*Patterndata*/ 
   struct patternmatch pactual;		/*Temp var to save the match class result*/
   struct patternfield returnval;	/*Obvious isnt it?*/
   struct pattern area;			/*area to check against*/
   int* returnpatterndata;		/*field with the patterns found*/

#ifdef USE_DEBUG
   clock_t starttime;
   starttime=clock();
   fprintf(stderr,"Running pattern search  width %ix%i patterns and %i,%i thresholds...\n",
      patternwidth,patternheight,xwidth,ywidth);
#endif

   area.brightness=(int*)malloc(sizeof(int[patternwidth*patternheight]));
   area.width=patternwidth;
   area.height=patternheight;
   /*Initialize Buffer for the pattern to check*/
   
   imdest = createim(widthim(imsource),heightim(imsource));
   *dest=imdest;
   /*We create a destination image the size of the source*/
   /*and give its adress back*/

   t=0;
   while (t<256) {
      color[t]=collorallocateim(imdest,t,t,t);
      t++;
   }
   /*We create some sort of 256 colors b/w colormap for the destination*/
   /*Later there will be even greyscale patterns, now as i write this thers only
     that b&w asciitable, but why should it be limited?*/

#ifdef USE_CLUSTER
      cluster_split();
      /*time to split up the work */
#endif

   x=(widthim(imdest)-xwidth)/patternwidth;
   y=(heightim(imdest)-ywidth)/patternheight;
   returnval.width=x;
   returnval.height=y;
   returnpatterndata=(int*)malloc(sizeof(int[x*y]));
   returnval.pattern=returnpatterndata;
#ifndef USE_CLUSTER 
   t=0;
#else
   t=cluster_split_min(0,y);
   y=cluster_split_max(0,y);
#ifdef USE_DEBUG
   fprintf(stderr,"process(%i): doing from %i till %i ...\n",pid(),t,y);   
#endif
#endif
   while (t<y) {
      tt=0;
      while (tt<x) {
         tx=patternwidth*tt;
	 ty=patternheight*t;
	 actual=-1;
         sum=-1;
	 sy=0;
	 while (sy<ywidth+1) {
	    sx=0;
	    while (sx<xwidth+1) {
	       i=0;
	       while (i<patternheight) {
	          ii=0;
	          while (ii<patternwidth) {
	             area.brightness[i*patternwidth+ii]=pixelbrightim(imsource,sx+tx+ii,sy+ty+i);
	             ii++;
	          }
	          i++;
	       }
               /*Filled the pattern buffer, now trying for best match*/
	       pactual= patternlist_bestmatch (list,&area);
	       if (pactual.differ<sum || sum<0) {
	          actual=pactual.patident;
		  sum=pactual.differ;
	       }
	          
	       sx++;
	    }
	    sy++;
         }
	 /*We test best match against width*width different positions
	   to catch THE pattern more likely */
	 icon=patternlist_pattern(list,actual);
	 i=0;
	 while (i<icon->height) {
	    ii=0;
	    while (ii<icon->width) {
	       drawpixelim(imdest,tx+ii,ty+i,icon->brightness[i*icon->width+ii]);
	       ii++;
	    }
	    i++;
	 }
	 /*We save the matching pattern in imdest*/
	 
	 returnpatterndata[t*x+tt]=actual;
	 /*And in the return var*/
	 tt++;
      }
      t++;
   }

#ifdef USE_CLUSTER
   sx=x*sizeof(int);
   y=(heightim(imdest)-ywidth)/patternheight;
   i=cluster_split_min(0,y);
   ii=cluster_split_max(0,y);

   if (pid()>0) {
      #ifdef USE_DEBUG
         fprintf(stderr,"cluster(%i)_pattern_sync: writing array part (%i - %i)to pid 0 ...\n",pid(),i,ii);
      #endif
      t=i;
      while (t<ii) {
	 cluster_sync_data_tomaster(&returnpatterndata[t*x],sx);
         t++;
      }
      #ifdef USE_DEBUG
         fprintf(stderr,"cluster(%i)_pattern_sync: done.\n",pid());
      #endif
   } else {
      t=ii;
      while (t<y) {
         #ifdef USE_DEBUG
	    if ((t/ii)!=i) {
               fprintf(stderr,"cluster(0)_pattern_sync: reading array parts from pid(%i)...\n",t/ii);
	       i=(t/ii);
	    }
         #endif
	 cluster_sync_data_fromslave(&returnpatterndata[t*x],sx,t/ii);
         t++;
      }
      #ifdef USE_DEBUG
         fprintf(stderr,"cluster(0)_pattern_sync: done.\n");
      #endif
   }

   processsyncim(imdest,returnval.height);
   cluster_regroup();
   /*re combine execution*/
#endif

   free(area.brightness);
#ifdef USE_DEBUG
   fprintf(stderr," ... took  %.4f seconds!\n",(1.0 * (clock() - starttime) / CLOCKS_PER_SEC));
#endif
   return returnval;
   /*and we are finnished*/

}


