
#include <windows.h>

#include "EffectI.h"
#include "PajaTypes.h"
#include "DataBlockI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "GizmoI.h"
#include "TimeSegmentC.h"
#include "FileIO.h"
#include "BBox2C.h"
#include "Composition.h"
#include "ParamI.h"
#include <string>
#include <vector>



using namespace PajaTypes;
using namespace Composition;
using namespace FileIO;
using namespace Edit;
using namespace PluginClass;

//
// Effect
//

EffectI::EffectI() :
	m_i32Flags( ITEM_EFFECT | ITEM_VISIBLE ),
	m_pParent( 0 ),
	m_pDemoInterface( 0 )
{
	m_pTimeSegment = TimeSegmentC::create_new();
}

EffectI::EffectI( EditableI* pOriginal ) :
	EditableI( pOriginal ),
	m_i32Flags( ITEM_EFFECT | ITEM_VISIBLE ),
	m_pParent( 0 ),
	m_pTimeSegment( 0 ),
	m_pDemoInterface( 0 )
{
	// empty
//	m_pTimeSegment = TimeSegmentC::create_new( 0 , 10 * 64 );
}

EffectI::~EffectI()
{
	if( get_original() )
		return;

	if( m_pTimeSegment )
		m_pTimeSegment->release();
}


void
EffectI::copy( EditableI* pEditable )
{
	EffectI*	pEffect = (EffectI*)pEditable;
	m_sName = pEffect->m_sName;
	m_i32Flags = pEffect->m_i32Flags;
	m_pTimeSegment->copy( pEffect->m_pTimeSegment );
	m_pParent = pEffect->m_pParent;
}

void
EffectI::restore( EditableI* pBlock )
{
	EffectI*	pEffect = (EffectI*)pBlock;
	m_sName = pEffect->m_sName;
	m_i32Flags = pEffect->m_i32Flags;
	m_pTimeSegment = pEffect->m_pTimeSegment; //->copy( pEffect->m_pTimeSegment );
	m_pParent = pEffect->m_pParent;

	// Let the parent know that we were changed.
	if( !get_original() )
	{
		if( m_pParent )
			m_pParent->update_notify( this );

		// Notify reference makers.
		for( std::list<EditableI*>::iterator It = m_lstReferences.begin(); It != m_lstReferences.end(); ++It )
		{
			EditableI*	pEdit = (*It);
			if( pEdit )
				pEdit->update_notify( this );
		}
	}
}

PluginClass::SuperClassIdC
EffectI::get_base_class_id() const
{
	return BASECLASS_EFFECT;
}

TimeSegmentC*
EffectI::get_timesegment()
{
	return m_pTimeSegment;
}

void
EffectI::set_name( const char* szName )
{
	m_sName = szName;
}

const char*
EffectI::get_name() const
{
	return m_sName.c_str();
}

void
EffectI::set_flags( int32 i32Flags )
{
	m_i32Flags = i32Flags;
}

void
EffectI::add_flags( int32 i32Flags )
{
	m_i32Flags |= i32Flags;
}

void
EffectI::del_flags( int32 i32Flags )
{
	m_i32Flags &= ~i32Flags;
}

void
EffectI::toggle_flags( int32 i32Flags )
{
	m_i32Flags ^= i32Flags;
}

int32
EffectI::get_flags()
{
	return m_i32Flags;
}

void
EffectI::set_parent( LayerC* pLayer )
{
	m_pParent = pLayer;
}

LayerC*
EffectI::get_parent() const
{
	return m_pParent;
}

SuperClassIdC
EffectI::get_super_class_id()
{
	return SUPERCLASS_EFFECT;
}

uint32
EffectI::save( SaveC* pSave )
{
	uint32	ui32Error = IO_OK;

	// make sure this string fits into the buffer when it's loaded back
	std::string	sStr = m_sName;
	if( sStr.size() > 255 )
		sStr.resize( 255 );

	// name
	ui32Error = pSave->write_str( sStr.c_str() );
	// flags
	ui32Error = pSave->write( &m_i32Flags, sizeof( m_i32Flags ) );
	// timesegment
	ui32Error = m_pTimeSegment->save( pSave );

	return ui32Error;
}

uint32
EffectI::load( LoadC* pLoad )
{
	uint32	ui32Error = IO_OK;
	char	szStr[256];

	// name
	ui32Error = pLoad->read_str( szStr );
	m_sName = szStr;
	// flags
	ui32Error = pLoad->read( &m_i32Flags, sizeof( m_i32Flags ) );
	// timesegment
	ui32Error = m_pTimeSegment->load( pLoad );

	return IO_OK;
}

uint32
EffectI::update_notify( EditableI* pCaller )
{
	uint32	ui32Ret = 0;
	uint32	ui32CurRet = 0;
	// Let the parent know that we were changed.
	if( m_pParent )
	{
		ui32CurRet = m_pParent->update_notify( pCaller );
		if( ui32CurRet )
			ui32Ret = ui32CurRet;
	}

	// Notify reference makers.
	for( std::list<EditableI*>::iterator It = m_lstReferences.begin(); It != m_lstReferences.end(); ++It )
	{
		EditableI*	pEdit = (*It);
		if( pEdit )
		{
			ui32CurRet = pEdit->update_notify( this );
			if( ui32CurRet )
				ui32Ret = ui32CurRet;
		}
	}

	return ui32Ret;
}

void
EffectI::initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface )
{
	// Store pointer to the interface.
	if( pInterface )
		m_pDemoInterface = pInterface;
}

void
EffectI::add_reference( EditableI* pEditable )
{
	m_lstReferences.push_back( pEditable );
}

void
EffectI::reset_references()
{
	m_lstReferences.clear();
}

int32
EffectI::get_reference_count()
{
	return (int32)m_lstReferences.size();
}

void
EffectI::draw_ui( uint32 ui32Flags )
{
	// empty
}
