// Tools_GUIMenu_Element_Base.cpp
//
// Created by Richard Rice - 30/11/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "GUIMenu/Tools_GUIMenu_Element_Base.h"

#ifdef ASURA_USE_GUI_MENU_SYSTEM

// Asura
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "GUIMenu/Asura_GUIMenu_Element_Base.h"
#include "GUIMenu/Asura_GUIMenu_Menu_Page.h"
#include "GUIMenu/Asura_GUIMenu_Modifier.h"
#include "Rendering/Asura_Render.h"

// Tools
#include "GUIMenu/Tools_Mode_GUIMenu.h"
#include "GUIMenu/Tools_GUIMenu_Widget_Base.h"

Tools_GUIMenu_Element_Base* Tools_GUIMenu_Element_Base::s_pxCurrentElement = 0;


Tools_GUIMenu_Element_Base::Tools_GUIMenu_Element_Base(Asura_GUIMenu_Element_Base* pxAsuraElement,Tools_GUIMenu_Root* pxToolsParent)
:Tools_GUIMenu_Root(pxAsuraElement,pxToolsParent)
, m_bPercDimsChanged( false)
{
	m_pxAsuraElement = pxAsuraElement;

	m_xPercentageDims.Zero();
}

void Tools_GUIMenu_Element_Base::Update()
{
	PARENT::Update();

	if( m_bPercDimsChanged && m_pxAsuraElement && m_pxAsuraElement->GetParentObject() )
	{
		Asura_Bounding_Rectangle xBounds(m_pxAsuraElement->GetUnscaledLocalBounds());
		xBounds.MaxX = xBounds.MinX + m_xPercentageDims.x * m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetWidth() / 100.0f;
		xBounds.MaxY = xBounds.MinY + m_xPercentageDims.y * m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetHeight() / 100.0f;
		m_pxAsuraElement->SetUnscaledLocalBounds( xBounds );
		m_bPercDimsChanged = false;
		m_bChanged = true;
		SetModified();
	}

	if( m_pxAsuraElement)
	{
		m_xPercentageDims = m_pxAsuraElement->GetUnscaledLocalBounds().GetDimension();
		if (m_pxAsuraElement->GetParentObject())
		{
			if (m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetWidth() > 0.0f)
			{
				m_xPercentageDims.x /= m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetWidth() / 100.0f;
				m_xPercentageDims.x = Asura_Maths::ClampToRange(m_xPercentageDims.x, 0.0f, 100.0f);
			}
			if (m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetHeight() > 0.0f)
			{
				m_xPercentageDims.y /= m_pxAsuraElement->GetParentObject()->GetUnscaledLocalBounds().GetHeight() / 100.0f;
				m_xPercentageDims.y = Asura_Maths::ClampToRange(m_xPercentageDims.y, 0.0f, 100.0f);
			}
		}
	}
}

void Tools_GUIMenu_Element_Base::Render()
{
	m_pxAsuraElement->Render( 0x0);//ffffffff);
	// force draw order to be correct.
	Asura_Render::FlushDisplay();
}

void Tools_GUIMenu_Element_Base::OnDeselection()
{
	s_pxCurrentElement = 0;

	PARENT::OnDeselection();
}

void Tools_GUIMenu_Element_Base::OnSelection()
{
	PARENT::OnSelection();

	s_pxCurrentElement = this;
}

void Tools_GUIMenu_Element_Base::AddBasicOverlayControls(Asura_Overlay* pxOverlay,Asura_Vector_2& xOffset)
{
	PARENT::AddBasicOverlayControls(pxOverlay,xOffset);
	Asura_Dialog* pxDialog;

	pxDialog = new Asura_Numerical_Dialog("Width %", xOffset, &m_xPercentageDims.x, 0.0f, 100.0f, 0.001f, "%3.3f", &m_bPercDimsChanged);
	pxDialog->SetEnabled(CanEditDimXPercentages());
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Height %", xOffset, &m_xPercentageDims.y, 0.0f, 100.0f, 0.001f, "%3.3f", &m_bPercDimsChanged);
	pxDialog->SetEnabled(CanEditDimYPercentages());
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();
}

void Tools_GUIMenu_Element_Base::AddOverlayControls(Asura_Overlay* pxOverlay,Asura_Vector_2& xOffset)
{
	PARENT::AddOverlayControls(pxOverlay,xOffset);

	if(m_pxToolsParent->IsWidget())
	{
		static_cast<Tools_GUIMenu_Widget_Base*>(m_pxToolsParent)->AddChildConditionOverlayControls(this,pxOverlay,xOffset);
	}
}

