// This sourcefile is created by Peter Jodda / peter@jodda.de
// It is under the Peter Jodda license:
// Everyboy may use it on his own risk. This header must stay in the file!
// If you expand this file, please contact me, that I can integrate the
// enhancemants in the original file.
//

// textgen.c 
// text-file generator

#include <string.h>
#include <stdio.h>
#include <stdlib.h>


#define MAX_ZEILE 500
#define INDEX_SIZE 4

class einText
{
   public:
      int nummer;
      int laenge;
      char string[255];
      class einText* nachfolger;
      
};



//---------------------------------------------------------


einText *textWurzel,*textEnde;
int hoechsteNummer;
int anzahlTexte;
int textGesamtLaenge;

unsigned char *textImage;
size_t   textImageGroesse;

//---------------------------------------------------------

static void haengeInListe(int nummer,char *text)
{
   einText *neuerText;

#ifdef DEBUG_AUSGABE   
   fprintf(stderr,"haenge in liste %d %s\n",nummer,text);   
#endif   
   // textelement erzeugen
   neuerText    = new einText;  
   anzahlTexte += 1;

   neuerText->nummer     = nummer;
   neuerText->laenge     = strlen(text);
   neuerText->nachfolger = NULL;
   strcpy(neuerText->string,text);
   
   textGesamtLaenge += neuerText->laenge + 1 ;
   
   // in liste einhaengen
   if(textWurzel==NULL)
   {
      // erste element
      hoechsteNummer = nummer;
      textWurzel = textEnde = neuerText;
      return;
   }
   if(nummer >hoechsteNummer)
   {
      // ans ende haengen
      textEnde->nachfolger = neuerText;      
      textEnde = neuerText;
      hoechsteNummer = nummer;
   }
   else   
   {
      // irgendwo in die mitte packen
      einText *aktuell,*vorgaenger;
      
      vorgaenger = NULL;
      aktuell = textWurzel;
      while(aktuell->nummer < nummer && aktuell != NULL)
      {
         vorgaenger = aktuell;
         aktuell    = aktuell->nachfolger;
      }
      if(vorgaenger != NULL)
      {
         vorgaenger ->nachfolger = neuerText;
         neuerText->nachfolger = aktuell;
      }
      else
      {
         // doch vorne rein 
         neuerText->nachfolger = textWurzel;
         textWurzel = neuerText;
      }
   }

}
//---------------------------------------------------------

static void prozessZeile(char *leseBuffer)
{
   int nummer;
   char *inBuffer,*inText;
   char text[MAX_ZEILE];
   
   inBuffer=leseBuffer;
   nummer =0;
   while(*inBuffer>='0' && *inBuffer<='9')
   {
      nummer=nummer*10 + (int)(*inBuffer - '0');
      inBuffer++;
   }
   
   while(*inBuffer !='\'' && *inBuffer !='\0')
      inBuffer++;
   if(*inBuffer =='\0')
      return;
   inBuffer ++;
   
   inText = text;
   while(*inBuffer !='\'' && *inBuffer !='\0')
   {
      *inText++ = *inBuffer++;
   }
   *inText ='\0';
   haengeInListe(nummer,text);
}

//---------------------------------------------------------

void leseTexte(char *dateiname)
{
   FILE *infile;
   char leseBuffer[MAX_ZEILE+1],*gelesen;

   infile = fopen(dateiname,"r");
   if(infile ==NULL)
      return ;

   gelesen = fgets(leseBuffer,MAX_ZEILE,infile);


   while(gelesen != NULL)
   {
      leseBuffer[MAX_ZEILE] = '\0';

      if(leseBuffer[0] >= '0' && leseBuffer[0] <= '9')
      {
         // ziffer am anfang, eine gueltige zeile
         prozessZeile(leseBuffer);
      }

      // naechste zeile lesen 
      gelesen = fgets(leseBuffer,MAX_ZEILE,infile);
   }
   
         
   fclose(infile);
}


