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

#include <vcl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <dir.h>
#pragma hdrstop

#include "main.h"
#include "inifiles.hpp"
#include "obj_label.h"
#include "obj_icon.h"
#include "obj_screen.h"
#include "obj_frame.h"
#include "GForm.h"
#include "OFDform.h"
#include "AForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMForm *MForm;

AnsiString apppath=GetCurrentDir();
AnsiString genpath=apppath;
AnsiString genpathimg=apppath;
AnsiString SFDpath;

TIniFile *ini=new TIniFile(apppath+"\\config.ini");

int wbmp[128][240];
TNewObj NewObj;

TProject *Project=NULL;
int screen;
int object;

TFonts *Fonts=NULL;

TMoveRec MoveRec[512];
int MoveRecN;
TMoveRec MovePts[512];
int MovePtsN;
int MovePtsS;

TSelObjs	SelObjs[512];
int SelObjsN;

bool edit=false;

bool exitting=false;

int buttonst=0x00000000;




//==============================================================================
// main
//==============================================================================
__fastcall TMForm::TMForm(TComponent* Owner)
	: TForm(Owner)
{
}

//==============================================================================
// show form
//==============================================================================
void __fastcall TMForm::FormShow(TObject *Sender)
{
	wimg->Picture->Bitmap->Width=XRES*2;
	wimg->Picture->Bitmap->Height=YRES*2;
	wimg->Picture->Bitmap->PixelFormat=pf24bit;

	LoadFonts();

	MBtnScrEdit->Enabled=false;

	MBtnClose->Enabled=false;
	MBtnSave->Enabled=false;
	MBtnScrDelete->Enabled=false;
	MForm->BtnDeleteScreen->Enabled=false;

	RefreshScreenList();

	NewObj.xr=0;
	NewObj.yr=0;
	ObjEditEnable(false);

	// load setting from ini
	// main
	OD1->InitialDir=ini->ReadString("MAIN","open_save_project","");
	SD1->InitialDir=OD1->InitialDir;
	// icon
	OiconForm->OPD1->InitialDir=ini->ReadString("ICON","icon_save_open_path","");
	OiconForm->SPD1->InitialDir=OiconForm->OPD1->InitialDir;
	OiconForm->RbDT->Checked=ini->ReadBool("ICON","transform_method",0);
	OiconForm->RbED->Checked=!OiconForm->RbDT->Checked;
	// generate
	genpath=ini->ReadString("GENERATE","generate_sources_path","");
	genpathimg=ini->ReadString("GENERATE","generate_images_path","");
	GenForm->CbGenScr->Checked=ini->ReadBool("GENERATE","gen_screens",1);
	GenForm->CbGenScrShittyKeil->Checked=ini->ReadBool("GENERATE","gen_screens_shitty_keil",1);
	GenForm->CbGenFont->Checked=ini->ReadBool("GENERATE","gen_fonts",1);
	GenForm->CbGenGUI->Checked=ini->ReadBool("GENERATE","gen_GUI",1);
	GenForm->CbGenTxtGrph->Checked=ini->ReadBool("GENERATE","gen_text_graphics",1);
	GenForm->CbGenLCD->Checked=ini->ReadBool("GENERATE","gen_LCD",1);
	GenForm->CbGenMODBUS->Checked=ini->ReadBool("GENERATE","gen_MODBUS",1);
	GenForm->CbAsk->Checked=ini->ReadBool("GENERATE","gen_ask_rewrite",0);

	Timer1->Enabled=true;
}

//==============================================================================
// close form
//==============================================================================
void __fastcall TMForm::MBtnExitClick(TObject *Sender)
{
	MForm->Close();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::FormClose(TObject *Sender, TCloseAction &Action)
{
	exitting=true;
	MBtnClose->Click();
	RemoveAllFonts();

	// save settings to ini
	// main
	ini->WriteString("MAIN","open_save_project",OD1->InitialDir);
	// icon
	ini->WriteString("ICON","icon_save_open_path",OiconForm->OPD1->InitialDir);
	ini->WriteBool("ICON","transform_method",OiconForm->RbDT->Checked);
	// generate
	ini->WriteString("GENERATE","generate_sources_path",genpath);
	ini->WriteString("GENERATE","generate_images_path",genpathimg);
	ini->WriteBool("GENERATE","gen_screens",GenForm->CbGenScr->Checked);
	ini->WriteBool("GENERATE","gen_screens_shitty_keil",GenForm->CbGenScrShittyKeil->Checked);
	ini->WriteBool("GENERATE","gen_fonts",GenForm->CbGenFont->Checked);
	ini->WriteBool("GENERATE","gen_GUI",GenForm->CbGenGUI->Checked);
	ini->WriteBool("GENERATE","gen_text_graphics",GenForm->CbGenTxtGrph->Checked);
	ini->WriteBool("GENERATE","gen_LCD",GenForm->CbGenLCD->Checked);
	ini->WriteBool("GENERATE","gen_MODBUS",GenForm->CbGenMODBUS->Checked);
	ini->WriteBool("GENERATE","gen_ask_rewrite",GenForm->CbAsk->Checked);

	delete(ini);
}
//==============================================================================
// about
//==============================================================================
void __fastcall TMForm::MbtnAboutClick(TObject *Sender)
{
	About_form->ShowModal();
}
//==============================================================================
// about timeout
//==============================================================================
void __fastcall TMForm::Timer1Timer(TObject *Sender)
{
	Timer1->Enabled=false;
	if(Timer1->Interval==2000)
		About_form->Close();
	else
	{
		Timer1->Interval=2000;
		Timer1->Enabled=true;
		About_form->Show();
	}


}








//**************************************************************
//**************************************************************
//******************** WORK IMAGE FUNCTIONS ********************
//**************************************************************
//**************************************************************

//==============================================================================
// work image mouse move
//==============================================================================
void __fastcall TMForm::wimgMouseMove(TObject *Sender, TShiftState Shift, int X,
			int Y)
{
	int x=X>>1,y=Y>>1;
	SB1->Panels->Items[0]->Text="x="+IntToStr(x)+", y="+IntToStr(y);

	if(Shift.Contains(ssLeft))
	{
		switch(NewObj.obj)
		{
			case obLine:
			case obFrame:
				if(NewObj.state==obsDown)
				{
					NewObj.xb=x<0?0:(x>239?239:x);
					NewObj.yb=y<0?0:(y>127?127:y);
				}
				break;
			case obLabel:
				if(NewObj.state==obsDown)
				{
					if((y+Fonts->font[NewObj.font].yres)>128) y=128-Fonts->font[NewObj.font].yres;
					if(y<0) y=0;
					NewObj.xb=x<0?0:(x>239?239:x);
					NewObj.yb=y;
				}
				break;
			case obIcon:
				if(NewObj.state==obsDown)
				{
					x>>=3;
					if((x*8+NewObj.xr)>240) x=(240-NewObj.xr)>>3;
					if(x<0) x=0;
					x*=8;
					if((y+NewObj.yr)>128) y=128-NewObj.yr;
					if(y<0) y=0;
					NewObj.xb=x;
					NewObj.yb=y;
				}
				break;
			case obMove:
				if(NewObj.state==obsMove)
				{
					if(MovePts[MovePtsS].type==obIcon)
						NewObj.dx=((x-NewObj.xa)>>3)*8;
					else
						NewObj.dx=x-NewObj.xa;

					NewObj.dy=y-NewObj.ya;
					if(Shift.Contains(ssCtrl))
					{
						NewObj.dx2+=x-NewObj.xb;
						NewObj.dy2+=y-NewObj.yb;
					}
					NewObj.xb=x;
					NewObj.yb=y;

				}
				break;
			case obSelect:
				if(NewObj.state==obsDown)
				{
					NewObj.xb=x;
					NewObj.yb=y;
				}
				if(NewObj.state==obsMove)
				{
					NewObj.dx=x-NewObj.xa;
					NewObj.dy=y-NewObj.ya;
				}
				break;
		}
	}
	PaintWorkImg();
}

//==============================================================================
// work image mouse down
//==============================================================================
void __fastcall TMForm::wimgMouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	int x=X>>1,y=Y>>1;

	if(Shift.Contains(ssLeft))
	{
		switch(NewObj.obj)
		{
			case obLine:
			case obFrame:
			case obLabel:
				if(NewObj.state==obsNone)
				{
					OlabelForm->Close();
					OiconForm->Close();
					OframeForm->Close();

					NewObj.xb=NewObj.xa=x;
					NewObj.yb=NewObj.ya=y;
					NewObj.state=obsDown;
				}
				break;
			case obIcon:
				if(NewObj.state==obsNone)
				{
					OlabelForm->Close();
					OiconForm->Close();
					OframeForm->Close();

					NewObj.xb=NewObj.xa=(x>>3)*8;
					NewObj.yb=NewObj.ya=y;
					NewObj.state=obsDown;
				}
				break;
			case obMove:
				if(NewObj.state==obsNone)
				{
					NewObj.xa=x;
					NewObj.ya=y;
					NewObj.state=obsUp;
					FindObject2move();
					if(MovePtsN!=0)
					{
						ObjEditEnable(true);
					}
				}
				else if(NewObj.state==obsMoveSelect)
				{
					NewObj.dx=0;
					NewObj.dy=0;
					NewObj.dx2=0;
					NewObj.dy2=0;
					NewObj.xa=x;
					NewObj.ya=y;
					NewObj.xb=x;
					NewObj.yb=y;
					NewObj.state=obsMove;
				}
				break;
			case obSelect:
				if(NewObj.state==obsNone)
				{
					NewObj.xa=NewObj.xb=x;
					NewObj.ya=NewObj.yb=y;
					NewObj.state=obsDown;
				}
				if(NewObj.state==obsSelect)
				{
					NewObj.dx=0;
					NewObj.dy=0;
					NewObj.xa=x;
					NewObj.ya=y;
					NewObj.state=obsMove;
				}
				break;
		}
	}
	else if(Shift.Contains(ssRight))
	{
		switch(NewObj.obj)
		{
			case obMove:
				if(NewObj.state==obsMoveSelect)
				{
					MovePtsS++;
					if(MovePtsS>=MovePtsN)
						MovePtsS=0;

					if(edit==true)
						OlabelForm->BtnCancel->Click();
				}
				break;
		}
	}
	PaintWorkImg();
}