u_int Tools_GUIMenu_Element_Base::GetFlagsToEdit() const
{
	return ASURA_GUIMENU_ACTION_FLAG_ALL;
}

void Tools_GUIMenu_Element_Base::Copy(const Tools_GUIMenu_Root* pxSource)
{
	PARENT::Copy(pxSource);

	if(m_pxToolsParent)
	{
		//Deals with copying list population functions for list box entries
		m_pxToolsParent->CopyDataForThisStoredInParent(pxSource, this);
	}
}

// returns whether this object supports e.g. position, or UVs etc.
bool Tools_GUIMenu_Element_Base::IsModifierTypeSupported( ASURA_GUIMENU_MODIFY_TYPE eType ) const
{
	switch (eType)
	{
	case ASURA_GUIMENU_MODIFY_WIDTH:
	case ASURA_GUIMENU_MODIFY_HEIGHT:
		return true;
	default:
		return PARENT::IsModifierTypeSupported(eType);
	}
}

const char* Tools_GUIMenu_Element_Base::GetLocalDataFlagName(u_int uFlagValue) const
{
	switch(uFlagValue)
	{
		case Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH :
			return "Width";
			break;

		case Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT :
			return "Height";
			break;

		default :
			return PARENT::GetLocalDataFlagName(uFlagValue);

	}
}

bool Tools_GUIMenu_Element_Base::CanBeMoved() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Root::ASURA_GUIMENU_ROOT_LOCAL_FLAG_POSITION);
}

bool Tools_GUIMenu_Element_Base::CanEditWidth() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH);
}

bool Tools_GUIMenu_Element_Base::CanEditHeight() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT);
}

bool Tools_GUIMenu_Element_Base::CanEditDimXPercentages() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH);
}

bool Tools_GUIMenu_Element_Base::CanEditDimYPercentages() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT);
}

bool Tools_GUIMenu_Element_Base::CanEditDisplayWidth() const
{
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_WIDTH);
}

bool Tools_GUIMenu_Element_Base::CanEditDisplayHeight() const
{	
	return ShouldStyleUseLocalDataFor(Asura_GUIMenu_Element_Base::ASURA_GUIMENU_ELEMENT_BASE_LOCAL_FLAG_HEIGHT);
}


void Tools_GUIMenu_Element_Base::AddModifierOverlayControls(Asura_GUIMenu_Modifier* pxModifier, Asura_Vector_2& xOffset )
{
	Asura_Dialog* pxDialog;

	switch(pxModifier->GetModifyType())
	{
		case ASURA_GUIMENU_MODIFY_WIDTH:
		{
			m_fModifierData = pxModifier->GetFloatData();

			pxDialog = new Asura_Numerical_Dialog("Width",xOffset,&m_fModifierData,0.0f,9999.0f,1.0f,"%.0f",&m_bModifierChanged);
			pxDialog->SetHelpText("The width to use when the modifier is active.");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
		break;

		case ASURA_GUIMENU_MODIFY_HEIGHT :
		{
			m_fModifierData = pxModifier->GetFloatData();

			pxDialog = new Asura_Numerical_Dialog("Height",xOffset,&m_fModifierData,0.0f,9999.0f,1.0f,"%.0f",&m_bModifierChanged);
			pxDialog->SetHelpText("The height to use when the modifier is active.");
			AddModifierDialog(pxDialog);
			xOffset.y += Asura_Dialog::DefaultSpacing();
		}
		break;

		default :
			PARENT::AddModifierOverlayControls(pxModifier,xOffset);
			break;
	}
}

void Tools_GUIMenu_Element_Base::InitialiseModifier(Asura_GUIMenu_Modifier* pxModifier)
{
	switch(pxModifier->GetModifyType())
	{
		case ASURA_GUIMENU_MODIFY_WIDTH:
			pxModifier->SetData(m_pxAsuraElement->GetUnscaledLocalBounds().GetWidth());
			break;

		case ASURA_GUIMENU_MODIFY_HEIGHT:
			pxModifier->SetData(m_pxAsuraElement->GetUnscaledLocalBounds().GetHeight());
			break;

		default :
			PARENT::InitialiseModifier(pxModifier);
			break;
	}
}

#endif //ASURA_USE_GUI_MENU_SYSTEM
