// objects.h - Base classes for object manager of GUI

#ifndef _OBJECTS_HEADER
#define _OBJECTS_HEADER

#include "rapidxml.hpp"
#include <vector>
#include <string>
#include <map>

extern "C" {
#include "../minzip/Zip.h"
}

using namespace rapidxml;

#include "../data.hpp"
#include "resources.hpp"
#include "pages.hpp"

class RenderObject
{
public:
    enum Placement {
        TOP_LEFT = 0,
        TOP_RIGHT = 1,
        BOTTOM_LEFT = 2,
        BOTTOM_RIGHT = 3,
        CENTER = 4,
		CENTER_X_ONLY = 5,
    };

public:
    RenderObject()              { mRenderX = 0; mRenderY = 0; mRenderW = 0; mRenderH = 0; mPlacement = TOP_LEFT; }
    virtual ~RenderObject()     {}

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void) = 0;

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void)        { return 0; }

    // GetRenderPos - Returns the current position of the object
    virtual int GetRenderPos(int& x, int& y, int& w, int& h)        { x = mRenderX; y = mRenderY; w = mRenderW; h = mRenderH; return 0; }

    // SetRenderPos - Update the position of the object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0)    { mRenderX = x; mRenderY = y; if (w || h) { mRenderW = w; mRenderH = h; } return 0; }

    // GetPlacement - Returns the current placement
    virtual int GetPlacement(Placement& placement)                  { placement = mPlacement; return 0; }

    // SetPlacement - Update the current placement
    virtual int SetPlacement(Placement placement)                   { mPlacement = placement; return 0; }

    // SetPageFocus - Notify when a page gains or loses focus
    virtual void SetPageFocus(int inFocus)                          { return; }

protected:
    int mRenderX, mRenderY, mRenderW, mRenderH;
    Placement mPlacement;
};

class ActionObject
{
public:
    ActionObject()              { mActionX = 0; mActionY = 0; mActionW = 0; mActionH = 0; }
    virtual ~ActionObject()     {}

public:
    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y)        { return 0; }

    // NotifyKey - Notify of a key press
    //  Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error
    virtual int NotifyKey(int key)                                  { return 1; }

    // GetRenderPos - Returns the current position of the object
    virtual int GetActionPos(int& x, int& y, int& w, int& h)        { x = mActionX; y = mActionY; w = mActionW; h = mActionH; return 0; }

    // SetRenderPos - Update the position of the object
    //  Return 0 on success, <0 on error
    virtual int SetActionPos(int x, int y, int w = 0, int h = 0);

    // IsInRegion - Checks if the request is handled by this object
    //  Return 0 if this object handles the request, 1 if not
    virtual int IsInRegion(int x, int y)                            { return ((x < mActionX || x > mActionX + mActionW || y < mActionY || y > mActionY + mActionH) ? 0 : 1); }

    // NotifyVarChange - Notify of a variable change
    //  Returns 0 on success, <0 on error
    virtual int NotifyVarChange(std::string varName, std::string value)     { return 0; }

protected:
    int mActionX, mActionY, mActionW, mActionH;
};

class Conditional
{
public:
    Conditional(xml_node<>* node);

public:
    bool IsConditionVariable(std::string var);
    bool isConditionTrue();
    bool isConditionValid();
    void NotifyPageSet();

protected:
    class Condition
    {
    public:
        std::string mVar1;
        std::string mVar2;
        std::string mCompareOp;
        std::string mLastVal;
    };

    std::vector<Condition> mConditions;

protected:
    bool isMounted(std::string vol);
    bool isConditionTrue(Condition* condition);

};

class InputObject
{
public:
    InputObject()              { HasInputFocus = 0; }
    virtual ~InputObject()     {}

public:
    // NotifyKeyboard - Notify of keyboard input
    //  Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error
    virtual int NotifyKeyboard(int key)                                  { return 1; }

	virtual int SetInputFocus(int focus)    { HasInputFocus = focus; return 1; }

protected:
	int HasInputFocus;
};

// Derived Objects
// GUIText - Used for static text
class GUIText : public RenderObject, public ActionObject, public Conditional