//==============================================================================
// work image mouse up
//==============================================================================
void __fastcall TMForm::wimgMouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	int x=X>>1,y=Y>>1;
	int Ax,Ay,Bx,By;
	unsigned char *isrc;
	void *obj;
	int i,j;

	if(/*Shift.Contains(ssLeft)*/true)
	{
		switch(NewObj.obj)
		{
			case obLine:
				if(NewObj.state==obsDown)
				{
					NewObj.xb=x<0?0:(x>239?239:x);
					NewObj.yb=y<0?0:(y>127?127:y);
					NewObj.state=obsNone;

					if(NewObj.xb!=NewObj.xa || NewObj.yb!=NewObj.ya)
					{
						CreateObjLine();
						((TObjLine*)(Project->scr[screen].obj[object].objptr))->Ax=NewObj.xa;
						((TObjLine*)(Project->scr[screen].obj[object].objptr))->Ay=NewObj.ya;
						((TObjLine*)(Project->scr[screen].obj[object].objptr))->Bx=NewObj.xb;
						((TObjLine*)(Project->scr[screen].obj[object].objptr))->By=NewObj.yb;
					}
				}
				break;
			case obFrame:
				if(NewObj.state==obsDown)
				{
					NewObj.xb=x<0?0:(x>239?239:x);
					NewObj.yb=y<0?0:(y>127?127:y);
					NewObj.state=obsNone;

					if(NewObj.xb!=NewObj.xa || NewObj.yb!=NewObj.ya)
					{
						Ax=NewObj.xa;
						Bx=NewObj.xb;
						Ay=NewObj.ya;
						By=NewObj.yb;
						if(Ax>Bx) {j=Ax;Ax=Bx;Bx=j;}
						if(Ay>By) {j=Ay;Ay=By;By=j;}
						CreateObjFrame();
						((TObjFrame*)(Project->scr[screen].obj[object].objptr))->Ax=Ax;
						((TObjFrame*)(Project->scr[screen].obj[object].objptr))->Ay=Ay;
						((TObjFrame*)(Project->scr[screen].obj[object].objptr))->Bx=Bx;
						((TObjFrame*)(Project->scr[screen].obj[object].objptr))->By=By;
						((TObjFrame*)(Project->scr[screen].obj[object].objptr))->style=NewObj.style;
					}

					NewObj.obj=obNone;
					NewObj.state=obsNone;
				}
				break;
			case obLabel:
				if(NewObj.state==obsDown)
				{
					if((y+Fonts->font[NewObj.font].yres)>128) y=128-Fonts->font[NewObj.font].yres;
					if(y<0) y=0;
					NewObj.xb=x<0?0:(x>239?239:x);
					NewObj.yb=y;
					NewObj.state=obsNone;

					CreateObjLabel();
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->Ax=NewObj.xb;
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->Ay=NewObj.yb;
					EditObjCstr(&(((TObjLabel*)(Project->scr[screen].obj[object].objptr))->str),NewObj.str);
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->font=NewObj.font;
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->btn=NewObj.btn;
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->btnact=NewObj.btnact;
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->btnanim=NewObj.btnanim;
					((TObjLabel*)(Project->scr[screen].obj[object].objptr))->btnactscr=NewObj.btnactscr;

					NewObj.obj=obNone;
					NewObj.state=obsNone;
				}
				break;
			case obIcon:
				if(NewObj.state==obsDown)
				{
					x>>=3;
					if((x*8+NewObj.xr)>240) x=(240-NewObj.xr)>>3;
					if(x<0) x=0;
					x*=8;
					if((y+NewObj.yr)>128) y=128-NewObj.yr;
					if(y<0) y=0;
					NewObj.xb=x;
					NewObj.yb=y;
					NewObj.state=obsNone;

					if(NewObj.xr!=0 && NewObj.yr!=0)
					{
						CreateObjIcon();
						((TObjIcon*)(Project->scr[screen].obj[object].objptr))->Ax=NewObj.xb;
						((TObjIcon*)(Project->scr[screen].obj[object].objptr))->Ay=NewObj.yb;
						((TObjIcon*)(Project->scr[screen].obj[object].objptr))->xr=NewObj.xr;
						((TObjIcon*)(Project->scr[screen].obj[object].objptr))->yr=NewObj.yr;
						isrc=((TObjIcon*)(Project->scr[screen].obj[object].objptr))->srcimg=(unsigned char*)malloc(sizeof(unsigned char)*(NewObj.xr)*(NewObj.yr));
						for(i=0;i<NewObj.yr;i++)
							memcpy((void*)(isrc+NewObj.xr*i),(void*)(&NewObj.srcimg[i][0]),NewObj.xr);
						isrc=((TObjIcon*)(Project->scr[screen].obj[object].objptr))->destimg=(unsigned char*)malloc(sizeof(unsigned char)*(NewObj.xr)*(NewObj.yr));
						for(i=0;i<NewObj.yr;i++)
							memcpy((void*)(isrc+NewObj.xr*i),(void*)(&NewObj.destimg[i][0]),NewObj.xr);
					}

					NewObj.obj=obNone;
					NewObj.state=obsNone;
				}
				break;
			case obMove:
				if(NewObj.state==obsMove)
				{
					Ax=Ay=Bx=By=0;
					if(MovePts[MovePtsS].pt==1)
					{
						Ax+=NewObj.dx;
						Ay+=NewObj.dy;
						Bx+=NewObj.dx2;
						By+=NewObj.dy2;
					}
					else if(MovePts[MovePtsS].pt==2)
					{
						Bx+=NewObj.dx;
						By+=NewObj.dy;
						Ax+=NewObj.dx2;
						Ay+=NewObj.dy2;
					}

					switch(MovePts[MovePtsS].type)
					{
						case obLine:
							((TObjLine*)(MovePts[MovePtsS].ptr))->Ax+=Ax;
							((TObjLine*)(MovePts[MovePtsS].ptr))->Ay+=Ay;
							((TObjLine*)(MovePts[MovePtsS].ptr))->Bx+=Bx;
							((TObjLine*)(MovePts[MovePtsS].ptr))->By+=By;
							break;
						case obFrame:
							((TObjFrame*)(MovePts[MovePtsS].ptr))->Ax+=Ax;
							((TObjFrame*)(MovePts[MovePtsS].ptr))->Ay+=Ay;
							((TObjFrame*)(MovePts[MovePtsS].ptr))->Bx+=Bx;
							((TObjFrame*)(MovePts[MovePtsS].ptr))->By+=By;
							break;
						case obLabel:
							((TObjLabel*)(MovePts[MovePtsS].ptr))->Ax+=Ax;
							((TObjLabel*)(MovePts[MovePtsS].ptr))->Ay+=Ay;
							break;
						case obIcon:
							((TObjIcon*)(MovePts[MovePtsS].ptr))->Ax+=Ax;
							((TObjIcon*)(MovePts[MovePtsS].ptr))->Ay+=Ay;
							break;
					}
					NewObj.state=obsNone;
					ObjEditEnable(false);
				}
				break;
			case obSelect:
				if(NewObj.state==obsDown)
				{
					NewObj.xb=x;
					NewObj.yb=y;
					FindObjects2move();
					if(SelObjsN!=0)
					{
						MForm->MBtnObjDelete->Enabled=true;
					}
				}
				if(NewObj.state==obsMove)
				{
					for(i=0;i<SelObjsN;i++)
					{
						obj=SelObjs[i].ptr;
						switch(SelObjs[i].type)
						{
							case obLine:
								((TObjLine*)(obj))->Ax+=NewObj.dx;
								((TObjLine*)(obj))->Ay+=NewObj.dy;
								((TObjLine*)(obj))->Bx+=NewObj.dx;
								((TObjLine*)(obj))->By+=NewObj.dy;
								break;
							case obFrame:
								((TObjFrame*)(obj))->Ax+=NewObj.dx;
								((TObjFrame*)(obj))->Ay+=NewObj.dy;
								((TObjFrame*)(obj))->Bx+=NewObj.dx;
								((TObjFrame*)(obj))->By+=NewObj.dy;
								break;
							case obLabel:
								((TObjFrame*)(obj))->Ax+=NewObj.dx;
								((TObjFrame*)(obj))->Ay+=NewObj.dy;
								break;
							case obIcon:
								((TObjIcon*)(obj))->Ax+=((NewObj.dx)>>3)*8;
								((TObjIcon*)(obj))->Ay+=NewObj.dy;
								break;
						}
					}
					NewObj.state=obsNone;
					ObjEditEnable(false);
				}
				break;
		}
	}
	PaintWorkImg();
}










//*************************************************************
//*************************************************************
//******************** GRAPHICAL FUNCTIONS ********************
//*************************************************************
//*************************************************************
//==============================================================================
// draw text string
//==============================================================================
void DrawText(int x, int y, int font, int color, int bcolor, char *str, int action)
{
	int i,j;
	int yr,xr;

	yr=Fonts->font[font].yres;

	if((x-2)<0)
		action=0;
	else if(action!=0)
	{
		for(j=1;j<yr;j++)
		{
			if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
				wbmp[y+j][x-2]=color;
		}
		for(j=0;j<yr+1;j++)
		{
			if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
				wbmp[y+j][x-1]=color;
		}
	}

	while(*str!='\0')
	{
		xr=Fonts->font[font].data[(unsigned char)*str].xres;
		if((x+xr+1)>239)
		{
			x=0;
			y+=yr;
		}
		if(action==0)
		{
			for(i=0;i<xr;i++)
			{
				for(j=0;j<yr;j++)
				{
					if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
					{
						if(Fonts->font[font].data[(unsigned char)*str].img[i][j]!=0x00)
							wbmp[y+j][x]=color;
						else if(bcolor!=-1)
							wbmp[y+j][x]=bcolor;
					}
				}
				x++;
			}
		}
		else
		{
			for(i=0;i<xr;i++)
			{
				for(j=0;j<yr+1;j++)
				{
					if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
					{
						if(Fonts->font[font].data[(unsigned char)*str].img[i][j]!=0x00)
							wbmp[y+j][x]=clWhite;
						else
							wbmp[y+j][x]=color;
					}
				}
				x++;
			}
			for(j=0;j<yr+1;j++)
			{
				if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
					wbmp[y+j][x]=color;
			}
		}
		x++;
		str++;
	}

	if(action!=0)
	{
		for(j=1;j<yr;j++)
		{
			if(x>=0 && x<240 && (y+yr)<129 && (y+j)>0)
				wbmp[y+j][x]=color;
		}
	}
}

