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

#ifndef MainFormH
#define MainFormH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
#include <ComCtrls.hpp>
#include <ToolWin.hpp>
#include <ExtCtrls.hpp>
#include <Buttons.hpp>
#include <ImgList.hpp>
#include <ActnList.hpp>
#include <Menus.hpp>
#include <Dialogs.hpp>
#include <ExtDlgs.hpp>
#include <Graphics.hpp>
#include <StdActns.hpp>
#include <System.Actions.hpp>
//---------------------------------------------------------------------------

#include <stack>

enum CELL_TYPE {ctEMPTY, ctOBSTACLE, ctCHARACTER, ctENEMY, ctPRIZE};

struct ColorID
{
	CELL_TYPE type;
	TColor color;
};

struct CellData
{
	int row;
	int col;
	CELL_TYPE ctype;
};

class TfrmMain : public TForm
{
__published:	// IDE-managed Components
	TStatusBar *barStatus;
	TPageControl *pgeWorld;
	TTabSheet *shtDesign;
	TPanel *pnlWorld;
	TDrawGrid *gridWorld;
	TPanel *pnlBottom;
	TSplitter *splitHorizontal;
	TMemo *mmoStatus;
	TToolBar *barColors;
	TToolButton *btnEmpty;
	TToolButton *btnObstacle;
	TToolButton *btnCharacter;
	TToolButton *btnEnemy;
	TToolButton *btnPrize;
	TImageList *lstImages;
	TActionList *lstActions;
	TMainMenu *mnuMain;
	TAction *actFileOpen;
	TAction *actFileSave;
	TAction *actFileNew;
	TAction *actFileExit;
	TAction *actFileSaveAs;
	TMenuItem *mnuFile;
	TMenuItem *mnuFileNew;
	TMenuItem *mnuFileOpen;
	TMenuItem *mnuFileSave;
	TMenuItem *mnuFileSaveAs;
	TMenuItem *N1;
	TMenuItem *mnuFileExit;
	TLabel *lblRows;
	TEdit *edtRows;
	TUpDown *spnRows;
	TLabel *lblColumns;
	TEdit *edtColumns;
	TUpDown *spnColumns;
	TOpenDialog *dlgFileOpen;
	TSaveTextFileDialog *dlgFileSaveText;
	TToolBar *barMainTools;
	TToolButton *btnFileNew;
	TToolButton *btnFileOpen;
	TToolButton *btnFileSave;
	TToolButton *btnFileSaveAs;
	TToolButton *btnSep1;
	TImageList *lstColors;
	TToolButton *btnTest;
	TAction *actTest;
	TAction *actShowGrid;
	TToolButton *btnDUMMY;
	TToolButton *btnGrid;
	TImage *imgPrize;
	TMenuItem *mnuHelp;
	TAction *actHelpAbout;
	TMenuItem *mnuHelpAbout;
	TMenuItem *mnuEdit;
	TMenuItem *mnuEditConfig;
	TAction *actEditConfiguration;
	TMenuItem *mnuEditUndo;
	TMenuItem *N2;
	TToolButton *btnUndo;
	TAction *actEditUndo;
	TAction *actEditRedo;
	TMenuItem *mnuEditRedo;
	TToolButton *btnRedo;
	TToolButton *btnSep2;
	TTabSheet *shtConfiguration;
	TComboBox *lstGravity;
	TLabel *lblGravity;
	TComboBox *lstJumpVelocity;
	TLabel *lblJumpVelocity;
	TComboBox *lstMoveVelocityHero;
	TLabel *lblEnemyIdleTime;
	TComboBox *lstMoveVelocityEnemy;
	TLabel *lblMoveVelocityHero;
	TComboBox *lstEnemyIdleTime;
	TLabel *lblMoveVelocityEnemy;
	TUpDown *spnHeroLives;
	TEdit *edtHeroLives;
	TLabel *lblHeroLives;
	TGroupBox *GroupBox1;
	TCheckBox *chkMultiJump;
	void __fastcall FormCreate(TObject *Sender);
	void __fastcall shtDesignResize(TObject *Sender);
	void __fastcall OnCellCountChange(TObject *Sender);
	void __fastcall gridWorldDrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State);
	void __fastcall gridWorldSelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect);
	void __fastcall splitHorizontalMoved(TObject *Sender);
	void __fastcall gridWorldMouseMove(TObject *Sender, TShiftState Shift, int X, int Y);
	void __fastcall gridWorldMouseLeave(TObject *Sender);
	void __fastcall gridWorldMouseEnter(TObject *Sender);
	void __fastcall ColorChange(TObject *Sender);
	void __fastcall actFileOpenExecute(TObject *Sender);
	void __fastcall actFileSaveExecute(TObject *Sender);
	void __fastcall actTestExecute(TObject *Sender);
	void __fastcall actFileNewExecute(TObject *Sender);
	void __fastcall actShowGridExecute(TObject *Sender);
	void __fastcall FormDestroy(TObject *Sender);
	void __fastcall gridWorldMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y);
	void __fastcall actHelpAboutExecute(TObject *Sender);
	void __fastcall actEditConfigurationExecute(TObject *Sender);
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
	void __fastcall actEditUndoExecute(TObject *Sender);
	void __fastcall actEditUndoUpdate(TObject *Sender);
	void __fastcall actEditRedoExecute(TObject *Sender);
	void __fastcall actEditRedoUpdate(TObject *Sender);
	void __fastcall FormShow(TObject *Sender);
private:
		// Some limitations (for now)
	static const int FMaxRows = 201;
	static const int FMaxColumns = 201;

		// Hold the values of the cells
	short FDataMap[FMaxRows][FMaxColumns];

	int FCellWidth;  // Width of a grid cell
	int FCellHeight; // Heigth of a grid cell
	short FRows;     // Number of rows in the grid
	short FColumns;  // Number of columns in the grid
	int FCurrRow;    // Currently selected row
	int FCurrColumn; // Currently selected column
	int FPrevRow;    // Previously selected row
	int FPrevColumn; // Previously selected column

	bool FOffGrid;        // mouse on/off the grid
	bool FShowGrid;       // Grid lines on/off
	TColor FGridColor;    // Color of the grid lines
	ColorID FCurrColorID; // Currently selected color (type)

	AnsiString FCurrFileName; // The filename to save the data to

		// Save the state of the cells for undo
	std::stack<CellData> UndoData;
	bool IsUndo;

	std::stack<CellData> RedoData;

	void InitializeApp(void);
	void AdjustGrid(void);
	void DisplayCurrentCellInStatusBar(void);
	void AddStatus(const char *text);
	void HighlightCell(bool Force = false);
	void ChangeGrid(bool Show);
	void DrawCell(int ACol, int ARow, TRect &Rect);	

	void PushUndo(void);
	void PopUndo(void);
	void PushRedo(void);
	void PopRedo(void);

	bool ImportMapData(const AnsiString &FileName);
	bool ExportMapData(const AnsiString &FileName);
	void WriteCS230ConfigFile(const AnsiString &FileName);
	void ReadCS230ConfigFile(const AnsiString &FileName);

	void __fastcall WMDropFiles(TWMDropFiles &Message);

public:
	__fastcall TfrmMain(TComponent* Owner);

	// To be compatible with Microsoft
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles)
END_MESSAGE_MAP(TForm)

};
//---------------------------------------------------------------------------
extern PACKAGE TfrmMain *frmMain;
//---------------------------------------------------------------------------
#endif
