#ifndef __XPAD_H
#define __XPAD_H


// Include system headers
#include <XBApp.h>
#include <XBFont.h>
#include "xPadXBFont.h"
#include <vector>
// Include local headers
#include "Resource.h"
#include "FileBrowser.h"
#include "KeyPadWindow.h"
#include "MenuSystem.h"
#include "SettingsWindow.h"

class CxPadXBFont;

using namespace std;

// Global settings
#define SCREEN_SIZE_X 640   //720 //640
#define SCREEN_SIZE_Y 480
#define MAX_VISIBLE_LINES 16


#define IN  
#define DEBUG_SEMITRANS_BLUE    0x80A6CAF0

#define SEMITRANS_BLUE          0x400A246A
#define SEMITRANS_LIGHTBLUE     0x40A6CAF0
#define COLOUR_BLUE             0xff0A246A
#define COLOUR_WHITE            0xffffffff
#define COLOUR_LIGHTBLUE        0xffA6CAF0
#define MENU_GRAY               0xffD4D0C8
#define MENU_GRAY_BORDER        0xff888888
#define MENU_ITEM_SELECT        0x400A246A
#define MENU_MAIN_SELECT        0x40A6CAF0
#define KEYPAD_BACK             0xff2965A1
#define KEYPAD_OUTLINE          0xff7BA9CE

#define MNU_FILE_NEW            1
#define MNU_FILE_OPEN           2
#define MNU_FILE_SAVE           3
#define MNU_FILE_SAVEAS         4
#define MNU_FILE_EXIT           5
#define MNU_EDIT_UNDO           6
#define MNU_EDIT_CUT            7
#define MNU_EDIT_COPY           8
#define MNU_EDIT_PASTE          9
#define MNU_EDIT_DELETE         10
#define MNU_EDIT_FIND           11
#define MNU_EDIT_FINDNEXT       12
#define MNU_EDIT_REPLACE        13
#define MNU_EDIT_GOTO           14
#define MNU_EDIT_SELECTALL      15
#define MNU_OPTIONS_SETTINGS    16
#define MNU_OPTIONS_DPADCONTROL 17




struct SCREENVERTEX
{
    D3DXVECTOR4 pos;   // The transformed position for the vertex point.
    DWORD       color; // The vertex color. 
};

#define D3DFVF_SCREENVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;


struct TRANSFORMED_VERTEX
{
    float	x,y,z, rhw; // The transfrmed screen position
    float	tu, tv;		// The texture coordinates
};
#define D3DFVF_CUSTOM_TRANSFORMED_VERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1)


#define DriveD "\\??\\D:"

#define MountPartitionC "\\Device\\Harddisk0\\Partition2"
#define MountPartitionD "\\Device\\Cdrom0"
#define MountPartitionE "\\Device\\Harddisk0\\Partition1"
#define MountPartitionF "\\Device\\Harddisk0\\Partition6"
#define MountPartitionX "\\Device\\Harddisk0\\Partition3"
#define MountPartitionY "\\Device\\Harddisk0\\Partition4"
#define MountPartitionZ "\\Device\\Harddisk0\\Partition5"


// Forward declarations
class CXFileBrowser;
class CXKeyPadWindow;
class CXMenuSystem;
class CXSettingsWindow;

class CXxPad : public CXBApplication
{
    enum MenuItem
    {
      ITEM_FILE,
      ITEM_EDIT
    };

    // Clone of the keyboard structure in our class.
    typedef struct _XINPUT_DEBUG_KEYSTROKE
    {
        BYTE VirtualKey;
        CHAR Ascii;
        BYTE Flags;
    };
    //struct FILELINE
    //{
    //  char linechars[256];
    //};

    LPDIRECT3DTEXTURE8      m_pBackground;

    FLOAT kpX;
    FLOAT kpY;
    // array of strings to represent the entire file
    // type def an array of string
    //typedef vector<char *> strings;
    typedef vector<string> strings; 

    strings fileContents;

    long filesize;
    bool reCalcFileSize;
    void calcFileSize();

    HRESULT RenderWindow();
    HRESULT RenderFileContents();
    HRESULT RenderTextSelector(DWORD color);



public:
    
