#include "stdafx.h"
#include "GeoExport.h"

#include <GameOS\GameOS.hpp>
#include <GameOS\ToolOS.hpp>
#include <proxies\makesinglesided.hpp>
#include <proxies\optimizeflatshading.hpp>
#include "MaxProxies\MaxProxyHeaders.hpp"
#include "ExportUtil.h"

#if !defined(DLLPLATFORM_DLLPLATFORM_HPP)
	#include "DLLPlatform\DLLPlatform.hpp"
#endif

//===========================================================================//

int	GeoExporter::DoExportWrap(const TCHAR *name,ExpInterface *ei,Interface *ip, BOOL suppressPrompts)
{

	StartExport(ip, CString("Exporting ERF data."), suppressPrompts?true:false);

	//
	// fill in all the directories
	//
	if (!LoadPlugCfg(ip))
		return false;


	MAXProxies::MAXScene *max_scene = MakeMaxScene(ip,m_strHintFile);
	Check_Object(max_scene);

	// Check for errors   
    if (!CheckForErrors(max_scene,ip))
    {
        return false;
    }

	ExportMaxScene(max_scene, ip, name);

	EndExport(ip);
	return true;	
}

/*******************************************************************************
/* function name: WriteOutGeometry_Video_Data_Files
/* description: write out .video file for specified geometries
/*******************************************************************************/
int GeoExporter::WriteOutGeometry_Video_Data_Files(
		const CString& path,const CString& fileName, const CString& strCageName, 
		const CString &lightFileName, RootGeo rootGeos[], int numOfRootGeos, bool bSetUniqueYes)

