//---------------------------------------------------------------------------
/*  fnt_creator / fnt_crt_main.cpp

    Program for converting windows fonts or bitmaps,
    to FNT files used by the k/os mp3 player.

    16.09.2001: rd, ver.0.0.1 initial release.

    Copyright (c)2000 by Robert Dubber, dubber@chello.nl
                        Thomas Kindler, thomas.kindler@gmx.de

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License, or (at your option) any later version. Read the
    full License at http://www.gnu.org/copyleft for more details.
*/

#include <vcl.h>
#include <stdio.h>
#pragma hdrstop

#include "fnt_crt_main.h"
#include "about.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
Graphics::TBitmap *Bitmap1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}


void __fastcall TForm1::convChar(int left, int top, int w, int h)
{
 FontChar *fc = &font[numChars];
 memset(fc, 0, sizeof(FontChar));

 char *d = fc->bmBits;
 fc->w = w;
 fc->h = h;

 for (int y=0; y < h; y+= 8)
    for (int x=0; x < w; x++) {
      for (int b=0; b<8; b++)
      {
        if (Bitmap1->Canvas->Pixels[x+left][y+b+top] == clWhite)
        {
           *d |= 1<<b;
           Bitmap1->Canvas->Pixels[x+left][y+b+top] = clRed;
        }
      }
      *d++;
    }
 TRect rectangle;
 rectangle.Left = 0;
 rectangle.Top = 0;
 rectangle.Right = Image1->Width; //320*zoom;
 rectangle.Bottom = Image1->Height;//200*zoom;
 Image1->Canvas->StretchDraw(rectangle,Bitmap1);
}


