#include "PajaTypes.h"
#include "SceneItemC.h"
#include "SceneC.h"
#include "LayerC.h"
#include "EffectI.h"
#include "GizmoI.h"
#include "ParamI.h"
#include "SceneItemListC.h"

using namespace PajaTypes;
using namespace Composition;


SceneItemListC::SceneItemListC() :
	m_i32SceneListItemsHeight( 0 ),
	m_i32ItemHeight( 16 ),
	m_bListUpdated( false ),
	m_pCurrentScene( 0 )
{
}

SceneItemListC::~SceneItemListC()
{
}

void
SceneItemListC::build_sceneitem_list( SceneC* pScene )
{
	m_pCurrentScene = pScene;

	// first purge the old list
	m_rSceneItems.clear();

	int32	y = 0;
	int32	x = 20;

	if( m_pCurrentScene ) {
		for( uint32 i = 0; i < m_pCurrentScene->get_layer_count(); i++ ) {
			LayerC*	pLayer = m_pCurrentScene->get_layer( i );

			SceneItemC	rItem;
			rItem.init( pLayer );
			rItem.set_x( x );
			rItem.set_y( y );
			rItem.set_height( m_i32ItemHeight );
			rItem.set_flags( pLayer->get_flags() | ITEM_LAYER );
			m_rSceneItems.push_back( rItem );

			y += m_i32ItemHeight;

			if( pLayer->get_flags() & ITEM_EXPANDED )
				add_effects( pLayer, x + 20, y );
		}
	}

	m_i32SceneListItemsHeight = y;
}


void
SceneItemListC::add_effects( LayerC* pLayer, int32 x, int32& y )
{
	for( uint32 i = 0; i < pLayer->get_effect_count(); i++ ) {
		EffectI*	pEffect = pLayer->get_effect( i );
		if( !(pEffect->get_flags() & ITEM_GUIHIDDEN) ) {

			SceneItemC	rItem;
			rItem.init( pEffect );
			rItem.set_x( x );
			rItem.set_y( y );
			rItem.set_height( m_i32ItemHeight );
			rItem.set_flags( pEffect->get_flags() | ITEM_EFFECT );
			m_rSceneItems.push_back( rItem );

			y += m_i32ItemHeight;

			if( pEffect->get_flags() & ITEM_EXPANDED )
				add_gizmos( pEffect, x + 20, y );
		}
	}
}

void
SceneItemListC::add_gizmos( EffectI* pFx, int32 x, int32& y )
{
	for( uint32 i = 0; i < pFx->get_gizmo_count(); i++ ) {
		GizmoI*	pGizmo = pFx->get_gizmo( i );
		if( !(pGizmo->get_flags() & ITEM_GUIHIDDEN) ) {
			
			SceneItemC	rItem;
			rItem.init( pGizmo );
			rItem.set_x( x );
			rItem.set_y( y );
			rItem.set_height( m_i32ItemHeight );
			rItem.set_flags( pGizmo->get_flags() );
			m_rSceneItems.push_back( rItem );

			y += m_i32ItemHeight;

			if( pGizmo->get_flags() & ITEM_EXPANDED )
				add_parameters( pGizmo, x + 20, y );
		}
	}
}

void
SceneItemListC::add_parameters( GizmoI* pGizmo, int32 x, int32& y )
{
	for( uint32 i = 0; i < pGizmo->get_parameter_count(); i++ ) {
		ParamI*	pParam = pGizmo->get_parameter( i );
		if( !(pParam->get_flags() & ITEM_GUIHIDDEN) ) {

			SceneItemC	rItem;
			rItem.init( pParam );
			rItem.set_x( x );
			rItem.set_y( y );
			rItem.set_flags( pParam->get_flags() );

			if( pParam->get_flags() & ITEM_EXPANDED )
			{
				if( pParam->get_type() == PARAM_TYPE_LINK )
				{
					ParamLinkC*	pParamLink = (ParamLinkC*)pParam;
					int32	i32ItemCount = __max( pParamLink->get_link_count(), 1 );
					y += i32ItemCount * m_i32ItemHeight;
				}
				else
				{
					rItem.set_height( pParam->get_expanded_height() );
					y += pParam->get_expanded_height();
				}
			}
			else
			{
				rItem.set_height( m_i32ItemHeight );
				y += m_i32ItemHeight;
			}

			m_rSceneItems.push_back( rItem );
		}
	}
}


uint32
SceneItemListC::get_sceneitem_count()
{
	if( !m_bListUpdated ) {
		build_sceneitem_list( m_pCurrentScene );
		m_bListUpdated = true;
	}
	return m_rSceneItems.size();
}

SceneItemC*
SceneItemListC::get_sceneitem( uint32 ui32Index )
{
	if( ui32Index >= m_rSceneItems.size() )
		return 0;
	return &m_rSceneItems[ui32Index];
}

int32
SceneItemListC::get_list_height()
{
	if( !m_bListUpdated ) {
		build_sceneitem_list( m_pCurrentScene );
		m_bListUpdated = true;
	}
	return m_i32SceneListItemsHeight;
}

void
SceneItemListC::set_item_height( int32 i32Height )
{
	m_bListUpdated = false;
	m_i32ItemHeight = i32Height;
}