//---------------------------------------------------------

static void writeInt(unsigned char *buffer,int wert)
{
   *buffer ++ = (unsigned char) (wert &0xff);
   wert >>= 8;
   *buffer ++ = (unsigned char) (wert &0xff);
   wert >>= 8;
   *buffer ++ = (unsigned char) (wert &0xff);
   wert >>= 8;
   *buffer ++ = (unsigned char) (wert &0xff);
}

//---------------------------------------------------------

static void generateTextImage()
{
   unsigned char *inImage,*inImageText;
   int i;
   int aktuellOffset;
   einText *aktuell;
   int slots;
   
   slots = hoechsteNummer+1;
   
   textImageGroesse  = INDEX_SIZE +INDEX_SIZE; // offset start + #texte
   textImageGroesse += INDEX_SIZE*slots;       // texte ptr ab start
   textImageGroesse += textGesamtLaenge;       // texte dazu
   
fprintf(stderr,"try to alloc %d bytes\n",textImageGroesse);   
   textImage = (unsigned char *) malloc(textImageGroesse);
   if(textImage ==NULL) 
      return;

   inImage=textImage;

   writeInt(inImage,INDEX_SIZE+INDEX_SIZE+INDEX_SIZE*slots);
   inImage += INDEX_SIZE;
   writeInt(inImage,slots);
   inImage += INDEX_SIZE;

   inImageText = &textImage[INDEX_SIZE+INDEX_SIZE+INDEX_SIZE*slots];

   aktuell=textWurzel;
   aktuellOffset=0;
   for(i=0;i<slots;i++)
   {
      // for alle texte
      if(aktuell != NULL && aktuell->nummer == i)
      {
         writeInt(inImage,aktuellOffset);
         inImage += INDEX_SIZE;
         strcpy((char *) inImageText,aktuell->string);
         inImageText   += aktuell->laenge + 1;
         aktuellOffset += aktuell->laenge + 1;
         aktuell=aktuell->nachfolger;
      }
      else
      {
         writeInt(inImage, -1);
         inImage += INDEX_SIZE;
      }
      
   } // for i


}

//---------------------------------------------------------

static void erzeugeAusgabe()
{
   char outname[]="text_data.c";
   FILE *outfile;
   unsigned char zeichen;
   int anzahl;
   int i;
   
   outfile = fopen(outname,"w");
   if(outfile ==NULL)
   {
      return;
   }
   fprintf(outfile,"/* definition der text-daten */\n\n");
   fprintf(outfile,"unsigned char text_memory_datei[] = {\n ");


   for(i=0;i<textImageGroesse;i++)
   {
      zeichen = textImage[i];
      fprintf(outfile,"0x%02x,",zeichen);
      anzahl++;
      if(anzahl>12)
      {
         anzahl=0;
         fprintf(outfile,"\n ");
      }  
   }
   fprintf(outfile," 0\n");
   fprintf(outfile," };\n");
   fprintf(outfile,"void * TextDataGetData(void)\n");
   fprintf(outfile," {\n");
   fprintf(outfile,"  return (void *) text_memory_datei;\n }\n\n");       
}

//----------------------------------------------------------------

int main(int anzahl, char *zeichen[])
{
   if(anzahl <2)
      return -1;

   // ein paar inititalisierungen
   textWurzel       = NULL;
   textEnde         = NULL;
   hoechsteNummer   =-1;
   anzahlTexte      = 0;
   textGesamtLaenge = 0;
   textImage        = NULL;
   textImageGroesse = 0;
      
   leseTexte(zeichen[1]); // texte einlesen

   fprintf(stderr,"%d texte gelesen, hoechsteNummer =%d, gesamtlaenge =%d\n",
   		anzahlTexte,hoechsteNummer,textGesamtLaenge);

   generateTextImage();

   erzeugeAusgabe();

   return 0;
}
