#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include "ocr.h"
#include "baum.h"
#include "win.h"
#include "main.h"
#ifdef TEXT2
#else
#include "german.h"
#endif

 extern char *OrginalBildPuffer;
 extern long Page_x,Page_y,Page_Bytes_pro_Zeile;
 extern long Max_x,Min_x,Min_y,Max_y;
 extern unsigned short int ByteIstGespiegelt[];
 extern struct BitBlockListe *BitBlockListeStartPtr;
 extern struct BitBlockListe *SegmentBitBlockListeStartPtr;
 extern struct LearndListe *ZeichenListeStart[35][16][16];

 XImage Bilder[1],Orginal[1],Icon;
 long Filter=8;
 char *arg1;
 long Statu = 0;
 long Action = 0;
 long Aktuell_t=0;
 struct BitBlockListe *SegmenteStart[10],*BlockListeStart[10],*Aktuell,*Aktuell_Zeile;
 struct Parameter ParaAktuell;


void SegmentStart();

void LoescheAlleBloecke(t)
long t;
{
 struct BitBlockListe *P1,*P2,*P3,*Pa1,*Pa2,*Pa3;  
 for (P1=SegmenteStart[t];P1!=NULL;P1=Pa1)  
 {  
  for (P2=P1->NextZeileInSegment;P2!=NULL;P2=Pa2)
  {     
   for (P3=P2->NextPtrInZeile;P3!=NULL;P3=Pa3)
   {
    Pa3=P3->NextPtrInZeile;
    P3->NextPtrInZeile=NULL;
    P3->NextSegmentBlockPtr=NULL;
    P3->NextPtrInSegment=NULL;
    P3->NextZeileInSegment=NULL;
   } /* for elemente */
   Pa2=P2=P2->NextZeileInSegment;
   free(P2);
  } /* for zeilen */
  Pa1=P1->NextSegmentBlockPtr;
  free(P1);
 } /* for segmente */
 SegmenteStart[t]=NULL;
}

void Seg_start()
{
 SegmentStart();;
}

void BerechneAbstaende(t1)
long t1;
{
 long Wert,t,xx,xxx,minimum,l;
 struct LearndListe  *Ptr;
 struct BitBlockListe *P1,*P2,*P3;  
 FILE *output;
 short int Flag;
 struct Objekt *PErsatz,*PErsatz1,*PErsatz2;
 
 output=fopen("tmp.dat","w+"); 
 for (P1=SegmenteStart[t1];P1!=NULL;P1=P1->NextSegmentBlockPtr)  
 {  
  if (P1->Geloescht==0)
  {
   minimum=P1->ddx*0.55;
   for (P2=P1->NextZeileInSegment;P2!=NULL;P2=P2->NextZeileInSegment)
   {     
    if (P2->Geloescht==0)
    {
     xx=0; xxx=0;
     Aktuell_Zeile=P2;
     for (P3=P2->NextPtrInZeile;P3!=NULL;P3=P3->NextPtrInZeile)
     {
      if (P3->Geloescht==0) 
      {
       xx=P3->x;
       if (((xx-xxx)>minimum) && (xxx!=0)) fprintf(output,"\n");
       xxx=P3->x+P3->dx;
       Wert=9999;
       Ptr=AnalysiereAlleWerteEinesSegments(P3,&Wert,&Flag);
       Aktuell=P3;
       if (Ptr!=NULL) {  strncpy(P3->Text,Ptr->Daten.Zeichen,3); } else { strcpy(P3->Text,""); }  
       }       
        if (P3->NextPtrInZeile!=NULL)
        {
         fprintf(output,"%s",P3->Text); 
        } else
        { /* upps letztes zeichen !*/ 
         l=strlen(P3->Text)-1;
         if (l<0) l=0;
         if ((P3->Text[l]=='-') || (P3->Text[l]=='~'))
         { /* bindestich loeschen */
           P3->Text[l]=0;
           fprintf(output,"%s",P3->Text); 
         } else
         { /* normales ende */
           fprintf(output,"%s\n",P3->Text); 
         }  
        }
      }
     }
    }
   }
  }
 for (t=0;t<65;t++) fprintf(output,"%c\n",1);
 fprintf(output,"END OF TMP-FILE\n"); 
 fclose(output); 
}


