text:
#include "stdafx.h"
#include <Metrics.h>
#include <fstream>
#include <CADMetrics.h>
#include <ToolKitPassThroughFunctions.h>
#include <iomanip>
#include <GraphicsFunctions.h>
#include "Joint.h"

#ifndef ISIS_VERSION_NUMBER_H
#define ISIS_VERSION_NUMBER_H
#include <ISISVersionNumber.h>
#endif

namespace isis
{

///////////////////////////////////////////////////////////////////////////////////////

void  ConvertCreoUnitToGMEUnit_Distance ( ProName in_DistanceUnit, std::string &out_ShortName, std::string &out_LongName  )
{
	char stringBuffer[PRO_NAME_SIZE];  // PRO_NAME_SIZE = 32

	std::string unit = ProWstringToString( stringBuffer, in_DistanceUnit );

	out_ShortName	= unit;
	out_LongName	= unit;

	if ( unit == "in" ) { out_ShortName = "inch";	out_LongName = "inch"; }
	if ( unit == "ft" ) { out_ShortName = "foot";	out_LongName = "foot"; }
	if ( unit == "mm" ) { out_ShortName = "mm";		out_LongName = "millimeter"; }
	if ( unit == "cm" ) { out_ShortName = "cm";		out_LongName = "centimeter"; }
	if ( unit == "m" )	{ out_ShortName = "m";		out_LongName = "meter"; }
	if ( unit == "km" )	{ out_ShortName = "km";		out_LongName = "kilometer"; }

}

///////////////////////////////////////////////////////////////////////////////////////
void  ConvertCreoUnitToGMEUnit_Mass ( ProName in_MassUnit,  std::string &out_ShortName, std::string &out_LongName  )
{
	char stringBuffer[PRO_NAME_SIZE];  // PRO_NAME_SIZE = 32

	std::string unit = ProWstringToString( stringBuffer, in_MassUnit );

	out_ShortName	= unit;
	out_LongName	= unit;

	if ( unit == "lbm" ){ out_ShortName = "lbm";		out_LongName = "poundmass"; }
	if ( unit == "g" )	{ out_ShortName = "g";			out_LongName = "gram"; }
	if ( unit == "kg" )	{ out_ShortName = "kg";			out_LongName = "kilogram"; }
	if ( unit == "tonne" )	{ out_ShortName = "tonne";  out_LongName = "tonne"; }

}
///////////////////////////////////////////////////////////////////////////////////////
void  ConvertCreoUnitToGMEUnit_Force ( ProName in_ForceUnit, std::string &out_ShortName, std::string &out_LongName  )
{
	char stringBuffer[PRO_NAME_SIZE];    // PRO_NAME_SIZE = 32

	std::string unit = ProWstringToString( stringBuffer, in_ForceUnit );

	out_ShortName	= unit;
	out_LongName	= unit;

	if ( unit == "lbf" ) { out_ShortName = "lbf";	out_LongName = "poundforce"; }
	if ( unit == "N" )	 { out_ShortName = "N";		out_LongName = "newton"; }

}
///////////////////////////////////////////////////////////////////////////////////////
void  ConvertCreoUnitToGMEUnit_Temperature ( ProName in_Temperature, std::string &out_ShortName, std::string &out_LongName  )
{
	char stringBuffer[PRO_NAME_SIZE];  // PRO_NAME_SIZE = 32

	std::string unit = ProWstringToString( stringBuffer, in_Temperature );

	out_ShortName	= unit;
	out_LongName	= unit;

	if ( unit == "C" )	{ out_ShortName = "C";	out_LongName = "centigrade"; }
	if ( unit == "F" )	{ out_ShortName = "F";	out_LongName = "fahrenheit"; }
	if ( unit == "K" )	{ out_ShortName = "K";	out_LongName = "kelvin"; }

}
///////////////////////////////////////////////////////////////////////////////////////
void ConvertCreoUnitToGMEUnit_Time ( ProName in_TimeUnit, std::string &out_ShortName, std::string &out_LongName  )
{
	char stringBuffer[PRO_NAME_SIZE];  // PRO_NAME_SIZE = 32

	std::string unit = ProWstringToString( stringBuffer, in_TimeUnit );

	out_ShortName	= unit;
	out_LongName	= unit;

	if ( unit == "sec" ) { out_ShortName = "sec";	out_LongName = "second"; }

}

///////////////////////////////////////////////////////////////////////////////////////////////////
void RetrieveUnits( ProMdl			in_Model,
					std::string		&out_DistanceUnit_ShortName,
					std::string		&out_DistanceUnit_LongName,

					std::string		&out_MassUnit_ShortName,
					std::string		&out_MassUnit_LongName,

					std::string		&out_ForceUnit_ShortName,
					std::string		&out_ForceUnit_LongName,

					std::string		&out_TimeUnit_ShortName,
					std::string		&out_TimeUnit_LongName,

					std::string		&out_TemperatureUnit_ShortName,
					std::string		&out_TemperatureUnit_LongName )
											throw(isis::application_exception)
{
	std::string unitsString;

	ProUnitsystem unitSystem;
	//ProUnititem unit, forceUnit, timeUnit, lengthUnit;
	ProUnititem massUnit, forceUnit, timeUnit, lengthUnit, temperatureUint;
	ProLine massUnitsLabel;
	ProUnitsystemType type;

	isis::isis_ProMdlPrincipalunitsystemGet (in_Model, &unitSystem);

	//  PRO_UNITTYPE_LENGTH          L
	//  PRO_UNITTYPE_MASS            M
	//  PRO_UNITTYPE_FORCE           F
	//  PRO_UNITTYPE_TIME            T
	//	PRO_UNITTYPE_TEMPERATURE     D

	isis::isis_ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_LENGTH, &lengthUnit);
	ConvertCreoUnitToGMEUnit_Distance( lengthUnit.name,out_DistanceUnit_ShortName, out_DistanceUnit_LongName  );

	try
	{
		isis::isis_ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_MASS, &massUnit);
		ConvertCreoUnitToGMEUnit_Mass(  massUnit.name, out_MassUnit_ShortName, out_MassUnit_LongName );
	}
	catch(...)
	{
		out_MassUnit_LongName = "Derived";
	}

	try
	{
	isis::isis_ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_FORCE, &forceUnit);
	ConvertCreoUnitToGMEUnit_Force( forceUnit.name, out_ForceUnit_ShortName, out_ForceUnit_LongName );
	}
	catch(...)
	{
		out_ForceUnit_ShortName = "Derived";
		out_ForceUnit_LongName = "Derived";
	}

	isis::isis_ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_TEMPERATURE , &timeUnit);
	ConvertCreoUnitToGMEUnit_Temperature( timeUnit.name, out_TemperatureUnit_ShortName, out_TemperatureUnit_LongName );

	isis::isis_ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_TIME, &temperatureUint);
	ConvertCreoUnitToGMEUnit_Time( temperatureUint.name, out_TimeUnit_ShortName, out_TimeUnit_LongName );

}

///////////////////////////////////////////////////////////////////////////////////////
	void RetrieveUnits_withDescriptiveErrorMsg(
					const std::string				&in_ComponentInstanceID,
					const isis::MultiFormatString	&in_ModelName,
					ProMdl							in_Model,
					std::string						&out_DistanceUnit_ShortName,
					std::string						&out_DistanceUnit_LongName,

					std::string						&out_MassUnit_ShortName,
					std::string						&out_MassUnit_LongName,

					std::string						&out_ForceUnit_ShortName,
					std::string						&out_ForceUnit_LongName,

					std::string						&out_TimeUnit_ShortName,
					std::string						&out_TimeUnit_LongName,

					std::string						&out_TemperatureUnit_ShortName,
					std::string						&out_TemperatureUnit_LongName )
											throw(isis::application_exception)
	{
		try
		{
			RetrieveUnits(	in_Model,
							out_DistanceUnit_ShortName,
							out_DistanceUnit_LongName,

							out_MassUnit_ShortName,
							out_MassUnit_LongName,

							out_ForceUnit_ShortName,
							out_ForceUnit_LongName,

							out_TimeUnit_ShortName,
							out_TimeUnit_LongName,

							out_TemperatureUnit_ShortName,
							out_TemperatureUnit_LongName );

		}
		catch(const isis::application_exception &exc)
		{
			std::stringstream errorString;
			errorString << "Error retrieving model units:" <<  std::endl <<
							"   ComponentInstanceID: " << in_ComponentInstanceID <<  std::endl <<
							"   ModelName:           " << in_ModelName <<  std::endl <<
							"   Error:               " << exc.what();
			throw isis::application_exception(errorString.str().c_str());
		}

	}

