// ------------------------------------------------------------------------------------ //
//																						//
//	File: Asura_GUIMenu_Widget_Group.cpp												//
//																						//
//	Description: group widgets class													//
//																						//
//	Created: Steve Keen - 9/11/06														//
//																						//
//	Copyright (C) 2006 Rebellion (Derby), All Rights Reserved.							//
// ------------------------------------------------------------------------------------ //

#include "Core/Asura.h"

#include "GUIMenu/Asura_GUIMenu_Widget_Group.h"

#ifdef ASURA_USE_GUI_MENU_SYSTEM
#include "Core/Asura_Hash.h"
#include "Core/Asura_String.h"

#include "GUIMenu/Asura_GUIMenu_System.h"
#include "GUIMenu/Asura_Profiling_GUIMenu.h"
#include "Rendering/Asura_Render.h"

#ifdef ASURA_TOOLS
#include "GUIMenu/Tools_GUIMenu_XMLExporter.h"
#endif

// --------------------------------------------------------------------------------------- 
// -- Constructors -----------------------------------------------------------------------

Asura_GUIMenu_Widget_Group::Asura_GUIMenu_Widget_Group(void)
{
	m_uType = ASURA_GUIMENU_TYPEID_WIDGET_GROUP;
	SetCanBeSelectable(false);
	m_uLinkedID = ASURA_HASH_ID_UNSET;

	ASURA_GUIMENU_PROFILE_COUNTINSTANCE(ASURA_GUIMENU_COUNTER__WIDGET_GROUP);
}

// --------------------------------------------------------------------------------------- 
// -- Destructor -------------------------------------------------------------------------

Asura_GUIMenu_Widget_Group::~Asura_GUIMenu_Widget_Group(void)
{
	ASURA_GUIMENU_PROFILE_COUNTDESTROYINSTANCE(ASURA_GUIMENU_COUNTER__WIDGET_GROUP);
}

// --------------------------------------------------------------------------------------- 
// -- Public Functions ------------------------------------------------------------------- 

// --------------------------------------------------------------------------------------- 

void Asura_GUIMenu_Widget_Group::Render( u_int uState )
{
	if (IsRenderingDisabled())
	{
		return;
	}

	ASURA_GUIMENU_PROFILE_START_TASK(ASURA_GUIMENU_PROFILE__WIDGET_GROUP);

	const u_int uContainerCount = GetContainerCount();
	for( u_int u=0; u<uContainerCount; u++)
	{
		if (m_ppxContainerParts[u]->IsWidget())
		{
			// don't check for "IsEnabled" - group widget state is ignored.
			// uState should contain menu state flags
			m_ppxContainerParts[u]->Render( uState );
		}
		else
		{
			//render elements that are directly placed in a group as if they were in the default state
			//RAR 22/08/2007
			m_ppxContainerParts[u]->Render(uState | ASURA_GUIMENU_ACTION_FLAG_IS_DEFAULT);
		}
		// (MH - 15.03.2007) attempt to fix ordering being broken sometimes.
		// could prove costly to render stuff without batching...
		Asura_Render::FlushDisplay();
	}

	ASURA_GUIMENU_PROFILE_END_TASK();
}

// --------------------------------------------------------------------------------------- 
Asura_GUIMenu_Widget_Base* Asura_GUIMenu_Widget_Group::FindSelectableWidgetAtPos(const Asura_Vector_2& xPos)
{
	//Calling directly to the root class , since the group widget should never be found as a selectable widget ,
	//but we still want to be able to check the children
	//RAR 30/08/2007
	return Asura_GUIMenu_Root::FindSelectableWidgetAtPos(xPos);
}

// --------------------------------------------------------------------------------------- 

void Asura_GUIMenu_Widget_Group::ReadFromChunkStream( Asura_Chunk_Stream& xStream, Asura_GUIMenu_Root* pxParentObject, u_int uChunkVersion)
{
//	u_int u, uContainerCount;

	PARENT::ReadFromChunkStream( xStream, pxParentObject, 0xffffffff);

	//Override whatever was read in , and make sure the group is flagged as unselectable. RAR 07/09/2007
	SetCanBeSelectable(false);

	if (uChunkVersion >= 1)
	{
		// -- read id hash of linekd group
		xStream >> m_uLinkedID;
	}

	ReadAllChildObjects( xStream, this);
}

// --------------------------------------------------------------------------------------- 

#ifdef ASURA_TOOLS
void Asura_GUIMenu_Widget_Group::WriteToChunkStream( Asura_Chunk_Stream& xStream) const
{

	WriteLocalChunkHeader( xStream, ASURA_CHUNK_WIDGET_GROUP_VERSION, GetType());

	PARENT::WriteToChunkStream( xStream);

	// -- output id hash of linked object
	xStream << m_uLinkedID;

	// -- write out any children --
	WriteChildObjectData( xStream);
}

void Asura_GUIMenu_Widget_Group::ExportToXML(Tools_GUIMenu_XMLExporter* pxExporter) const
{
	PARENT::ExportToXML( pxExporter );

	pxExporter->AddToBuffer( pxExporter->GetTabs() );
	pxExporter->AddToBuffer( "<Group_data>\n" );
	pxExporter->IncTabs();
	// -- output id hash of linked object
	pxExporter->AddToBufferHex( m_uLinkedID );
	pxExporter->DecTabs();
	pxExporter->AddToBuffer( pxExporter->GetTabs() );
	pxExporter->AddToBuffer( "</Group_data>\n" );

}
#endif

// --------------------------------------------------------------------------------------- 
#ifdef ASURA_TOOLS
void Asura_GUIMenu_Widget_Group::UpdateLocalDataFromStyle( void)
{
	PARENT::UpdateLocalDataFromStyle();

	// -- nothing to do in here at the moment --
}

bool Asura_GUIMenu_Widget_Group::CheckForCyclicLink(Asura_Hash_ID uHashID)
{
	Asura_GUIMenu_Root* pxGUIObject = Asura_GUIMenu_System::FindWidgetObjectByID(uHashID);
	Asura_Hash_ID uNewHashID = static_cast<Asura_GUIMenu_Widget_Group*>(pxGUIObject)->GetLinkedGroup();
	if (uNewHashID == ASURA_HASH_ID_UNSET) return false;
	if (uNewHashID == GetID()) return true;
	return CheckForCyclicLink(uNewHashID);
}

void Asura_GUIMenu_Widget_Group::SetLinkedGroup(Asura_Hash_ID uHashID)
{
	m_uLinkedID = uHashID;
}
#endif

// --------------------------------------------------------------------------------------- 
// -- Protected Functions ------------------------------------------------------------------


void Asura_GUIMenu_Widget_Group::SetupDefaultElements( void)
{

}

// --------------------------------------------------------------------------------------- 
// -- Private Functions ------------------------------------------------------------------


// --------------------------------------------------------------------------------------- 

#endif // ASURA_USE_GUI_MENU_SYSTEM