{
public:
    // w and h may be ignored, in which case, no bounding box is applied
    GUIText(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // Retrieve the size of the current string (dynamic strings may change per call)
    virtual int GetCurrentBounds(int& w, int& h);

    // Notify of a variable change
    virtual int NotifyVarChange(std::string varName, std::string value);

	// Set maximum width in pixels
	virtual int SetMaxWidth(unsigned width);

	// Set number of characters to skip (for scrolling)
	virtual int SkipCharCount(unsigned skip);

public:
	bool isHighlighted;

protected:
    std::string mText;
    std::string mLastValue;
    COLOR mColor;
	COLOR mHighlightColor;
    Resource* mFont;
    int mIsStatic;
    int mVarChanged;
    int mFontHeight;
	unsigned maxWidth;
	unsigned charSkip;
	bool hasHighlightColor;

protected:
    std::string parseText(void);
};

// GUIImage - Used for static image
class GUIImage : public RenderObject
{
public:
    GUIImage(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // SetRenderPos - Update the position of the object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

public:
	bool isHighlighted;

protected:
    Resource* mImage;
	Resource* mHighlightImage;
};

// GUIFill - Used for fill colors
class GUIFill : public RenderObject
{
public:
    GUIFill(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

protected:
    COLOR mColor;
};

// GUIAction - Used for standard actions
class GUIAction : public ActionObject, public Conditional
{
public:
    GUIAction(xml_node<>* node);

public:
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
    virtual int NotifyKey(int key);
    virtual int NotifyVarChange(std::string varName, std::string value);
	virtual int doActions();

protected:
    class Action
    {
    public:
        std::string mFunction;
        std::string mArg;
    };

    std::vector<Action> mActions;
    int mKey;

protected:
    int getKeyByName(std::string key);
    virtual int doAction(Action action, int isThreaded = 0);
    static void* thread_start(void *cookie);
	void simulate_progress_bar(void);
    int flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache);
	void operation_start(const string operation_name);
	void operation_end(const int operation_status, const int simulate);
	static void* command_thread(void *cookie);
};

class GUIConsole : public RenderObject, public ActionObject
{
public:
    GUIConsole(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // SetRenderPos - Update the position of the object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

    // IsInRegion - Checks if the request is handled by this object
    //  Return 0 if this object handles the request, 1 if not
    virtual int IsInRegion(int x, int y);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error (Return error to allow other handlers)
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

protected:
    enum SlideoutState
    {
        hidden = 0,
        visible,
        request_hide,
        request_show
    };
    Resource* mFont;
    Resource* mSlideoutImage;
    COLOR mForegroundColor;
    COLOR mBackgroundColor;
    COLOR mScrollColor;
    unsigned int mFontHeight;
    int mCurrentLine;
    unsigned int mLastCount;
    unsigned int mMaxRows;
    int mStartY;
    int mSlideoutX, mSlideoutY, mSlideoutW, mSlideoutH;
    int mSlideinX, mSlideinY, mSlideinW, mSlideinH;
    int mConsoleX, mConsoleY, mConsoleW, mConsoleH;
    int mLastTouchX, mLastTouchY;
    int mSlideMultiplier;
    int mSlideout;
    SlideoutState mSlideoutState;

protected:
    virtual int RenderSlideout(void);
    virtual int RenderConsole(void);

};

class GUIButton : public RenderObject, public ActionObject, public Conditional
{
public:
    GUIButton(xml_node<>* node);
    virtual ~GUIButton();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // SetPos - Update the position of the render object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

protected:
    GUIImage* mButtonImg;
    Resource* mButtonIcon;
    GUIText* mButtonLabel;
    GUIAction* mAction;
    int mTextX, mTextY, mTextW, mTextH;
    int mIconX, mIconY, mIconW, mIconH;
    bool mRendered;
	bool hasHighlightColor;
	bool renderHighlight;
	COLOR mHighlightColor;
};

class GUICheckbox: public RenderObject, public ActionObject, public Conditional
{
public:
    GUICheckbox(xml_node<>* node);
    virtual ~GUICheckbox();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // SetPos - Update the position of the render object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

protected:
    Resource* mChecked;
    Resource* mUnchecked;
    GUIText* mLabel;
    int mTextX, mTextY;
    int mCheckX, mCheckY, mCheckW, mCheckH;
    int mLastState;
    bool mRendered;
    std::string mVarName;
};

class GUIFileSelector : public RenderObject, public ActionObject
{
public:
    GUIFileSelector(xml_node<>* node);
    virtual ~GUIFileSelector();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

    // NotifyVarChange - Notify of a variable change
    virtual int NotifyVarChange(std::string varName, std::string value);

    // SetPos - Update the position of the render object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