///////////////////////////////////////////////////////////////////////////////////////
/*
void RetrieveMaterial(	const std::string &in_ModelName,
						ProSolid part,
						std::string &out_MaterialName ) throw(isis::application_exception)
{

	ProMaterial  material;

	try
	{
		isis::isis_ProMaterialCurrentGet( part, &material );

		char stringBuffer[PRO_NAME_SIZE];  // PRO_NAME_SIZE = 32
		out_MaterialName = ProWstringToString( stringBuffer, material.matl_name );
	}
	catch (...)
	{
		// out_MaterialName = "NOT_DEFINED";
		std::string TempError =
					"Material not defined for part: " + in_ModelName +
					".  To compute mass properties, all parts must have a material assignment. "  +
					" Please open the model with Creo and select File Prepare \"Model Properties\"" +
					" to assign a material to the model.";
					throw isis::application_exception(TempError.c_str());
	}
}
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
void PopulateMatrix(	int					in_NumRows,
						int					in_NumColumns,
						const double		in_MatrixBuffer[4][4],
						CADMetrics::Rows	&out_RowsRoot)
{
	for (int i = 0; i < in_NumRows; ++i )
	{
		CADMetrics::Row		   rowRoot = CADMetrics::Row::Create(out_RowsRoot);

		for (int j = 0; j < in_NumColumns; ++j )
		{
			CADMetrics::Column	columnRoot = CADMetrics::Column::Create(rowRoot);
			columnRoot.Value() = in_MatrixBuffer[i][j];
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void PopulateScalar( const std::string		in_Name,
					 double					in_Value,
					 const std::string		in_Unit,
					 CADMetrics::Scalars	&out_ScalarsRoot )
{
	CADMetrics::Scalar   scalarRoot = CADMetrics::Scalar::Create( out_ScalarsRoot );
	scalarRoot.Name()  = in_Name;
	scalarRoot.Value() = in_Value;
	scalarRoot.Unit()  = in_Unit;
}

struct MetricsDefined
{
	bool massProp_Defined;
	bool interiaAtDefaultCSys_Defined;
	bool interiaAtCOG_Defined;
	bool surfaceArea_Defined;

	MetricsDefined(): massProp_Defined(false),
						interiaAtDefaultCSys_Defined(false),
						interiaAtCOG_Defined(false),
						surfaceArea_Defined(false) {}
	bool anomalyOccurred()
	{
		return (!massProp_Defined || !interiaAtDefaultCSys_Defined || !interiaAtCOG_Defined || !surfaceArea_Defined);
	}

};

/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_Single_MetricComponent(
			const std::string													&in_ComponentID,
			std::map<std::string, isis::CADComponentData>						&in_CADComponentData_map,
			std::set<int>														&in_out_DataCreated_for_MetricIDs,
			std::map<int, MetricsDefined>										&out_MetricID_to_Anomalies_map,
			CADMetrics::MetricComponents										&out_metricComponentsRoot )
																						throw (isis::application_exception)
{
	log4cpp::Category& logcat_consoleandfile = log4cpp::Category::getInstance(LOGCAT_CONSOLEANDLOGFILE);

	if ( !in_CADComponentData_map[in_ComponentID].massProperties.massProperties_RetrievalInvoked )
	{
			std::stringstream errorString;
			errorString << "ERROR, Function - " + std::string(__FUNCTION__) << ", could not create metrics file.  Mass properties were not retrieved prior to writing metrics file.";
			throw isis::application_exception(errorString.str());
	}

	if ( !in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Defined )
	{
			std::stringstream errorString;
			errorString << "ERROR, Function - " + std::string(__FUNCTION__) << ", could not create metrics file.  Bounding box was not retrieved prior to writing metrics file.";
			throw isis::application_exception(errorString.str());
	}

	// Check if data for the MetricID has NOT been created.
	if ( in_out_DataCreated_for_MetricIDs.find( in_CADComponentData_map[in_ComponentID].metricID ) == in_out_DataCreated_for_MetricIDs.end() )
	{
		////////////////////////////
		// Create Metric Component
		////////////////////////////
		CADMetrics::MetricComponent  metricComponentRoot = 	CADMetrics::MetricComponent::Create( out_metricComponentsRoot );

		////////////////////////
		// Add Attributes
		////////////////////////
		metricComponentRoot.CoordinateSystem() = std::string("DEFAULT");
		metricComponentRoot.MetricID() = in_CADComponentData_map[in_ComponentID].metricID;
		metricComponentRoot.Name() = std::string(in_CADComponentData_map[in_ComponentID].name);

		//metricComponentRoot.SpecialInstruction() = isis::SpecialInstruction_string(in_CADComponentData_map[in_ComponentID].specialInstruction);
		metricComponentRoot.SpecialInstruction() = in_CADComponentData_map[in_ComponentID].specialInstruction.ToCommaDelimitedString();

		if ( in_CADComponentData_map[in_ComponentID].cyPhyComponent )
			metricComponentRoot.ComponentDefinitionSource() =  ComponentDefinitionSource_string(COMPONENT_DEFINITION_SOURCE_CYPHY);
		else
			metricComponentRoot.ComponentDefinitionSource() =  ComponentDefinitionSource_string(COMPONENT_DEFINITION_SOURCE_CAD_MODEL);

		// Model Type
		if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_PART )
			metricComponentRoot.Type() = "PART";
		else
			metricComponentRoot.Type() = "ASSEMBLY";

		///////////////////////////////
		// Mass Properties
		///////////////////////////////

		double   MatrixBuffer[4][4];
		double   MatrixBuffer_temp[4][4];

		/////////////////////////////////////////
		// Check if Mass Properties are Defined
		////////////////////////////////////////
		MetricsDefined MetricsDefined;

		MetricsDefined.massProp_Defined				= in_CADComponentData_map[in_ComponentID].massProperties.massProperties_Defined;
		MetricsDefined.interiaAtDefaultCSys_Defined = in_CADComponentData_map[in_ComponentID].massProperties.coordSysInertiaTensor_Defined;
		MetricsDefined.interiaAtCOG_Defined			= in_CADComponentData_map[in_ComponentID].massProperties.cGInertiaTensor_Defined;
		MetricsDefined.surfaceArea_Defined			= in_CADComponentData_map[in_ComponentID].massProperties.surfaceArea_Defined;

		if ( MetricsDefined.anomalyOccurred() )
			out_MetricID_to_Anomalies_map[in_CADComponentData_map[in_ComponentID].metricID] = MetricsDefined;

		////////////////////////
		// CG
		////////////////////////

		CADMetrics::CG  cGRoot = CADMetrics::CG::Create( metricComponentRoot );

		cGRoot.X() = in_CADComponentData_map[in_ComponentID].massProperties.centerOfGravity[0];
		cGRoot.Y() = in_CADComponentData_map[in_ComponentID].massProperties.centerOfGravity[1];
		cGRoot.Z() = in_CADComponentData_map[in_ComponentID].massProperties.centerOfGravity[2];

		////////////////////////
		// Bounding Box
		////////////////////////

		CADMetrics::BoundingBox boundingBoxRoot = CADMetrics::BoundingBox::Create(metricComponentRoot);

		boundingBoxRoot.X() =  in_CADComponentData_map[in_ComponentID].boundingBox.Dimensions_xyz[0];
		boundingBoxRoot.Y() =  in_CADComponentData_map[in_ComponentID].boundingBox.Dimensions_xyz[1];
		boundingBoxRoot.Z() =  in_CADComponentData_map[in_ComponentID].boundingBox.Dimensions_xyz[2];

		CADMetrics::OutlinePoints rootOutlinePoints = CADMetrics::OutlinePoints::Create(boundingBoxRoot);

		CADMetrics::Point  rootPoint_1 = CADMetrics::Point::Create(rootOutlinePoints);
		CADMetrics::Point  rootPoint_2 = CADMetrics::Point::Create(rootOutlinePoints);
		rootPoint_1.X() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_1.x;
		rootPoint_1.Y() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_1.y;
		rootPoint_1.Z() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_1.z;

		rootPoint_2.X() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_2.x;
		rootPoint_2.Y() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_2.y;
		rootPoint_2.Z() = in_CADComponentData_map[in_ComponentID].boundingBox.boundingBox_Point_2.z;

		///////////////////////////////////////////////
		// Interia Tensor at Default Coordinate System
		//////////////////////////////////////////////
		if ( MetricsDefined.massProp_Defined && MetricsDefined.interiaAtDefaultCSys_Defined )
		{
			for ( int i = 0; i < 3; ++i )
				for ( int j = 0; j < 3; ++j )
					MatrixBuffer[i][j] =in_CADComponentData_map[in_ComponentID].massProperties.coordSysInertiaTensor[i][j];

			CADMetrics::InertiaTensor  inertiaDefaultCSysTensorRoot = CADMetrics::InertiaTensor::Create( metricComponentRoot );
			inertiaDefaultCSysTensorRoot.At() = isis::CADInertiaAt_string(CAD_DEFAULT_CSYS);

			CADMetrics::Rows		   rowsInertiaDefaultCSysTensorRoot = CADMetrics::Rows::Create(inertiaDefaultCSysTensorRoot);

			PopulateMatrix(	3, 3, MatrixBuffer, rowsInertiaDefaultCSysTensorRoot  );
		}
		///////////////////////////////////////////////
		// Interia Tensor at Center of Gravity
		//////////////////////////////////////////////
		if (  MetricsDefined.massProp_Defined && MetricsDefined.interiaAtCOG_Defined )
		{
			for ( int i = 0; i < 3; ++i )
				for ( int j = 0; j < 3; ++j )
					MatrixBuffer[i][j] = in_CADComponentData_map[in_ComponentID].massProperties.cGInertiaTensor[i][j];

			CADMetrics::InertiaTensor  inertiaCOGTensorRoot = CADMetrics::InertiaTensor::Create( metricComponentRoot );
			inertiaCOGTensorRoot.At() = isis::CADInertiaAt_string(CAD_CENTER_OF_GRAVITY);
			CADMetrics::Rows		   rowsInertiaCOGTensorRoot = CADMetrics::Rows::Create(inertiaCOGTensorRoot);

			PopulateMatrix(	3, 3, MatrixBuffer, rowsInertiaCOGTensorRoot  );
		}
		//////////////////////////////////
		// Principal Moments of Intertia
		//////////////////////////////////

		if (  MetricsDefined.massProp_Defined )
		{

			// Rotation Matrix
			CADMetrics::PrincipleMomentsOfInertia   principleMomentsOfInertiaRoot = CADMetrics::PrincipleMomentsOfInertia::Create( metricComponentRoot );
			CADMetrics::RotationMatrix			    rotationMatrixRoot = CADMetrics::RotationMatrix::Create( principleMomentsOfInertiaRoot );
			CADMetrics::Rows						rowsRotationMatrixRoot = CADMetrics::Rows::Create(rotationMatrixRoot);

			for ( int i = 0; i < 3; ++i )
				for ( int j = 0; j < 3; ++j )
					MatrixBuffer[i][j] =  in_CADComponentData_map[in_ComponentID].massProperties.principalAxis_RotationMatrix[i][j];
			PopulateMatrix(	3, 3, MatrixBuffer, rowsRotationMatrixRoot  );

			// Principal Moments
			CADMetrics::Rows	rowsPrincipleMomentsOfInertiaValues = CADMetrics::Rows::Create(principleMomentsOfInertiaRoot);

			for ( int i = 0; i < 3; ++i ) MatrixBuffer[i][0] =  in_CADComponentData_map[in_ComponentID].massProperties.principalMomentsOfInertia[i];

			PopulateMatrix(	3, 1,MatrixBuffer, rowsPrincipleMomentsOfInertiaValues  );
		}

		////////////////////////
		// Units
		////////////////////////

		std::string		distanceUnit_LongName;
		std::string		distanceUnit_ShortName;

		std::string		massUnit_LongName;
		std::string		massUnit_ShortName;

		std::string		forceUnit_LongName;
		std::string		forceUnit_ShortName;

		std::string		temperatureUnit_LongName;
		std::string		temperatureUnit_ShortName;

		std::string		timeUnit_LongName;
		std::string		timeUnit_ShortName;

		//std::cout << std::endl << "=====> Model Units, Model: " << in_CADComponentData_map[in_ComponentID].name;

		RetrieveUnits_withDescriptiveErrorMsg(
						in_CADComponentData_map[in_ComponentID].componentID,
						in_CADComponentData_map[in_ComponentID].name,
						in_CADComponentData_map[in_ComponentID].modelHandle,
						distanceUnit_ShortName,		distanceUnit_LongName,
						massUnit_ShortName,			massUnit_LongName,
						forceUnit_ShortName,			forceUnit_LongName,
						timeUnit_ShortName,			timeUnit_LongName,
						temperatureUnit_ShortName,	temperatureUnit_LongName );

		std::string forceUnit_temp;
		if ( forceUnit_LongName == "Derived" )
			forceUnit_temp = massUnit_ShortName + " " + distanceUnit_ShortName + "/" + timeUnit_ShortName + "2";
		else
			forceUnit_temp = forceUnit_ShortName;

		CADMetrics::Units  unitsRoot = CADMetrics::Units::Create( metricComponentRoot );

		unitsRoot.Distance()	= distanceUnit_LongName;
		unitsRoot.Force()		= forceUnit_temp;
		unitsRoot.Mass()		= massUnit_LongName;
		unitsRoot.Temperature() = temperatureUnit_LongName;
		unitsRoot.Time()		= timeUnit_LongName;

		////////////////////////
		// Scalars
		////////////////////////
		if ( MetricsDefined.massProp_Defined || MetricsDefined.surfaceArea_Defined )
		{
			CADMetrics::Scalars  scalarsRoot = CADMetrics::Scalars::Create( metricComponentRoot );
			//   ScalarType (const Value_type&,
			//        const Name_type&,
			//        const Unit_type&);

			// Surface Area
			if ( MetricsDefined.surfaceArea_Defined )
				PopulateScalar( "SurfaceArea", in_CADComponentData_map[in_ComponentID].massProperties.surfaceArea, distanceUnit_ShortName + "2", scalarsRoot );

			if (MetricsDefined.massProp_Defined)
			{
				// Volume
				PopulateScalar( "Volume", in_CADComponentData_map[in_ComponentID].massProperties.volume, distanceUnit_ShortName + "3", scalarsRoot );

				// Density
				// Note - Only parts have a density.  Assemblies do not have densities.
				if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_PART )
				{
					PopulateScalar( "Density", in_CADComponentData_map[in_ComponentID].massProperties.density, massUnit_ShortName + "/" + distanceUnit_ShortName + "3", scalarsRoot );
				}

				// Mass
				PopulateScalar( "Mass", in_CADComponentData_map[in_ComponentID].massProperties.mass, massUnit_ShortName, scalarsRoot );
			}
		}

		//////////////////////////////////
		// Material
		//////////////////////////////////

		if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_PART )
		{
			std::string material_temp = "Undefined";
			try
			{ // zzzz Material need to check for
				RetrieveMaterial(	in_CADComponentData_map[in_ComponentID].name,
									in_CADComponentData_map[in_ComponentID].modelHandle, material_temp );
			}
			catch (...)
			{
			}

			CADMetrics::Material  materialRoot = CADMetrics::Material::Create( metricComponentRoot );
			materialRoot.Type() = material_temp;
		}

		////////////////////////
		// Children
		////////////////////////
		if ( in_CADComponentData_map[in_ComponentID].children.size() > 0 )
		{

			CADMetrics::Children childrenRoot = CADMetrics::Children::Create( metricComponentRoot );

			for ( std::list<std::string>::const_iterator i = in_CADComponentData_map[in_ComponentID].children.begin();
				  i != in_CADComponentData_map[in_ComponentID].children.end();
				  ++i )
			{

				// The last item in componentPaths is the path from the parent assembly to the child.  The other
				// entries in componentPaths are paths from higher up assemblies.
				std::list<int>  assemblyToChild_compentPath;
				assemblyToChild_compentPath.push_back( in_CADComponentData_map[*i].componentPaths.back());

				RetrieveTranformationMatrix_Assembly_to_Child ( in_ComponentID,
																assemblyToChild_compentPath,
																in_CADComponentData_map,
																//PRO_B_FALSE,  // bottom up = False
																PRO_B_TRUE,  // bottom up = True, Changed this 8/8/2013, V1.4.6
																MatrixBuffer );
				// At this point MatrixBuffer would contain
				// Rotation		3 X 3,  rows 0 thru 2
				// Translation	1 X 3,  row 3

				// Rotation Matrix
				CADMetrics::ChildMetric		 childMetricRoot = CADMetrics::ChildMetric::Create( childrenRoot );
				childMetricRoot.MetricID() = in_CADComponentData_map[*i].metricID;
				childMetricRoot.ComponentInstanceID() = in_CADComponentData_map[*i].componentID;
				CADMetrics::RotationMatrix	 childRotationMatrixRoot = CADMetrics::RotationMatrix::Create( childMetricRoot );
				CADMetrics::Rows			 rowsChildRotationMatrixRoot = CADMetrics::Rows::Create( childRotationMatrixRoot );

				// Transpose the rotation matrix. Ricardo and SWRI need the transposed the roatation matrix.
				// Interactively, if you retrieve the transformation from the assembly to the detail part, the
				// transposed matrix is returned.  This change was done for v1.4.17.0, 10/02/2013
				for ( int i = 0; i < 3; ++i )
					for ( int j = 0; j < 3; ++j )
						MatrixBuffer_temp[j][i] =  MatrixBuffer[i][j];

				PopulateMatrix(	3, 3, MatrixBuffer_temp, rowsChildRotationMatrixRoot  );

				CADMetrics::Translation	 childTranslationRoot = CADMetrics::Translation::Create( childMetricRoot );
				childTranslationRoot.X() = MatrixBuffer[3][0];
				childTranslationRoot.Y() = MatrixBuffer[3][1];
				childTranslationRoot.Z() = MatrixBuffer[3][2];

			}

		}  // END if ( in_CADComponentData_map[in_ComponentID].children.size() > 0 )

		in_out_DataCreated_for_MetricIDs.insert(in_CADComponentData_map[in_ComponentID].metricID);

	}  // END if ( in_out_DataCreated_for_MetricIDs.find( in_CADComponentData_map[in_ComponentID].metricID ) == in_out_DataCreated_for_MetricIDs.end() )
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_MetricComponents(
			const std::string																&in_ComponentID,
			std::map<std::string, isis::CADComponentData>									&in_CADComponentData_map,
			std::set<int>																	&in_out_DataCreated_for_MetricIDs,
			std::map<int, MetricsDefined>													&out_MetricID_to_Anomalies_map,
			CADMetrics::MetricComponents													&out_metricComponentsRoot )
																						throw (isis::application_exception)
{

	Populate_Single_MetricComponent(	in_ComponentID,
										in_CADComponentData_map,
										in_out_DataCreated_for_MetricIDs,
										out_MetricID_to_Anomalies_map,
										out_metricComponentsRoot );

	if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_ASSEMBLY )
	{
		for ( std::list<string>::const_iterator i(in_CADComponentData_map[in_ComponentID].children.begin());
			i != in_CADComponentData_map[in_ComponentID].children.end();
			++i )
		{

			Populate_MetricComponents( 	*i,
										in_CADComponentData_map,
										in_out_DataCreated_for_MetricIDs,
										out_MetricID_to_Anomalies_map,
										out_metricComponentsRoot );
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
void PopulateJoints_for_SingleComponent(
			const std::string													&in_ComponentID,
			std::map<std::string, isis::CADComponentData>						&in_CADComponentData_map,
			std::set<int>														&in_out_DataCreated_for_MetricIDs,
			std::map<int, MetricsDefined>										&out_MetricID_to_Anomalies_map,
			CADMetrics::Joints													&out_jointsRoot )
																						throw (isis::application_exception)
{
	log4cpp::Category& logcat = log4cpp::Category::getInstance(LOGCAT_LOGFILEONLY);

	if ( in_CADComponentData_map[in_ComponentID].constraintDef.constraints.size() == 0  ) return;  // No constraints and therefore no joints

	////////////////////////////
	// Create Joint Component
	////////////////////////////

	for each ( const ConstraintData &i in  in_CADComponentData_map[in_ComponentID].constraintDef.constraints )
	{
		// For now, skip constraints that do not have a junction defined.  When the junction information
		// is completed for CyPhy leaf-assemblies, then constraints should have a junction defined.
		// At that time, an exception should be thrown instead of the continue in the following statement.
		if ( !i.computedJointData.junctiondDefined_withoutGuide ) continue;

		///////////////////////////////////
		// Get Constrained-to Information
		///////////////////////////////////
		std::set<std::string>  constrainedToComponentInstanceIDs;

		// Derived from Constraint Pairs
		for each ( std::string j in i.constrainedTo_ComponentInstanceIDs_DerivedFromConstraintPairs )
		{
			if ( in_CADComponentData_map[j].modelType == PRO_MDL_PART ||
				 (in_CADComponentData_map[j].specialInstruction != CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT))
									constrainedToComponentInstanceIDs.insert(j);
		}

		// Inferred from Leaf Assemblies
		for each ( std::string j in i.constrainedTo_ComponentInstanceIDs_InferredFromLeafAssemblySubordinates )
		{
			if ( in_CADComponentData_map[j].modelType == PRO_MDL_PART ||
			   (in_CADComponentData_map[j].specialInstruction != CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT))
									constrainedToComponentInstanceIDs.insert(j);
		}

		// If there are no constrained-to parts, continue.  This would occur for the first part added to the assembly,
		// which would be constrained to its assembly.  Constraints between parts are of interest, but constraints
		// to assemblies are not of interest.
		if ( constrainedToComponentInstanceIDs.size() == 0 )
		{
			logcat.warnStream() << "Component was not constrained to a part. This is usually due to the first component added to an assembly would only be constrained to the assembly and thus not constrained to a part. " + in_ComponentID;
			continue;
		}

		//////////////////////////////
		// Joint
		/////////////////////////////

		CADMetrics::Joint  jointRoot = CADMetrics::Joint::Create(out_jointsRoot);

		//jointRoot.AssembledComponentInstanceID() = i.constrainedFrom_InstanceID.size()!=0?i.constrainedFrom_InstanceID:in_ComponentID;
		jointRoot.AssembledComponentInstanceID() = in_ComponentID;
		jointRoot.Type() = CADJointType_string( i.computedJointData.jointType_withoutguide );

		jointRoot.ID() = i.inputJoint.JointID;

		if (in_CADComponentData_map[jointRoot.AssembledComponentInstanceID()].modelType == PRO_MDL_ASSEMBLY &&
			in_CADComponentData_map[jointRoot.AssembledComponentInstanceID()].specialInstruction == CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT )
		{
			logcat.warnStream() << "Only parts and assemblies without CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT appear in joints: " << (string)jointRoot.AssembledComponentInstanceID();
			continue;
		}

		//////////////////////////////
		// ConstrainedToComponents
		/////////////////////////////

		CADMetrics::ConstrainedToComponents  constrainedToComponentsRoot = CADMetrics::ConstrainedToComponents::Create(jointRoot);

		//for each ( ConstraintPair j in  i.constraintPairs )
		//	for each (ConstraintFeature k in j.constraintFeatures)
		//		if ( k.componentInstanceID != in_ComponentID ) constrainedToComponentInstanceIDs.insert(k.componentInstanceID);

		// This does not belong here
		// if (constrainedToComponentInstanceIDs.size()>1)
		//{
		//	throw isis::application_exception("There are more than 2 parts mixed up within one connection. This is a modelling mistake. Component ID: " + in_ComponentID);
		//}

		//if (i.constrainedTo_InstanceID.size()!=0 && constrainedToComponentInstanceIDs.size()==1)
		//{
		//	constrainedToComponentInstanceIDs.clear();
		//	constrainedToComponentInstanceIDs.insert(i.constrainedTo_InstanceID);
		//}

		// Check for dependencies due to a leaf assembly in CyPhy having subordinates
		//for each ( const std::string &constrainedto in i.constrainedTo_ComponentInstanceIDs_InferredFromLeafAssemblySubordinates)
		//{
		//	constrainedToComponentInstanceIDs.insert(constrainedto);
		//}

		for each ( const std::string &j in constrainedToComponentInstanceIDs)
		{
			CADMetrics::ConstrainedToComponent  constrainedToComponent = CADMetrics::ConstrainedToComponent::Create(constrainedToComponentsRoot);
			constrainedToComponent.ComponentInstanceID() =  j;
		}

		//////////////////////////////
		// GlobalCoordinateSystem
		/////////////////////////////
		CADMetrics::GlobalCoordinateSystem  globalCoordinateSystemRoot = CADMetrics::GlobalCoordinateSystem::Create(jointRoot);

		CADMetrics::Location		location	 = CADMetrics::Location::Create(globalCoordinateSystemRoot);
		CADMetrics::Orientation		orientation	 = CADMetrics::Orientation::Create(globalCoordinateSystemRoot);
		CADMetrics::Rotation		rotation	 = CADMetrics::Rotation::Create(globalCoordinateSystemRoot);

		std::vector<double> values;
		// location
		values.push_back(i.computedJointData.globalJointPosition.location.x);
		values.push_back(i.computedJointData.globalJointPosition.location.y);
		values.push_back(i.computedJointData.globalJointPosition.location.z);
		location.ArrayValue() = values;

		location.Units() = "millimeter";

		// orientation
		values.clear();
		values.push_back(i.computedJointData.globalJointPosition.orientation.x);
		values.push_back(i.computedJointData.globalJointPosition.orientation.y);
		values.push_back(i.computedJointData.globalJointPosition.orientation.z);
		orientation.ArrayValue() = values;
		orientation.Units() = "millimeter";

		// Rotation
		rotation.Value() = i.computedJointData.globalJointPosition.rotation;
		rotation.Units() = "radians";

	}  // END for each ( ConstraintData i in  in_CADComponentData_map[in_ComponentID].constraintDef.constraints )

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_Joints(
			const std::string																&in_ComponentID,
			std::map<std::string, isis::CADComponentData>									&in_CADComponentData_map,
			std::set<int>																	&in_out_DataCreated_for_MetricIDs,
			std::map<int, MetricsDefined>													&out_MetricID_to_Anomalies_map,
			CADMetrics::Joints													&out_jointsRoot )
																						throw (isis::application_exception)
{

	// Only add joint information for parts or assemblies that should be treated as one body.
	if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_PART ||
	   ( in_CADComponentData_map[in_ComponentID].specialInstruction != CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT ) )
			PopulateJoints_for_SingleComponent(	in_ComponentID,
												in_CADComponentData_map,
												in_out_DataCreated_for_MetricIDs,
												out_MetricID_to_Anomalies_map,
												out_jointsRoot );

	if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_ASSEMBLY )
	{
		for ( std::list<string>::const_iterator i(in_CADComponentData_map[in_ComponentID].children.begin());
			i != in_CADComponentData_map[in_ComponentID].children.end();
			++i )
		{

			Populate_Joints( 	*i,
										in_CADComponentData_map,
										in_out_DataCreated_for_MetricIDs,
										out_MetricID_to_Anomalies_map,
										out_jointsRoot );
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_Joints_MetaData(
			const std::vector<std::string>					&in_ListOfComponentIDsInTheAssembly,
			std::map<std::string, isis::CADComponentData>	&in_CADComponentData_map,
			CADMetrics::Joints								&out_jointsRoot )
																throw (isis::application_exception)
{
	bool foundProcessingInstruction = false;
	for each ( const std::string &i in in_ListOfComponentIDsInTheAssembly)
	{
		if (	in_CADComponentData_map[i].modelType ==  PRO_MDL_ASSEMBLY  &&
				CyPhyLeafAssembly ( i, in_CADComponentData_map ) &&
				in_CADComponentData_map[i].specialInstruction != CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT  )
		{
			foundProcessingInstruction = true;
			break;
		}
	}

	if ( foundProcessingInstruction )
	{
		CADMetrics::JointsMetaData  jointsMetaDataRoot = CADMetrics::JointsMetaData::Create(out_jointsRoot);

		for each ( const std::string &i in in_ListOfComponentIDsInTheAssembly)
		{
			if (	in_CADComponentData_map[i].modelType ==  PRO_MDL_ASSEMBLY  &&
					CyPhyLeafAssembly ( i, in_CADComponentData_map ) &&
					in_CADComponentData_map[i].specialInstruction != CAD_SPECIAL_INSTRUCTION_HAS_KINEMATIC_JOINT  )
			{
				CADMetrics::ComponentInstanceData  componentInstanceDataRoot = CADMetrics::ComponentInstanceData::Create(jointsMetaDataRoot);
				componentInstanceDataRoot.ComponentInstanceID() = i;
				componentInstanceDataRoot.Primary()   = Metrics_JointsComponentInstanceData_Primary_string(METRICS_JOINTS_LEAF_ASSEMBLY_NO_KINEMATIC_JOINTS);
				componentInstanceDataRoot.Secondary() = Metrics_JointsComponentInstanceData_Secondary_string(METRICS_JOINTS_TREAT_AS_ONE_BODY);
			}
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_Assemblies(
			const std::string													&in_ComponentID,
			std::map<std::string, isis::CADComponentData>						&in_CADComponentData_map,
			CADMetrics::CADComponent											&out_CADComponent )

{
	if ( in_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_ASSEMBLY )
	{
		if ( in_CADComponentData_map[in_ComponentID].children.size() > 0 )
		{
			// We want the order to be in the order of the CAD Assembly and not in the order of CADAssembly.xml
			bool sortRequired = true;

			for each ( const std::string &i in in_CADComponentData_map[in_ComponentID].children )
			{
				if ( in_CADComponentData_map[i].dataInitialSource == INITIAL_SOURCE_DERIVED_FROM_LEAF_ASSEMBLY_DESCENDANTS )
				{
					sortRequired = false;
					break;
				}
			}

			std::vector<std::string> children;

			if ( sortRequired )
			{
				// Make sure sort keys are all unique.  This is a verification that a modification was not made elsewhere in this program
				// that caused the sort keys to be malformed.
				std::set<int> sortKeys;
				for each ( const std::string &i in in_CADComponentData_map[in_ComponentID].children )
				{
					if ( sortKeys.find(in_CADComponentData_map[i].addedToAssemblyOrdinal ) != sortKeys.end() )
					{
						std::stringstream errorString;
						errorString << std::endl << "Redundant sort key for a child of: "
						"  Component Instance ID: " <<  in_ComponentID << std::endl <<
						"  Model Name:            " <<  in_CADComponentData_map[in_ComponentID].name <<  std::endl <<
						"  Model Type:            " <<  ProMdlType_string(in_CADComponentData_map[in_ComponentID].modelType)  <<  std::endl <<
						"  Children:              ";
						for each ( const std::string &j in in_CADComponentData_map[in_ComponentID].children )
						{
							errorString << std::endl <<
							"     Component Instance ID: " <<  in_ComponentID << std::endl <<
							"     Model Name:   " <<  in_CADComponentData_map[j].name <<  std::endl <<
							"     Model Type:   " <<  ProMdlType_string(in_CADComponentData_map[j].modelType) <<  std::endl <<
							"	  Sort Ordinal: " <<  in_CADComponentData_map[j].addedToAssemblyOrdinal;
						}
						throw isis::application_exception(errorString.str());
					}
					else
					{
						sortKeys.insert(in_CADComponentData_map[i].addedToAssemblyOrdinal);
					}
				}

				std::map<int, std::string> sortID_to_ComponentInstanceID_map;
				for each ( const std::string &i in in_CADComponentData_map[in_ComponentID].children )
					sortID_to_ComponentInstanceID_map[in_CADComponentData_map[i].addedToAssemblyOrdinal] = i;

				for each ( const std::pair<int, std::string> &i in sortID_to_ComponentInstanceID_map )  children.push_back(i.second);
			}
			else
			{
				// Sort not required
				for each ( const std::string &i in in_CADComponentData_map[in_ComponentID].children ) children.push_back(i);
			}

			//for ( std::list<string>::const_iterator i(in_CADComponentData_map[in_ComponentID].children.begin());
		 	//	i != in_CADComponentData_map[in_ComponentID].children.end();
			//	++i )

			for each ( const std::string &i in children )
			{
				CADMetrics::CADComponent	cADComponentRoot = CADMetrics::CADComponent::Create(out_CADComponent);

				cADComponentRoot.ComponentInstanceID() = i;
				cADComponentRoot.MetricID() = in_CADComponentData_map[i].metricID;

				if ( in_CADComponentData_map[i].modelType == PRO_MDL_ASSEMBLY )
				{
					Populate_Assemblies(	i,
											in_CADComponentData_map,
											out_CADComponent );
				}
			}
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Assign_MetricIDs_To_Components(
			const std::string									&in_ComponentID,
			std::map<std::string, isis::CADComponentData>		&in_out_CADComponentData_map,
			int													&in_out_NextMetricID,
			std::map< std::string, int>							&in_out_ModelName_MetricID_map,
			std::map<int, std::string>							&in_out_MetricID_ModelName_map )
																						throw (isis::application_exception)
{
	std::string ModelNameWithSuffix = AmalgamateModelNameWithSuffix( in_out_CADComponentData_map[in_ComponentID].name,
																	 in_out_CADComponentData_map[in_ComponentID].modelType );

	if ( ( in_out_CADComponentData_map[in_ComponentID].parametricParametersPresent )  ||
		 ( in_out_CADComponentData_map[in_ComponentID].specialInstruction == CAD_SPECIAL_INSTRUCTION_SIZE_TO_FIT ) ||
		 ( in_out_ModelName_MetricID_map.find( ModelNameWithSuffix ) == in_out_ModelName_MetricID_map.end() ) )
	{
		in_out_CADComponentData_map[in_ComponentID].metricID = in_out_NextMetricID;

		// Don't add parametric and SIZE_TO_FIT models to in_out_ModelName_MetricID.  This will force
		// parametric and SIZE_TO_FIT models to always have a unique MetricID.
		if ( ( !in_out_CADComponentData_map[in_ComponentID].parametricParametersPresent )  &&
		 ( in_out_CADComponentData_map[in_ComponentID].specialInstruction != CAD_SPECIAL_INSTRUCTION_SIZE_TO_FIT ))
		{
			in_out_ModelName_MetricID_map[ModelNameWithSuffix] = in_out_NextMetricID;
		}
		in_out_MetricID_ModelName_map[in_out_NextMetricID] = ModelNameWithSuffix;
		++in_out_NextMetricID;
	}
	else
	{
		in_out_CADComponentData_map[in_ComponentID].metricID = in_out_ModelName_MetricID_map[ ModelNameWithSuffix ];
	}

	if ( in_out_CADComponentData_map[in_ComponentID].modelType == PRO_MDL_ASSEMBLY )
	{
		for ( std::list<string>::const_iterator i(in_out_CADComponentData_map[in_ComponentID].children.begin());
			i != in_out_CADComponentData_map[in_ComponentID].children.end();
			++i )
		{
			Assign_MetricIDs_To_Components( *i,
											in_out_CADComponentData_map,
											in_out_NextMetricID,
											in_out_ModelName_MetricID_map,
											in_out_MetricID_ModelName_map);
		}
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MetricsNotDefinedErrors( const MetricsDefined &in_MetricsDefined,
							  std::list<std::string> &out_ErrorStrings )
{
	if ( !in_MetricsDefined.massProp_Defined )
	{
		out_ErrorStrings.push_back( CADMetricsError_string(CAD_MASS_PROPERTIES_NOT_DEFINED));
	}
	else
	{
		if ( !in_MetricsDefined.interiaAtDefaultCSys_Defined )
			out_ErrorStrings.push_back( CADMetricsError_string(CAD_INTERIA_AT_DEFAULT_CSYS_NOT_DEFINED));
		if ( !in_MetricsDefined.interiaAtCOG_Defined )
			out_ErrorStrings.push_back( CADMetricsError_string(CAD_INTERIA_AT_CENTER_OF_GRAVITY_NOT_DEFINED));

	}

	if ( !in_MetricsDefined.surfaceArea_Defined )
		out_ErrorStrings.push_back( CADMetricsError_string(CAD_SURFACE_AREA_NOT_DEFINED));

	if (out_ErrorStrings.size() == 0 )
		out_ErrorStrings.push_back("NONE");

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Populate_Anomalies(	std::map<int, MetricsDefined>	&in_MetricID_to_Anomalies_map,
							CADMetrics::Anomalies			&out_AanomaliesRoot)
{
	for each ( std::pair<int, MetricsDefined>  i in in_MetricID_to_Anomalies_map )
	{
		char metricID_buffer[64];
		itoa(i.first, metricID_buffer,10);

		std::list<std::string> errorStrings;

		MetricsNotDefinedErrors(i.second, errorStrings);

		for each (std::string j in errorStrings )
		{
			CADMetrics::Anomaly	anomalyRoot = CADMetrics::Anomaly::Create(out_AanomaliesRoot);
			anomalyRoot.MetricID() = metricID_buffer;
			anomalyRoot.Error() = j;
		}
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Log_Anomalies(	const std::map<int, MetricsDefined>	&in_MetricID_to_Anomalies_map,
					const std::string					&in_MeticsOutputXML_PathAndFileName,
						  std::map<int, std::string>	&in_MetricID_ModelName_map)
{
	log4cpp::Category& logcat_fileonly = log4cpp::Category::getInstance(LOGCAT_LOGFILEONLY);
	if (in_MetricID_to_Anomalies_map.size() > 0 )
	{
		logcat_fileonly.warnStream() << "";
	}

	for each ( std::pair<int, MetricsDefined>  i in in_MetricID_to_Anomalies_map )
	{
		std::list<std::string> errorStrings;

		MetricsNotDefinedErrors(i.second, errorStrings);

		for each (std::string j in errorStrings )
			logcat_fileonly.warnStream() << METRICS_FILE_ERROR_string << ", Metric ID: " << i.first << "  Model Name: " <<  setiosflags(ios::left) << std::setw(35) <<in_MetricID_ModelName_map[i.first]  << " Error: " << j;
	}
	if (in_MetricID_to_Anomalies_map.size() > 0 )
		logcat_fileonly.warnStream() << "For a mapping of Metric ID to Component ID, see " << in_MeticsOutputXML_PathAndFileName;

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OutputCADMetricsToXML_Driver(
							bool											in_regenerationSucceeded_ForAllAssemblies,
							bool											in_OutputJoints,
							const isis::CADAssemblies						&in_CADAssemblies,
							std::map<std::string, isis::CADComponentData>	&in_CADComponentData_map,
							const std::string								&in_MeticsOutputXML_PathAndFileName,
							const std::string								&in_LogFile_PathAndFileName )
							throw (isis::application_exception, std::exception)
{
		log4cpp::Category& logcat_fileonly = log4cpp::Category::getInstance(LOGCAT_LOGFILEONLY);
		log4cpp::Category& logcat_consoleandfile = log4cpp::Category::getInstance(LOGCAT_CONSOLEANDLOGFILE);

		isis::IfFileExists_DeleteFile( in_MeticsOutputXML_PathAndFileName);

		if ( in_regenerationSucceeded_ForAllAssemblies )
		{
			logcat_consoleandfile.infoStream() << "";
			logcat_consoleandfile.infoStream() << "Creating Metrics File";

			bool metricsErrorOccurred;
			isis::OutputCADMetricsToXML(in_CADAssemblies, in_CADComponentData_map,  in_MeticsOutputXML_PathAndFileName, in_OutputJoints, metricsErrorOccurred);
			logcat_consoleandfile.infoStream() << "   Created: " + in_MeticsOutputXML_PathAndFileName;

			if ( metricsErrorOccurred )
			{
				logcat_consoleandfile.errorStream() << "   Error(s) occurred when creating the metrics file.  To view the errors, search on" << log4cpp::eol <<
										  "   " << isis::METRICS_FILE_ERROR_string <<" in "<< in_LogFile_PathAndFileName << ".  The errors are listed at the end of this file." << log4cpp::eol <<
										  "   Also, the errors are listed in the \"Anomalies\" section of " << in_MeticsOutputXML_PathAndFileName << ".";
			}
		}
		else
		{
			logcat_consoleandfile.errorStream() << "Metrics File - Did NOT create a metrics file because the attempts to regenerate the assembly failed.";
		}

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OutputCADMetricsToXML( const isis::CADAssemblies						&in_CADAssemblies,
							std::map<std::string, isis::CADComponentData>	&in_CADComponentData_map,
							const std::string								&in_MeticsOutputXML_PathAndFileName,
							bool											in_OutputJoints,
							bool											&out_ErrorOccurred )
							throw (isis::application_exception, std::exception)
{
	////////////////////////
	// Setup UDM out file
	////////////////////////
	Udm::SmartDataNetwork dn_CADMetricRoot(CADMetrics::diagram);
	dn_CADMetricRoot.CreateNew(in_MeticsOutputXML_PathAndFileName, "CADMetrics", CADMetrics::CADMetricRoot::meta);

	try
	{
		int nextMetricID = 1;
		std::map< std::string, int > modelName_MetricID_map;
		std::map<int, std::string>	 metricID_ModelName_map;
		std::set<int>				 dataCreated_for_MetricIDs;
		//std::set<int>				 metricIDs_ChildrenDefined;

		//////////////////////////////////////////////////////////////////////////////////
		// Assign MetricIDs to CADComponents (i.e. contained in in_CADComponentData_map )
		///////////////////////////////////////////////////////////////////////////////////
		for ( std::list<TopLevelAssemblyData>::const_iterator i(in_CADAssemblies.topLevelAssemblies.begin());
				i != in_CADAssemblies.topLevelAssemblies.end();
				++i )
		{
			Assign_MetricIDs_To_Components( i->assemblyComponentID,
											in_CADComponentData_map,
											nextMetricID,
											modelName_MetricID_map,
											metricID_ModelName_map);
		}

		//for ( std::map< std::string, int >::const_iterator temp_i(ModelName_MetricID.begin());
		//	  temp_i != ModelName_MetricID.end(); ++temp_i )
		//{
		//	std::cout << std::endl << "ModelName_MetricID, Model Name: " << temp_i->first << " MetricID: " << temp_i->second;
		//}

		//////////////////////////////
		// Cast to root of UDM object
		//////////////////////////////
		CADMetrics::CADMetricRoot CADMetricRoot = CADMetrics::CADMetricRoot::Cast(dn_CADMetricRoot.GetRootObject());
		CADMetricRoot.VersionInfo() = ISIS_METRIC_FILE_VERSION;

		//  Anomalies
		CADMetrics::Anomalies  anomaliesRoot = CADMetrics::Anomalies::Create( CADMetricRoot );

		//  Assemblies
		CADMetrics::Assemblies  assembliesRoot = CADMetrics::Assemblies::Create( CADMetricRoot );

		// MetricComponents
		CADMetrics::MetricComponents metricComponentsRoot = CADMetrics::MetricComponents::Create( CADMetricRoot );

		CADMetrics::Joints jointsRoot = CADMetrics::Joints::Create( CADMetricRoot );

		std::map<int, MetricsDefined> metricID_to_Anomalies_map;

		////////////////////////
		// Populate XML Tree
		////////////////////////
		for ( std::list<TopLevelAssemblyData>::const_iterator i(in_CADAssemblies.topLevelAssemblies.begin());
				i != in_CADAssemblies.topLevelAssemblies.end();
				++i )
		{
			//CADMetrics::MetricComponent  metricComponentRoot = 	CADMetrics::MetricComponent::Create( metricComponentsRoot );
			Populate_MetricComponents(	i->assemblyComponentID,
										in_CADComponentData_map,
										dataCreated_for_MetricIDs,
										metricID_to_Anomalies_map,
										metricComponentsRoot );

			CADMetrics::Assembly    assemblyRoot = 	CADMetrics::Assembly::Create( assembliesRoot );
			assemblyRoot.ConfigurationID() = i->configurationID;
			CADMetrics::CADComponent    cADComponentRoot = 	CADMetrics::CADComponent::Create( assemblyRoot );
			cADComponentRoot.ComponentInstanceID() = i->assemblyComponentID;
			cADComponentRoot.MetricID() = in_CADComponentData_map[i->assemblyComponentID].metricID;

			Populate_Assemblies(	i->assemblyComponentID,
									in_CADComponentData_map,
									cADComponentRoot );

			if ( in_OutputJoints)
			{
				Populate_Joints( i->assemblyComponentID,
								 in_CADComponentData_map,
								 dataCreated_for_MetricIDs,
								 metricID_to_Anomalies_map,
								 jointsRoot );

				isis::ComponentVistorBuildListOfComponentIDs  assemblyComponentIDs_ExcludingTopAssembly(true);
				isis::VisitComponents(i->assemblyComponentID, in_CADComponentData_map, assemblyComponentIDs_ExcludingTopAssembly );

				Populate_Joints_MetaData(	assemblyComponentIDs_ExcludingTopAssembly.listOfComponentIDs,
											in_CADComponentData_map,
											jointsRoot );
			}

		}

		Populate_Anomalies( metricID_to_Anomalies_map, anomaliesRoot );
		Log_Anomalies( metricID_to_Anomalies_map, in_MeticsOutputXML_PathAndFileName, metricID_ModelName_map );

		if ( metricID_to_Anomalies_map.size() == 0 )
			out_ErrorOccurred = false;
		else
			out_ErrorOccurred = true;

		///////////////////////////
		// Write XML File
		//////////////////////////
		if ( dn_CADMetricRoot.isOpen()) dn_CADMetricRoot.CloseWithUpdate();
	}
	catch ( ... )
	{
		// If any error occurs, do not save the metrics xml file.  It makes no sense to save a metrics file
		// with erroneous data.
		if ( dn_CADMetricRoot.isOpen()) dn_CADMetricRoot.CloseNoUpdate();
		throw;
	}

}

} // end namespace isis


text:
package org.acegisecurity.providers;

import org.acegisecurity.AuthenticationException;

/**
 * @deprecated use {@link org.springframework.security.authentication.ProviderNotFoundException}
 */