    CXFileBrowser		  *m_FileBrowser;
		CXKeyPadWindow	  *m_KeyPadWindow;
    CXMenuSystem      *m_MenuSystem;
    CXSettingsWindow  *m_SettingsWindow;

    int curLine;
    int curLinePage;
    int curCol;
    int curColVirt;
    int curColPage;
    int totalLines;
    bool ignoreInput;
    CHAR lastKBChar;

  
    enum Mode
    {
       MODE_NORMAL,
       MODE_MENU,
       MODE_MENU_FILE,
       MODE_FILESELECT,
       MODE_FILESAVEAS,
       MODE_SETTINGS
    };

	  enum CntrlMode
	  {
		  CONTROL_LEFTSTICK,
		  CONTROL_DPAD
	  };

	  CntrlMode controlMode;


    CXxPad();
    HRESULT Initialize();
    HRESULT Render();
    HRESULT Cleanup();
    HRESULT FrameMove();

    HRESULT RenderQuad(  LPDIRECT3DTEXTURE8 pTexture, FLOAT fAlpha );

    VOID    DrawLine( FLOAT x1, FLOAT y1, FLOAT x2, FLOAT y2, DWORD dwColor );
    VOID    DrawRect( FLOAT x1, FLOAT y1, FLOAT x2, FLOAT y2, DWORD dwStartColor, DWORD dwEndColor );
    VOID    DrawRectOutline( FLOAT x1, FLOAT y1, FLOAT x2, FLOAT y2, DWORD dwColor );
    VOID    RenderTile( const D3DXVECTOR4& rc, const LPDIRECT3DTEXTURE8 pTile) const;
    VOID    RenderImage( const D3DXVECTOR4& rc, const LPDIRECT3DTEXTURE8 pTile, FLOAT fAlpha, FLOAT fTopWarp, FLOAT fBottomWarp ) const;

    Mode curMode;
    // Packed resources for the app
    CXBPackedResource       m_xprResource;

    XBGAMEPAD* GetGamePad();

    void ChangeDrive(IN PUNICODE_STRING DeviceName);
    void OpenFile(LPCTSTR filename);
    void SaveFile(LPCTSTR filename);
    char currentFilename[MAX_PATH];
    void ResetWorkspace();
    void ResetMenuSystem();
    void RenderKeypadWindow();
    void MoveKeypadWindow();
    
    // Font
    CXBFont                 m_Font;
    CxPadXBFont             m_editFont;

    // Keyboard routines
    void ProcessKeyboard();

    // Faster Helper functions for common tasks
    
    // Editing window
    void MoveCursorUp(int count = 1);
    bool movingUp;
    bool BeginCursorUpRepeat();

    void MoveCursorDown(int count = 1);
    bool movingDown;
    bool BeginCursorDownRepeat();

    void MoveCursorLeft(int count = 1);
    bool movingLeft;
    bool BeginCursorLeftRepeat();

    void MoveCursorRight(int count = 1);
    bool movingRight;
    bool BeginCursorRightRepeat();

    bool IsCharacterOfType(int position, char character);
    int  CountNumberOfTabs(string sline, bool onlyToCurPos = false);

    // Holding x down
    bool holdingXDown;
    bool BeginButtonXRepeat();
    bool holdingADown;
    bool BeginButtonARepeat();
    bool holdingBDown;
    bool BeginButtonBRepeat();
    bool holdingLTDown;
    bool BeginButtonLTRepeat();
    bool holdingRTDown;
    bool BeginButtonRTRepeat();


    void InsertStringAtCursor(string stringToInsert);
    void InsertCurrentCharacterFromKeypadAtCursor();
    void InsertLineAtCursor();
    void DeleteCharactersAtCursor(int count);
    void DeleteLinesAtCursor(int count);
    int GetCurrentLineLength();
    void ValidateCursorHorizPos();
    void MoveCursorToStartOfLine();
    void MoveCursorToEndOfLine();


    // General
    void DrawRectWithBorder( FLOAT x1, FLOAT y1, FLOAT x2, FLOAT y2, DWORD dwStartColor, DWORD dwEndColor, DWORD dwBorderColor );
    
    // Menu callback processing.
    void ProcessMenuFeedback(int feedbackID);



};

#endif // __XPAD_H