void OcrStart()
{
 long t; 
 t=0;
 {
  {
   {
     long x,y,dx,dy;
     struct BitBlockListe *Ptr;
     x=0;
     y=0;
     dx=Orginal[t].width;
     dy=Orginal[t].height;
     /* erstelle Datenelement */
     Ptr=calloc(1,sizeof(struct BitBlockListe));    
     if (Ptr==NULL) { MemoryError(); }
     Ptr->Bytes_pro_Zeile=0;
     Ptr->x=x;
     Ptr->y=y;
     Ptr->Startx=x;
     Ptr->Starty=y;
     Ptr->Bild=0;
     Ptr->SegmentNummer=-1;
     Ptr->SpaltenNummer=-1;
     Ptr->XSpiegel=0;
     Ptr->YSpiegel=0;
     Ptr->Untere_Zeile=-1;
     Ptr->Obere_Zeile=-1;
     Ptr->Geloescht=0;
     Ptr->dx=dx;
     Ptr->dy=dy; 
     Ptr->xx=x+dx;
     Ptr->yy=y+dy;       
     Ptr->NextPtrInZeile=NULL;
     Ptr->NextSegmentBlockPtr=NULL;
     Ptr->NextPtrInSegment=NULL;
     Ptr->NextPtr=NULL;
     SegmenteStart[t]=Ptr;
   }
   Aktuell_t=t;
   SegmentBitBlockListeStartPtr=SegmenteStart[t];
   BitBlockListeStartPtr=BlockListeStart[t];
   Page_x= Orginal[t].width;
   Page_y= Orginal[t].height;
   Page_Bytes_pro_Zeile = Orginal[t].bytes_per_line ;
   OrginalBildPuffer = Orginal[t].data ;
   Bloecke_in_Segmente();
   FindeZeilen() ;
   VerschmelzeBitBloeckeInZeile();
   VergleicheAufSymetrieUndWsa(); 
   BerechneAbstaende(t); 
   LoescheAlleBloecke(t);
   WoerterbuchUndSemantikCheck();
  }
 }
}

void SegmentStart()
{
 long t; 
  t=0;
   BitBlockListeStartPtr=BlockListeStart[t];
   Page_x= Orginal[t].width;
   Page_y= Orginal[t].height;
   Page_Bytes_pro_Zeile = Orginal[t].bytes_per_line ;
   OrginalBildPuffer = Orginal[t].data ;
   Finde_SegmentBloecke();
   SegmenteStart[t]=SegmentBitBlockListeStartPtr;
}

void Ocr_SegmentStart()
{
 SegmentStart(); 
 OcrStart();
}

void LeseBMP(datei,tw)
char *datei;
long tw;
{
 long max_Bytes;
 char *Ptr,*Ptr1;
 long x,y,dx,dy,t;
 FILE *fd;
 unsigned char Header_Ptr[0x40];
 dx=0; dy=0;
 fd=fopen(datei,"rb"); 
 if (fd==NULL) return;
 fread(&Header_Ptr,  0x36, 1, fd);
 t=leselong(Header_Ptr+0x12);
 dx=t;
 if (t&31) { max_Bytes=(t>>5)*4+4; } else { max_Bytes=(t>>5)*4; }
 dy=leselong(Header_Ptr+0x14);
 if (dy==0) dy=leselong(Header_Ptr+0x16); 
 Orginal[tw].width=dx;
 Orginal[tw].height=dy;
 Orginal[tw].bytes_per_line=max_Bytes;
 Ptr=calloc(dy*max_Bytes,1) ; 
 if (Ptr==NULL) return;
 Orginal[tw].data=Ptr;
 if (Ptr==NULL) { MemoryError(); } 
 
 t=leselong(Header_Ptr+0x0A);
 fseek(fd,t,SEEK_SET);
 fread(Ptr,1,dy*max_Bytes,fd);
 Ptr1=Ptr;
 for (t=0;t<dy*max_Bytes;t++) { *Ptr1=~*Ptr1; Ptr1++; } 
 {
  char *P,*P1;
  char z;
  P=Ptr;
  P1=Ptr+(dy-1)*max_Bytes;
  for (y=0;y<(dy>>1);y++)
  {
   for (x=0;x<max_Bytes;x++)
   {
    z=*P;
    *P=*P1;
    *P1=z;
    P++;
    P1++;
   } 
   P1=P1-max_Bytes-max_Bytes;
  } 
 }
 fclose(fd); 

}