@Deprecated
public class ProviderNotFoundException extends AuthenticationException {

    public ProviderNotFoundException(String msg) {
        super(msg);
    }

    public ProviderNotFoundException(String msg, Throwable t) {
        super(msg, t);
    }

    @Override
    public org.springframework.security.core.AuthenticationException toSpring() {
        return (org.springframework.security.core.AuthenticationException) new org.springframework.security.authentication.ProviderNotFoundException(toString()).initCause(this);
    }

    public static ProviderNotFoundException fromSpring(org.springframework.security.authentication.ProviderNotFoundException x) {
        return new ProviderNotFoundException(x.toString(), x);
    }

}

redpajama_set_name: RedPajamaGithub


text:
local size = cc.Director:getInstance():getWinSize()
local scheduler = cc.Director:getInstance():getScheduler()

local kTagTileMap = 1
local kTagSpriteManager = 1
local kTagAnimation1 = 1
local kTagBitmapAtlas1 = 1
local kTagBitmapAtlas2 = 2
local kTagBitmapAtlas3 = 3
local kTagSprite1 = 0
local kTagSprite2 = 1
local kTagSprite3 = 2
local kTagSprite4 = 3
local kTagSprite5 = 4
local kTagSprite6 = 5
local kTagSprite7 = 6
local kTagSprite8 = 7

