XSIPLUGINCALLBACK CStatus OutputImportTxt()
{
	// prepare the import.txt file
	CString strOut = CUtils::BuildPath(Get3DCoatParam( L"coatLocation" ).GetValue(), L"import.txt");

	std::ofstream tfw;
	tfw.open(strOut.GetAsciiString(), std::ios_base::out | std::ios_base::trunc );
	if (tfw.is_open())
	{
		CString objTmp = Get3DCoatParam( L"tempLocation" ).GetValue();
		tfw << objTmp.GetAsciiString();
		tfw << "\n";

		CString objOut = objTmp.GetSubString(0, objTmp.ReverseFindString(CUtils::Slash())+1);
		objOut += L"output.obj";

		tfw << objOut.GetAsciiString();
		tfw << "\n";

		int typePaint = Get3DCoatParam( L"typePaint" ).GetValue();

	//Paint mesh in 3D-Coat using per-pixel painting [ppp]
	//Paint mesh in 3D-Coat using microvertex painting [mv]
	//Paint mesh in 3D-Coat using Ptex [ptex]
	//Perform UV-mapping in 3D-Coat [uv]
	//Drop reference mesh to 3D-Coat [ref]
	//Drop retopo mesh as new layer in 3D-Coat [retopo]
	//Drop mesh in 3D-Coat as voxel object [vox] 
	//Drop mesh in 3D-Coat as new pen alpha [alpha]
	//Drop mesh in 3D-Coat as new merging primitive for voxels [prim]
        //Drop mesh in 3D-Coat as a curve profile [curv]
	//Drop mesh in 3D-Coat for Auto-retopology [autopo]

		CString strPaint = L"[";
		switch (typePaint)
		{
			case 0:
				strPaint += L"ppp";
				break;
			case 1:
				strPaint += L"mv";
				break;
			case 2:
				strPaint += L"ptex";
				break;
			case 3:
				strPaint += L"uv";
				break;
			case 4:
				strPaint += L"ref";
				break;
			case 5:
				strPaint += L"retopo";
				break;
			case 6:
				strPaint += L"vox";
				break;
			case 7:
				strPaint += L"alpha";
				break;
			case 8:
				strPaint += L"prim";
				break;
			case 9:
                		strPaint += L"curv";
				break;
			case 10:
				strPaint += L"autopo";
				break;
		}

		strPaint += L"]";

		tfw << strPaint.GetAsciiString();

		bool bExpSkipIm = Get3DCoatParam( L"bExpSkipImp" ).GetValue();
		if(bExpSkipIm)
		{
			tfw << "\n";
			tfw << "[SkipImport]";
		}

		bool bExpSkipExp = Get3DCoatParam( L"bExpSkipExp" ).GetValue();
		if(bExpSkipExp)
		{
			tfw << "\n";
			tfw << "[SkipExport]";
		}

		tfw.close();
	}

	return CStatus::OK;
}
CString* CLocalizationEngine::GetString(const char* aId)
{
	CString* lLocalizedString = new CString(aId); //if String can't be found, use the indentifier for the String
	CString* lStringId = new CString(aId);
	CString* lFileName;
	CString* lCategoryName;
	CString* lStringName;
	TInt lStartIndex = 0;
	TInt lDotIndex = 0;

	//Find FileName
	lDotIndex = lStringId->FindString(lStartIndex,"."); //find location of seperator
	if(lDotIndex == -1)
	{
		lLocalizedString->Replace("ID FILENAME ERROR!");

		//clean up
		delete lStringId;

		return lLocalizedString;
	}
	else
	{
		lFileName = lStringId->GetSubString(lStartIndex,lDotIndex);
		lStartIndex = lDotIndex + 1; //skip dot
	}

	//Find CategoryName
	lDotIndex = lStringId->FindString(lStartIndex,"."); //find location of seperator
	if(lDotIndex == -1)
	{
		lLocalizedString->Replace("ID CATEGORYNAME ERROR!");

		//clean up
		delete lStringId;
		delete lFileName;

		return lLocalizedString;
	}
	else
	{
		lCategoryName = lStringId->GetSubString(lStartIndex,lDotIndex - lStartIndex);
		lStartIndex = lDotIndex + 1; //skip dot
	}

	//get StringName
	lStringName = lStringId->GetSubString(lStartIndex, lStringId->GetLength() - lStartIndex); //cut the last part of the String that remains
	if(lStringName == NULL)
	{
		lLocalizedString->Replace("ID STRINGNAME ERROR!");

		//clean up
		delete lStringId;
		delete lFileName;
		delete lCategoryName;

		return lLocalizedString;
	}

	//call method to handle the actual lookup
	GetStringFromFile(lFileName, lCategoryName, lStringName, lLocalizedString);

	//clean up
	delete lStringId;
	delete lFileName;
	delete lCategoryName;
	delete lStringName;

	return lLocalizedString;
}
XSIPLUGINCALLBACK CStatus OutputMaterials( Selection& in_sel )
{
	// prepare the mtl file
	Project prj = app.GetActiveProject();
	Scene scn = prj.GetActiveScene();
	CString tmpLocation = Get3DCoatParam( L"tempLocation" ).GetValue();

	ULONG npos = tmpLocation.ReverseFindString(L".");
	CString substr = tmpLocation.GetSubString(0, npos+1);
	CString strOut = substr + L"mtl";	

	//app.LogMessage(L"strOut:" + strOut);

	std::ofstream matfw;
	matfw.open(strOut.GetAsciiString(), std::ios_base::out | std::ios_base::trunc);
	if (matfw.is_open())
	{
		CRefArray tempMats;

		for(int i=0; i< in_sel.GetCount(); i++)
		{
			X3DObject xobj(in_sel.GetItem(i));

			// Get a geometry accessor from the selected object	
			Primitive prim = xobj.GetActivePrimitive();
			PolygonMesh mesh = prim.GetGeometry();
			if (!mesh.IsValid()) return CStatus::False;

			CGeometryAccessor ga = mesh.GetGeometryAccessor();

			// get the material objects used by the mesh
			CRefArray materials = ga.GetMaterials();

			for (LONG n=0; n < materials.GetCount(); n++)
			{
				bar.PutStatusText( L"materials" );

				Material mat(materials[n]);
				bool inMats = false;
				//app.LogMessage(CString(n) +L" : "+ CString(i)+ L" :" + mat.GetName());

				for(int m = 0; m < tempMats.GetCount(); m++)
				{
					Material tmat(tempMats[m]);
					if(mat.GetName() == tmat.GetName())
					{
						inMats = true;
						break;
					}
				}

				//app.LogMessage(CString(inMats));

				if(!inMats)
				{
					CString string = L"newmtl " + mat.GetName() + L"\n";
					matfw << string.GetAsciiString();

					Parameter surf = mat.GetParameters().GetItem(L"surface");
					Shader lShader(surf.GetSource());
					//app.LogMessage(L"shader: " + lShader.GetFullName());
					//app.LogMessage(L"shader: " + lShader.GetProgID());
					if ( lShader.GetProgID() == L"Softimage.material-phong.1" )
					{
						float r, g, b, a;

						lShader.GetColorParameterValue(L"ambient", r, g, b, a );
						CString ka = L"Ka " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b);
						lShader.GetColorParameterValue(L"diffuse", r, g, b, a );
						CString kd = L"Kd " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b);
						lShader.GetColorParameterValue(L"specular", r, g, b, a );
						CString ks = L"Ks " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b);
						float ns = lShader.GetParameterValue(L"shiny");
						float d = 1.0f;
						CValue illum = 2;

						matfw << ka.GetAsciiString();
						matfw << "\n";
						matfw << kd.GetAsciiString();
						matfw << "\n";
						matfw << ks.GetAsciiString();
						matfw << "\n";
						matfw << "Ns ";
						matfw << FormatNumber(ns).GetAsciiString();
						matfw << "\n";
						matfw << "d ";
						matfw << FormatNumber(d).GetAsciiString();
						matfw << "\n";
						matfw << "illum ";
						matfw << illum.GetAsText().GetAsciiString();
						matfw << "\n";

						Parameter diff = lShader.GetParameters().GetItem(L"diffuse");
						Shader lImageD(diff.GetSource());

						if (lImageD.GetProgID() == L"Softimage.txt2d-image-explicit.1")
						{
							Parameter tex = lImageD.GetParameters().GetItem(L"tex");
							ImageClip2 lTextureD(tex.GetSource());

							//app.LogMessage( L"Found texture shader: " + lTexture.GetFullName() + L", Class: " + lTexture.GetClassIDName() + L", Type: " + lTexture.GetType() );
							app.LogMessage(L"texture GetFileName: " + lTextureD.GetFileName());
							matfw << "map_Kd ";
							matfw << lTextureD.GetFileName().GetAsciiString();
							matfw << "\n";
						}

						Parameter spec = lShader.GetParameters().GetItem(L"specular");
						Shader lImageS(spec.GetSource());

						if (lImageS.GetProgID() == L"Softimage.txt2d-image-explicit.1")
						{
							Parameter tex = lImageD.GetParameters().GetItem(L"tex");
							ImageClip2 lTextureS(tex.GetSource());

							//app.LogMessage( L"Found texture shader: " + lTexture.GetFullName() + L", Class: " + lTexture.GetClassIDName() + L", Type: " + lTexture.GetType() );
							//app.LogMessage(L"texture GetFileName: " + lTexture.GetFileName());
							matfw << "map_Ks ";
							matfw << lTextureS.GetFileName().GetAsciiString();
							matfw << "\n";
						}
					}
					tempMats.Add(mat);
					matfw << "\n";
					matfw << "\n";
				}
			}		
		}
		matfw.close();
	}
	return CStatus::OK;
}
void CLocalizationEngine::BuildIndexForLanguageFile(CString* aFileName)
{
	//find FileIndex and reset other attributes
	iFileIndex = -1;
	for(TInt lFileIndex = 0; lFileIndex < iFileEntries->GetCount(); lFileIndex++)
	{
		if(iFileEntries->Get(lFileIndex)->FileName->EqualTo(aFileName))
		{
			iFileIndex = lFileIndex;
			break;
		}
	}
	//reset state to be ready for reading data
	iState = EStateReady;
	iCategoryIndex = -1;
	iStringIndex = -1;
	iByteLocationInFile = 0;

	CString* lFullPath = GetFullPathForFileName(aFileName->GetData());
	TInt lFileContentSize = CAssetDirectory::GetAssetFileSizeInBytes(lFullPath->GetData());
	TUint8* lFileContent = CAssetDirectory::ReadAssetFile(lFullPath->GetData());
	//need to expend the memory block by 1 byte to append the NULL character
	lFileContent = (TUint8*) realloc(lFileContent, sizeof(TUint8) * (lFileContentSize + 1));
	lFileContent[lFileContentSize] = '\0';
	//convert the file content to a CString
	CString* lFileContentAsString = new CString((char*) lFileContent);
	//clean up
	delete[] lFileContent; //made a copy of it
	delete lFullPath;

	//go through the file and build up an index to the String Values
	for (TInt lIndex = 0; lIndex < lFileContentAsString->GetLength(); lIndex++)
	{
		CString* lCharacter = lFileContentAsString->GetSubString(lIndex, 1);

		switch (iState)
		{
			case EStateReady:
			{
				HandleReadyState(lCharacter);
				break;
			}
			case EStateLookingForEndOfCategoryName:
			{
				HandleEndOfCategoryNameState(lCharacter);
				break;
			}
			case EStateLookingForEndOfStringId:
			{
				HandleEndOfStringId(lCharacter);
				break;
			}
			case EStateLookingForBeginningOfStringValue:
			{
				HandleBeginningOfStringValue(lCharacter);
				break;
			}
			case EStateLookingForEndOfStringValue:
			{
				HandleEndOfStringValue(lCharacter);
				break;
			}
			case EStateComment:
			{
				HandleCommentState(lCharacter);
				break;
			}
		}

		iByteLocationInFile += lCharacter->GetSizeOfStringInBytes(); //need increment the byte Location
		delete lCharacter; //not needed anymore
	}

	//not needed anymore
	delete lFileContentAsString;
}