void LadeBitmap(Pfad)
char *Pfad;
{
 long t;
 t=0;
 LeseBMP(Pfad,0); 
 BitBlockListeStartPtr=NULL;
 Page_x= Orginal[t].width;
 Page_y= Orginal[t].height;
 Page_Bytes_pro_Zeile = Orginal[t].bytes_per_line ;
 OrginalBildPuffer = Orginal[t].data ;
 Finde_Bloecke();
 BlockListeStart[t]=BitBlockListeStartPtr;
 BitBlockListeStartPtr=NULL;
}

void MainInit()
{
 long t;
 t=0;
 {
   SegmenteStart[t]=NULL;
   BlockListeStart[t]=NULL;
   Bilder[t].width=0;
   Bilder[t].height=0;
   Bilder[t].data=NULL;
   Bilder[t].xoffset=0;
   Bilder[t].format=XYBitmap;
   Bilder[t].byte_order=MSBFirst;
   Bilder[t].bitmap_unit=8;
   Bilder[t].bitmap_bit_order=MSBFirst;
   Bilder[t].bitmap_pad=8;
   Bilder[t].depth=1;
   Bilder[t].bytes_per_line=0;
   Bilder[t].bits_per_pixel=1;
   Bilder[t].obdata=NULL;
   Bilder[t].red_mask=0;
   Bilder[t].blue_mask=0;
   Bilder[t].green_mask=0;
   Orginal[t].width=0;
   Orginal[t].height=0;
   Orginal[t].data=NULL;
   Orginal[t].xoffset=0;
   Orginal[t].format=XYBitmap;
   Orginal[t].byte_order=MSBFirst;
   Orginal[t].bitmap_unit=8;
   Orginal[t].bitmap_bit_order=MSBFirst;
   Orginal[t].bitmap_pad=8;
   Orginal[t].depth=1;
   Orginal[t].bytes_per_line=0;
   Orginal[t].bits_per_pixel=1;
   Orginal[t].obdata=NULL;
   Orginal[t].red_mask=0;
   Orginal[t].blue_mask=0;
   Orginal[t].green_mask=0;
 }
   Icon.width=16;
   Icon.height=16;
   Icon.data=NULL;
   Icon.xoffset=0;
   Icon.format=XYBitmap;
   Icon.byte_order=MSBFirst;
   Icon.bitmap_unit=8;
   Icon.bitmap_bit_order=MSBFirst;
   Icon.bitmap_pad=8;
   Icon.depth=1;
   Icon.bytes_per_line=2;
   Icon.bits_per_pixel=1;
   Icon.obdata=NULL;
   Icon.red_mask=0;
   Icon.blue_mask=0;
   Icon.green_mask=0;
}

/***************************************************************
Procedure        : void main()
****************************************************************/

int main (argc,argv)
 int  argc;        
 char *argv[];
{  
 long t;
 t=0;
 if (argc==3) t=1;
 if (argc==4) t=2;
 if (t==0) { fprintf(stderr,TEXT97,argv[0]); exit(-1); }
 makeBaum(argv[t]);
 
 MainInit(); 
 OcrInit();
 LadeBitmap(argv[t+1]);
 if (t==1)
 {
  OcrStart();
 } else
 {
  Ocr_SegmentStart();
 }
 return(0);
 }