    // SetPageFocus - Notify when a page gains or loses focus
    virtual void SetPageFocus(int inFocus);

protected:
    struct FileData {
        std::string fileName;
        unsigned char fileType;     // Uses d_type format from struct dirent
        mode_t protection;          // Uses mode_t format from stat
        uid_t userId;
        gid_t groupId;
        off_t fileSize;
        time_t lastAccess;          // Uses time_t format from stat
        time_t lastModified;        // Uses time_t format from stat
        time_t lastStatChange;      // Uses time_t format from stat
    };

protected:
    virtual int GetSelection(int x, int y);

    virtual int GetFileList(const std::string folder);
    static bool fileSort(FileData d1, FileData d2);

protected:
    std::vector<FileData> mFolderList;
    std::vector<FileData> mFileList;
    std::string mPathVar;
    std::string mExtn;
    std::string mVariable;
	std::string mSortVariable;
	std::string mSelection;
	std::string mHeaderText;
	std::string mLastValue;
    int actualLineHeight;
	int mStart;
    int mLineSpacing;
	int mSeparatorH;
	int mHeaderSeparatorH;
    int mShowFolders, mShowFiles, mShowNavFolders;
    int mUpdate;
    int mBackgroundX, mBackgroundY, mBackgroundW, mBackgroundH;
	int mHeaderH;
	static int mSortOrder;
	int startY;
	int scrollingSpeed;
	int scrollingY;
	int mHeaderIsStatic;
	int touchDebounce;
    unsigned mFontHeight;
    unsigned mLineHeight;
    int mIconWidth, mIconHeight, mFolderIconHeight, mFileIconHeight, mFolderIconWidth, mFileIconWidth, mHeaderIconHeight, mHeaderIconWidth;
    Resource* mHeaderIcon;
	Resource* mFolderIcon;
    Resource* mFileIcon;
    Resource* mBackground;
    Resource* mFont;
    COLOR mBackgroundColor;
    COLOR mFontColor;
	COLOR mHeaderBackgroundColor;
	COLOR mHeaderFontColor;
	COLOR mSeparatorColor;
	COLOR mHeaderSeparatorColor;
	bool hasHighlightColor;
	bool hasFontHighlightColor;
	bool isHighlighted;
	COLOR mHighlightColor;
	COLOR mFontHighlightColor;
	int startSelection;
};

class GUIListBox : public RenderObject, public ActionObject
{
public:
    GUIListBox(xml_node<>* node);
    virtual ~GUIListBox();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

    // NotifyVarChange - Notify of a variable change
    virtual int NotifyVarChange(std::string varName, std::string value);

    // SetPos - Update the position of the render object
    //  Return 0 on success, <0 on error
    virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

    // SetPageFocus - Notify when a page gains or loses focus
    virtual void SetPageFocus(int inFocus);

protected:
    struct ListData {
        std::string displayName;
		std::string variableValue;
		unsigned int selected;
    };

protected:
    virtual int GetSelection(int x, int y);

protected:
    std::vector<ListData> mList;
    std::string mVariable;
	std::string mSelection;
	std::string currentValue;
    int mStart;
    int mLineSpacing;
    int mUpdate;
    int mBackgroundX, mBackgroundY, mBackgroundW, mBackgroundH;
	static int mSortOrder;
    unsigned mFontHeight;
    unsigned mLineHeight;
    int mIconWidth, mIconHeight;
    Resource* mIconSelected;
    Resource* mIconUnselected;
    Resource* mBackground;
    Resource* mFont;
    COLOR mBackgroundColor;
    COLOR mFontColor;
};

// GUIAnimation - Used for animations
class GUIAnimation : public RenderObject
{
public:
    GUIAnimation(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

protected:
    AnimationResource* mAnimation;
    int mFrame;
    int mFPS;
    int mLoop;
    int mRender;
    int mUpdateCount;
};

class GUIProgressBar : public RenderObject, public ActionObject
{
public:
    GUIProgressBar(xml_node<>* node);

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // NotifyVarChange - Notify of a variable change
    //  Returns 0 on success, <0 on error
    virtual int NotifyVarChange(std::string varName, std::string value);

protected:
    Resource* mEmptyBar;
    Resource* mFullBar;
    std::string mMinValVar;
    std::string mMaxValVar;
    std::string mCurValVar;
    float mSlide;
    float mSlideInc;
    int mSlideFrames;
    int mLastPos;

protected:
    virtual int RenderInternal(void);       // Does the actual render

};

class GUISlider : public RenderObject, public ActionObject
{
public:
    GUISlider(xml_node<>* node);
    virtual ~GUISlider();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

protected:
    GUIAction* sAction;
    Resource* sSlider;
    Resource* sSliderUsed;
    Resource* sTouch;
    int sTouchW, sTouchH;
    int sCurTouchX;
    int sUpdate;
};

#define MAX_KEYBOARD_LAYOUTS 5
#define MAX_KEYBOARD_ROWS 9
#define MAX_KEYBOARD_KEYS 20
#define KEYBOARD_ACTION 253
#define KEYBOARD_LAYOUT 254
#define KEYBOARD_SWIPE_LEFT 252
#define KEYBOARD_SWIPE_RIGHT 251
#define KEYBOARD_ARROW_LEFT 250
#define KEYBOARD_ARROW_RIGHT 249
#define KEYBOARD_HOME 248
#define KEYBOARD_END 247
#define KEYBOARD_ARROW_UP 246
#define KEYBOARD_ARROW_DOWN 245
#define KEYBOARD_SPECIAL_KEYS 245
#define KEYBOARD_BACKSPACE 8

class GUIKeyboard : public RenderObject, public ActionObject, public Conditional
{
public:
	GUIKeyboard(xml_node<>* node);
    virtual ~GUIKeyboard();

public:
	virtual int Render(void);
	virtual int Update(void);
	virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
	virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);

protected:
	virtual int GetSelection(int x, int y);

protected:
	struct keyboard_key_class
    {
        unsigned char key;
		unsigned char longpresskey;
        unsigned int end_x;
		unsigned int layout;
    };