--------------------------------------------------------------------
--
-- LabelAtlasTest
--
--------------------------------------------------------------------

local LabelAtlasTest = {}
LabelAtlasTest.layer = nil
LabelAtlasTest.__index = LabelAtlasTest
local m_time = 0

function LabelAtlasTest.step(dt)
    m_time = m_time + dt
    local string = string.format("%2.2f Test", m_time)

    local label1_origin = LabelAtlasTest.layer:getChildByTag(kTagSprite1)
    local label1 = tolua.cast(label1_origin, "LabelAtlas")
    label1:setString(string)	--

    local label2_origin = LabelAtlasTest.layer:getChildByTag(kTagSprite2)
    local label2 = tolua.cast(label2_origin, "LabelAtlas")
    string = string.format("%d", m_time)

    label2:setString(string)
end

function LabelAtlasTest.onNodeEvent(tag)
    if tag == "exit" then
        LabelAtlasTest.layer:unscheduleUpdate()
    end
end

function LabelAtlasTest.create()
    m_time = 0
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    LabelAtlasTest.layer = layer

    local label1 = cc.LabelAtlas:_create("123 Test", "fonts/tuffy_bold_italic-charmap.plist")
    layer:addChild(label1, 0, kTagSprite1)
    label1:setPosition( cc.p(10,100) )
    label1:setOpacity( 200 )

    local label2 = cc.LabelAtlas:_create("0123456789", "fonts/tuffy_bold_italic-charmap.plist")
    layer:addChild(label2, 0, kTagSprite2)
    label2:setPosition( cc.p(10,200) )
    label2:setOpacity( 32 )

    layer:scheduleUpdateWithPriorityLua(LabelAtlasTest.step, 0)

    Helper.titleLabel:setString("LabelAtlas")
    Helper.subtitleLabel:setString("Updating label should be fast")

    layer:registerScriptHandler(LabelAtlasTest.onNodeEvent)
    return layer
