/*
    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 TFormMemoryEditorH
#define TFormMemoryEditorH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.Dialogs.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.Grids.hpp>
#include <Vcl.Menus.hpp>
#include <Vcl.StdCtrls.hpp>
#include "TFormEditValue.h"
#include "..\Emulator\TEmulator.h"
#include "..\Settings\TSettings.h"


// Events types
typedef void __fastcall (__closure *TMemoryEditorEvent)(tNativeCPC* NativeCPC);


//---------------------------------------------------------------------------
class TFormMemoryEditor : public TForm
{
__published:	// Composants gérés par l'EDI
  TTabControl *TabControlMemoryContent;
  TScrollBar *ScrollBarDump;
  TStringGrid *StringGridDump;
  TPageControl *PageControlOperations;
  TTabSheet *TabSheetAddress;
  TTabSheet *TabSheetSearch;
  TTabSheet *TabSheetFill;
  TPanel *PanelAddress1;
  TLabel *LabelRegisters;
  TPanel *PanelFormatSearch;
  TEdit *EditSearch;
  TPanel *PanelStatus;
  TLabel *LabelCurrentAddress;
  TPanel *PanelCurrentAddress;
  TCheckBox *CheckBoxStringCaseSensitive;
  TPanel *PanelFormatFillFrom;
  TPanel *PanelFillFrom;
  TLabel *LabelFillFrom;
  TLabel *LabelFillTo;
  TPanel *PanelFormatFillTo;
  TPanel *PanelFillTo;
  TLabel *LabelFillData;
  TPanel *PanelFormatFillData;
  TPanel *PanelFillData;
  TPanel *PanelAddress2;
  TLabel *LabelSearch;
  TTabSheet *TabSheetDump;
  TLabel *LabelDumpFrom;
  TPanel *PanelFormatExportFrom;
  TPanel *PanelExportFrom;
  TLabel *LabelDumpTo;
  TPanel *PanelFormatExportTo;
  TPanel *PanelExportTo;
  TSaveDialog *SaveDialog;
  TOpenDialog *OpenDialog;
  TTabSheet *TabSheetBanks;
  TLabel *LabelBanksRead;
  TLabel *LabelBanksWrite;
	TLabel *LabelBanksRangeC000;
	TLabel *LabelBanksRange8000;
	TLabel *LabelBanksRange4000;
	TLabel *LabelBanksRange0000;
	TLabel *LabelBanksAddress;
	TPanel *PanelButtonBankRead4000;
	TPanel *PanelButtonBankWrite4000;
	TPanel *PanelButtonBankRead8000;
	TPanel *PanelButtonBankWrite8000;
	TPanel *PanelButtonBankWrite0000;
	TPanel *PanelButtonBankWriteC000;
	TPanel *PanelButtonBankRead0000;
	TPanel *PanelButtonBankReadC000;
  TPanel *PanelEditValue;
  TEdit *EditValue;
  TPanel *PanelButtonRefresh;
	TPanel *PanelCheckMonitoring;
  TPanel *PanelButtonSetAddress1;
  TPanel *PanelButtonGoToAddress1;
  TPanel *PanelButtonSetAddress2;
  TPanel *PanelButtonGoToAddress2;
  TPanel *PanelButtonRegBC;
  TPanel *PanelButtonRegBCAlt;
  TPanel *PanelButtonRegDE;
  TPanel *PanelButtonRegDEAlt;
  TPanel *PanelButtonRegHL;
  TPanel *PanelButtonRegHLAlt;
  TPanel *PanelButtonRegSP;
  TPanel *PanelButtonRegPC;
  TPanel *PanelButtonRegIX;
  TPanel *PanelButtonRegIY;
  TPanel *PanelButtonSearchNext;
  TPanel *PanelButtonSetFillFrom;
  TPanel *PanelButtonSetFillTo;
  TPanel *PanelButtonSetFillData;
  TPanel *PanelButtonFill;
  TPanel *PanelButtonDumpSetFullLimits;
  TPanel *PanelButtonSetDumpFrom;
  TPanel *PanelButtonSetDumpTo;
  TPanel *PanelButtonDumpExportText;
  TPanel *PanelButtonDumpExportBinary;
  TPanel *PanelButtonDumpImportBinary;
  TPanel *PanelButtonSetAddress3;
  TPanel *PanelAddress3;
  TPanel *PanelButtonGoToAddress3;
  TPanel *PanelButtonSetAddress4;
  TPanel *PanelAddress4;
  TPanel *PanelButtonGoToAddress4;
	TLabel *LabelHelpMemoryDump;
	TPanel *PanelButtonGoCurrentAddress;
	TPopupMenu *PopupMenuMemoryCell;
	TMenuItem *AddReadWriteMemoryBreakpointMenu;
	TPanel *PanelButtonAddBreakpoint;
	TPanel *PanelCheckShowASCII7Bits;
	TPanel *PanelCheckShowDiff;
	TMenuItem *SetZ80InstructionsTopAddressMenu;
	TPanel *PanelButtonShowInstruction;
	TLabel *LabelRAMBanksBaseAddress;
	TComboBox *ComboBoxRAMBanksBaseAddress;
	TLabel *LabelRAMBanksMapping;
	TComboBox *ComboBoxRAMBanksMapping;
	TLabel *LabelRAMSettings;
  void __fastcall FormShow(TObject *Sender);
  void __fastcall FormHide(TObject *Sender);
  void __fastcall FormResize(TObject *Sender);
  void __fastcall StringGridDumpSelectCell(TObject *Sender, int ACol,
          int ARow, bool &CanSelect);
  void __fastcall ScrollBarDumpChange(TObject *Sender);
  void __fastcall PanelMarkerAddressClick(TObject *Sender);
  void __fastcall StringGridDumpKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
  void __fastcall StringGridDumpMouseWheelDown(TObject *Sender,
          TShiftState Shift, TPoint &MousePos, bool &Handled);
  void __fastcall StringGridDumpMouseWheelUp(TObject *Sender,
          TShiftState Shift, TPoint &MousePos, bool &Handled);
  void __fastcall TabControlMemoryContentChange(TObject *Sender);
  void __fastcall StringGridDumpClick(TObject *Sender);
  void __fastcall PanelFormatSearchClick(TObject *Sender);
  void __fastcall PageControlOperationsChange(TObject *Sender);
  void __fastcall PanelFormatFillFromClick(TObject *Sender);
  void __fastcall PanelFormatFillToClick(TObject *Sender);
  void __fastcall PanelFormatFillDataClick(TObject *Sender);
  void __fastcall PanelFillFromClick(TObject *Sender);
  void __fastcall PanelFillToClick(TObject *Sender);
  void __fastcall PanelFillDataClick(TObject *Sender);
  void __fastcall PanelCurrentAddressClick(TObject *Sender);
  void __fastcall StringGridDumpGetEditMask(TObject *Sender, int ACol,
          int ARow, AnsiString &Value);
  void __fastcall StringGridDumpKeyPress(TObject *Sender, char &Key);
  void __fastcall FormDestroy(TObject *Sender);
  void __fastcall PanelFormatExportFromClick(TObject *Sender);
  void __fastcall PanelFormatExportToClick(TObject *Sender);
  void __fastcall StringGridDumpMouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
  void __fastcall PanelExportFromClick(TObject *Sender);
  void __fastcall PanelExportToClick(TObject *Sender);
  void __fastcall TabControlMemoryContentDrawTab(TCustomTabControl *Control, int TabIndex,
          const TRect &Rect, bool Active);
  void __fastcall StringGridDumpDrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
          TGridDrawState State);
  void __fastcall PageControlOperationsDrawTab(TCustomTabControl *Control, int TabIndex,
          const TRect &Rect, bool Active);
  void __fastcall StringGridDumpDblClick(TObject *Sender);
  void __fastcall EditValueKeyPress(TObject *Sender, System::WideChar &Key);
  void __fastcall EditValueExit(TObject *Sender);
  void __fastcall EditValueChange(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 PanelButtonRefreshClick(TObject *Sender);
  void __fastcall PanelCheckMonitoringClick(TObject *Sender);
  void __fastcall PanelButtonSetAddressClick(TObject *Sender);
  void __fastcall PanelButtonGoToAddressClick(TObject *Sender);
  void __fastcall PanelButtonRegBCClick(TObject *Sender);
  void __fastcall PanelButtonRegBCAltClick(TObject *Sender);
  void __fastcall PanelButtonRegDEClick(TObject *Sender);
  void __fastcall PanelButtonRegDEAltClick(TObject *Sender);
  void __fastcall PanelButtonRegHLClick(TObject *Sender);
  void __fastcall PanelButtonRegHLAltClick(TObject *Sender);
  void __fastcall PanelButtonRegSPClick(TObject *Sender);
  void __fastcall PanelButtonRegPCClick(TObject *Sender);
  void __fastcall PanelButtonRegIXClick(TObject *Sender);
  void __fastcall PanelButtonRegIYClick(TObject *Sender);
  void __fastcall PanelButtonSearchNextClick(TObject *Sender);
  void __fastcall PanelButtonSetFillFromClick(TObject *Sender);
  void __fastcall PanelButtonSetFillToClick(TObject *Sender);
  void __fastcall PanelButtonSetFillDataClick(TObject *Sender);
  void __fastcall PanelButtonFillClick(TObject *Sender);
  void __fastcall PanelButtonDumpSetFullLimitsClick(TObject *Sender);
  void __fastcall PanelButtonSetDumpFromClick(TObject *Sender);
  void __fastcall PanelButtonSetDumpToClick(TObject *Sender);
  void __fastcall PanelButtonDumpExportTextClick(TObject *Sender);
  void __fastcall PanelButtonDumpExportBinaryClick(TObject *Sender);
  void __fastcall PanelButtonDumpImportBinaryClick(TObject *Sender);
	void __fastcall PanelButtonBankRead4000Click(TObject *Sender);
	void __fastcall PanelButtonBankWrite4000Click(TObject *Sender);
	void __fastcall PanelButtonBankRead8000Click(TObject *Sender);
	void __fastcall PanelButtonBankWrite8000Click(TObject *Sender);
	void __fastcall PanelButtonBankRead0000Click(TObject *Sender);
	void __fastcall PanelButtonBankWrite0000Click(TObject *Sender);
	void __fastcall PanelButtonBankReadC000Click(TObject *Sender);
	void __fastcall PanelButtonBankWriteC000Click(TObject *Sender);
	void __fastcall ScrollBarDumpKeyPress(TObject *Sender, System::WideChar &Key);
	void __fastcall PanelButtonGoCurrentAddressClick(TObject *Sender);
	void __fastcall PanelButtonAddBreakpointClick(TObject *Sender);
	void __fastcall PanelCheckShowASCII7BitsClick(TObject *Sender);
	void __fastcall PanelCheckShowDiffClick(TObject *Sender);
	void __fastcall SetZ80InstructionsTopAddressMenuClick(TObject *Sender);
	void __fastcall EditSearchKeyPress(TObject *Sender, System::WideChar &Key);
	void __fastcall ComboBoxDrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State);
	void __fastcall ComboBoxRAMBanksBaseAddressChange(TObject *Sender);
	void __fastcall ComboBoxRAMBanksMappingChange(TObject *Sender);

private:	// Déclarations utilisateur
  //
  // Members
  //
  TSettings* mSettingsP;
  bool mPaused;
  bool mMonitoring;
	tULong mCurrentAddress;
  tULong mTopAddress;
	tULong mMaxTopAddress;
  tULong mMemoryStartAddress;
  tULong mMemorySize;
  TMemoryEditorEvent mShowMemoryDumpRoutine;
  TMemoryEditorEvent mWriteDataRoutine;
  TMemoryEditorEvent mSearchASCIIRoutine;
  TMemoryEditorEvent mSearchHexRoutine;
  TMemoryEditorEvent mMemoryDiffRoutine;
	AnsiString mCurrentData;
  tULong mFillFromAddress;
  tULong mFillToAddress;
  tULong mFillData;
	tULong mExportFromAddress;
  tULong mExportToAddress;
  char* mSearchBytes;
  int mSearchLength;
  int mChangeValueIncrement;
  int mChangeValueNextRequested;
  bool mChangeValueHexa;
	TFormEditValue* mFormEditValue;
	tUChar* mPreviousMemory;
	tUChar* mMemoryDiff;
	bool mShowASCII7Bits;
	bool mShowDiffHighlight;

	//
  // Methods
  //
  AnsiString __fastcall GetTitle(void);
	void __fastcall WMMove(TMessage &Message);
	void __fastcall SetSettings(TSettings* Value);
  void __fastcall SetDisplayRows(int Value);
  inline tULong __fastcall GetCurrentAddress(void) { return mCurrentAddress; };
  void __fastcall SetCurrentAddress(tULong Value);
  void __fastcall SetMemorySize(tULong Value);
  inline tULong __fastcall GetTopAddress(void) { return mTopAddress; };
	void __fastcall SetTopAddress(tULong Value);
  void __fastcall SetMemoryStartAddress(tULong Value);
  void __fastcall SetMemoryIndex(int Value);
  void __fastcall ShowBankedREADDump(tNativeCPC* NativeCPC);
  void __fastcall ShowBankedWRITEDump(tNativeCPC* NativeCPC);
  void __fastcall ShowEntireRAMDump(tNativeCPC* NativeCPC);
  void __fastcall ShowLowerROMDump(tNativeCPC* NativeCPC);
  void __fastcall ShowUpperROMDump(tNativeCPC* NativeCPC);
  void __fastcall WriteDataBankedREAD(tNativeCPC* NativeCPC);
  void __fastcall WriteDataBankedWRITE(tNativeCPC* NativeCPC);
  void __fastcall WriteDataEntireRAM(tNativeCPC* NativeCPC);
  void __fastcall WriteDataLowerROM(tNativeCPC* NativeCPC);
  void __fastcall WriteDataUpperROM(tNativeCPC* NativeCPC);
  void __fastcall SearchASCIIBankedREAD(tNativeCPC* NativeCPC);
  void __fastcall SearchHexBankedREAD(tNativeCPC* NativeCPC);
  void __fastcall SearchASCIIBankedWRITE(tNativeCPC* NativeCPC);
  void __fastcall SearchHexBankedWRITE(tNativeCPC* NativeCPC);
  void __fastcall SearchASCIIEntireRAMMemory(tNativeCPC* NativeCPC);
  void __fastcall SearchHexEntireRAMMemory(tNativeCPC* NativeCPC);
  void __fastcall SearchASCIILowerROMMemory(tNativeCPC* NativeCPC);
  void __fastcall SearchHexLowerROMMemory(tNativeCPC* NativeCPC);
  void __fastcall SearchASCIIUpperROMMemory(tNativeCPC* NativeCPC);
  void __fastcall SearchHexUpperROMMemory(tNativeCPC* NativeCPC);
  void __fastcall PerformBankedREADDiff(tNativeCPC* NativeCPC);
  void __fastcall PerformBankedWRITEDiff(tNativeCPC* NativeCPC);
  void __fastcall PerformLowerROMDiff(tNativeCPC* NativeCPC);
  void __fastcall PerformUpperROMDiff(tNativeCPC* NativeCPC);
  void __fastcall PerformEntireRAMDiff(tNativeCPC* NativeCPC);
	void __fastcall UpdateBanks(tNativeCPC* NativeCPC);
  bool __fastcall OnCPCEvent(tULong Condition, tNativeCPC* NativeCPC);
	//
  // Private Properties
	//
	__property int DisplayRows = { write=SetDisplayRows };
	__property tULong CurrentAddress = { read=GetCurrentAddress, write=SetCurrentAddress };
	__property tULong MemorySize = { write=SetMemorySize };
	__property tULong MemoryStartAddress = { write=SetMemoryStartAddress };
	__property tULong TopAddress = { read=GetTopAddress, write=SetTopAddress };
	__property int MemoryIndex = { write=SetMemoryIndex };

public:		// Déclarations utilisateur
	//
	// Public Properties
	//
	__property AnsiString Title = { read=GetTitle };
	__property TSettings* Settings = { write=SetSettings };

	//
  // API
  //
  __fastcall TFormMemoryEditor(TComponent* Owner);
	void __fastcall ShowCurrentAddress(tULong Address);

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