//---------------------------------------------------------------------------
void __fastcall TForm1::Convert(void)
{
  numChars = 0;
  AnsiString tmp;

  for (int y=0; y < Bitmap1->Height; y++)  {
    int maxCh = 0;

    for (int x=0;  x < Bitmap1->Width; x++)  {
      int cw = 0, ch = 0;
      // find out width and height of the character
      //
      while (Bitmap1->Canvas->Pixels[x+cw][y] != clBlack && (x+cw < Bitmap1->Width))
        cw++;
      while (Bitmap1->Canvas->Pixels[x][y+ch] != clBlack && (y+ch < Bitmap1->Height))
        ch++;

      if (cw != 0 && ch != 0) {
        convChar(x, y, cw, ch);
        tmp.sprintf( "# %3d:  %d x %d pixels",numChars+opt_asciilow, cw, ch );
        Memo1->Lines->Add(tmp);
        numChars++;
      }

      // advance to next character, and note down the
      // maximum character height
      //
      x += cw;
      if (ch > maxCh) maxCh = ch;
    }

    // advance to the next line
    //
    y += maxCh;
    if (maxCh) Memo1->Lines->Add("");
  }

  tmp.sprintf("%d characters converted.", numChars);
  Memo1->Lines->Add(tmp);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::SaveBitmap1Click(TObject *Sender)
{
  if (SaveDialog1->Execute())
  {
    try
    {
        Bitmap1->SaveToFile(SaveDialog1->FileName);
        AnsiString fnt_filename = SaveDialog1->FileName;
        fnt_filename =  fnt_filename.SubString(1, fnt_filename.Length() -3) + "fnt";
    }
    catch (...)
    {
        ShowMessage("Error saving bitmap.");
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Bitmap1 = new Graphics::TBitmap();
    numChars = 0;
    Memo1->Clear();
    opt_asciilow = 32;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
    Bitmap1->ReleaseHandle();
    delete Bitmap1;
}

//---------------------------------------------------------------------------
void __fastcall TForm1::LoadBitmap1Click(TObject *Sender)
{
  TRect rectangle;

  if (OpenPictureDialog1->Execute())
  {
    try
    {
        Memo1->Clear();
        Bitmap1->LoadFromFile(OpenPictureDialog1->FileName);
        rectangle.Left = 0;
        rectangle.Top = 0;
        rectangle.Right = Image1->Width;
        rectangle.Bottom = Image1->Height;
        Image1->Canvas->StretchDraw(rectangle,Bitmap1);
        StatusBar1->SimpleText = "Bitmap loaded.";
    }
    catch (...)
    {
        ShowMessage("Error loading bitmap.");
    }
  }
}


//---------------------------------------------------------------------------
void __fastcall TForm1::New1Click(TObject *Sender)
{
  int xCharPosition=0;
  int yCharPosition=0;
  TSize char_size;
  int offset=0;
  TFontStyles stylefont;

  if (FontDialog1->Execute())
  {
    try
    {
        Memo1->Clear();
        TRect rectangle;

        rectangle.Left = 0;
        rectangle.Top = 0;
        rectangle.Right = 320;
        rectangle.Bottom = 200;

        stylefont = FontDialog1->Font->Style;
        Bitmap1->PixelFormat = (TPixelFormat)3;
        Bitmap1->Height = 200;
        Bitmap1->Width = 320;
        Bitmap1->Canvas->Brush->Color = clBlack;
        Bitmap1->Canvas->Rectangle(rectangle);
        Bitmap1->Canvas->Font = FontDialog1->Font;
        Bitmap1->Canvas->Brush->Color = (TColor) 0xFC5454;
        Bitmap1->Canvas->Font->Color = clWhite;

        if (stylefont.Contains(fsItalic))
        {
                char_size  =  Bitmap1->Canvas->TextExtent("A");
                offset += char_size.cx;
        }
        if (stylefont.Contains(fsBold))
        {
                char_size  =  Bitmap1->Canvas->TextExtent("A");
                offset += char_size.cx;
        }

        for (int y=0; y<6; y++)
        {
                for (int x=0; x<16; x++)
                {
                        AnsiString textStr;
                        textStr.printf("%c",x+(16*y)+32);
                        Bitmap1->Canvas->TextOut(xCharPosition,yCharPosition,textStr);
                        yCharPosition = Bitmap1->Canvas->PenPos.y;
                        char_size  =  Bitmap1->Canvas->TextExtent(textStr);
                        xCharPosition = xCharPosition + char_size.cx + 1 + offset;
                }
                xCharPosition = 0;
                yCharPosition = yCharPosition + char_size.cy + 2;
        }
        rectangle.Left = 0;
        rectangle.Top = 0;
        rectangle.Right = Image1->Width;
        rectangle.Bottom = Image1->Height;
        Image1->Canvas->StretchDraw(rectangle,Bitmap1);
        StatusBar1->SimpleText = "Font created.";
    }
    catch (...)
    {
        ShowMessage("Error creating new font.");
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
   Close();
}
//---------------------------------------------------------------------------
unsigned __fastcall TForm1::imagesize(int w, int h)
{
  return w * ((h + 7)/8)+4;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Save()
{
  FILE *f = fopen(opt_fontfile.c_str(), "wb");
  if (!f) {
    perror("");
    return;
  }

  fwrite(&numChars,     sizeof(numChars), 1, f);
  fwrite(&opt_asciilow, sizeof(numChars), 1, f);

  for (int i=0; i<numChars; i++)
    fwrite(&font[i], imagesize(font[i].w, font[i].h), 1, f);
  fclose(f);
  StatusBar1->SimpleText = "Bitmap saved.";
}

//---------------------------------------------------------------------------
void __fastcall TForm1::ExportFnt1Click(TObject *Sender)
{
  TRect rectangle;

  if (Bitmap1->Empty) {
        ShowMessage("Nothing to create.");
        return;
  }


  if (SaveDialog2->Execute())
  {
    try
    {
        Memo1->Clear();
        Bitmap1->SaveToFile(SaveDialog2->FileName);
        AnsiString fnt_filename = SaveDialog2->FileName;
        opt_fontfile =  fnt_filename.SubString(1, fnt_filename.Length() -3) + "fnt";
        Convert();
        Save();
        StatusBar1->SimpleText = "FNT file saved.";
    }
    catch (...)
    {
        ShowMessage("Error creating /saving FNT file.");
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::About1Click(TObject *Sender)
{
        Form2->ShowModal();
}
//---------------------------------------------------------------------------