end

--------------------------------------------------------------------
--
-- LabelAtlasColorTest
--
--------------------------------------------------------------------

local LabelAtlasColorTest = {}
LabelAtlasColorTest.layer = nil
LabelAtlasColorTest.__index = LabelAtlasColorTest
local m_time = 0

function LabelAtlasColorTest.step(dt)
    m_time = m_time + dt
    local string = string.format("%2.2f Test", m_time)
    local label1_origin = LabelAtlasColorTest.layer:getChildByTag(kTagSprite1)
    local label1 = tolua.cast(label1_origin, "LabelAtlas")
    label1:setString(string)

    local label2_origin = LabelAtlasColorTest.layer:getChildByTag(kTagSprite2)
    local label2 = tolua.cast(label2_origin, "LabelAtlas")
    string = string.format("%d", m_time)

    label2:setString(string)
end

function LabelAtlasColorTest.actionFinishCallback()
    cclog("Action finished")
end

function LabelAtlasColorTest.onNodeEvent(tag)
    if tag == "exit" then
        LabelAtlasColorTest.layer:unscheduleUpdate()
    end
end

function LabelAtlasColorTest.create()
    m_time = 0

    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    LabelAtlasColorTest.layer = layer

    local label1 = cc.LabelAtlas:_create("123 Test", "fonts/tuffy_bold_italic-charmap.plist")
    layer:addChild(label1, 0, kTagSprite1)
    label1:setPosition( cc.p(10,100) )
    label1:setOpacity( 200 )

    local label2 = cc.LabelAtlas:_create("0123456789", "fonts/tuffy_bold_italic-charmap.plist")
    layer:addChild(label2, 0, kTagSprite2)
    label2:setPosition( cc.p(10,200) )
    label2:setColor(cc.c3b(255, 0, 0))

    local fade = cc.FadeOut:create(1.0)
    local fade_in = fade:reverse()

    local cb = cc.CallFunc:create(LabelAtlasColorTest.actionFinishCallback)

    local seq = cc.Sequence:create(fade, fade_in, cb)
    local repeatAction = cc.RepeatForever:create( seq )
    label2:runAction( repeatAction )

    layer:registerScriptHandler(LabelAtlasColorTest.onNodeEvent)
    layer:scheduleUpdateWithPriorityLua(LabelAtlasColorTest.step, 0)

    Helper.titleLabel:setString("LabelAtlas")
    Helper.subtitleLabel:setString("Opacity + Color should work at the same time")

    return layer
end

--------------------------------------------------------------------
--
-- Atlas3
--
-- Use any of these editors to generate BMFonts:
-- 	 http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
-- 	 http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
-- 	 http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
-- 	 http://www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------
local Atlas3 = {}
Atlas3.layer = nil
Atlas3.__index = Atlas3

function Atlas3.onNodeEvent(tag)
    if tag == "exit" then
        Atlas3.layer:unscheduleUpdate()
    end
end

function Atlas3.create()
    cclog("Atlas3.create")
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Atlas3.layer = layer

    m_time = 0

    local col = cc.LayerColor:create( cc.c4b(128,128,128,255) )
    layer:addChild(col, -10)

    local label1 = cc.LabelBMFont:create("Test",  "fonts/bitmapFontTest2.fnt")

    -- testing anchors
    label1:setAnchorPoint( cc.p(0,0) )
    layer:addChild(label1, 0, kTagBitmapAtlas1)

    local fade = cc.FadeOut:create(1.0)
    local fade_in = fade:reverse()

    local seq = cc.Sequence:create(fade,fade_in)
    local repeatAction = cc.RepeatForever:create(seq)
    label1:runAction(repeatAction)

    --VERY IMPORTANT
    --color and opacity work OK because bitmapFontAltas2 loads a BMP image (not a PNG image)
    --If you want to use both opacity and color, it is recommended to use NON premultiplied images like BMP images
    --Of course, you can also tell XCode not to compress PNG images, but I think it doesn't work as expected
    local label2 = cc.LabelBMFont:create("Test", "fonts/bitmapFontTest2.fnt")

    -- testing anchors
    label2:setAnchorPoint( cc.p(0.5, 0.5) )
    label2:setColor(cc.c3b(255, 0, 0 ))
    layer:addChild(label2, 0, kTagBitmapAtlas2)

    label2:runAction( tolua.cast(repeatAction:clone(), "Action") )

    local label3 = cc.LabelBMFont:create("Test", "fonts/bitmapFontTest2.fnt")
    -- testing anchors
    label3:setAnchorPoint( cc.p(1,1) )
    layer:addChild(label3, 0, kTagBitmapAtlas3)

    label1:setPosition( VisibleRect:leftBottom() )
    label2:setPosition( VisibleRect:center() )
    label3:setPosition( VisibleRect:rightTop() )

    layer:registerScriptHandler(Atlas3.onNodeEvent)
    layer:scheduleUpdateWithPriorityLua(Atlas3.step, 0)

    Helper.titleLabel:setString( "LabelBMFont" )
    Helper.subtitleLabel:setString( "Testing alignment. Testing opacity + tint" )

    return layer
end

function Atlas3.step(dt)
    m_time = m_time + dt
    local string = string.format("%2.2f Test j", m_time)

    local label1 = tolua.cast(Atlas3.layer:getChildByTag(kTagBitmapAtlas1), "LabelBMFont")
    label1:setString(string)

    local label2 = tolua.cast(Atlas3.layer:getChildByTag(kTagBitmapAtlas2), "LabelBMFont")
    label2:setString(string)

    local label3 = tolua.cast(Atlas3.layer:getChildByTag(kTagBitmapAtlas3), "LabelBMFont")
    label3:setString(string)
end

--------------------------------------------------------------------
--
-- Atlas4
--
-- Use any of these editors to generate BMFonts:
--     http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--     http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--     http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--     http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------
local Atlas4 = {}
Atlas4.layer = nil
Atlas4.__index = Atlas4
Atlas4.stepEntry = nil

function Atlas4.onNodeEvent(tag)
    if tag == "enter" then
        Atlas4.stepEntry = scheduler:scheduleScriptFunc(Atlas4.step, 0.1, false)
    elseif tag == "exit" then
        scheduler:unscheduleScriptEntry(Atlas4.stepEntry)
    end
end