//==============================================================================
// draw image
//==============================================================================
void DrawImg(int x, int y, int color, int bcolor, int src, TObjIcon *obj)
{
	int i,j;

	if(src==0)
	{
		for(i=x;i<x+NewObj.xr;i++)
			if(i>=0 && i<XRES)
				for(j=y;j<y+NewObj.yr;j++)
					if(j>=0 && j<YRES)
					{
						if(NewObj.destimg[j-y][i-x]==0x00)
							wbmp[j][i]=color;
						else
							wbmp[j][i]=bcolor;
					}
	}
	else
	{
		unsigned char *icon=obj->destimg;
		int xr=obj->xr;
		int yr=obj->yr;

		for(i=x;i<x+xr;i++)
			if(i>=0 && i<XRES)
				for(j=y;j<y+yr;j++)
					if(j>=0 && j<YRES)
					{
						if(icon[(i-x) + (j-y)*xr]==0x00)
							wbmp[j][i]=color;
						else
							wbmp[j][i]=bcolor;
					}
	}
}

//==============================================================================
// dral line from A to B
//==============================================================================
void DrawLine(int Ax, int Ay, int Bx, int By, int color)
{
	int temp;
	int dx,dy;
	int ystep;
	int i;


	if(((unsigned int)(Ax)>=XRES && (unsigned int)(Bx)>=XRES) || ((unsigned int)(Ay)>=YRES && (unsigned int)(By)>=YRES))
		return;

	// switch into I.Q or IV.Q
	if(Ax>Bx)
	{
		temp=Ax;
		Ax=Bx;
		Bx=temp;
		temp=Ay;
		Ay=By;
		By=temp;
	}

	dx=Bx-Ax;
	dy=By-Ay;

	if(dy>0)
		ystep=1;
	else
	{
		ystep=-1;
		dy=-dy;
	}

	if(dx>=dy)
	{
		temp=dx;
		for(i=0;i<=dx;i++)
		{
			if((unsigned int)(Ax)<XRES && (unsigned int)(Ay)<YRES)
				wbmp[Ay][Ax]=color;
			temp-=(dy+1);
			if(temp<0)
			{
				temp+=(dx+1);
				Ay+=ystep;
			}
			Ax++;
		}
	}
	else
	{
		temp=dy;
		for(i=0;i<=dy;i++)
		{
			if((unsigned int)(Ax)<XRES && (unsigned int)(Ay)<YRES)
				wbmp[Ay][Ax]=color;
			temp-=(dx+1);
			if(temp<0)
			{
				temp+=(dy+1);
				Ax++;
			}
			Ay+=ystep;
		}
	}
}

//==============================================================================
// paint work image
//==============================================================================
void PaintWorkImg(void)
{
	void *obj;
	int i,j,k;
	int Ax,Ay,Bx,By;
	int color,bcolor;
	int style;

	// clear image
	memset((void*)wbmp,0xFF,XRES*YRES*sizeof(int));

	if(Project!=NULL && Project->screens!=0)
	{

		Ax=NewObj.xa;
		Ay=NewObj.ya;
		Bx=NewObj.xb;
		By=NewObj.yb;
		switch(NewObj.obj)
		{
			case obLine:
				if(NewObj.state!=obsNone)
					DrawLine(Ax,Ay,Bx,By,0xCC5500);
				break;
			case obFrame:
				if(NewObj.state!=obsNone)
				{
					if(Ax>Bx) {j=Ax;Ax=Bx;Bx=j;}
					if(Ay>By) {j=Ay;Ay=By;By=j;}

					if(NewObj.style==fstFilled)
					{
						for(k=Ay;k<=By;k++)
							for(j=Ax;j<=Bx;j++)
								wbmp[k][j]=0xCC5500;
					}
					else
					{
						DrawLine(Ax,Ay,Bx,Ay,0xCC5500);
						DrawLine(Ax,By,Bx,By,0xCC5500);
						DrawLine(Ax,Ay,Ax,By,0xCC5500);
						DrawLine(Bx,Ay,Bx,By,0xCC5500);
						if(NewObj.style==fstDouble)
						{
							Ax+=2;Ay+=2;Bx-=2;By-=2;
							DrawLine(Ax,Ay,Bx,Ay,0xCC5500);
							DrawLine(Ax,By,Bx,By,0xCC5500);
							DrawLine(Ax,Ay,Ax,By,0xCC5500);
							DrawLine(Bx,Ay,Bx,By,0xCC5500);
						}
					}
				}
				break;
			case obLabel:
				if(NewObj.state!=obsNone)
					DrawText(Bx,By,NewObj.font,0xCC5500,0xDDDDF2,NewObj.str,(NewObj.btnanim==bcaYes)&&(NewObj.btnact!=atNone));
				break;
			case obIcon:
				if(NewObj.state!=obsNone && NewObj.xr!=0 && NewObj.yr!=0)
				{
					DrawImg(Bx,By,0xCC5500,0xDDDDF2,0,NULL);
				}
				break;
			case obSelect:
				if(NewObj.state==obsDown)
				{
					DrawLine(Ax,Ay,Bx,Ay,0x55CC00);
					DrawLine(Ax,By,Bx,By,0x55CC00);
					DrawLine(Ax,Ay,Ax,By,0x55CC00);
					DrawLine(Bx,Ay,Bx,By,0x55CC00);
				}
				break;
		}


		for(i=0;i<Project->scr[screen].objects;i++)
		{
			obj=Project->scr[screen].obj[i].objptr;
			color=0x000000;
			bcolor=-1;
			Ax=Ay=Bx=By=0;

			if(obj==MovePts[MovePtsS].ptr && NewObj.obj==obMove && (NewObj.state==obsMoveSelect || NewObj.state==obsMove))
			{
				color=0xCC5500;
				bcolor=0xDDDDF2;
				if(NewObj.state==obsMove)
				{
					if(MovePts[MovePtsS].pt==1)
					{
						Ax=NewObj.dx;
						Ay=NewObj.dy;
						Bx=NewObj.dx2;
						By=NewObj.dy2;

					}
					else if(MovePts[MovePtsS].pt==2)
					{
						Bx=NewObj.dx;
						By=NewObj.dy;
						Ax=NewObj.dx2;
						Ay=NewObj.dy2;
					}
				}
			}
			else if(NewObj.obj==obSelect && (NewObj.state==obsSelect || NewObj.state==obsMove))
			{
				if(ObjIsSelMember(obj))
				{
					color=0xCC5500;
					bcolor=0xDDDDF2;
					if(NewObj.state==obsMove)
					{
						Ax=Bx=NewObj.dx;
						Ay=By=NewObj.dy;
					}
				}
			}

			switch(Project->scr[screen].obj[i].type)
			{
				case obLine:
					Ax+=((TObjLine*)obj)->Ax;
					Ay+=((TObjLine*)obj)->Ay;
					Bx+=((TObjLine*)obj)->Bx;
					By+=((TObjLine*)obj)->By;
					DrawLine(Ax,Ay,Bx,By,color);
					break;
				case obFrame:
					Ax+=((TObjFrame*)obj)->Ax;
					Ay+=((TObjFrame*)obj)->Ay;
					Bx+=((TObjFrame*)obj)->Bx;
					By+=((TObjFrame*)obj)->By;

					if(edit==true && obj==MovePts[MovePtsS].ptr)
						style=NewObj.style;
					else
						style=((TObjFrame*)obj)->style;

					if(Ax>Bx) {j=Ax;Ax=Bx;Bx=j;}
					if(Ay>By) {j=Ay;Ay=By;By=j;}

					if(style==fstFilled)
					{
						for(k=Ay;k<=By;k++)
							for(j=Ax;j<=Bx;j++)
								wbmp[k][j]=color;
					}
					else
					{
						DrawLine(Ax,Ay,Bx,Ay,color);
						DrawLine(Ax,By,Bx,By,color);
						DrawLine(Ax,Ay,Ax,By,color);
						DrawLine(Bx,Ay,Bx,By,color);
						if(style==fstDouble)
						{
							Ax+=2;Ay+=2;Bx-=2;By-=2;
							DrawLine(Ax,Ay,Bx,Ay,color);
							DrawLine(Ax,By,Bx,By,color);
							DrawLine(Ax,Ay,Ax,By,color);
							DrawLine(Bx,Ay,Bx,By,color);
						}
					}
					break;
				case obLabel:
					Ax+=((TObjLabel*)obj)->Ax;
					Ay+=((TObjLabel*)obj)->Ay;
					if(edit==true && obj==MovePts[MovePtsS].ptr)
						DrawText(Ax,Ay,NewObj.font,color,bcolor,NewObj.str,(NewObj.btnanim==bcaYes)&&(NewObj.btnact!=atNone));
					else
						DrawText(Ax,Ay,((TObjLabel*)obj)->font,color,bcolor,((TObjLabel*)obj)->str,(((TObjLabel*)obj)->btnanim==bcaYes)&&(((TObjLabel*)obj)->btnact!=atNone)&&(((TObjLabel*)obj)->btn!=buttonst));
					break;
				case obIcon:
					Ax+=((TObjIcon*)obj)->Ax;
					Ay+=((TObjIcon*)obj)->Ay;
					if(edit==true && obj==MovePts[MovePtsS].ptr)
						DrawImg(Ax,Ay,color,bcolor,0,NULL);
					else
						DrawImg(Ax,Ay,color,bcolor,1,(TObjIcon*)obj);
					break;
			}
		}
	}

	// repaint image
	RepaintWimg();

	// refresh info panel
	RefreshInfo();
}

