//
// Tools_Module_Selection.h
//
// Created by Richard Rice - 15/10/2002
// 
// Copyright (C) 2002 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __TOOLS_MODULE_SELECTION_H__
#define __TOOLS_MODULE_SELECTION_H__

#include "Tools_Undo.h"
#include "Core/Asura_Maths.h"
#include "Misc/list_tem.hpp"

///////////////////////////////////////////////////////////////////////////////////////
struct ModuleSelectionUndoData
{
	enum UndoType
	{
		UndoType_Added,
		UndoType_Removed,
		UndoType_ForceInt = 0xffffffff,
	};
	
	enum UndoType m_eUndoType;
	int m_iModuleIndex;
};

class ModuleSelectionUndo : public FixedSizeUndo
{
public :
	ModuleSelectionUndo()
	:FixedSizeUndo(10000,sizeof(ModuleSelectionUndoData)){}

	void ProcessUndoData(void*);
	
	void LogModuleSelected(int iModule);
	void LogModuleDeselected(int iModule);
};
///////////////////////////////////////////////////////////////////////////////////////

enum ModuleSelectionMode
{
	ModuleSelectionMode_Object,
	ModuleSelectionMode_Region,
};

class Tools_Module_Selection
{
public :
	static void Initialise(bool bAllowMultipleSelect = true);
	static void Shutdown();

	static void Activate();
	static void Deactivate();

	static void Update()  {Asura_Assert(s_pxThis,"");s_pxThis->UpdateMain();}
	static void Render()  {Asura_Assert(s_pxThis,"");s_pxThis->RenderMain();}

	static bool IsActive() {Asura_Assert(s_pxThis,"");return s_pxThis->m_bIsActive;}

	//get the first module in the selection list , or -1 if none selected
	//(only really makes sense with multiple selection turned off)
	static int GetSelected();
	static int GetHighlitModule();

	static int GetNumSelected();
	static bool IsSelected(int iModuleIndex);
	static const List<int>* GetSelectionList();

	//get the centre of the BB around the selected modules
	static Asura_Vector_3 GetCentreOfSelection();


//selection overlay functions
	static void ToggleSelectionOverlay(void);
	static bool SelectionOverlayIsOn(void);

    static void RequestSingleSelection( int iModuleIndex )
    {
        if( s_pxThis )
        {
            s_pxThis->Select( iModuleIndex, false );
        }
    }

	static void DeleteModule(int iModuleIndex)
	{
		if(s_pxThis) s_pxThis->DeleteModuleMain(iModuleIndex);
	}

	static void AddToSelection(int iModuleIndex)
	{
		if(s_pxThis) s_pxThis->Select(iModuleIndex, true);
	}


private :
	Tools_Module_Selection(bool bAllowMultipleSelect);
	~Tools_Module_Selection();

	//loads/saves data for this mode
	void TransferModeData(int mode);


	void CreateSelectionOverlay();

	void UpdateMain();
	void RenderMain( void ) const;
	
	void HandleKeyboard();
	void HandleMouseSelection();

	
	void SelectAll();
	void DeselectAll();
	void SelectRegion(int iModuleIndex);
	void DeselectRegion(int iModuleIndex);
	void Select(int iModuleIndex,bool bMultiSelect);
	void Deselect(int iModuleIndex);
	void InvertSelection();
	void SelectByName();


	void HideSelection();
	void HideUnselected();
	void Unhide() const;
	void UnhideAndSelect();

	void Undo();
	void Redo();

	void DeleteModuleMain(int iModuleIndex);

	//static functions for overlay
	static void _SelectAll()  {Asura_Assert(s_pxThis,"");s_pxThis->SelectAll();}
	static void _DeselectAll()  {Asura_Assert(s_pxThis,"");s_pxThis->DeselectAll();}
	static void _InvertSelection()  {Asura_Assert(s_pxThis,"");s_pxThis->InvertSelection();}
	static void _HideSelection()  {Asura_Assert(s_pxThis,"");s_pxThis->HideSelection();}
	static void _HideUnselected()  {Asura_Assert(s_pxThis,"");s_pxThis->HideUnselected();}
	static void _Unhide()  {Asura_Assert(s_pxThis,"");s_pxThis->Unhide();}
	static void _UnhideAndSelect()  {Asura_Assert(s_pxThis,"");s_pxThis->UnhideAndSelect();}
	static void _Undo()  {Asura_Assert(s_pxThis,"");s_pxThis->Undo();}
	static void _Redo()  {Asura_Assert(s_pxThis,"");s_pxThis->Redo();}
	static void _SelectByName()  {Asura_Assert(s_pxThis,"");s_pxThis->SelectByName();}

	

	List<int> m_xSelectedModules;
	bool m_bAllowMultipleSelect;

	Asura_Vector_2 m_xSelectionOverlayPosition;
	bool m_bSelectionOverlayOpen;
	u_int m_uSelectionOverlayMinimised;

	bool m_bShowSelection;
	int m_iHighlitModule;

	int m_iSelectionMode;//value from enum ModuleSelectionMode
	int m_iSelectionModeListOffset;//just used since I need a paramater for the list overlay thingy

	bool m_bIsActive;


	//used to determine whether the mouse button was pressed to start polygon selection
	//(allows use of non-debounced button , excepet when it would be underiable)
	bool m_bButtonDownForSelection;

	ModuleSelectionUndo m_xSelectionUndo;

	static Tools_Module_Selection* s_pxThis;


	friend class ModuleSelectionUndo;
};


#endif //__TOOLS_MODULE_SELECTION_H__