function Atlas4.create()
    cclog("Atlas4.create")
    m_time = 0
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Atlas4.layer = layer

    -- Upper Label
    local label = cc.LabelBMFont:create("Bitmap Font Atlas", "fonts/bitmapFontTest.fnt")
    layer:addChild(label)

    local s = cc.Director:getInstance():getWinSize()

    label:setPosition( cc.p(s.width/2, s.height/2) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    local BChar = label:getChildByTag(0)
    local FChar = label:getChildByTag(7)
    local AChar = label:getChildByTag(12)

    local rotate = cc.RotateBy:create(2, 360)
    local rot_4ever = cc.RepeatForever:create(rotate)

    local scale = cc.ScaleBy:create(2, 1.5)
    local scale_back = scale:reverse()

    local scale_seq = cc.Sequence:create(scale, scale_back)
    local scale_4ever = cc.RepeatForever:create(scale_seq)

    local jump = cc.JumpBy:create(0.5, cc.p(0, 0), 60, 1)
    local jump_4ever = cc.RepeatForever:create(jump)

    local fade_out = cc.FadeOut:create(1)
    local fade_in = cc.FadeIn:create(1)

    local seq = cc.Sequence:create(fade_out, fade_in)
    local fade_4ever = cc.RepeatForever:create(seq)

    BChar:runAction(rot_4ever)
    BChar:runAction(scale_4ever)
    FChar:runAction(jump_4ever)
    AChar:runAction(fade_4ever)

    -- Bottom Label
    local label2 = cc.LabelBMFont:create("00.0", "fonts/bitmapFontTest.fnt")
    layer:addChild(label2, 0, kTagBitmapAtlas2)
    label2:setPosition( cc.p(s.width/2.0, 80) )

    local lastChar = label2:getChildByTag(3)
    lastChar:runAction(tolua.cast( rot_4ever:clone(), "Action" ))

    layer:registerScriptHandler(Atlas4.onNodeEvent)

    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString( "Using fonts as cc.Sprite objects. Some characters should rotate.")
    return layer
end

function Atlas4.draw()
    local s = cc.Director:getInstance():getWinSize()
    cc.DrawPrimitives.drawLine( cc.p(0, s.height/2), cc.p(s.width, s.height/2) )
    cc.DrawPrimitives.drawLine( cc.p(s.width/2, 0), cc.p(s.width/2, s.height) )
end

function Atlas4.step(dt)
    m_time = m_time + dt

    local string = string.format("%04.1f", m_time)

    local label1 = tolua.cast(Atlas4.layer:getChildByTag(kTagBitmapAtlas2), "LabelBMFont")
    label1:setString(string)
end

--------------------------------------------------------------------
--
-- Atlas5
--
-- Use any of these editors to generate BMFonts:
--	   http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--	   http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--	   http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--	   http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------

local Atlas5 = {}
Atlas5.layer = nil
function Atlas5:create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Atlas5.layer = layer

    local label = cc.LabelBMFont:create("abcdefg", "fonts/bitmapFontTest4.fnt")
    layer:addChild(label)

    local s = cc.Director:getInstance():getWinSize()

    label:setPosition( cc.p(s.width/2, s.height/2) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString("Testing padding")
    return layer
end

--------------------------------------------------------------------
--
-- Atlas6
--
-- Use any of these editors to generate BMFonts:
--	   http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--	   http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--	   http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--	   http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------
local Atlas6 = {}
Atlas6.layer = nil

function Atlas6:create()
    cclog("Atlas6:create")
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Atlas6.layer = layer

    local s = cc.Director:getInstance():getWinSize()
    local label = cc.LabelBMFont:create("FaFeFiFoFu", "fonts/bitmapFontTest5.fnt")
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, s.height/2+50) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    label = cc.LabelBMFont:create("fafefifofu", "fonts/bitmapFontTest5.fnt")
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, s.height/2) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    label = cc.LabelBMFont:create("aeiou", "fonts/bitmapFontTest5.fnt")
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, s.height/2-50) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString("Rendering should be OK. Testing offset")
    return layer
end

--------------------------------------------------------------------
--
-- AtlasBitmapColor
--
-- Use any of these editors to generate BMFonts:
--     http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--     http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--     http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--     http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------
local AtlasBitmapColor = { layer= nil }
function AtlasBitmapColor:create()
    local layer = cc.Layer:create()
    AtlasBitmapColor.layer = layer
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    local label = cc.LabelBMFont:create("Blue", "fonts/bitmapFontTest5.fnt")
    label:setColor( cc.c3b(0, 0, 255 ))
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, s.height/4) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )

    label = cc.LabelBMFont:create("Red", "fonts/bitmapFontTest5.fnt")
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, 2*s.height/4) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )
    label:setColor( cc.c3b(255, 0, 0) )

    label = cc.LabelBMFont:create("G", "fonts/bitmapFontTest5.fnt")
    layer:addChild(label)
    label:setPosition( cc.p(s.width/2, 3*s.height/4) )
    label:setAnchorPoint( cc.p(0.5, 0.5) )
    label:setColor( cc.c3b(0, 255, 0 ))
    label:setString("Green")

    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString("Testing color")
    return layer
end

--------------------------------------------------------------------
--
-- AtlasFastBitmap
--
-- Use any of these editors to generate BMFonts:
--     http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--     http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--     http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--     http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------

local AtlasFastBitmap = { layer = nil }
function AtlasFastBitmap:create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    AtlasFastBitmap.layer = layer

    math.randomseed(os.time())
    -- Upper Label
    local i = 0
    for i = 0, 100, 1 do
        local str = string.format("-%d-", i)
        local label = cc.LabelBMFont:create(str, "fonts/bitmapFontTest.fnt")
        layer:addChild(label)

        local s = cc.Director:getInstance():getWinSize()

        local p = cc.p( math.random() * s.width, math.random() * s.height)
        label:setPosition( p )
        label:setAnchorPoint(cc.p(0.5, 0.5))
    end

    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString("Creating several cc.LabelBMFont with the same .fnt file should be fast")
    return layer
end

--------------------------------------------------------------------
--
-- BitmapFontMultiLine
--
-- Use any of these editors to generate BMFonts:
--     http:--glyphdesigner.71squared.com/ (Commercial, Mac OS X)
--     http:--www.n4te.com/hiero/hiero.jnlp (Free, Java)
--     http:--slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
--     http:--www.angelcode.com/products/bmfont/ (Free, Windows only)
--
--------------------------------------------------------------------
local BitmapFontMultiLine = {}

function BitmapFontMultiLine:create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    local s = nil

    -- Left
    local label1 = cc.LabelBMFont:create(" Multi line\nLeft", "fonts/bitmapFontTest3.fnt")
    label1:setAnchorPoint(cc.p(0,0))
    layer:addChild(label1, 0, kTagBitmapAtlas1)

    s = label1:getContentSize()
    cclog("content size: %.2fx%.2f", s.width, s.height)

    -- Center
    local label2 = cc.LabelBMFont:create("Multi line\nCenter", "fonts/bitmapFontTest3.fnt")
    label2:setAnchorPoint(cc.p(0.5, 0.5))
    layer:addChild(label2, 0, kTagBitmapAtlas2)

    s= label2:getContentSize()
    cclog("content size: %.2fx%.2f", s.width, s.height)

    -- right
    local label3 = cc.LabelBMFont:create("Multi line\nRight\nThree lines Three", "fonts/bitmapFontTest3.fnt")
    label3:setAnchorPoint(cc.p(1, 1))
    layer:addChild(label3, 0, kTagBitmapAtlas3)

    s = label3:getContentSize()
    cclog("content size: %.2fx%.2f", s.width, s.height)

    label1:setPosition(VisibleRect:leftBottom())
    label2:setPosition(VisibleRect:center())
    label3:setPosition(VisibleRect:rightTop())
    Helper.titleLabel:setString("LabelBMFont")
    Helper.subtitleLabel:setString("Multiline + anchor point")
    return layer
end

--------------------------------------------------------------------
--
-- LabelsEmpty
--
--------------------------------------------------------------------

local LabelsEmpty = {}
LabelsEmpty.layer = nil
LabelsEmpty.setEmpty = false
LabelsEmpty.updateEntry = nil

function LabelsEmpty.onNodeEvent(tag)
    if tag == "enter" then
        LabelsEmpty.updateEntry = scheduler:scheduleScriptFunc(LabelsEmpty.updateStrings, 1.0, false)
    elseif tag == "exit" then
        scheduler:unscheduleScriptEntry(LabelsEmpty.updateEntry)
    end
end

function LabelsEmpty.create()
    cclog("LabelsEmpty.create")

    local layer = cc.Layer:create()
    LabelsEmpty.layer = layer
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    -- cc.LabelBMFont
    local label1 = cc.LabelBMFont:create("", "fonts/bitmapFontTest3.fnt")
    layer:addChild(label1, 0, kTagBitmapAtlas1)
    label1:setPosition(cc.p(s.width/2, s.height-100))

    -- cc.LabelTTF
    local label2 = cc.LabelTTF:create("", "Arial", 24)
    layer:addChild(label2, 0, kTagBitmapAtlas2)
    label2:setPosition(cc.p(s.width/2, s.height/2))

    -- cc.LabelAtlas
    local label3 = cc.LabelAtlas:_create("", "fonts/tuffy_bold_italic-charmap.png", 48, 64,  string.byte(" "))
    layer:addChild(label3, 0, kTagBitmapAtlas3)
    label3:setPosition(cc.p(s.width/2, 0+100))

    layer:registerScriptHandler(LabelsEmpty.onNodeEvent)

    LabelsEmpty.setEmpty = false
    Helper.titleLabel:setString("Testing empty labels")
    Helper.subtitleLabel:setString("3 empty labels: LabelAtlas, LabelTTF and LabelBMFont")
    return layer
end

function LabelsEmpty.updateStrings(dt)
    local label1 = tolua.cast(LabelsEmpty.layer:getChildByTag(kTagBitmapAtlas1), "LabelBMFont")
    local label2 = tolua.cast(LabelsEmpty.layer:getChildByTag(kTagBitmapAtlas2), "LabelTTF")
    local label3 = tolua.cast(LabelsEmpty.layer:getChildByTag(kTagBitmapAtlas3), "LabelAtlas")

    if( LabelsEmpty.setEmpty == false) then
        label1:setString("not empty")
        label2:setString("not empty")
        label3:setString("hi")
        LabelsEmpty.setEmpty = true
    else
        label1:setString("")
        label2:setString("")
        label3:setString("")
        LabelsEmpty.setEmpty = false
    end
end

--------------------------------------------------------------------
--
-- LabelBMFontHD
--
--------------------------------------------------------------------
local LabelBMFontHD = {

}

function LabelBMFontHD.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    -- cc.LabelBMFont
    local label1 = cc.LabelBMFont:create("TESTING RETINA DISPLAY", "fonts/konqa32.fnt")
    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/2))

    Helper.titleLabel:setString("Testing Retina Display BMFont")
    Helper.subtitleLabel:setString("loading arista16 or arista16-hd")
    return layer
end

--------------------------------------------------------------------
--
-- LabelAtlasHD
--
--------------------------------------------------------------------
local LabelAtlasHD = {}
function LabelAtlasHD.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    -- cc.LabelBMFont
    local label1 = cc.LabelAtlas:_create("TESTING RETINA DISPLAY", "fonts/larabie-16.plist")
    label1:setAnchorPoint(cc.p(0.5, 0.5))

    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/2))

    Helper.titleLabel:setString("LabelAtlas with Retina Display")
    Helper.subtitleLabel:setString("loading larabie-16 / larabie-16-hd")
    return layer
end

--------------------------------------------------------------------
--
-- LabelGlyphDesigner
--
--------------------------------------------------------------------

local LabelGlyphDesigner = {}
function LabelGlyphDesigner.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    local colorlayer = cc.LayerColor:create(cc.c4b(128,128,128,255))
    layer:addChild(colorlayer, -10)

    -- cc.LabelBMFont
    local label1 = cc.LabelBMFont:create("Testing Glyph Designer", "fonts/futura-48.fnt")
    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/2))
    Helper.titleLabel:setString("Testing Glyph Designer")
    Helper.subtitleLabel:setString("You should see a font with shawdows and outline")

    return layer
end

--------------------------------------------------------------------
--
-- LabelTTFTest
--
--------------------------------------------------------------------

local LabelTTFTest = {
    _layer       = nil,
    _plabel      = nil,
    _eHorizAlign = cc.TEXT_ALIGNMENT_LEFT,
    _eVertAlign  = cc.VERTICAL_TEXT_ALIGNMENT_TOP
}