//==============================================================================
// repaint work image
//==============================================================================
void RepaintWimg(void)
{
	int i,k;
	unsigned char *pl;

	for(k=0;k<YRES;k++)
	{
		pl=(unsigned char*)MForm->wimg->Picture->Bitmap->ScanLine[k*2];
		for(i=0;i<XRES;i++)
		{
			*pl++=wbmp[k][i]&0x0000FF;
			*pl++=(wbmp[k][i]&0x00FF00)>>8;
			*pl++=(wbmp[k][i]&0xFF0000)>>16;
			*pl++=wbmp[k][i]&0x0000FF;
			*pl++=(wbmp[k][i]&0x00FF00)>>8;
			*pl++=(wbmp[k][i]&0xFF0000)>>16;
		}
		pl=(unsigned char*)MForm->wimg->Picture->Bitmap->ScanLine[k*2+1];
		for(i=0;i<XRES;i++)
		{
			*pl++=wbmp[k][i]&0x0000FF;
			*pl++=(wbmp[k][i]&0x00FF00)>>8;
			*pl++=(wbmp[k][i]&0xFF0000)>>16;
			*pl++=wbmp[k][i]&0x0000FF;
			*pl++=(wbmp[k][i]&0x00FF00)>>8;
			*pl++=(wbmp[k][i]&0xFF0000)>>16;
		}
	}
	MForm->wimg->Repaint();
}











//***********************************************
//***********************************************
//******************** FONTS ********************
//***********************************************
//***********************************************

//==============================================================================
// deallocate last font
//==============================================================================
void DeallocateLastFont(void)
{
	if(Fonts->fonts==1)
		free((void*)(Fonts->font));
	else
		Fonts->font=(TCFont*)realloc((void*)(Fonts->font),sizeof(TCFont)*(Fonts->fonts-1));
}

//==============================================================================
// load fonts
//==============================================================================
int LoadFonts(void)
{
	int done;
	struct ffblk ffblk;
	FILE *fr;
	char fname[260];
	char *str1;
	int i;
	int fid;

	if(Fonts==NULL)
	{
		Fonts=(TFonts*)malloc(sizeof(TFonts)*1);
		Fonts->fonts=0;
		Fonts->font=NULL;
	}

	done=findfirst((apppath+"\\fonts\\*.fnt").c_str(),&ffblk,0);
	while(!done)
	{
		if(Fonts->fonts==0)
			Fonts->font=(TCFont*)malloc(sizeof(TCFont)*1);
		else
			Fonts->font=(TCFont*)realloc((void*)(Fonts->font),sizeof(TCFont)*(Fonts->fonts+1));
		Fonts->fonts++;
		fid=Fonts->fonts-1;

		fr=fopen((apppath+"\\fonts\\"+AnsiString(ffblk.ff_name)).c_str(),"rb");
		if(fr!=NULL)
		{
			fread((void*)fname,1,16,fr);
			if(memcmp(fname,"SMfont_generV1.0",16)==0)
			{
				// read font name (prefix)
				str1=fname;
				while((*str1++=fgetc(fr))!='\0');

				strcpy(Fonts->font[fid].prefix,fname);

				// read yres
				Fonts->font[fid].yres=fgetc(fr);

				// now read all chars
				for(i=0;i<257;i++)
				{ // for each
					str1=fname;
					while((*str1++=fgetc(fr))!='\0');
					strcpy(Fonts->font[fid].data[i].name,fname);
					Fonts->font[fid].data[i].xres=fgetc(fr);
					fread((void*)(Fonts->font[fid].data[i].img),1,8*16,fr);
				}
			}
			else
			{
				DeallocateLastFont();
			}
		}
		else
		{
			DeallocateLastFont();
		}
		fclose(fr);

		done=findnext(&ffblk);
	}

	if(Fonts!=NULL)
	{
		MForm->ComboFontList->Clear();
		for(i=0;i<Fonts->fonts;i++)
		{
			MForm->ComboFontList->ItemsEx->AddItem(AnsiString(Fonts->font[i].prefix),7,7,-1,-1,NULL);
		}
		if(Fonts->fonts>0)
		{
			MForm->ComboFontList->ItemIndex=0;
			MForm->LblFontHeight->Caption=Fonts->font[0].yres;
		}
	}

	if(Fonts==NULL || Fonts->fonts==0)
	{
		MessageBox(MForm->Handle,"Missing font files in folder \"fonts\"!\nClosing application.","Loading fonts ...",MB_ICONERROR);
		MForm->Close();
	}

	return(0);
}

//==============================================================================
// remove all fonts
//==============================================================================
void RemoveAllFonts(void)
{
	if(Fonts!=NULL)
	{
		if(Fonts->font!=NULL)
		{
			free((void*)(Fonts->font));
			Fonts->font=NULL;
		}
		free((void*)Fonts);
	}
}

//==============================================================================
// font height
//==============================================================================
void __fastcall TMForm::ComboFontListChange(TObject *Sender)
{
	if(Fonts!=NULL && Fonts->fonts>0)
	{
		MForm->LblFontHeight->Caption=Fonts->font[ComboFontList->ItemIndex].yres;
		DrawFontPreview(ComboFontList->ItemIndex);
	}
}

void DrawFontPreview(int font)
{
	int x=5,y=5;
	int i,j;
	int xr,yr;
	int c;
	unsigned char *str=Fonts->font[font].prefix;

	yr=Fonts->font[font].yres;

	MForm->FontImg->Canvas->Pen->Color=clBlack;
	MForm->FontImg->Canvas->Brush->Color=clWhite;
	MForm->FontImg->Canvas->Rectangle(0,0,MForm->FontImg->Width,MForm->FontImg->Height);

	while((c=*str)!='\0')
	{
		xr=Fonts->font[font].data[*str].xres;
		for(i=0;i<xr;i++)
		{
			for(j=0;j<yr;j++)
			{
				MForm->FontImg->Canvas->Pixels[x+i][y+j]=(Fonts->font[font].data[c].img[i][j]==1)?clBlack:clWhite;
			}
		}
		x+=xr+1;
		str++;
	}
}








//*************************************************
//*************************************************
//******************** OBJECTS ********************
//*************************************************
//*************************************************
//==============================================================================
// delete object click
//==============================================================================
void __fastcall TMForm::MBtnObjDeleteClick(TObject *Sender)
{
	int i,j;

	if(NewObj.obj==obMove)
		RemoveObject();
	else if(NewObj.obj==obSelect)
	{
		MovePtsS=0;
		for(i=0;i<SelObjsN;i++)
		{
			for(j=0;j<Project->scr[screen].objects;j++)
				if(SelObjs[i].ptr==Project->scr[screen].obj[j].objptr)
				{
					MovePts[0].type=SelObjs[i].type;
					MovePts[0].ptr=SelObjs[i].ptr;
					MovePts[0].obj_id=j;
					RemoveObject();
					break;
				}
		}
	}
	ObjEditEnable(false);
	NewObj.state=obsNone;

	PaintWorkImg();
}
//==============================================================================
// edit object click
//==============================================================================
void __fastcall TMForm::MBtnObjEditClick(TObject *Sender)
{
	unsigned char *ustr;
	int i;

	if(edit==false)
	{
		switch(MovePts[MovePtsS].type)
		{
			case obFrame:
				NewObj.xa=((TObjFrame*)(MovePts[MovePtsS].ptr))->Ax;
				NewObj.xb=((TObjFrame*)(MovePts[MovePtsS].ptr))->Bx;
				NewObj.ya=((TObjFrame*)(MovePts[MovePtsS].ptr))->Ay;
				NewObj.yb=((TObjFrame*)(MovePts[MovePtsS].ptr))->By;
				NewObj.style=((TObjFrame*)(MovePts[MovePtsS].ptr))->style;
				edit=true;
				OframeForm->Show();
				break;
			case obLabel:
				strcpy(NewObj.str,((TObjLabel*)(MovePts[MovePtsS].ptr))->str);
				NewObj.font=((TObjLabel*)(MovePts[MovePtsS].ptr))->font;
				NewObj.btn=((TObjLabel*)(MovePts[MovePtsS].ptr))->btn;
				NewObj.btnact=((TObjLabel*)(MovePts[MovePtsS].ptr))->btnact;
				NewObj.btnactscr=((TObjLabel*)(MovePts[MovePtsS].ptr))->btnactscr;
				NewObj.btnanim=((TObjLabel*)(MovePts[MovePtsS].ptr))->btnanim;
				edit=true;
				OlabelForm->Show();
				break;
			case obIcon:
				object=MovePts[MovePtsS].obj_id;
				NewObj.xr=((TObjIcon*)(MovePts[MovePtsS].ptr))->xr;
				NewObj.yr=((TObjIcon*)(MovePts[MovePtsS].ptr))->yr;
				ustr=((TObjIcon*)(MovePts[MovePtsS].ptr))->srcimg;
				for(i=0;i<NewObj.yr;i++)
					memcpy((void*)(&NewObj.srcimg[i][0]),(void*)(ustr + i*NewObj.xr),NewObj.xr);
				ustr=((TObjIcon*)(MovePts[MovePtsS].ptr))->destimg;
				for(i=0;i<NewObj.yr;i++)
					memcpy((void*)(&NewObj.destimg[i][0]),(void*)(ustr + i*NewObj.xr),NewObj.xr);
				edit=true;
				OiconForm->Show();
				break;
		}
	}
}
//==============================================================================
// remove object
//==============================================================================
int RemoveObject(void)
{
	char *str;
	unsigned char *ustr;
	int n;

	// deallocate object sub objects
	switch(MovePts[MovePtsS].type)
	{
		case obLabel:
			str=((TObjLabel*)(MovePts[MovePtsS].ptr))->str;
			if(str!=NULL)
				free((void*)str);
			break;
		case obIcon:
			ustr=((TObjIcon*)(MovePts[MovePtsS].ptr))->srcimg;
			if(ustr!=NULL)
				free((void*)ustr);
			ustr=((TObjIcon*)(MovePts[MovePtsS].ptr))->destimg;
			if(ustr!=NULL)
				free((void*)ustr);
			break;
		default:
			break;
	}

	// deallocate object structure
	free((void*)(MovePts[MovePtsS].ptr));

	if((n=Project->scr[screen].objects)==1)
	{
		// deallocate object entries array
		free((void*)(Project->scr[screen].obj));

		Project->scr[screen].obj=NULL;
		Project->scr[screen].objects=0;
		object=0;
	}
	else
	{
		if(MovePts[MovePtsS].obj_id!=(n-1))
		{
			// if this wasn't last object, move last object into the gap
			Project->scr[screen].obj[MovePts[MovePtsS].obj_id].objptr=Project->scr[screen].obj[n-1].objptr;
			Project->scr[screen].obj[MovePts[MovePtsS].obj_id].type=Project->scr[screen].obj[n-1].type;
		}

		// shrink object entries array by 1 entry
		Project->scr[screen].obj=(TObj*)realloc((void*)(Project->scr[screen].obj),sizeof(TObj)*(n-1));

		Project->scr[screen].objects=n-1;
		object=n-2;
	}

	return(0);
}