int32
SceneItemListC::get_item_height()
{
	return m_i32ItemHeight;
}

void
SceneItemListC::expand_item( SceneItemC* pItem )
{
	if( !pItem )
		return;

	if( pItem->get_type() == SCENEITEM_LAYER ) {
		pItem->get_layer()->add_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_EFFECT ) {
		pItem->get_effect()->add_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_GIZMO ) {
		pItem->get_gizmo()->add_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_PARAMETER ) {
		pItem->get_parameter()->add_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}



/*
	if( !m_pCurrentScene )
		return;

	if( item.m_i32Layer != -1 ) {
		LayerC*	pLayer = m_pCurrentScene->get_layer( item.m_i32Layer );

		if( item.m_i32Effect != - 1 ) {
			EffectI*	pFx = pLayer->get_effect( item.m_i32Effect );

			if( item.m_i32Gizmo != -1 ) {
				GizmoI*	pGizmo = pFx->get_gizmo( item.m_i32Gizmo );

				if( item.m_i32Parameter != - 1 ) {
					ParamI*	pParam = pGizmo->get_parameter( item.m_i32Parameter );
					pParam->add_flags( ITEM_EXPANDED ); // expand gizmo
				}
				else
					pGizmo->add_flags( ITEM_EXPANDED ); // expand gizmo
			}
			else
				pFx->add_flags( ITEM_EXPANDED ); // expand effect
		}
		else
			pLayer->add_flags( ITEM_EXPANDED ); // expand this layer

		m_bListUpdated = false;
	}
*/
}

void
SceneItemListC::collapse_item( SceneItemC* pItem )
{
	if( !pItem )
		return;

	if( pItem->get_type() == SCENEITEM_LAYER ) {
		pItem->get_layer()->del_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_EFFECT ) {
		pItem->get_effect()->del_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_GIZMO ) {
		pItem->get_gizmo()->del_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_PARAMETER ) {
		pItem->get_parameter()->del_flags( ITEM_EXPANDED );
		m_bListUpdated = false;
	}


/*	if( !m_pCurrentScene )
		return;

	if( item.m_i32Layer != -1 ) {
		LayerC*	pLayer = m_pCurrentScene->get_layer( item.m_i32Layer );

		if( item.m_i32Effect != - 1 ) {
			EffectI*	pFx = pLayer->get_effect( item.m_i32Effect );

			if( item.m_i32Gizmo != -1 ) {
				GizmoI*	pGizmo = pFx->get_gizmo( item.m_i32Gizmo );

				if( item.m_i32Parameter != - 1 ) {
					ParamI*	pParam = pGizmo->get_parameter( item.m_i32Parameter );
					pParam->del_flags( ITEM_EXPANDED ); // collapse parameter
				}
				else
					pGizmo->del_flags( ITEM_EXPANDED ); // collapse gizmo
			}
			else
				pFx->del_flags( ITEM_EXPANDED ); // collapse effect
		}
		else
			pLayer->del_flags( ITEM_EXPANDED ); // collapse this layer

		m_bListUpdated = false;
	}*/
}

void
SceneItemListC::set_item_flags( SceneItemC* pItem, int32 i32Flags )
{
	if( !pItem )
		return;

	if( pItem->get_type() == SCENEITEM_LAYER ) {
		pItem->get_layer()->set_flags( i32Flags );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_EFFECT ) {
		pItem->get_effect()->set_flags( i32Flags );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_GIZMO ) {
		pItem->get_gizmo()->set_flags( i32Flags );
		m_bListUpdated = false;
	}
	else if( pItem->get_type() == SCENEITEM_PARAMETER ) {
		pItem->get_parameter()->set_flags( i32Flags );
		m_bListUpdated = false;
	}


/*	if( !m_pCurrentScene )
		return;

	if( item.m_i32Layer != -1 ) {
		LayerC*	pLayer = m_pCurrentScene->get_layer( item.m_i32Layer );

		if( item.m_i32Effect != - 1 ) {
			EffectI*	pFx = pLayer->get_effect( item.m_i32Effect );

			if( item.m_i32Gizmo != -1 ) {
				GizmoI*	pGizmo = pFx->get_gizmo( item.m_i32Gizmo );

				if( item.m_i32Parameter != - 1 ) {
					ParamI*	pParam = pGizmo->get_parameter( item.m_i32Parameter );
					pParam->set_flags( i32Flags );
				}
				else
					pGizmo->set_flags( i32Flags ); // expand gizmo
			}
			else
				pFx->set_flags( i32Flags ); // expand effect
		}
		else
			pLayer->set_flags( i32Flags ); // expand this layer

		m_bListUpdated = false;
	}*/
}

void
SceneItemListC::layer_list_modified()
{
	m_bListUpdated = false;
}

void
SceneItemListC::remove_cont_sample_data()
{
	if( m_bListUpdated ) {
		for( uint32 i = 0; i < m_rSceneItems.size(); i++ ) {
			m_rSceneItems[i].delete_controller_sampledata();
/*			if( m_rSceneItems[i].m_pContData ) {
				delete m_rSceneItems[i].m_pContData;
				m_rSceneItems[i].m_pContData = 0;
			}*/
		}
	}
	else {
		build_sceneitem_list( m_pCurrentScene );
		m_bListUpdated = true;
	}
}


