#include "stdafx.h"
#include"Export.h"
#include"pixelwhippro.h"

using namespace gosFX;

#define INDENT "\t"

void ExportCurve(FILE *fl,gosFX::Curve *Curve,char *CurveName,CString prefix)
{
	CString CType;

	switch(Curve->m_type)
	{
	case gosFX::Curve::e_ConstantType:	CType="Constant";	break;
	case gosFX::Curve::e_LinearType: CType="Linear";			break;
	case gosFX::Curve::e_SplineType:	CType="Spline";		break;
	case gosFX::Curve::e_ComplexType:CType="Complex";		break;
	case gosFX::Curve::e_ComplexComplexType: CType="ComplexComplex";		break;
	case gosFX::Curve::e_ComplexLinearType: CType="ComplexLinear";		break;
	case gosFX::Curve::e_ComplexSplineType: CType="ComplexSpline";		break;
	case gosFX::Curve::e_ConstantComplexType: CType="ConstantComplex";	break;
	case gosFX::Curve::e_ConstantLinearType: CType="ConstantLinear";		break;
	case gosFX::Curve::e_ConstantSplineType:CType="ConstantSpline";		break;
	case gosFX::Curve::e_SplineLinearType: CType="SplineLinear";			break;
	}


	fprintf(fl,"\n%sStartCurve[%s,%s]\n",(LPCSTR)prefix,CType,CurveName);
	CString newprefix=prefix+INDENT;
	LPCSTR npx=(LPCSTR)newprefix;

//	fprintf(fl,"%sCurveType=%s\n",npx,(LPCSTR)CType);
	switch(Curve->m_type)
	{
	case gosFX::Curve::e_ConstantType:
		{
			gosFX::ConstantCurve *LCurve=(gosFX::ConstantCurve *)Curve;
			fprintf(fl,"%sValue=%f\n",npx,LCurve->m_value);
		}
		break;
		
	case gosFX::Curve::e_LinearType:
		{
			gosFX::LinearCurve *LCurve=(gosFX::LinearCurve *)Curve;
			fprintf(fl,"%sStartValue=%f\n",npx,LCurve->m_value);
			fprintf(fl,"%sSlope=%f\n",npx,LCurve->m_slope);
		}
		break;
		
	case gosFX::Curve::e_SplineType:
		{
			gosFX::SplineCurve *LCurve=(gosFX::SplineCurve *)Curve;
			fprintf(fl,"%sStartValue=%f\n",npx,LCurve->ComputeValue(0.0f,0.0f));
			fprintf(fl,"%sStartSlope=%f\n",npx,LCurve->ComputeSlope(0.0f));
			fprintf(fl,"%sEndValue=%f\n",npx,LCurve->ComputeValue(1.0f,0.0f));
			fprintf(fl,"%sEndSlope=%f\n",npx,LCurve->ComputeSlope(1.0f));
		}
		break;
		
	case gosFX::Curve::e_ComplexType:
		{
			gosFX::ComplexCurve *LCurve=(gosFX::ComplexCurve *)Curve;
			fprintf(fl,"%sNumberOfKeys=%i\n",npx,LCurve->GetKeyCount());
			CString lprefix=newprefix+INDENT;
			LPCSTR lpx=(LPCSTR)lprefix;
			for(int i=0;i<LCurve->GetKeyCount();i++)
			{
				fprintf(fl,"%sStartCurveKey\n",npx);
				fprintf(fl,"%sTime=%f\n",lpx,(*LCurve)[i].m_time);
				fprintf(fl,"%sSlope=%f\n",lpx,(*LCurve)[i].m_slope);
				fprintf(fl,"%sValue=%f\n",lpx,(*LCurve)[i].m_value);
				fprintf(fl,"%sEndCurveKey\n",npx);
			}
		}
		break;
		
	case gosFX::Curve::e_ComplexComplexType:
		{
			gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::ComplexCurve,gosFX::Curve::e_ComplexComplexType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::ComplexCurve,gosFX::Curve::e_ComplexComplexType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
	case gosFX::Curve::e_ComplexLinearType:
		{
			gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::LinearCurve,gosFX::Curve::e_ComplexLinearType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::LinearCurve,gosFX::Curve::e_ComplexLinearType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
		
	case gosFX::Curve::e_ComplexSplineType:	
		{
			gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::SplineCurve,gosFX::Curve::e_ComplexSplineType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ComplexCurve, gosFX::SplineCurve,gosFX::Curve::e_ComplexSplineType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
	case gosFX::Curve::e_ConstantComplexType:
		{
			gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::ComplexCurve,gosFX::Curve::e_ConstantComplexType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::ComplexCurve,gosFX::Curve::e_ConstantComplexType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
	case gosFX::Curve::e_ConstantLinearType:
		{
			gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::LinearCurve,gosFX::Curve::e_ConstantLinearType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::LinearCurve,gosFX::Curve::e_ConstantLinearType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
	case gosFX::Curve::e_ConstantSplineType:
		{
			gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::SplineCurve,gosFX::Curve::e_ConstantSplineType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::ConstantCurve, gosFX::SplineCurve,gosFX::Curve::e_ConstantSplineType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
	case gosFX::Curve::e_SplineLinearType:
		{
			gosFX::SeededCurveOf<gosFX::SplineCurve, gosFX::LinearCurve,gosFX::Curve::e_SplineLinearType> *LCurve=
				(gosFX::SeededCurveOf<gosFX::SplineCurve, gosFX::LinearCurve,gosFX::Curve::e_SplineLinearType> *)Curve;
			fprintf(fl,"%sSeeded=%s\n",npx,LCurve->m_seeded?"TRUE":"FALSE");
			ExportCurve(fl,&(LCurve->m_ageCurve),"AgeCurve",newprefix);
			ExportCurve(fl,&(LCurve->m_seedCurve),"SeedCurve",newprefix);
		}
		break;
		
		}
		fprintf(fl,"%sEndCurve[%s]\n\n",(LPCSTR)prefix,(LPCSTR)CurveName);
}

void ExportState(FILE *fl,MidLevelRenderer::MLRState *State,char *Name,CString prefix)
{
	
	fprintf(fl,"\n%sStart State[%s]\n",(LPCSTR)prefix,Name);
	CString newprefix=prefix+INDENT;
	LPCSTR npx=(LPCSTR)newprefix;
	
	int AStyle;
	if(State->GetWireFrameMode()==MidLevelRenderer::MLRState::WireFrameOnlyMode)
	{
		AStyle=3;
	}
	else
	{
		if(State->GetZBufferWriteMode()==MidLevelRenderer::MLRState::ZBufferWriteOnMode)
			if(State->GetAlphaMode()==MidLevelRenderer::MLRState::OneInvAlphaMode)
				AStyle=1;
			else
				if(State->GetAlphaMode()==MidLevelRenderer::MLRState::AlphaInvAlphaMode)
					AStyle=2;
				else
					AStyle=0;
				else
					if(State->GetAlphaMode()==MidLevelRenderer::MLRState::OneInvAlphaMode)
						AStyle=4;
					else
						if(State->GetAlphaMode()==MidLevelRenderer::MLRState::AlphaInvAlphaMode)
							AStyle=5;
						else
							AStyle=0;
	}
	
	switch(AStyle)
	{
	case 0: 
		fprintf(fl,"%sAlphaMode=%s\n",npx,"Default");
		break;
	case 1: 
		fprintf(fl,"%sAlphaMode=%s\n",npx,"OneInvAlphaZWriteOn");
		break;
	case 2: 
		fprintf(fl,"%sAlphaMode=%s\n",npx,"AlphaInvAlphaZWriteOn");
		break;
	case 3:
		fprintf(fl,"%sAlphaMode=%s\n",npx,"WireFrame");
		break;
	case 4: 
		fprintf(fl,"%sAlphaMode=%s\n",npx,"OneInvAlphaZWriteOff");
		break;
	case 5: 
		fprintf(fl,"%sAlphaMode=%s\n",npx,"AlphaInvAlphaZWriteOff");
		break;
	}
	
	CString TextureName;
	if(State->GetTextureHandle()!=0)
	{
		TextureName=((*MidLevelRenderer::MLRTexturePool::Instance)[State])->GetTextureName();
	}
	else
	{
		TextureName="None";
	}
	
	fprintf(fl,"%sTexture=%s\n",npx,(LPCSTR)TextureName);
	fprintf(fl,"%sEndState[%s]\n\n",(LPCSTR)prefix,Name);
	
}

void ExportEffect(FILE *fl,gosFX::Effect::Specification *spec,CString px)
{
	CString etype;
	switch (spec->GetClassID())
	{
	case gosFX::EffectClassID:			etype="EffectClass"; break;
	case gosFX::ParticleCloudClassID:	etype="ParticleCloud"; break;
	case gosFX::PointCloudClassID:		etype="PointCloud"; break;
	case gosFX::SpinningCloudClassID:	etype="SpinningCloud"; break;
	case gosFX::ShardCloudClassID:		etype="ShardCloud"; break;
	case gosFX::PertCloudClassID:		etype="PertCloud"; break;
	case gosFX::CardCloudClassID:		etype="CardCloud"; break;
	case gosFX::ShapeCloudClassID:		etype="ShapeCloud"; break;
	case gosFX::EffectCloudClassID:		etype="EffectCloud"; break;
	case gosFX::SingletonClassID:		etype="Singleton"; break;
	case gosFX::CardClassID:			etype="Card"; break;
	case gosFX::ShapeClassID:			etype="Shape"; break;
	}

	fprintf(fl,"\n%sStartEffect[%s,%s]\n",(LPCSTR)px,(LPCSTR)etype,(char *)spec->m_name);
	CString prefix=px+INDENT;
	LPCSTR prx=(LPCSTR)prefix;
	
	
//	fprintf(fl,"%sEffectType=%s\n",prx,(LPCSTR)etype);
	
	
	if(spec->GetClassID()!=gosFX::EffectClassID)
	{
		if(spec->GetClassID()==gosFX::CardClassID || spec->GetClassID()==gosFX::ShapeClassID)
		{
			gosFX::Singleton__Specification *tspec;
			tspec=Cast_Pointer(gosFX::Singleton__Specification *,spec);
			Check_Object(tspec);
			
			fprintf(fl,"%sAlignZUsingX=%s\n",prx,tspec->m_alignZUsingX?"TRUE":"FALSE");
			fprintf(fl,"%sAlignZUsingY=%s\n",prx,tspec->m_alignZUsingY?"TRUE":"FALSE");
			ExportCurve(fl,&tspec->m_scale,"Scale",prefix);
			ExportCurve(fl,&tspec->m_red,"Singleton Color Red",prefix);
			ExportCurve(fl,&tspec->m_green,"Singleton Color Green",prefix);
			ExportCurve(fl,&tspec->m_blue,"Singleton Color Blue",prefix);
			ExportCurve(fl,&tspec->m_alpha,"Singleton Color Alpha",prefix);
		}
		
		
		
		// Particle Cloud
		switch (spec->GetClassID())	
		{
		case gosFX::CardClassID:
			{
				gosFX::Card__Specification *tspec;
				tspec=Cast_Pointer(gosFX::Card__Specification *,spec);
				Check_Object(tspec);
				
				
				ExportCurve(fl,&tspec->m_halfHeight,"HalfHeight",prefix);
				ExportCurve(fl,&tspec->m_aspectRatio,"AspectRatio",prefix);
				ExportCurve(fl,&tspec->m_UOffset,"UOffset",prefix);
				ExportCurve(fl,&tspec->m_VOffset,"VOffset",prefix);
				ExportCurve(fl,&tspec->m_USize,"USize",prefix);
				ExportCurve(fl,&tspec->m_VSize,"VSize",prefix);
			}
			break;
			
		case gosFX::ShapeClassID:
			{
				gosFX::Shape__Specification *tspec;
				tspec=Cast_Pointer(gosFX::Shape__Specification *,spec);
				Check_Object(tspec);
				
				//!!!!!!!!!!! No Access to Shape what to put here?!
				/*
				*/
			}
			break;
			
		default:
			{
				gosFX::ParticleCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::ParticleCloud__Specification *,spec);
				
				fprintf(fl,"%sMaxParticleCount=%i\n",prx,tspec->m_maxParticleCount);
				ExportCurve(fl,&tspec->m_pDrag,"ParticleDrag",prefix);
				ExportCurve(fl,&tspec->m_particlesPerSecond,"ParticlesPerSecond",prefix);
				ExportCurve(fl,&tspec->m_startingSpeed,"StartingSpeed",prefix);
				ExportCurve(fl,&tspec->m_minimumDeviation,"MinimumDeviation",prefix);
				ExportCurve(fl,&tspec->m_maximumDeviation,"MaximumDeviation",prefix);
				ExportCurve(fl,&tspec->m_pLifeSpan,"ParticleLifeSpan",prefix);
				ExportCurve(fl,&tspec->m_startingPopulation,"StartingPopulation",prefix);
				ExportCurve(fl,&tspec->m_emitterSizeX,"EmmiterSizeX",prefix);
				ExportCurve(fl,&tspec->m_emitterSizeY,"EmmiterSizeY",prefix);
				ExportCurve(fl,&tspec->m_emitterSizeZ,"EmmiterSizeZ",prefix);
				ExportCurve(fl,&tspec->m_pEtherVelocityX,"EtherVelocityX",prefix);
				ExportCurve(fl,&tspec->m_pEtherVelocityY,"EtherVelocityY",prefix);
				ExportCurve(fl,&tspec->m_pEtherVelocityZ,"EtherVelocityZ",prefix);
				ExportCurve(fl,&tspec->m_pAccelerationX,"ParticleAccelerationX",prefix);
				ExportCurve(fl,&tspec->m_pAccelerationY,"ParticleAccelerationY",prefix);
				ExportCurve(fl,&tspec->m_pAccelerationZ,"ParticleAccelerationZ",prefix);
				ExportCurve(fl,&tspec->m_pRed,"ParticleColorRed",prefix);
				ExportCurve(fl,&tspec->m_pGreen,"ParticleColorGreen",prefix);
				ExportCurve(fl,&tspec->m_pBlue,"ParticleColorBlue",prefix);
				ExportCurve(fl,&tspec->m_pAlpha,"ParticleColorAlpha",prefix);
			}
			
			
			// Spinning CLoud
			if(spec->GetClassID()!=gosFX::PointCloudClassID)
			{
				gosFX::SpinningCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::SpinningCloud__Specification *,spec);
				Check_Object(tspec);
				
				fprintf(fl,"%sRandomStartingPosition=%s\n",prx,tspec->m_randomStartingRotation?"TRUE":"FALSE");
				fprintf(fl,"%sAlignZUsingX=%s\n",prx,tspec->m_alignZUsingX?"TRUE":"FALSE");
				fprintf(fl,"%sAlignZUsingY=%s\n",prx,tspec->m_alignZUsingY?"TRUE":"FALSE");
				ExportCurve(fl,&tspec->m_pSpin,"Spin",prefix);
				ExportCurve(fl,&tspec->m_pScale,"Scale",prefix);
			}
		} //end of CS 1
		
		switch (spec->GetClassID())	
		{
		case gosFX::EffectCloudClassID:
			{
				gosFX::EffectCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::EffectCloud__Specification *,spec);
				Check_Object(tspec);
				
			}
			break;
		case gosFX::PointCloudClassID:
			{
				gosFX::PointCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::PointCloud__Specification *,spec);
				Check_Object(tspec);
				
				
			}
			break;
			
		case gosFX::ShardCloudClassID:
			{
				gosFX::ShardCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::ShardCloud__Specification *,spec);
				Check_Object(tspec);
				ExportCurve(fl,&tspec->m_size,"Size",prefix);
				ExportCurve(fl,&tspec->m_angularity,"Angularity",prefix);
			}
			break;
			
		case gosFX::ShapeCloudClassID:
			{
				gosFX::ShapeCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::ShapeCloud__Specification *,spec);
				Check_Object(tspec);
				/*  !!!!!!!!!!!!! More Shape Problems
				LastItem=m_PTree.InsertItem("Shape",0,0,ParItem,LastItem);			
				CSet[cnt].SetType(CurveSet::SHAPECLOUDPANEL,&tspec);
				m_PTree.SetItemData(LastItem,(DWORD)&CSet[cnt]);
				cnt++;
				*/
				
			}
			break;
			
		case gosFX::PertCloudClassID:
			{
				gosFX::PertCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::PertCloud__Specification *,spec);
				Check_Object(tspec);
				
				ExportCurve(fl,&tspec->m_pCenterRed,"CenterColorRed",prefix);
				ExportCurve(fl,&tspec->m_pCenterGreen,"CenterColorGreen",prefix);
				ExportCurve(fl,&tspec->m_pCenterBlue,"CenterColorBlue",prefix);
				ExportCurve(fl,&tspec->m_pCenterAlpha,"CenterColorAlpha",prefix);
				ExportCurve(fl,&tspec->m_size,"Size",prefix);
				ExportCurve(fl,&tspec->m_perturbation,"Perturbation",prefix);
			}
			break;
			
		case gosFX::CardCloudClassID:
			{
				gosFX::CardCloud__Specification *tspec;
				tspec=Cast_Pointer(gosFX::CardCloud__Specification *,spec);
				Check_Object(tspec);
				
				ExportCurve(fl,&tspec->m_halfHeight,"HalfHeight",prefix);
				ExportCurve(fl,&tspec->m_aspectRatio,"AspectRatio",prefix);
				ExportCurve(fl,&tspec->m_UOffset,"UOffset",prefix);
				ExportCurve(fl,&tspec->m_VOffset,"VOffset",prefix);
				ExportCurve(fl,&tspec->m_USize,"USize",prefix);
				ExportCurve(fl,&tspec->m_VSize,"VSize",prefix);
			}
			break;
		}
}