{
	
	CString videoFileName = fileName+".video";
    NotationFile videofile;

	// Is there a light node
	if (lightFileName != "")
	{
		// NotationFile videofile;
		Page *vidpage = videofile.AddPage("LightLOD");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","ShapeComponent");
		vidpage->SetEntry("Geometry",lightFileName);
		if (bSetUniqueYes)
		{
			vidpage->SetEntry("Unique", true);
		}
		vidpage = videofile.AddPage("LightWatcher");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","AttributeWatcherOfInt");
		vidpage->SetEntry("Attribute","IsDark");
		vidpage->SetEntry("SimulationShouldExecute","1");
		
		vidpage = videofile.AddPage("LightSwitch");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","SwitchComponent");
		vidpage->SetEntry("Input","LightWatcher");
		vidpage->SetEntry("Child","LightLOD");
	}

	bool fDamLodsPresent = false;
    bool fLodsPresent = false;

	// There should be at least one root geometry
	Verify(numOfRootGeos>=1);

	// If there is more than one root geometry
	// each one will need a ShapeComponent/SlidingShapeComponent,
	// and we need a GroupComponent to get all the shape compoments
	if (numOfRootGeos > 1)
	{

		for (int i=0; i<numOfRootGeos; i++) {
			CString erf_filename = rootGeos[i].name;
			erf_filename += ".erf";
			if (gos_DoesFileExist(path+erf_filename))
			{
				Page *page = videofile.SetPage(rootGeos[i].name);
				Check_Object(page);
				page->SetEntry("Type",rootGeos[i].type);
				page->SetEntry("Geometry",erf_filename);
				if (bSetUniqueYes)
				{
					page->SetEntry("Unique", true);
				}
				if (rootGeos[i].type == "SlidingShapeComponent") {
					page->SetEntry("Transform",rootGeos[i].transform);
					page->SetEntry("SimulationShouldExecute", "yes");
					page->SetEntry("Unique", true);
				}
			}
		}

		Page* vidpage = videofile.SetPage("Group");
		Check_Object(vidpage);
		vidpage->SetEntry("Type", "GroupComponent");
		for (i=0; i<numOfRootGeos; i++) {
			CString erf_filename = rootGeos[i].name;
			erf_filename += ".erf";
			if (gos_DoesFileExist(path+erf_filename))
				vidpage->AppendEntry("Child", rootGeos[i].name);
		}

		vidpage = videofile.SetPage("Watcher");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","AttributeWatcherOfInt");
		vidpage->SetEntry("Attribute","VisualRepresentation");
		vidpage->SetEntry("SimulationShouldExecute","1");
		
		vidpage = videofile.SetPage("DamageAppearance");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","SwitchComponent");
		vidpage->SetEntry("Input","Watcher");
		vidpage->SetEntry("Child", "Group");
	}

	// If there is only one root geometry
	else if (numOfRootGeos == 1)
	{
	
		bool bDoCage = false;
		CString name_ext = rootGeos[0].name;
		name_ext = name_ext.Right(4);
		if ((0==stricmp("cage",name_ext)) && strCageName.GetLength())
			bDoCage = true;

		// Cage need some special entries
		if (bDoCage)
		{
			Page *vidpage = videofile.SetPage("Fake1");
			Check_Object(vidpage);
			vidpage->SetEntry("Type","GroupComponent");

			vidpage = videofile.SetPage("Fake2");
			Check_Object(vidpage);
			vidpage->SetEntry("Type","GroupComponent");

			vidpage = videofile.SetPage("Cage");
			Check_Object(vidpage);
			vidpage->SetEntry("Type","ShapeComponent");
			vidpage->SetEntry("Geometry",strCageName);
			if (bSetUniqueYes)
			{
				vidpage->SetEntry("Unique", true);
			}
			vidpage->SetEntry("DisableShadow","true");

			vidpage = videofile.SetPage("DestroyedCage");
			Check_Object(vidpage);
			vidpage->SetEntry("Type","ShapeComponent");
			vidpage->SetEntry("Geometry",strCageName);
			if (bSetUniqueYes)
			{
				vidpage->SetEntry("Unique", true);
			}
			vidpage->SetEntry("DisableShadow","true");
		}

		CString erf_filename = rootGeos[0].name;
		erf_filename += ".erf";
		if (gos_DoesFileExist(path+erf_filename))
		{
			fLodsPresent = true; // at least one present					
			Page *page = videofile.SetPage("LOD");
			Check_Object(page);
			page->SetEntry("Type",rootGeos[0].type);
			page->SetEntry("Geometry",erf_filename);
			if (bSetUniqueYes)
			{
				page->SetEntry("Unique", true);
			}
			if (rootGeos[0].type == "SlidingShapeComponent") {
				page->SetEntry("Transform",rootGeos[0].transform);
				page->SetEntry("SimulationShouldExecute", "yes");
			}
		}

		CString erf_DAM_filename = rootGeos[0].name;;
		erf_DAM_filename += "_DAM.erf";
        if (gos_DoesFileExist(path+erf_DAM_filename))
		{
			fDamLodsPresent = true; // at least one present					
			Page *page = videofile.SetPage("DAMLOD");
			page->SetEntry("Type","ShapeComponent");
			page->SetEntry("Geometry",erf_DAM_filename);
			if (bSetUniqueYes)
			{
				page->SetEntry("Unique", true);
			}
		}
		
		Page* vidpage = videofile.SetPage("Watcher");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","AttributeWatcherOfInt");
		vidpage->SetEntry("Attribute","VisualRepresentation");
		vidpage->SetEntry("SimulationShouldExecute","1");
		
		vidpage = videofile.SetPage("DamageAppearance");
		Check_Object(vidpage);
		vidpage->SetEntry("Type","SwitchComponent");
		vidpage->SetEntry("Input","Watcher");

		if (fLodsPresent)
			vidpage->AppendEntry("Child","LOD");
		if (fDamLodsPresent)
			vidpage->AppendEntry("Child","DAMLOD");
		if (bDoCage) {
			vidpage->AppendEntry("Child","Fake1");
			vidpage->AppendEntry("Child","Fake2");
			vidpage->AppendEntry("Child","Cage");
			vidpage->AppendEntry("Child","DestroyedCage");
		}
	}
	
	//
	// HACKHACK - Locator has to be last no matter what so add any pages we need from above in case we get here first..
	//
	if (lightFileName != "")
	{
		Page* vidpage = videofile.SetPage("Locator");
		Check_Object(vidpage);
		vidpage->AppendEntry("Child","LightSwitch");
		vidpage->AppendEntry("Child","DamageAppearance");
	}

	else {
		Page* vidpage = videofile.SetPage("Locator");
		vidpage->AppendEntry("Child","DamageAppearance");
	}
	
	videofile.SaveAs(path+videoFileName);
	
	return 0;
}

/*******************************************************************************
/* function name: GetRootGeos
/* description: Traverse the max node to determine which geometries are going into
/*	the .video file
/*******************************************************************************/
int GeoExporter::GetRootGeos(CString path, RootGeo rootGeos[], int* numOfRootGeos, INode *node)
{
	TurnOffExceptions();
	for (int x=node->NumberOfChildren()-1;x>=0;x--)
	{

		GetRootGeos(path, rootGeos, numOfRootGeos, node->GetChildNode(x));
		TSTR value;
		INode *pChild = node->GetChildNode(x);
		CString name = pChild->GetName();
		name.MakeLower();

		// Does its name contains "KEEP_"
		if (name.Find("keep_")>=0 &&
			gos_DoesFileExist(path+name+".erf")) {

			rootGeos[*numOfRootGeos].name = name;
			if (pChild->GetUserPropString("ANIMATE",value))
			{
				// Use SlidingShapeComponent for animated textures
				rootGeos[*numOfRootGeos].type = "SlidingShapeComponent";

                CString str(value);
                int index = str.Find(",",0);
                if (index>=0)
                    str = str.Left(index);

				str.MakeUpper();
				if (str == "LTREAD")
					rootGeos[*numOfRootGeos].transform = "LTread";
				else if (str == "RTREAD")
					rootGeos[*numOfRootGeos].transform = "RTread";
			}
			else 
				rootGeos[*numOfRootGeos].type = "ShapeComponent";

			(*numOfRootGeos)++;
		}
		TurnOnExceptions();
	}

	return 0;
}