function LabelTTFTest.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    LabelTTFTest._layer       = layer
    LabelTTFTest._plabel      = nil
    LabelTTFTest._eHorizAlign = cc.TEXT_ALIGNMENT_LEFT
    LabelTTFTest._eVertAlign  = cc.VERTICAL_TEXT_ALIGNMENT_TOP

    local blockSize = cc.size(200, 160)
    local s = cc.Director:getInstance():getWinSize()

    local colorLayer = cc.LayerColor:create(cc.c4b(100, 100, 100, 255), blockSize.width, blockSize.height)
    colorLayer:setAnchorPoint(cc.p(0,0))
    colorLayer:setPosition(cc.p((s.width - blockSize.width) / 2, (s.height - blockSize.height) / 2))

    layer:addChild(colorLayer)

    cc.MenuItemFont:setFontSize(30)
    local item1 = cc.MenuItemFont:create("Left")
    item1:registerScriptTapHandler(LabelTTFTest.setAlignmentLeft)
    local item2 = cc.MenuItemFont:create("Center")
    item2:registerScriptTapHandler(LabelTTFTest.setAlignmentCenter)
    local item3 = cc.MenuItemFont:create("Right")
    item3:registerScriptTapHandler(LabelTTFTest.setAlignmentRight)

    local menu = cc.Menu:create()
    menu:addChild(item1)
    menu:addChild(item2)
    menu:addChild(item3)
    menu:alignItemsVerticallyWithPadding(4)
    menu:setPosition(cc.p(50, s.height / 2 - 20))
    layer:addChild(menu)

    menu = cc.Menu:create()

    item1 = cc.MenuItemFont:create("Top")
    item1:registerScriptTapHandler(LabelTTFTest.setAlignmentTop)
    item2 = cc.MenuItemFont:create("Middle")
    item2:registerScriptTapHandler(LabelTTFTest.setAlignmentMiddle)
    item3 = cc.MenuItemFont:create("Bottom")
    item3:registerScriptTapHandler(LabelTTFTest.setAlignmentBottom)

    menu:addChild(item1)
    menu:addChild(item2)
    menu:addChild(item3)

    menu:alignItemsVerticallyWithPadding(4)
    menu:setPosition(cc.p(s.width - 50, s.height / 2 - 20))
    layer:addChild(menu)

    LabelTTFTest.updateAlignment()

    layer:registerScriptHandler(LabelTTFTest.onNodeEvent)

    Helper.titleLabel:setString("Testing cc.LabelTTF")
    Helper.subtitleLabel:setString("Select the buttons on the sides to change alignment")

    return layer
end

function LabelTTFTest.onNodeEvent(tag)
    if tag == "exit" then
        if LabelTTFTest._plabel ~= nil then
            LabelTTFTest._plabel:release()
        end
    end
end

function LabelTTFTest.updateAlignment()
    local blockSize = cc.size(200, 160)
    local s = cc.Director:getInstance():getWinSize()

    if LabelTTFTest._plabel ~= nil then
        LabelTTFTest._plabel:removeFromParent(true)
        LabelTTFTest._plabel:release()
    end

    LabelTTFTest._plabel = cc.LabelTTF:create(LabelTTFTest.getCurrentAlignment(), "Marker Felt", 32,
                                             blockSize, LabelTTFTest._eHorizAlign, LabelTTFTest._eVertAlign)
    LabelTTFTest._plabel:retain()

    LabelTTFTest._plabel:setAnchorPoint(cc.p(0,0))
    LabelTTFTest._plabel:setPosition(cc.p((s.width - blockSize.width) / 2, (s.height - blockSize.height)/2 ))

    LabelTTFTest._layer:addChild(LabelTTFTest._plabel)
end

function LabelTTFTest.setAlignmentLeft(pSender)
    LabelTTFTest._eHorizAlign = cc.TEXT_ALIGNMENT_LEFT
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.setAlignmentCenter(pSender)
    LabelTTFTest._eHorizAlign = cc.TEXT_ALIGNMENT_CENTER
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.setAlignmentRight(pSender)
    LabelTTFTest._eHorizAlign = cc.TEXT_ALIGNMENT_RIGHT
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.setAlignmentTop(pSender)
    LabelTTFTest._eVertAlign = cc.VERTICAL_TEXT_ALIGNMENT_TOP
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.setAlignmentMiddle(pSender)
    LabelTTFTest._eVertAlign = cc.VERTICAL_TEXT_ALIGNMENT_CENTER
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.setAlignmentBottom(pSender)
    LabelTTFTest._eVertAlign = cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM
    LabelTTFTest.updateAlignment()
end

function LabelTTFTest.getCurrentAlignment()
    local vertical = nil
    local horizontal = nil
    if LabelTTFTest._eVertAlign == cc.VERTICAL_TEXT_ALIGNMENT_TOP then
        vertical = "Top"
    elseif LabelTTFTest._eVertAlign ==  cc.VERTICAL_TEXT_ALIGNMENT_CENTER then
        vertical = "Middle"
    elseif LabelTTFTest._eVertAlign ==  cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM then
        vertical = "Bottom"
    end

    if LabelTTFTest._eHorizAlign == cc.TEXT_ALIGNMENT_LEFT then
        horizontal = "Left"
    elseif LabelTTFTest._eHorizAlign == cc.TEXT_ALIGNMENT_CENTER then
        horizontal = "Center"
    elseif LabelTTFTest._eHorizAlign == cc.TEXT_ALIGNMENT_RIGHT then
        horizontal = "Right"
    end

    return string.format("Alignment %s %s", vertical, horizontal)
end

--------------------------------------------------------------------
--
-- Atlas1
--
--------------------------------------------------------------------
--Atlas1:Atlas1()
--{
--    m_textureAtlas = cc.TextureAtlas:create(s_AtlasTest, 3); m_textureAtlas:retain();
--
--    cc.size s = cc.Director:getInstance():getWinSize();
--
--    --
--    -- Notice: u,v tex coordinates are inverted
--    --
--    V3F_C4B_T2F_Quad quads[] =
--    {
--        {
--            {{0,0,0},cc.c4b(0,0,255,255),{0.0f,1.0f},},                -- bottom left
--            {{s.width,0,0},cc.c4b(0,0,255,0),{1.0f,1.0f},},            -- bottom right
--            {{0,s.height,0},cc.c4b(0,0,255,0),{0.0f,0.0f},},            -- top left
--            {{s.width,s.height,0},{0,0,255,255},{1.0f,0.0f},},    -- top right
--        },
--        {
--            {{40,40,0},cc.c4b(255,255,255,255),{0.0f,0.2f},},            -- bottom left
--            {{120,80,0},cc.c4b(255,0,0,255),{0.5f,0.2f},},            -- bottom right
--            {{40,160,0},cc.c4b(255,255,255,255),{0.0f,0.0f},},        -- top left
--            {{160,160,0},cc.c4b(0,255,0,255),{0.5f,0.0f},},            -- top right
--        },
--
--        {
--            {{s.width/2,40,0},cc.c4b(255,0,0,255),{0.0f,1.0f},},        -- bottom left
--            {{s.width,40,0},cc.c4b(0,255,0,255),{1.0f,1.0f},},        -- bottom right
--            {{s.width/2-50,200,0},cc.c4b(0,0,255,255),{0.0f,0.0f},},        -- top left
--            {{s.width,100,0},cc.c4b(255,255,0,255),{1.0f,0.0f},},        -- top right
--        },
--
--    };
--
--
--    for( int i=0;i<3;i++)
--    {
--        m_textureAtlas:updateQuad(&quads[i], i);
--    }
--}
--
--Atlas1:~Atlas1()
--{
--    m_textureAtlas:release();
--}
--
--void Atlas1:draw()
--{
--    -- GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
--    -- GL_TEXTURE_2D
--
--    m_textureAtlas:drawQuads();
--
----    [textureAtlas drawNumberOfQuads:3];
--
--}
--
--std:string Atlas1:title()
--{
--    return "TextureAtlas";
--}
--
--std:string Atlas1:subtitle()
--{
--    return "Manual creation of cc.TextureAtlas";
--}

local LabelTTFMultiline = {
    layer = nil
}

function LabelTTFMultiline.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    local center = cc.LabelTTF:create("word wrap \"testing\" (bla0) bla1 'bla2' [bla3] (bla4) {bla5} {bla6} [bla7] (bla8) [bla9] 'bla0' \"bla1\"",
                                     "Paint Boy",
                                     32,
                                     cc.size(s.width/2,200),
                                     cc.TEXT_ALIGNMENT_CENTER,
                                     cc.VERTICAL_TEXT_ALIGNMENT_TOP)

    center:setPosition(cc.p(s.width / 2, 150))

    layer:addChild(center)
    Helper.titleLabel:setString("Testing cc.LabelTTF Word Wrap")
    Helper.subtitleLabel:setString("Word wrap using cc.LabelTTF and a custom TTF font")

    return layer
end

local LabelTTFChinese = {}

function LabelTTFChinese.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    local size = cc.Director:getInstance():getWinSize()
    local pLable = cc.LabelTTF:create("中国", "Marker Felt", 30)
    pLable:setPosition(cc.p(size.width / 2, size.height /2))
    layer:addChild(pLable)
    Helper.titleLabel:setString("Testing cc.LabelTTF with Chinese character")
    return layer
end

local LabelBMFontChinese = {}
function LabelBMFontChinese.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local size = cc.Director:getInstance():getWinSize()
    local pLable = cc.LabelBMFont:create("中国", "fonts/bitmapFontChinese.fnt")
    pLable:setPosition(cc.p(size.width / 2, size.height /2))
    layer:addChild(pLable)

    Helper.titleLabel:setString("Testing cc.LabelBMFont with Chinese character")
    return layer
end

-- BitmapFontMultiLineAlignment

local  LongSentencesExample =  "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
local  LineBreaksExample    = "Lorem ipsum dolor\nsit amet\nconsectetur adipisicing elit\nblah\nblah"
local  MixedExample         = "ABC\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt\nDEF"

local  ArrowsMax             = 0.95
local  ArrowsMin             = 0.7

local  LeftAlign             = 0
local  CenterAlign           = 1
local  RightAlign            = 2

local  LongSentences         = 0
local  LineBreaks            = 1
local  Mixed                 = 2

local  alignmentItemPadding  = 50
local  menuItemPaddingCenter = 50

local BitmapFontMultiLineAlignment = {
    _pLabelShouldRetain = nil,
    _pArrowsBarShouldRetain = nil,
    _pArrowsShouldRetain = nil,
    _pLastSentenceItem = nil,
    _drag = false,
}

function BitmapFontMultiLineAlignment.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    layer:setTouchEnabled(true)

    -- ask director the the window size
    local size = cc.Director:getInstance():getWinSize()

    -- create and initialize a Label
    BitmapFontMultiLineAlignment._pLabelShouldRetain = cc.LabelBMFont:create(LongSentencesExample, "fonts/markerFelt.fnt", size.width/1.5, cc.TEXT_ALIGNMENT_CENTER)
    BitmapFontMultiLineAlignment._pLabelShouldRetain:retain()

    BitmapFontMultiLineAlignment._pArrowsBarShouldRetain = cc.Sprite:create("Images/arrowsBar.png")
    BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:retain()
    BitmapFontMultiLineAlignment._pArrowsShouldRetain = cc.Sprite:create("Images/arrows.png")
    BitmapFontMultiLineAlignment._pArrowsShouldRetain:retain()

    cc.MenuItemFont:setFontSize(20)
    local longSentences = cc.MenuItemFont:create("Long Flowing Sentences")
    longSentences:registerScriptTapHandler(BitmapFontMultiLineAlignment.stringChanged)
    local lineBreaks    = cc.MenuItemFont:create("Short Sentences With Intentional Line Breaks")
    lineBreaks:registerScriptTapHandler(BitmapFontMultiLineAlignment.stringChanged)
    local mixed         = cc.MenuItemFont:create("Long Sentences Mixed With Intentional Line Breaks")
    mixed:registerScriptTapHandler(BitmapFontMultiLineAlignment.stringChanged)
    local stringMenu    = cc.Menu:create()
    stringMenu:addChild(longSentences)
    stringMenu:addChild(lineBreaks)
    stringMenu:addChild(mixed)
    stringMenu:alignItemsVertically()

    longSentences:setColor(cc.c3b(255, 0, 0))
    BitmapFontMultiLineAlignment._pLastSentenceItem = longSentences

    longSentences:setTag(LongSentences)
    lineBreaks:setTag(LineBreaks)
    mixed:setTag(Mixed)

    cc.MenuItemFont:setFontSize(30)

    local left          = cc.MenuItemFont:create("Left")
    left:registerScriptTapHandler(BitmapFontMultiLineAlignment.alignmentChanged)
    local center        = cc.MenuItemFont:create("Center")
    center:registerScriptTapHandler(BitmapFontMultiLineAlignment.alignmentChanged)
    local right         = cc.MenuItemFont:create("Right")
    right:registerScriptTapHandler(BitmapFontMultiLineAlignment.alignmentChanged)

    local alignmentMenu = cc.Menu:create()
    alignmentMenu:addChild(left)
    alignmentMenu:addChild(center)
    alignmentMenu:addChild(right)

    alignmentMenu:alignItemsHorizontallyWithPadding(alignmentItemPadding)

    center:setColor(cc.c3b(255, 0, 0))
    BitmapFontMultiLineAlignment._pLastAlignmentItem = center
    left:setTag(LeftAlign)
    center:setTag(CenterAlign)
    right:setTag(RightAlign)

    -- position the label on the center of the screen
    BitmapFontMultiLineAlignment._pLabelShouldRetain:setPosition(cc.p(size.width/2, size.height/2))

    BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:setVisible(false)

    local arrowsWidth = (ArrowsMax - ArrowsMin) * size.width
    BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:setScaleX(arrowsWidth / BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:getContentSize().width)
    BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:setPosition( ((ArrowsMax + ArrowsMin) / 2) * size.width, BitmapFontMultiLineAlignment._pLabelShouldRetain:getPositionY() )

    BitmapFontMultiLineAlignment.snapArrowsToEdge()

    stringMenu:setPosition(cc.p(size.width/2, size.height - menuItemPaddingCenter))
    alignmentMenu:setPosition(cc.p(size.width/2, menuItemPaddingCenter+15))

    layer:addChild(BitmapFontMultiLineAlignment._pLabelShouldRetain)
    layer:addChild(BitmapFontMultiLineAlignment._pArrowsBarShouldRetain)
    layer:addChild(BitmapFontMultiLineAlignment._pArrowsShouldRetain)
    layer:addChild(stringMenu)
    layer:addChild(alignmentMenu)
    layer:registerScriptHandler(BitmapFontMultiLineAlignment.onNodeEvent)
    layer:registerScriptTouchHandler(BitmapFontMultiLineAlignment.onTouchEvent)
    return layer