if(spec->GetClassID()==gosFX::EffectCloudClassID)
{
	gosFX::EffectCloud__Specification *tspec;
	tspec=Cast_Pointer(gosFX::EffectCloud__Specification *,spec);
	Check_Object(tspec);
	
	if(tspec->m_particleEffectID!=BADINDEX)
	{
		CString lprefix=prefix+INDENT;
		LPCSTR lpx=(LPCSTR)lprefix;
		fprintf(fl,"\n%sStartChildEffect\n",(LPCSTR)px);
		ExportEffect(fl,gosFX::EffectLibrary::Instance->m_effects[tspec->m_particleEffectID],lprefix);
		fprintf(fl,"%sEndChildEffect\n\n",(LPCSTR)px);
	}
}
else
{
	gosFX::Event *event;
	Stuff::ChainIteratorOf<gosFX::Event*> eitr(&(spec->m_events));
	eitr.First();
	while(NULL!=(event=eitr.ReadAndNext()))
	{
		CString lprefix=prefix+INDENT;
		LPCSTR lpx=(LPCSTR)lprefix;
		
		fprintf(fl,"\n%sStartChildEffect\n",(LPCSTR)px);
		Stuff::Point3D pnt(0,0,0);
		pnt*=event->m_localToParent;
		
		fprintf(fl,"%sLocationX=%f\n",(LPCSTR)lpx,pnt.x);
		fprintf(fl,"%sLocationY=%f\n",(LPCSTR)lpx,pnt.y);
		fprintf(fl,"%sLocationZ=%f\n",(LPCSTR)lpx,pnt.z);
		
		gosFX::Effect::Specification *tspec=gosFX::EffectLibrary::Instance->m_effects[event->m_effectID];
		ExportEffect(fl,tspec,lprefix);
		fprintf(fl,"%sEndChildEffect\n\n",(LPCSTR)px);
	}
}

fprintf(fl,"%sEndEffect[%s]\n\n",(LPCSTR)px,(char *)spec->m_name);

}

bool IsRootEffect(gosFX::Effect::Specification *ospec)
{
	int effnum;
	for(effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
	{
		gosFX::Effect::Specification *spec=gosFX::EffectLibrary::Instance->m_effects[effnum];
		gosFX::Event *event;
		
		Stuff::ChainIteratorOf<gosFX::Event*> eitr(&(spec->m_events));
		eitr.First();
		while(NULL!=(event=eitr.ReadAndNext()))
		{
			if(event->m_effectID==ospec->m_effectID) return false;
		}
		
		
	}
	
	return true;
}