//==============================================================================
// objects buttons enable
//==============================================================================
void ObjectsActivated(bool active)
{
	MForm->BtnOlabel->Enabled=active;
	MForm->BtnOline->Enabled=active;
	MForm->BtnOframe->Enabled=active;
	MForm->BtnOicon->Enabled=active;
	MForm->BtnOmove->Enabled=active;
	MForm->BtnOselect->Enabled=active;
	MForm->BtnOmouse->Enabled=active;

	MForm->MBtnOlabel->Enabled=active;
	MForm->MBtnOline->Enabled=active;
	MForm->MBtnOframe->Enabled=active;
	MForm->MBtnOicon->Enabled=active;
	MForm->MBtnOmove->Enabled=active;
	MForm->MBtnOselect->Enabled=active;
}

//==============================================================================
// edit, delete buttons enable
//==============================================================================
void ObjEditEnable(bool active)
{
	MForm->MBtnObjEdit->Enabled=active;
	MForm->MBtnObjDelete->Enabled=active;
}

//==============================================================================
// objects buttons
//==============================================================================
void __fastcall TMForm::MBtnOlineClick(TObject *Sender)
{
	PostMessage(BtnOline->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::MBtnOframeClick(TObject *Sender)
{
	PostMessage(BtnOframe->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::MBtnOlabelClick(TObject *Sender)
{
	PostMessage(BtnOlabel->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::MBtnOiconClick(TObject *Sender)
{
	PostMessage(BtnOicon->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::MBtnOselectClick(TObject *Sender)
{
	PostMessage(BtnOselect->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::MBtnOmoveClick(TObject *Sender)
{
	PostMessage(BtnOmove->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOlineClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obLine;
	NewObj.state=obsNone;

	MForm->SB1->Panels->Items[1]->Text="Line: left mouse to draw line";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOframeClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obFrame;
	NewObj.state=obsNone;
	NewObj.style=fstSingle;

	OframeForm->Show();

	MForm->SB1->Panels->Items[1]->Text="Frame: left mouse to draw frame";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOlabelClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obLabel;
	NewObj.state=obsNone;
	strcpy(NewObj.str,"Label");
	NewObj.font=0;

	NewObj.btn=0;
	NewObj.btnact=atNone;
	NewObj.btnactscr=NULL;
	NewObj.btnanim=bcaYes;

	OlabelForm->Show();

	MForm->SB1->Panels->Items[1]->Text="Label: left mouse to place label";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOiconClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obIcon;
	NewObj.state=obsNone;
	NewObj.xr=NewObj.yr=0;
	OiconForm->Show();

	MForm->SB1->Panels->Items[1]->Text="Icon: left mouse to place icon";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOmoveClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obMove;
	NewObj.state=obsNone;

	MForm->SB1->Panels->Items[1]->Text="Move: left mouse click to select object";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOselectClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obSelect;
	NewObj.state=obsNone;

	MForm->SB1->Panels->Items[1]->Text="Select: left mouse to select objects";
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnOmouseClick(TObject *Sender)
{
	EditClose();

	NewObj.obj=obNone;
	NewObj.state=obsNone;

	MForm->SB1->Panels->Items[1]->Text="";
}

//==============================================================================
// close edit forms
//==============================================================================
void EditClose(void)
{
	OlabelForm->Close();
	OiconForm->Close();
	OframeForm->Close();

	ObjEditEnable(false);
	PaintWorkImg();
}

//==============================================================================
// move objects
//==============================================================================
void FindObjects2move(void)
{
	int i;
	int x1,y1,x2,y2;
	void *obj;

	SelObjsN=0;

	x1=NewObj.xa;
	y1=NewObj.ya;
	x2=NewObj.xb;
	y2=NewObj.yb;

	// build points list
	for(i=0;i<(MoveRecN=Project->scr[screen].objects);i++)
	{
		obj=Project->scr[screen].obj[i].objptr;
		switch(Project->scr[screen].obj[i].type)
		{
			case obLine:
				if(FO2mMember(((TObjLine*)obj)->Ax,((TObjLine*)obj)->Ay,x1,y1,x2,y2) || FO2mMember(((TObjLine*)obj)->Bx,((TObjLine*)obj)->By,x1,y1,x2,y2))
				{
					SelObjs[SelObjsN].ptr=obj;
					SelObjs[SelObjsN].type=obLine;
					SelObjs[SelObjsN].obj_id=i;
					SelObjsN++;
				}
				break;
			case obFrame:
				if(FO2mMember(((TObjFrame*)obj)->Ax,((TObjFrame*)obj)->Ay,x1,y1,x2,y2) || FO2mMember(((TObjFrame*)obj)->Bx,((TObjFrame*)obj)->By,x1,y1,x2,y2))
				{
					SelObjs[SelObjsN].ptr=obj;
					SelObjs[SelObjsN].type=obFrame;
					SelObjs[SelObjsN].obj_id=i;
					SelObjsN++;
				}
				break;
			case obLabel:
				if(FO2mMember(((TObjLabel*)obj)->Ax,((TObjLabel*)obj)->Ay,x1,y1,x2,y2))
				{
					SelObjs[SelObjsN].ptr=obj;
					SelObjs[SelObjsN].type=obLabel;
					SelObjs[SelObjsN].obj_id=i;
					SelObjsN++;
				}
				break;
			case obIcon:
				if(FO2mMember(((TObjIcon*)obj)->Ax,((TObjIcon*)obj)->Ay,x1,y1,x2,y2))
				{
					SelObjs[SelObjsN].ptr=obj;
					SelObjs[SelObjsN].type=obIcon;
					SelObjs[SelObjsN].obj_id=i;
					SelObjsN++;
				}
				break;
		}
	}

	if(SelObjsN==0)
	{
		NewObj.state=obsNone;
		MForm->SB1->Panels->Items[1]->Text="Select: no objects selected!";
	}
	else
	{
		NewObj.state=obsSelect;
		MForm->SB1->Panels->Items[1]->Text="Select: left mouse to move objects";
	}
}

//==============================================================================
// move single object
//==============================================================================
void FindObject2move(void)
{
	int i;
	int x,y,j,k,l;
	int dt1,dt2;
	void *obj;

	MoveRecN=0;

	x=NewObj.xa;
	y=NewObj.ya;

	// build points list
	for(i=0;i<(MoveRecN=Project->scr[screen].objects);i++)
	{
		switch(Project->scr[screen].obj[i].type)
		{
			case obLine:
				obj=Project->scr[screen].obj[i].objptr;
				j=((TObjLine*)obj)->Ax;
				k=((TObjLine*)obj)->Ay;
				dt1=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));
				j=((TObjLine*)obj)->Bx;
				k=((TObjLine*)obj)->By;
				dt2=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));

				if(dt1<dt2)
				{
					MoveRec[i].dt=dt1;
					MoveRec[i].pt=1;
				}
				else
				{
					MoveRec[i].dt=dt2;
					MoveRec[i].pt=2;
				}
				MoveRec[i].ptr=obj;
				MoveRec[i].type=obLine;
				MoveRec[i].obj_id=i;
				break;
			case obFrame:
				obj=Project->scr[screen].obj[i].objptr;
				j=((TObjFrame*)obj)->Ax;
				k=((TObjFrame*)obj)->Ay;
				dt1=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));
				j=((TObjFrame*)obj)->Bx;
				k=((TObjFrame*)obj)->By;
				dt2=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));

				if(dt1<dt2)
				{
					MoveRec[i].dt=dt1;
					MoveRec[i].pt=1;
				}
				else
				{
					MoveRec[i].dt=dt2;
					MoveRec[i].pt=2;
				}
				MoveRec[i].ptr=obj;
				MoveRec[i].type=obFrame;
				MoveRec[i].obj_id=i;
				break;
			case obLabel:
				obj=Project->scr[screen].obj[i].objptr;
				j=((TObjLabel*)obj)->Ax;
				k=((TObjLabel*)obj)->Ay;
				dt1=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));

				MoveRec[i].dt=dt1;
				MoveRec[i].pt=1;
				MoveRec[i].ptr=obj;
				MoveRec[i].type=obLabel;
				MoveRec[i].obj_id=i;
				break;
			case obIcon:
				obj=Project->scr[screen].obj[i].objptr;
				j=((TObjIcon*)obj)->Ax;
				k=((TObjIcon*)obj)->Ay;
				dt1=sqrt((double)((x-j)*(x-j)+(y-k)*(y-k)));

				MoveRec[i].dt=dt1;
				MoveRec[i].pt=1;
				MoveRec[i].ptr=obj;
				MoveRec[i].type=obIcon;
				MoveRec[i].obj_id=i;
				break;

		}
	}

	// get less than 25 difference points count
	// and make filter for less than 6 difference
	j=0;
	k=0;
	for(i=0;i<MoveRecN;i++)
	{
		if(MoveRec[i].dt<25)
		{
			j++;
			l=i;
		}
		if(MoveRec[i].dt<6)
		{
			MovePts[k]=MoveRec[i];
			k++;
		}
	}

	// if 0, select nothing
	if(j==0)
	{
		MovePtsN=0;
		MForm->SB1->Panels->Items[1]->Text="Move: no object near to cursor!";
		NewObj.state=obsNone;
	}
	else if(j==1)
	{ // if only 1, then chose it
		MovePts[0]=MoveRec[l];
		MovePtsN=1;
		MForm->SB1->Panels->Items[1]->Text="Move: left mouse button to move object";
		NewObj.state=obsMoveSelect;
	}
	else
	{ // if more than 1
		MovePtsN=k;
		MForm->SB1->Panels->Items[1]->Text="Move: right click to choose near object, left to move it";
		NewObj.state=obsMoveSelect;
	}
	MovePtsS=0;

}

//==============================================================================
// other selection member
//==============================================================================
bool ObjIsSelMember(void *obj)
{
	int i;

	for(i=0;i<SelObjsN;i++)
		if(obj==SelObjs[i].ptr)
			return(true);

	return(false);
}

//==============================================================================
// selection member?
//==============================================================================
bool FO2mMember(int Ax,int Ay,int x1,int y1,int x2,int y2)
{
	int tmp;

	if(x1>x2)
	{
		tmp=x1;
		x1=x2;
		x2=tmp;
	}
	if(y1>y2)
	{
		tmp=y1;
		y1=y2;
		y2=tmp;
	}

	if(Ax>=x1 && Ax<=x2 && Ay>=y1 && Ay<=y2)
		return(true);

	return(false);
}

//==============================================================================
// create object line
//==============================================================================
int CreateObjLine(void)
{
	if(Project->scr[screen].objects==0)
		Project->scr[screen].obj=(TObj*)malloc(sizeof(TObj)*1);
	else
		Project->scr[screen].obj=(TObj*)realloc((void*)(Project->scr[screen].obj),sizeof(TObj)*(Project->scr[screen].objects+1));

	Project->scr[screen].objects++;
	object=Project->scr[screen].objects-1;
	Project->scr[screen].obj[object].type=obLine;
	Project->scr[screen].obj[object].objptr=(TObjLine*)malloc(sizeof(TObjLine)*1);

	return(0);
}

//==============================================================================
// create object frame
//==============================================================================
int CreateObjFrame(void)
{
	if(Project->scr[screen].objects==0)
		Project->scr[screen].obj=(TObj*)malloc(sizeof(TObj)*1);
	else
		Project->scr[screen].obj=(TObj*)realloc((void*)(Project->scr[screen].obj),sizeof(TObj)*(Project->scr[screen].objects+1));

	Project->scr[screen].objects++;
	object=Project->scr[screen].objects-1;
	Project->scr[screen].obj[object].type=obFrame;
	Project->scr[screen].obj[object].objptr=(TObjFrame*)malloc(sizeof(TObjFrame)*1);

	return(0);
}

//==============================================================================
// create object label
//==============================================================================
int CreateObjLabel(void)
{
	if(Project->scr[screen].objects==0)
		Project->scr[screen].obj=(TObj*)malloc(sizeof(TObj)*1);
	else
		Project->scr[screen].obj=(TObj*)realloc((void*)(Project->scr[screen].obj),sizeof(TObj)*(Project->scr[screen].objects+1));

	Project->scr[screen].objects++;
	object=Project->scr[screen].objects-1;
	Project->scr[screen].obj[object].type=obLabel;
	Project->scr[screen].obj[object].objptr=(TObjLabel*)malloc(sizeof(TObjLabel)*1);

	((TObjLabel*)(Project->scr[screen].obj[object].objptr))->str=NULL;
	((TObjLabel*)(Project->scr[screen].obj[object].objptr))->btnactscr=NULL;
	return(0);
}

//==============================================================================
// create object icon
//==============================================================================
int CreateObjIcon(void)
{
	if(Project->scr[screen].objects==0)
		Project->scr[screen].obj=(TObj*)malloc(sizeof(TObj)*1);
	else
		Project->scr[screen].obj=(TObj*)realloc((void*)(Project->scr[screen].obj),sizeof(TObj)*(Project->scr[screen].objects+1));

	Project->scr[screen].objects++;
	object=Project->scr[screen].objects-1;
	Project->scr[screen].obj[object].type=obIcon;
	Project->scr[screen].obj[object].objptr=(TObjIcon*)malloc(sizeof(TObjIcon)*1);

	((TObjIcon*)(Project->scr[screen].obj[object].objptr))->xr=0;
	((TObjIcon*)(Project->scr[screen].obj[object].objptr))->yr=0;
	((TObjIcon*)(Project->scr[screen].obj[object].objptr))->srcimg=NULL;
	((TObjIcon*)(Project->scr[screen].obj[object].objptr))->destimg=NULL;
	return(0);
}











//*************************************************
//*************************************************
//******************** SCREENS ********************
//*************************************************
//*************************************************
//==============================================================================
// new screen
//==============================================================================
void __fastcall TMForm::MBtnScrNewClick(TObject *Sender)
{
	PostMessage(BtnNewScreen->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnNewScreenClick(TObject *Sender)
{
	if(Project!=NULL)
	{
		CreateScreen();
		EditObjCstr(&(Project->scr[screen].name),("Screen"+IntToStr(Project->screens)).c_str());
		OscreenForm->Ename->Text=AnsiString(Project->scr[screen].name);
		if(OscreenForm->ShowModal()==mrCancel)
		{
			RemoveScreen();
		}
		RefreshScreenList();
	}
	else
	{
		if(MessageBox(Handle,"Create/open some project first!\nCreate new one?","New screen ...",MB_ICONQUESTION|MB_YESNO)==mrYes)
		{
			MBtnNewPrj->Click();
			PostMessage(BtnNewScreen->Handle,BM_CLICK,0,0);
		}
	}
	PaintWorkImg();
}
//==============================================================================
// delete screen click
//==============================================================================
void __fastcall TMForm::MBtnScrDeleteClick(TObject *Sender)
{
	PostMessage(BtnDeleteScreen->Handle,BM_CLICK,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TMForm::BtnDeleteScreenClick(TObject *Sender)
{
	RemoveScreen();
	RefreshScreenList();
	PaintWorkImg();
}
//==============================================================================
// edit screen click
//==============================================================================
void __fastcall TMForm::MBtnScrEditClick(TObject *Sender)
{
	OscreenForm->Ename->Text=AnsiString(Project->scr[screen].name);
	OscreenForm->ShowModal();
	RefreshScreenList();
	PaintWorkImg();
}
//==============================================================================
// screen list change
//==============================================================================
void __fastcall TMForm::ComboScreensChange(TObject *Sender)
{
	screen=ComboScreens->ItemIndex;
	object=0;
	NewObj.obj=obNone;
	NewObj.state=obsNone;
	PaintWorkImg();
}
//==============================================================================
// refresh screen list
//==============================================================================
void RefreshScreenList(void)
{
	int i;

	MForm->ComboScreens->Clear();

	if(Project!=NULL)
	{
		for(i=0;i<Project->screens;i++)
			MForm->ComboScreens->AddItem(AnsiString(Project->scr[i].name),NULL);

		MForm->ComboScreens->ItemIndex=screen;

		MForm->MBtnScrEdit->Enabled=(Project->screens>0);
		MForm->MBtnScrDelete->Enabled=(Project->screens>0);
		MForm->BtnDeleteScreen->Enabled=(Project->screens>0);
		MForm->MBtnGenerateSrc->Enabled=(Project->screens>0);
		MForm->MBtnGenImgs->Enabled=(Project->screens>0);
		ObjectsActivated(Project->screens>0);
	}
	else
	{
		MForm->MBtnScrEdit->Enabled=false;
		MForm->MBtnScrDelete->Enabled=false;
		MForm->BtnDeleteScreen->Enabled=false;
		MForm->MBtnGenerateSrc->Enabled=false;
		MForm->MBtnGenImgs->Enabled=false;
		ObjectsActivated(false);
	}

	RefreshInfo();
}

//==============================================================================
// create screen
//==============================================================================
int CreateScreen(void)
{
	if(Project->screens==0)
		Project->scr=(TScr*)malloc(sizeof(TScr)*1);
	else
		Project->scr=(TScr*)realloc((void*)(Project->scr),sizeof(TScr)*(Project->screens+1));

	// sreens number
	(Project->screens)++;
	// no objects in screen
	screen=Project->screens-1;
	Project->scr[screen].objects=0;
	Project->scr[screen].name=NULL;
	Project->scr[screen].obj=NULL;
	object=0;

	MForm->LblScr->Caption="Screen list ("+IntToStr(Project->screens)+" screens):";

	return(0);
}

//==============================================================================
// remove screen
//==============================================================================
int RemoveScreen(void)
{
	int i,j;
	int objs,n;

	if(Project!=NULL && Project->screens>0 && screen>=0 && screen<Project->screens)
	{
		// remove references to this screen
		for(i=0;i<Project->screens;i++)
		{
			for(j=0;j<Project->scr[i].objects;j++)
			{
				if(Project->scr[i].obj[j].type==obLabel && ((TObjLabel*)(Project->scr[i].obj[j].objptr))->btn!=0 && ((TObjLabel*)(Project->scr[i].obj[j].objptr))->btnact==atNewScr && ((TObjLabel*)(Project->scr[i].obj[j].objptr))->btnactscr==Project->scr[screen].name)
					((TObjLabel*)(Project->scr[i].obj[j].objptr))->btnactscr=NULL;
			}
		}

		objs=Project->scr[screen].objects;
		// first remove all objects in this screen
		for(i=0;i<objs;i++)
		{
			MovePts[0].type=Project->scr[screen].obj[0].type;
			MovePts[0].ptr=Project->scr[screen].obj[0].objptr;
			MovePts[0].obj_id=0;
			RemoveObject();
		}

		// now erase screen
		if(Project->scr[screen].name!=NULL)
		{
			free(Project->scr[screen].name);
			Project->scr[screen].name=NULL;
		}

		if((n=Project->screens)==1)
		{
			// this is last screen
			free((void*)(Project->scr));
			Project->scr=NULL;
			Project->screens=0;
		}
		else
		{
			// more than 1 screen
			if(screen!=(n-1))
			{
				// it's not last screen, move last one into gap
				Project->scr[screen]=Project->scr[n-1];
			}

			Project->scr=(TScr*)realloc((void*)(Project->scr),sizeof(TScr)*(n-1));
			Project->screens=n-1;
			screen=n-2;
		}
	}

	return(0);
}








//*************************************************
//*************************************************
//******************** PROJECT ********************
//*************************************************
//*************************************************
//==============================================================================
// open click
//==============================================================================
void __fastcall TMForm::MBtnOpenClick(TObject *Sender)
{
	int mr;

	OpenRepeat:

	if(Project==NULL)
	{
		LoadProject();

		MBtnClose->Enabled=true;
		MBtnSave->Enabled=true;
	}
	else
	{
		if((mr=MessageBox(Handle,"Save current project before closing it?","Open project ...",MB_ICONQUESTION|MB_YESNOCANCEL))!=mrCancel)
		{
			if(mr==mrYes)
			{
				// save it
				MBtnSave->Click();
			}
			// close it
			MBtnClose->Click();

			goto OpenRepeat;
		}
	}

	RefreshScreenList();
	PaintWorkImg();
}

//==============================================================================
// save click
//==============================================================================
void __fastcall TMForm::MBtnSaveClick(TObject *Sender)
{
	SaveProject();
	RefreshScreenList();
	PaintWorkImg();
}

//==============================================================================
// close project
//==============================================================================
void __fastcall TMForm::MBtnCloseClick(TObject *Sender)
{
	if(Project!=NULL)
	{
		if(exitting==true && MessageBox(Handle,"Save current project before closing it?","Exit ...",MB_ICONQUESTION|MB_YESNO)==mrYes)
		{
			// save it
			MBtnSave->Click();
		}
		// close it

		RemoveProject();
		RefreshScreenList();
		PaintWorkImg();

		MBtnClose->Enabled=false;
		MBtnSave->Enabled=false;
		MBtnScrDelete->Enabled=false;
		BtnDeleteScreen->Enabled=false;
	}
}

//==============================================================================
// new project click
//==============================================================================
void __fastcall TMForm::MBtnNewPrjClick(TObject *Sender)
{
	int mr;

	if(Project==NULL)
	{
		CreateProject();

		MBtnClose->Enabled=true;
		MBtnSave->Enabled=true;
	}
	else
	{
		if((mr=MessageBox(Handle,"Save current project before closing it?","New project ...",MB_ICONQUESTION|MB_YESNOCANCEL))!=mrCancel)
		{
			if(mr==mrYes)
			{
				// save it
				MBtnSave->Click();
			}
			// close it
			MBtnClose->Click();
			PostMessage(MBtnNewPrj->Handle,BM_CLICK,0,0);
		}
	}

	RefreshScreenList();
	PaintWorkImg();
}

//==============================================================================
// read string from file
//==============================================================================
void ReadPrjStr(FILE *fr,char *str)
{
	while((*str++=fgetc(fr))!=0);
}

//==============================================================================
// load project
//==============================================================================
int LoadProject(void)
{
	FILE *fr=NULL;
	TScr *scr;
	void *obj;
	int scrs,objs;
	int type,size;
	int i,j,k;
	int fonts;
	bool fontren;
	char FontRenT[128];
	char str[1024];

	LoadProjectRetry:

	if(MForm->OD1->Execute()==true)
	{
		fr=fopen(MForm->OD1->FileName.c_str(),"rb");
		if(fr!=NULL)
		{
			// file opened

			// store path
			MForm->SD1->InitialDir=ExtractFileDir(MForm->OD1->FileName);
			MForm->OD1->InitialDir=ExtractFileDir(MForm->OD1->FileName);

			fread((void*)str,sizeof(char),16,fr);
			if(memcmp(str,"ScreenGenSMv1.00",16)==0)
			{
				// correct file format


				// create project
				CreateProject();
				// read name
				ReadPrjStr(fr,str);
				EditObjCstr(&(Project->name),str);
				// read screens count
				fread((void*)&scrs,sizeof(int),1,fr);


				for(i=0;i<scrs;i++)
				{
					CreateScreen();
					scr=&(Project->scr[i]);
					ReadPrjStr(fr,str);
					EditObjCstr(&(scr->name),str);

					fread((void*)&objs,sizeof(int),1,fr);
					for(j=0;j<objs;j++)
					{
						fread((void*)&type,sizeof(int),1,fr);
						switch(type)
						{
							case obLine:
								CreateObjLine();
								obj=scr->obj[object].objptr;
								fread((void*)obj,sizeof(TObjLine),1,fr);
								break;
							case obFrame:
								CreateObjFrame();
								obj=scr->obj[object].objptr;
								fread((void*)obj,sizeof(TObjFrame),1,fr);
								break;
							case obLabel:
								CreateObjLabel();
								obj=scr->obj[object].objptr;
								fread((void*)&(((TObjLabel*)obj)->Ax),sizeof(int),1,fr);
								fread((void*)&(((TObjLabel*)obj)->Ay),sizeof(int),1,fr);
								fread((void*)&(((TObjLabel*)obj)->font),sizeof(int),1,fr);
								fread((void*)&(((TObjLabel*)obj)->btn),sizeof(int),1,fr);
								fread((void*)&(((TObjLabel*)obj)->btnact),sizeof(int),1,fr);
								fread((void*)&(((TObjLabel*)obj)->btnanim),sizeof(int),1,fr);
								ReadPrjStr(fr,str);
								if(str[0]!='\0' && ((TObjLabel*)obj)->btn!=0 && ((TObjLabel*)obj)->btnact==atNewScr)
									EditObjCstr(&(((TObjLabel*)obj)->btnactscr),str);
								ReadPrjStr(fr,str);
								EditObjCstr(&(((TObjLabel*)obj)->str),str);
								break;
							case obIcon:
								CreateObjIcon();
								obj=scr->obj[object].objptr;
								fread((void*)&(((TObjIcon*)obj)->Ax),sizeof(int),1,fr);
								fread((void*)&(((TObjIcon*)obj)->Ay),sizeof(int),1,fr);
								fread((void*)&(((TObjIcon*)obj)->xr),sizeof(int),1,fr);
								fread((void*)&(((TObjIcon*)obj)->yr),sizeof(int),1,fr);
								size=(((TObjIcon*)obj)->xr)*(((TObjIcon*)obj)->yr);
								if(size!=0)
								{
									((TObjIcon*)obj)->srcimg=(unsigned char*)malloc(sizeof(unsigned char)*size);
									fread((void*)(((TObjIcon*)obj)->srcimg),sizeof(char),size,fr);
									((TObjIcon*)obj)->destimg=(unsigned char*)malloc(sizeof(unsigned char)*size);
									fread((void*)(((TObjIcon*)obj)->destimg),sizeof(char),size,fr);
								}
								break;
						}
					}
				}


				memset((void*)FontRenT,-1,128);

				// read used fonts number
				fread((void*)&fonts,sizeof(int),1,fr);

				// for each font
				for(i=0;i<fonts;i++)
				{
					fread((void*)&k,sizeof(int),1,fr);
					ReadPrjStr(fr,str);
					if(k>=Fonts->fonts)
					{
						MessageBox(MForm->Handle,("Can't found font \""+AnsiString(str)+"\" used in this project!\nAll labels using this font will be changed to \""+AnsiString(Fonts->font[0].prefix)+"\".").c_str(),"Loading project ...",MB_ICONEXCLAMATION);
						FontRenT[k]=0;
					}
					else if(strcmp(Fonts->font[k].prefix,str)!=0)
					{
						MessageBox(MForm->Handle,("Font \""+AnsiString(str)+"\" used in this project has another ID than loaded font!\nTrying to find correct font.").c_str(),"Loading project ...",MB_ICONEXCLAMATION);
						// font numbe changed
						fontren=false;
						for(j=0;j<Fonts->fonts;j++)
						{
							if(strcmp(str,Fonts->font[j].prefix)==0)
							{
								fontren=true;
								FontRenT[k]=j;
								break;
							}
						}
						if(fontren==false)
						{
							MessageBox(MForm->Handle,("Can't found font \""+AnsiString(str)+"\" used in this project!\nAll labels using this font will be changed to \""+AnsiString(Fonts->font[0].prefix)+"\".").c_str(),"Loading project ...",MB_ICONEXCLAMATION);
							FontRenT[k]=0;
						}
					}
				}
				fclose(fr);

				// now change all font numbers if changed
				for(i=0;i<Project->screens;i++)
					for(j=0;j<Project->scr[i].objects;j++)
						if(Project->scr[i].obj[j].type==obLabel && (k=FontRenT[((TObjLabel*)(Project->scr[i].obj[j].objptr))->font])>=0)
							((TObjLabel*)(Project->scr[i].obj[j].objptr))->font=k;


				/*FILE *fw;
				fw=fopen("dbg.txt","wt");
				for(i=0;i<128;i++)
					fprintf(fw,"%2d => %2d\n",i,FontRenT[i]);
				fclose(fw);*/

				// make references form label atNewScr to screens
				for(i=0;i<scrs;i++)
				{
					for(j=0;j<Project->scr[i].objects;j++)
					{
						obj=Project->scr[i].obj[j].objptr;
						if(Project->scr[i].obj[j].type==obLabel && ((TObjLabel*)obj)->btn!=0 && ((TObjLabel*)obj)->btnact==atNewScr && ((TObjLabel*)obj)->btnactscr!=NULL)
						{
							for(k=0;k<scrs;k++)
							{
								if(strcmp(((TObjLabel*)obj)->btnactscr,Project->scr[k].name)==0)
								{
									free((void*)(((TObjLabel*)obj)->btnactscr));
									((TObjLabel*)obj)->btnactscr=Project->scr[k].name;
									break;
								}
							}
						}
					}
				}
			}
			else
			{
				// invalid file format
				fclose(fr);
				if(MessageBox(MForm->Handle,"Invalid file format.\nTry another one?","Loading project ...",MB_ICONQUESTION|MB_YESNO)==mrYes)
				{
					goto LoadProjectRetry;
				}
			}
		}
		else
		{
			// can't open file
			if(MessageBox(MForm->Handle,"Can't open selected file.\nTry again?","Loading project ...",MB_ICONQUESTION|MB_YESNO)==mrYes)
			{
				goto LoadProjectRetry;
			}
		}
	}
	return(0);
}

//==============================================================================
// save project
//==============================================================================
int SaveProject(void)
{
	FILE *fw=NULL;
	TScr *scr;
	void *obj;
	int scrs,objs;
	int i,j;
	char UsedFonts[128];
	int fonts;

	memset((void*)UsedFonts,0,128);

	SaveProjectRetry:

	if(Project!=NULL)
	{
		// project exists
		if((scrs=Project->screens)>0)
		{
			// not empty project
			if(MForm->SD1->Execute()==true)
			{
				fw=fopen(MForm->SD1->FileName.c_str(),"wb");
				if(fw!=NULL)
				{
					// file opened for writting

					// store path
					MForm->OD1->InitialDir=ExtractFileDir(MForm->SD1->FileName);
					MForm->SD1->InitialDir=ExtractFileDir(MForm->SD1->FileName);

					// write file ID
					fprintf(fw,"ScreenGenSMv1.00");
					// write prj name
					fprintf(fw,"%s%c",(Project->name==NULL) ? "" : Project->name,'\0');
					// write screen count
					fwrite((void*)&(Project->screens),sizeof(int),1,fw);

					for(i=0;i<scrs;i++)
					{
						scr=&(Project->scr[i]);
						fprintf(fw,"%s%c",(scr->name==NULL) ? "" : scr->name,'\0');
						fwrite((void*)&(scr->objects),sizeof(int),1,fw);

						objs=scr->objects;
						for(j=0;j<objs;j++)
						{
							obj=scr->obj[j].objptr;
							fwrite((void*)&(scr->obj[j].type),sizeof(int),1,fw);
							switch(scr->obj[j].type)
							{
								case obLine:
									fwrite((void*)obj,1,sizeof(TObjLine),fw);
									break;
								case obFrame:
									fwrite((void*)obj,1,sizeof(TObjFrame),fw);
									break;
								case obLabel:
									fwrite((void*)&(((TObjLabel*)obj)->Ax),sizeof(int),1,fw);
									fwrite((void*)&(((TObjLabel*)obj)->Ay),sizeof(int),1,fw);
									fwrite((void*)&(((TObjLabel*)obj)->font),sizeof(int),1,fw);
									UsedFonts[((TObjLabel*)obj)->font]=1;
									fwrite((void*)&(((TObjLabel*)obj)->btn),sizeof(int),1,fw);
									fwrite((void*)&(((TObjLabel*)obj)->btnact),sizeof(int),1,fw);
									fwrite((void*)&(((TObjLabel*)obj)->btnanim),sizeof(int),1,fw);
									fprintf(fw,"%s%c",(((TObjLabel*)obj)->btnactscr==NULL) ? "" : ((TObjLabel*)obj)->btnactscr,'\0');
									fprintf(fw,"%s%c",(((TObjLabel*)obj)->str==NULL) ? "" : ((TObjLabel*)obj)->str,'\0');
									break;
								case obIcon:
									fwrite((void*)&(((TObjIcon*)obj)->Ax),sizeof(int),1,fw);
									fwrite((void*)&(((TObjIcon*)obj)->Ay),sizeof(int),1,fw);
									fwrite((void*)&(((TObjIcon*)obj)->xr),sizeof(int),1,fw);
									fwrite((void*)&(((TObjIcon*)obj)->yr),sizeof(int),1,fw);
									fwrite((void*)(((TObjIcon*)obj)->srcimg),sizeof(char),(((TObjIcon*)obj)->xr)*(((TObjIcon*)obj)->yr),fw);
									fwrite((void*)(((TObjIcon*)obj)->destimg),sizeof(char),(((TObjIcon*)obj)->xr)*(((TObjIcon*)obj)->yr),fw);
									break;
							}
						}
					}

					// total fonts
					fonts=0;
					for(i=0;i<128;i++)
						if(UsedFonts[i]==1) fonts++;

					// save used fonts number
					fwrite((void*)&fonts,sizeof(int),1,fw);

					// save used fonts list (IDs and names)
					for(i=0;i<128;i++)
						if(UsedFonts[i]==1)
						{
							fwrite((void*)&i,sizeof(int),1,fw);
							fprintf(fw,"%s%c",Fonts->font[i].prefix,'\0');
						}

					fclose(fw);
				}
				else
				{
					// can't create file
					if(MessageBox(MForm->Handle,"Can't create project file.\nTry again?","Save project ...",MB_YESNO|MB_ICONQUESTION)==mrYes)
					{
						// try again
						goto SaveProjectRetry;
					}
				}
			}
		}
		else
		{
			//empty project
			MessageBox(MForm->Handle,"Can't save empty project!","Save project ...",MB_ICONEXCLAMATION);
		}
	}

	return(0);
}

//==============================================================================
// create project
//==============================================================================
int CreateProject(void)
{
	if(Project==NULL)
	{ // no project yet
		// create project base struct
		Project=(TProject*)malloc(sizeof(TProject));
		// no screens yet
		Project->screens=0;
		Project->name=NULL;
		Project->scr=NULL;
		screen=-1;
	}
	else
	{ // some project found
		return(1);
	}
	return(0);
}
//==============================================================================
// remove project
//==============================================================================
int RemoveProject(void)
{
	int scrs;
	int i;

	if(Project!=NULL)
	{
		// if there are some screens, remove them

		if(Project->name!=NULL)
		{
			free(Project->name);
			Project->name=NULL;
		}

		if((scrs=Project->screens)>0)
		{
			for(i=0;i<scrs;i++)
			{
				screen=0;
				RemoveScreen();
			}
		}

		// now remove project structure
		free((void*)Project);
		Project=NULL;
	}

	return(0);
}












//**************************************************
//**************************************************
//******************** GENERATE ********************
//**************************************************
//**************************************************
//==============================================================================
// generate screen sources
//==============================================================================
void __fastcall TMForm::MBtnGenerateSrcClick(TObject *Sender)
{
	GenForm->ShowModal();
}

//==============================================================================
// generate screen images
//==============================================================================
void __fastcall TMForm::MBtnGenImgsClick(TObject *Sender)
{
	int i;
	int scr=screen;

	if(Project!=NULL && Project->screens>0)
	{
		SFDpath=genpathimg;
		if(SFD->ShowModal()==mrOk)
		{
			genpathimg=SFDpath;
			for(i=0;i<Project->screens;i++)
			{
				screen=i;
				PaintWorkImg();
				wimg->Picture->Bitmap->SaveToFile(genpathimg+"\\"+AnsiString(Project->scr[i].name)+".bmp");
			}
		}
		screen=scr;
		PaintWorkImg();
	}
}








//***********************************************
//***********************************************
//******************** OTHER ********************
//***********************************************
//***********************************************

//==============================================================================
// compare strings case insensitive
//==============================================================================
int strcmp_ci(char *str1, char *str2)
{
	char c;
	while ((c=toupper(*str1++))==toupper(*str2++))
		if (c=='\0') return(0);
	return (-1);
}

//==============================================================================
// copy string to pointed loacation with allocation
//==============================================================================
int EditObjCstr(char **dest,char *src)
{
	if(*dest!=NULL)
	{
		free((void*)(*dest));
		*dest=NULL;
	}

	if(strlen(src)>0)
	{
		*dest=(char*)malloc(sizeof(char)*strlen(src)+1);
		strcpy(*dest,src);
	}

	return(0);
}

//==============================================================================
// infos
//==============================================================================
void RefreshInfo(void)
{
	if(Project!=NULL)
	{
		MForm->LblScrs->Caption=Project->screens;
		if(Project->screens>0)
			MForm->LblObjs->Caption=Project->scr[screen].objects;
		else
			MForm->LblObjs->Caption=0;
	}
	else
	{
		MForm->LblScrs->Caption=0;
		MForm->LblObjs->Caption=0;
	}

	if(Fonts!=NULL)
		MForm->LblFonts->Caption=Fonts->fonts;
	else
		MForm->LblFonts->Caption=0;
}



//==============================================================================
// button press emulation
//==============================================================================
void __fastcall TMForm::Image1MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=1;
	PaintWorkImg();
}
void __fastcall TMForm::Image1MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image1MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();	
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image2MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=2;
	PaintWorkImg();	
}
void __fastcall TMForm::Image2MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();	
}
void __fastcall TMForm::Image2MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();		
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image3MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=3;
	PaintWorkImg();
}
void __fastcall TMForm::Image3MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image3MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image4MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=4;
	PaintWorkImg();
}
void __fastcall TMForm::Image4MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image4MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image5MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=5;
	PaintWorkImg();
}
void __fastcall TMForm::Image5MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image5MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image6MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=6;
	PaintWorkImg();
}
void __fastcall TMForm::Image6MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image6MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image7MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=7;
	PaintWorkImg();
}
void __fastcall TMForm::Image7MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image7MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------
void __fastcall TMForm::Image8MouseDown(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=8;
	PaintWorkImg();
}
void __fastcall TMForm::Image8MouseUp(TObject *Sender, TMouseButton Button,
			TShiftState Shift, int X, int Y)
{
	buttonst=0;
	PaintWorkImg();
}
void __fastcall TMForm::Image8MouseLeave(TObject *Sender)
{
	buttonst=0;
	PaintWorkImg();
}
//---------------------------------------------------------------------------