end

function BitmapFontMultiLineAlignment.onNodeEvent(tag)
    if tag == "onexit" then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:release()
        BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:release()
        BitmapFontMultiLineAlignment._pArrowsShouldRetain:release()
    end
end

function BitmapFontMultiLineAlignment.stringChanged(tag, sender)
    local item = tolua.cast(sender, "MenuItemFont")
    item:setColor(cc.c3b(255, 0, 0))
    BitmapFontMultiLineAlignment._pLastAlignmentItem:setColor(cc.c3b(255, 255, 255))
    BitmapFontMultiLineAlignment._pLastAlignmentItem = item

    if item:getTag() == LongSentences then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setString(LongSentencesExample)
    elseif item:getTag() == LineBreaks then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setString(LineBreaksExample)
    elseif item:getTag() == Mixed then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setString(MixedExample)
    end

    BitmapFontMultiLineAlignment.snapArrowsToEdge()
end

function BitmapFontMultiLineAlignment.alignmentChanged(tag, sender)
    -- cclog("BitmapFontMultiLineAlignment.alignmentChanged, tag:"..tag)
    local item = tolua.cast(sender, "MenuItemFont")
    item:setColor(cc.c3b(255, 0, 0))
    BitmapFontMultiLineAlignment._pLastAlignmentItem:setColor(cc.c3b(255, 255, 255))
    BitmapFontMultiLineAlignment._pLastAlignmentItem = item

    if tag == LeftAlign then
        cclog("LeftAlign")
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setAlignment(cc.TEXT_ALIGNMENT_LEFT)
    elseif tag == CenterAlign then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setAlignment(cc.TEXT_ALIGNMENT_CENTER)
    elseif tag == RightAlign then
        BitmapFontMultiLineAlignment._pLabelShouldRetain:setAlignment(cc.TEXT_ALIGNMENT_RIGHT)
    end

    BitmapFontMultiLineAlignment.snapArrowsToEdge()
end

function BitmapFontMultiLineAlignment.onTouchEvent(eventType, x, y)
    -- cclog("type:"..eventType.."["..x..","..y.."]")
    if eventType == "began" then
        if cc.rectContainsPoint(BitmapFontMultiLineAlignment._pArrowsShouldRetain:getBoundingBox(), cc.p(x, y)) then
            BitmapFontMultiLineAlignment._drag = true
            BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:setVisible(true)
            return true
        end
    elseif eventType == "ended" then
        BitmapFontMultiLineAlignment._drag = false
        BitmapFontMultiLineAlignment.snapArrowsToEdge()
        BitmapFontMultiLineAlignment._pArrowsBarShouldRetain:setVisible(false)
    elseif eventType == "moved" then
        if BitmapFontMultiLine._drag == false then
            return
        end

        local winSize = cc.Director:getInstance():getWinSize()
        BitmapFontMultiLineAlignment._pArrowsShouldRetain:setPosition(
            math.max(math.min(x, ArrowsMax*winSize.width), ArrowsMin*winSize.width),
            BitmapFontMultiLineAlignment._pArrowsShouldRetain:getPositionY())

        local labelWidth = math.abs(BitmapFontMultiLineAlignment._pArrowsShouldRetain:getPositionX() - BitmapFontMultiLineAlignment._pLabelShouldRetain:getPositionX()) * 2

        BitmapFontMultiLineAlignment._pLabelShouldRetain:setWidth(labelWidth)

    end
end

function BitmapFontMultiLineAlignment.snapArrowsToEdge()
    BitmapFontMultiLineAlignment._pArrowsShouldRetain:setPosition(
        BitmapFontMultiLineAlignment._pLabelShouldRetain:getPositionX() + BitmapFontMultiLineAlignment._pLabelShouldRetain:getContentSize().width/2, BitmapFontMultiLineAlignment._pLabelShouldRetain:getPositionY()
    )
end

--/ LabelTTFA8Test

local LabelTTFA8Test = {}

function LabelTTFA8Test.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    local colorlayer = cc.LayerColor:create(cc.c4b(128, 128, 128, 255))
    layer:addChild(colorlayer, -10)

    -- cc.LabelBMFont
    local label1 = cc.LabelTTF:create("Testing A8 Format", "Marker Felt", 48)
    layer:addChild(label1)
    label1:setColor(cc.c3b(255, 0, 0))
    label1:setPosition(cc.p(s.width/2, s.height/2))

    local fadeOut = cc.FadeOut:create(2)
    local fadeIn = cc.FadeIn:create(2)

    local seq = cc.Sequence:create(fadeOut, fadeIn)
    local forever = cc.RepeatForever:create(seq)
    label1:runAction(forever)

    Helper.titleLabel:setString("Testing A8 Format")
    Helper.subtitleLabel:setString("RED label, fading In and Out in the center of the screen")
    return layer
end

--/ BMFontOneAtlas
local BMFontOneAtlas = {}
function BMFontOneAtlas.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)

    local s = cc.Director:getInstance():getWinSize()

    local label1 = cc.LabelBMFont:create("This is Helvetica", "fonts/helvetica-32.fnt", cc.LABEL_AUTOMATIC_WIDTH, cc.TEXT_ALIGNMENT_LEFT, cc.p(0, 0))
    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/3*2))

    local label2 = cc.LabelBMFont:create("And this is Geneva", "fonts/geneva-32.fnt", cc.LABEL_AUTOMATIC_WIDTH, cc.TEXT_ALIGNMENT_LEFT, cc.p(0, 128))
    layer:addChild(label2)
    label2:setPosition(cc.p(s.width/2, s.height/3*1))
    Helper.titleLabel:setString("LabelBMFont with one texture")
    Helper.subtitleLabel:setString("Using 2 .fnt definitions that share the same texture atlas.")
    return layer
end

--/ BMFontUnicode
local BMFontUnicode = {}
function BMFontUnicode.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("LabelBMFont with Unicode support")
    Helper.subtitleLabel:setString("You should see 3 differnt labels: In Spanish, Chinese and Korean")

    local s = cc.Director:getInstance():getWinSize()

    local label1 = cc.LabelBMFont:create("Buen día", "fonts/arial-unicode-26.fnt", 200, cc.TEXT_ALIGNMENT_LEFT)
    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/4*3))

    local label2 = cc.LabelBMFont:create("美好的一天", "fonts/arial-unicode-26.fnt")
    layer:addChild(label2)
    label2:setPosition(cc.p(s.width/2, s.height/4*2))

    local label3 = cc.LabelBMFont:create("良い一日を", "fonts/arial-unicode-26.fnt")
    layer:addChild(label3)
    label3:setPosition(cc.p(s.width/2, s.height/4*1))

    return layer
end

--BMFontInit

local BMFontInit = {}
function BMFontInit.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("LabelBMFont init")
    Helper.subtitleLabel:setString("Test for support of init method without parameters.")

    local s = cc.Director:getInstance():getWinSize()
    local bmFont = cc.LabelBMFont:create()
    --cc.LabelBMFont* bmFont = [cc.LabelBMFont create:@"Foo" fntFile:@"arial-unicode-26.fnt"]
    bmFont:setFntFile("fonts/helvetica-32.fnt")
    bmFont:setString("It is working!")
    layer:addChild(bmFont)
    bmFont:setPosition(cc.p(s.width/2,s.height/4*2))
    return layer
end

-- TTFFontInit

local TTFFontInit = {}
function TTFFontInit.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("LabelTTF init")
    Helper.subtitleLabel:setString("Test for support of init method without parameters.")

    local s = cc.Director:getInstance():getWinSize()

    local font = cc.LabelTTF:create()
    font:setFontName("Marker Felt")
    font:setFontSize(48)
    font:setString("It is working!")
    layer:addChild(font)
    font:setPosition(cc.p(s.width/2,s.height/4*2))
    return layer
end

-- Issue1343

local Issue1343 = {}
function Issue1343.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("Issue 1343")
    Helper.subtitleLabel:setString("You should see: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz.,'")

    local s = cc.Director:getInstance():getWinSize()

    local bmFont = cc.LabelBMFont:create()
    bmFont:setFntFile("fonts/font-issue1343.fnt")
    bmFont:setString("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz.,'")
    layer:addChild(bmFont)
    bmFont:setScale(0.3)

    bmFont:setPosition(cc.p(s.width/2,s.height/4*2))
    return layer
end

local LabelBMFontBounds = {}
function LabelBMFontBounds.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("Testing LabelBMFont Bounds")
    Helper.subtitleLabel:setString("You should see string enclosed by a box")

    local s = cc.Director:getInstance():getWinSize()

    local colorlayer = cc.LayerColor:create(cc.c4b(128,128,128,255))
    layer:addChild(colorlayer, -10)

    -- cc.LabelBMFont
    local label1 = cc.LabelBMFont:create("Testing Glyph Designer", "fonts/boundsTestFont.fnt")

    layer:addChild(label1)
    label1:setPosition(cc.p(s.width/2, s.height/2))
    return layer
end

function LabelBMFontBounds.draw()
    -- cc.size labelSize = label1:getContentSize()
    -- cc.size origin = cc.Director:getInstance():getWinSize()

    -- origin.width = origin.width / 2 - (labelSize.width / 2)
    -- origin.height = origin.height / 2 - (labelSize.height / 2)

    -- cc.p vertices[4]=

    --     cc.p(origin.width, origin.height),
    --     cc.p(labelSize.width + origin.width, origin.height),
    --     cc.p(labelSize.width + origin.width, labelSize.height + origin.height),
    --     cc.p(origin.width, labelSize.height + origin.height)
    -- end
    -- ccDrawPoly(vertices, 4, true)
end

--------------------------------------------------------------------
--
-- LabelTTFAlignment
--
--------------------------------------------------------------------
local LabelTTFAlignment = {}
function LabelTTFAlignment.create()
    local layer = cc.Layer:create()
    Helper.initWithLayer(layer)
    Helper.titleLabel:setString("LabelTTF alignment")
    Helper.subtitleLabel:setString("Tests alignment values")

    local s = cc.Director:getInstance():getWinSize()

    local ttf0 = cc.LabelTTF:create("Alignment 0\nnew line", "Helvetica", 12,
                                   cc.size(256, 32), cc.TEXT_ALIGNMENT_LEFT)
    ttf0:setPosition(cc.p(s.width/2,(s.height/6)*2))
    ttf0:setAnchorPoint(cc.p(0.5,0.5))
    layer:addChild(ttf0)

    local ttf1 = cc.LabelTTF:create("Alignment 1\nnew line", "Helvetica", 12,
                                   cc.size(245, 32), cc.TEXT_ALIGNMENT_CENTER)
    ttf1:setPosition(cc.p(s.width/2,(s.height/6)*3))
    ttf1:setAnchorPoint(cc.p(0.5,0.5))
    layer:addChild(ttf1)

    local ttf2 = cc.LabelTTF:create("Alignment 2\nnew line", "Helvetica", 12,
                                   cc.size(245, 32), cc.TEXT_ALIGNMENT_RIGHT)
    ttf2:setPosition(cc.p(s.width/2,(s.height/6)*4))
    ttf2:setAnchorPoint(cc.p(0.5,0.5))
    layer:addChild(ttf2)
    return layer
end

function LabelTest()
    cclog("LabelTest")
    m_time = 0
    local scene = cc.Scene:create()

    Helper.createFunctionTable = {
        LabelAtlasTest.create,
        LabelAtlasColorTest.create,
        Atlas3.create,
        Atlas4.create,
        Atlas5.create,
        Atlas6.create,
        AtlasBitmapColor.create,
        AtlasFastBitmap.create,
        BitmapFontMultiLine.create,
        LabelsEmpty.create,
        LabelBMFontHD.create,
        LabelAtlasHD.create,
        LabelGlyphDesigner.create,
        --	  Atlas1,
        LabelTTFTest.create,
        LabelTTFMultiline.create,
        LabelTTFChinese.create,
        LabelBMFontChinese.create,
        BitmapFontMultiLineAlignment.create,
        LabelTTFA8Test.create,
        BMFontOneAtlas.create,
        BMFontUnicode.create,
        BMFontInit.create,
        TTFFontInit.create,
        Issue1343.create,
        LabelTTFAlignment.create,
        LabelBMFontBounds.create
    }
    scene:addChild(LabelAtlasTest.create())
    scene:addChild(CreateBackMenuItem())
    return scene
end


text: module.exports = require('./index.common');