/*
    CaPriCe Forever - Amstrad CPC 464/664/6128 emulator
    Copyright (C) 2014-2015 by Frédéric Coste

    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 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef TFormDebuggerH
#define TFormDebuggerH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Grids.hpp>
#include "..\Emulator\TEmulator.h"
#include "..\Settings\TSettings.h"
#include "TFormEditValue.h"
//---------------------------------------------------------------------------
class TFormDebugger : public TForm
{
__published:	// Composants gérés par l'EDI
  TPanel *PanelButtonRun;
  TPanel *PanelButtonPlay;
  TPanel *PanelButtonStep;
  TPanel *PanelButtonPlayTillVBL;
  TPanel *PanelButtonPlayTillHBL;
	TPageControl *PageControlData;
	TTabSheet *TabSheetBreakpoints;
	TPanel *PanelButtonBreakpointsUseNone;
	TPanel *PanelButtonBreakpointsUseAll;
	TStringGrid *StringGridBreakpoints;
	TPanel *PanelButtonBreakpointsAdd;
	TPanel *PanelButtonBreakpointsDel;
	TPanel *PanelButtonBreakpointsAddPPC;
	TPanel *PanelButtonStepOUT;
	TPanel *PanelButtonShowInstruction;
	TPanel *PanelButtonShowMemory;
	TPanel *PanelButtonShowPC;
	TGroupBox *GroupBoxSelectedBreakpoint;
	TPanel *PanelCheckUseBreakpoint;
	TPanel *PanelBreakpointAddress;
	TPanel *PanelCheckBreakpointPC;
	TPanel *PanelCheckBreakpointRead;
	TPanel *PanelCheckBreakpointWrite;
	TTabSheet *TabSheetTime;
	TLabel *LabelTitleTimeFromResetUS;
	TLabel *LabelTitleTimeFromResetS;
	TLabel *LabelTimeFromResetS;
	TLabel *LabelTimeFromResetUS;
	TLabel *LabelTimeFromLastPauseMS;
	TLabel *LabelTimeFromLastPauseUS;
	TLabel *LabelTitleTimeFromLastPauseMS;
	TLabel *LabelTitleTimeFromLastPauseUS;
	TPanel *PanelCheckLowerROM;
	TPanel *PanelCheckUpperROM;
	TPanel *PanelBreakpointUpperROMIndex;
        void __fastcall FormResize(TObject *Sender);
  void __fastcall FormShow(TObject *Sender);
  void __fastcall FormHide(TObject *Sender);
  void __fastcall PanelButtonMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
  void __fastcall PanelButtonMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
  void __fastcall PanelButtonRunClick(TObject *Sender);
  void __fastcall PanelButtonPlayClick(TObject *Sender);
  void __fastcall PanelButtonStepClick(TObject *Sender);
  void __fastcall PanelButtonPlayTillVBLClick(TObject *Sender);
  void __fastcall PanelButtonPlayTillHBLClick(TObject *Sender);
	void __fastcall PageControlDataDrawTab(TCustomTabControl *Control, int TabIndex,
          const TRect &Rect, bool Active);
	void __fastcall StringGridBreakpointsDrawCell(TObject *Sender, int ACol, int ARow,
          TRect &Rect, TGridDrawState State);
	void __fastcall PanelButtonBreakpointsAddClick(TObject *Sender);
	void __fastcall StringGridBreakpointsSelectCell(TObject *Sender, int ACol, int ARow,
          bool &CanSelect);
	void __fastcall FormDestroy(TObject *Sender);
	void __fastcall PanelCheckUseBreakpointClick(TObject *Sender);
	void __fastcall PanelButtonBreakpointsUseNoneClick(TObject *Sender);
	void __fastcall PanelButtonBreakpointsUseAllClick(TObject *Sender);
	void __fastcall PanelButtonBreakpointsDelClick(TObject *Sender);
	void __fastcall PanelCheckBreakpointPCClick(TObject *Sender);
	void __fastcall PanelCheckBreakpointWriteClick(TObject *Sender);
	void __fastcall PanelCheckBreakpointReadClick(TObject *Sender);
	void __fastcall StringGridBreakpointsMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
	void __fastcall StringGridBreakpointsKeyPress(TObject *Sender, System::WideChar &Key);
	void __fastcall PanelBreakpointAddressClick(TObject *Sender);
	void __fastcall StringGridBreakpointsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift);
	void __fastcall StringGridBreakpointsClick(TObject *Sender);
	void __fastcall PanelButtonBreakpointsAddPPCClick(TObject *Sender);
	void __fastcall PanelButtonStepOUTClick(TObject *Sender);
	void __fastcall PanelButtonShowInstructionClick(TObject *Sender);
	void __fastcall PanelButtonShowMemoryClick(TObject *Sender);
	void __fastcall PanelButtonShowPCClick(TObject *Sender);
	void __fastcall PanelCheckLowerROMClick(TObject *Sender);
	void __fastcall PanelCheckUpperROMClick(TObject *Sender);
	void __fastcall PanelBreakpointUpperROMIndexClick(TObject *Sender);



private:	// Déclarations utilisateur
  //
  // Members
  //
  TSettings* mSettingsP;
  bool mPaused;
  bool mPauseRequested;
  bool mStepByStep;
  bool mRunTillVBL;
  bool mRunTillHBL;
  bool mPreviousVBL;
  bool mPreviousHBL;
	tTimer mTimerLastPause;
	TList* mBreakpointsList;
	tULong mCurrentPC;
	tULong mCurrentPPC;
	tULong mCurrentMemoryRead;
	tULong mCurrentMemoryWrite;
	bool mCurrentLowerROM;
	bool mCurrentUpperROM;
	tUChar mCurrentUpperROMIndex;
	TEmulatorBreakpoint mStepOUTbreakpoint;
	bool mPausedByBreakpoint;
	TFormEditValue* mFormEditValue;
	//
	// Methods
  //
  AnsiString __fastcall GetTitle(void);
  void __fastcall WMMove(TMessage &Message);
  void __fastcall SetSettings(TSettings* Value);
  void __fastcall UpdateControls(bool Pause, bool StepByStep);
	void __fastcall UpdateTimes(void);
	bool __fastcall OnCPCEvent(tULong Condition, tNativeCPC* NativeCPC);
	void __fastcall UpdateBreakpointsGUI(bool Pause);
	void __fastcall UpdateBreakpointPanel(void);
	bool __fastcall AddBreakpoint(TEmulatorBreakpoint* NewBreakpointP);
	void __fastcall DeleteBreakpoint(TEmulatorBreakpoint* BreakpointP);
	void __fastcall SelectActiveBreakpoint(void);
	void __fastcall FillBreakpoints(void);
	void __fastcall SelectBreakpoint(int Index);
	void __fastcall AddBreakpointPC(tULong Address, bool Use);
	void __fastcall AddBreakpointPC(TEmulatorBreakpoint Breakpoint, bool Use);
	void __fastcall AddBreakpointMem(tULong Address, bool Use, bool Read, bool Write);
	void __fastcall AddBreakpointMem(TEmulatorBreakpoint Breakpoint, bool Use);

	//
	// Private properties
	//
	__property AnsiString Title = { read=GetTitle };

public:		// Déclarations utilisateur
	//
	// Public properties
	//
	__property TSettings* Settings = { write=SetSettings };

	//
	// API
	//
	__fastcall TFormDebugger(TComponent* Owner);

	void __fastcall Run(void);
	void __fastcall Play(void);
	void __fastcall Step(void);
	void __fastcall Next(void);
	void __fastcall ToggleBreakpointPC(tULong Address);
	void __fastcall ToggleBreakpointPC(TEmulatorBreakpoint Breakpoint);
	void __fastcall ToggleBreakpointMem(TEmulatorBreakpoint Breakpoint);

#pragma option push -vi-
BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(WM_MOVE, TMessage, WMMove);
END_MESSAGE_MAP(TForm)
#pragma option pop
};
//---------------------------------------------------------------------------
extern PACKAGE TFormDebugger *FormDebugger;
//---------------------------------------------------------------------------
#endif
