#ifndef __LISTCTRL_H__
#define __LISTCTRL_H__

#include <wx/wx.h>
#include <wx/listctrl.h>
#include <wx/popupwin.h>
#include <wx/xrc/xmlres.h>

#include "common.h"
#include "draganddrop.h"
namespace VRUT
{
	class ListCtrl;
	class ListCtrlPopup;

	class ListCtrl : public wxListCtrl
	{
	public:

		enum ORDER
		{
			ORDER_NONE,
			ORDER_BY_ID,
			ORDER_BY_NAME,
		};

	private:

		wxImageList * imageList;
		std::vector<int> imageIndexVector; // [itemId] -> imageIndex
		std::vector<unsigned long> idVector; // [itemId] -> id
		std::vector<wxString> nameVector; // [itemId] -> imageIndex
		std::vector<long> itemIdVector; // [id] -> itemId
		ORDER order;
		// scene id needed for drag & drop
		SCENE_ID sceneID;

		void LocalInit();
		void ParseItemDefinition(const wxString &definition, unsigned long &id, wxString &name, wxString &iconName, bool &isActive);
		void Unselect();
		static int wxCALLBACK ItemCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData);

	public:

		ListCtrl();

		ListCtrl(wxWindow * parent, wxWindowID id, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxLC_ICON,
			const wxValidator & validator = wxDefaultValidator, const wxString & name = wxListCtrlNameStr);

		bool Create(wxWindow * parent, wxWindowID id, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxLC_ICON,
			const wxValidator & validator =	wxDefaultValidator, const wxString & name = wxListCtrlNameStr);

		virtual ~ListCtrl();

		void SetSceneID(const int id);
		SCENE_ID GetSceneID() const;

		wxString GetValue() const;

		bool AddItem(const wxString &definition, bool updateGui);
		bool UpdateItem(const wxString &definition, bool updateGui);
		bool RemoveItem(const wxString &definition, bool updateGui);
		bool SelectByValue(const wxString &value);
		void RemoveAllItems();

		void SetOrder(ORDER order);
		void Sort();
		void UpdateColumns();
		void UpdateListGui();

		void OnBeginDrag(wxListEvent& evt);
		void OnListKeyDown(wxListEvent& evt);
		void OnRightDown(wxMouseEvent &evt);

		DECLARE_DYNAMIC_CLASS(ListCtrl)
	};

	class ListCtrlXmlHandler: public wxXmlResourceHandler
	{
	public:
		// Constructor.
		ListCtrlXmlHandler()
		{
			// wxListCtrl styles
			XRC_ADD_STYLE(wxLC_LIST);
			XRC_ADD_STYLE(wxLC_REPORT);
			XRC_ADD_STYLE(wxLC_ICON);
			XRC_ADD_STYLE(wxLC_SMALL_ICON);
			XRC_ADD_STYLE(wxLC_ALIGN_TOP);
			XRC_ADD_STYLE(wxLC_ALIGN_LEFT);
			XRC_ADD_STYLE(wxLC_AUTOARRANGE);
			XRC_ADD_STYLE(wxLC_USER_TEXT);
			XRC_ADD_STYLE(wxLC_EDIT_LABELS);
			XRC_ADD_STYLE(wxLC_NO_HEADER);
			XRC_ADD_STYLE(wxLC_SINGLE_SEL);
			XRC_ADD_STYLE(wxLC_SORT_ASCENDING);
			XRC_ADD_STYLE(wxLC_SORT_DESCENDING);
			XRC_ADD_STYLE(wxLC_VIRTUAL);
			XRC_ADD_STYLE(wxLC_HRULES);
			XRC_ADD_STYLE(wxLC_VRULES);
			XRC_ADD_STYLE(wxLC_NO_SORT_HEADER);

			AddWindowStyles();
		}

		// Creates the control and returns a pointer to it.
		virtual wxObject *DoCreateResource()
		{
			XRC_MAKE_INSTANCE(control, ListCtrl)

			control->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle(), wxDefaultValidator, GetName());

			SetupWindow(control);

			return control;
		}

		// Returns true if we know how to create a control for the given node.
		virtual bool CanHandle(wxXmlNode *node)
		{
			return IsOfClass(node, wxT("ListCtrl"));
		}

		// Register with wxWidgets' dynamic class subsystem.
		DECLARE_DYNAMIC_CLASS(ListCtrlXmlHandler)
	};

	class ListCtrlPopup : public wxPopupTransientWindow
	{
	private:

		ListCtrl *listControl;
		std::vector<wxCheckBox*> orderCheckBoxVector;
		ListCtrl::ORDER order;

	public:
		ListCtrlPopup(ListCtrl *listControl, ListCtrl::ORDER order);

	protected:
		void UpdateOrderGui();

		virtual void OnDismiss();
		void OnCheckBox(wxCommandEvent& event);
	};
}

#endif /* __LISTCTRL_H__ */