	Resource* keyboardImg[MAX_KEYBOARD_LAYOUTS];
	struct keyboard_key_class keyboard_keys[MAX_KEYBOARD_LAYOUTS][MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS];
	bool mRendered;
	std::string mVariable;
	unsigned int cursorLocation;
	unsigned int currentLayout;
	unsigned int row_heights[MAX_KEYBOARD_LAYOUTS][MAX_KEYBOARD_ROWS];
	unsigned int KeyboardWidth, KeyboardHeight;
	int rowY, colX, highlightRenderCount, hasHighlight;
	GUIAction* mAction;
	COLOR mHighlightColor;
};

// GUIInput - Used for keyboard input
class GUIInput : public RenderObject, public ActionObject, public Conditional, public InputObject
{
public:
    // w and h may be ignored, in which case, no bounding box is applied
    GUIInput(xml_node<>* node);
	virtual ~GUIInput();

public:
    // Render - Render the full object to the GL surface
    //  Return 0 on success, <0 on error
    virtual int Render(void);

    // Update - Update any UI component animations (called <= 30 FPS)
    //  Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
    virtual int Update(void);

    // Notify of a variable change
    virtual int NotifyVarChange(std::string varName, std::string value);

	// NotifyTouch - Notify of a touch event
    //  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
    virtual int NotifyTouch(TOUCH_STATE state, int x, int y);

	virtual int NotifyKeyboard(int key);

protected:
	virtual int GetSelection(int x, int y);

	// Handles displaying the text properly when chars are added, deleted, or for scrolling
	virtual int HandleTextLocation(int x);

protected:
    GUIText* mInputText;
	GUIAction* mAction;
	Resource* mBackground;
	Resource* mCursor;
	Resource* mFont;
	std::string mText;
    std::string mLastValue;
	std::string mVariable;
	std::string mMask;
	std::string mMaskVariable;
    COLOR mBackgroundColor;
	COLOR mCursorColor;
	int scrollingX;
	int lastX;
	int mCursorLocation;
	int mBackgroundX, mBackgroundY, mBackgroundW, mBackgroundH;
	int mFontY;
	unsigned skipChars;
	unsigned mFontHeight;
	unsigned CursorWidth;
	bool mRendered;
	bool HasMask;
	bool DrawCursor;
	bool isLocalChange;
	bool HasAllowed;
	bool HasDisabled;
	std::string AllowedList;
	std::string DisabledList;
	unsigned MinLen;
	unsigned MaxLen;
};

class HardwareKeyboard
{
public:
	HardwareKeyboard(void);
	virtual ~HardwareKeyboard();

public:
	virtual int KeyDown(int key_code);
	virtual int KeyUp(int key_code);
	virtual int KeyRepeat(void);
};

// Helper APIs
bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w = NULL, int* h = NULL, RenderObject::Placement* placement = NULL);

#endif  // _OBJECTS_HEADER

