//
// Tools_Entity_Glass_Object.cpp
//
// Created by Andrew Weinkove - 18/07/2002
// 
// Copyright (C) 2002 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Tools_Entity_Glass_Object.h"

#include "Debugging/Asura_Assert.h"
#include "Interface/Asura_Dialog.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Camera/Asura_Camera.h"
#include "Interface/Asura_Overlay.h"
#include "SpecialFX/Asura_Shard_System.h"
#include "Core/Asura_TextureManagement.h"

#include "Entity/Asura_Entity.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Entity/Glass/Asura_ServerEntity_Glass.h"
#include "Entity/Glass/Asura_ClientEntity_Glass.h"
#include "Entity/Glass/Asura_Entity_Glass_Messages.h"
#include "SpecialFX/Asura_SFX_GlassSmash.h"

#include "Core/Asura_HashedList.h"

#include "Entity/Tools_Entity_Data.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Objects/Tools_WorldSpaceRectangle_Object.h"
#include "Objects/Tools_Object_System.h"
#include "Misc/Tools_Timed_Messages.h"
#include "Texturing/Tools_PickTexture.h"


/////////////////////////
// Static data members //
/////////////////////////
const char* const Tools_Entity_Glass_Object::s_szLongName  = "Glass";
const char* const Tools_Entity_Glass_Object::s_szShortName = "Glass";

Tools_Entity_Glass_Object *Tools_Entity_Glass_Object::s_pxThisObjectForTesting = NULL;

Asura_Hashed_List<Tools_Entity_Glass_Object> Tools_Entity_Glass_Object::s_xList;


///////////////////////////////
// Tools_Entity_Glass_Object //
///////////////////////////////

/// DWE - 01/08/2003 15:23:24 - Because I've fixed the creation of the client side glass to be made by message
/// You can no longer pass the pointer to client glass, but I'm sending the create (client update) msg in this
/// function so the pointer is correctly set.
Tools_Entity_Glass_Object::Tools_Entity_Glass_Object(Asura_ServerEntity_Glass* pxGlassServer, Asura_ClientEntity_Glass* pxGlassClient)
: Tools_Entity_PhysicalObject(NULL) // ignored
, m_pxGlassServer(pxGlassServer)
, m_pxGlassClient(pxGlassClient)
, m_fTopLeftU(0.0f)
, m_fTopLeftV(0.0f)
, m_fBottomRightU(1.0f)
, m_fBottomRightV(1.0f)
, m_fTestSmashForce(0.5f)
, m_fTestSmashXCoord(0.5f)
, m_fTestSmashYCoord(0.5f)
, m_fTestBlastForce(0.5f)
, m_bBlastPaneDirection(true)
{
	Asura_Assert(pxGlassServer && pxGlassServer->GetClassification() == AsuraEntityClass_Glass,"Not glass");

	// Tools object data.
	Type = TOT_Entity_Glass;

	Asura_String xMeshName("ToolsShape_CutsceneTrackPoint");
	Mesh = Asura_Mesh_System::GetMesh(xMeshName);

	
	if (m_pxGlassServer)
	{
		Position    = m_pxGlassServer->m_xPane.CalculateCentre();
		Orientation = m_pxGlassServer->m_xPane.Orientation;

		m_fTopLeftU     = m_pxGlassServer->m_afU[0];
		m_fTopLeftV     = m_pxGlassServer->m_afV[0];
		m_fBottomRightU = m_pxGlassServer->m_afU[3];
		m_fBottomRightV = m_pxGlassServer->m_afV[3];

		m_xToolsColour.m_fA = float(0x000000ff & (m_pxGlassServer->m_uColour >> 24)) / 255.0f;
		m_xToolsColour.m_fR   = float(0x000000ff & (m_pxGlassServer->m_uColour >> 16)) / 255.0f;
		m_xToolsColour.m_fG = float(0x000000ff & (m_pxGlassServer->m_uColour >> 8)) / 255.0f;
		m_xToolsColour.m_fB  = float(0x000000ff & (m_pxGlassServer->m_uColour)) / 255.0f;
	
		m_bUseTextureAsEnvironmentMap = m_pxGlassServer->m_bUseEnvironmentMap;
		// Create the pane object
		char szPaneName[200];
		sprintf(szPaneName,"%s - Pane", GetName());
		new Tools_WorldSpaceRectangle_Object(szPaneName, &m_pxGlassServer->m_xPane, &m_pxPaneObject);

		Asura_Assert(m_pxPaneObject, "");
		if (m_pxPaneObject)
		{
			m_pxPaneObject->SetObjectToPosition(this);
		}

		m_bIsDestructible = m_pxGlassServer->IsDestructible();
		m_fHealth = m_pxGlassServer->GetHealth();
	}
	
	if(!m_pxGlassClient)
	{
		m_pxGlassServer->MakeClientUpdateMessage();

		m_pxGlassClient = Asura_ClientEntity_Glass::FindEntity(m_pxGlassServer->GetGuid());
	}

	s_xList.AddToList(this);

}

Tools_Entity_Glass_Object::~Tools_Entity_Glass_Object()
{
	s_xList.RemoveFromList(this);

	if (m_pxPaneObject)
	{
		Tools_Object_System::DeleteObject(m_pxPaneObject);
	}
	if (s_pxThisObjectForTesting == this)
	{
		s_pxThisObjectForTesting = NULL;
	}
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CreationHelper: Helper function to add a new physical object in tools.
//
// pfnCreateServer : Fn ptr, creates server object (eg <Project>_ServerEntity_Glass)
// pfnCreateClient : Fn ptr, creates server object (eg <Project>_ClientEntity_Glass)
// pfnCreateTools  : Fn ptr, creates tools object from server object (eg Tools<Project>_Entity_Glass)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tools_Entity_Glass_Object::CreationHelper( Asura_ServerEntity_Glass* (*pfnCreateServer)(Asura_Guid),
												Asura_ClientEntity_Glass* (*pfnCreateClient)(void),
												Tools_Object* (*pfnCreateTools)(Asura_Entity* pxEntity),
												const Asura_Vector_3& xCornerPosition, 
												const Asura_Matrix_3x3& xOrientation, 
												const Asura_Vector_2& xEdgeLengths)
{
	// Get a new GUID
	Asura_Guid uGuid = Asura_Entity_System::GetCreatedByToolsGuid();

	// Set up tools data and auto-create a unique name (prompt for new name if there is a clash).
	Tools_Entity_Data* pxToolsData = CreateToolsDataWithDefaultName(s_szLongName, s_szShortName, uGuid, GetNamePrefix());
	if (!pxToolsData) return; // give up

	// Create the game specfic server object and set its data.
	Asura_ServerEntity_Glass* pxServerObject = pfnCreateServer(uGuid);

	Asura_Assert(pxServerObject,"");
	if (pxServerObject)
	{
		pxServerObject->ToolsData = pxToolsData;
		pxServerObject->SetOrientation(xOrientation);
		pxServerObject->SetCornerPosition(xCornerPosition);
		pxServerObject->CopyOrientationToPane();
		pxServerObject->m_xPane.Dimensions = xEdgeLengths;
	}


	// Create the client side object too.
	Asura_Entity_System::SetNextClientGuid(uGuid);
	Asura_ClientEntity_Glass* pxClientObject= pfnCreateClient();

	Asura_Assert(pxClientObject,"");
	if (pxClientObject)
	{
		pxClientObject->m_xPane.Orientation = xOrientation;
		pxClientObject->m_xPane.CornerPosition = xCornerPosition;
		pxClientObject->m_xPane.Dimensions = xEdgeLengths;
	}

	// Move tools position to centre of pane.
	pxToolsData->Position = pxClientObject->m_xPane.CalculateCentre();

	// Create the game specific tools object and select it.
	Tools_Object* pxToolsObject = pfnCreateTools(pxServerObject);
	Tools_Object_System::SelectObject(pxToolsObject);
}




void Tools_Entity_Glass_Object::EditWorldSpaceRectangle()
{
	Asura_Assert(s_pxThisObjectForTesting && s_pxThisObjectForTesting->m_pxPaneObject,"");
	if (s_pxThisObjectForTesting && s_pxThisObjectForTesting->m_pxPaneObject)
	{
		s_pxThisObjectForTesting->m_pxPaneObject->SetObjectToPosition(s_pxThisObjectForTesting);
		//select and move to the volume object
		Tools_Object_System::GotoAndSelect(s_pxThisObjectForTesting->m_pxPaneObject);
	}
}


void Tools_Entity_Glass_Object::ChooseTexture()
{
	Asura_Assert(s_pxThisObjectForTesting,"");
	if (s_pxThisObjectForTesting)
	{
		int iNewTexture = Tools_PickTexture::PickTexture(0,ASURA_TEXTURE_NONE,PICKTEXTURE_ALLTEXTURES);

		if (iNewTexture != ASURA_TEXTURE_NONE)
		{
			const Asura_String *pxTextureName = Asura_Texture_Management::GetTextureName(iNewTexture);
			
			if (s_pxThisObjectForTesting->m_pxGlassServer)
			{
				s_pxThisObjectForTesting->m_pxGlassServer->m_xTextureName = *pxTextureName;
			}

			if (s_pxThisObjectForTesting->m_pxGlassClient)
			{
				s_pxThisObjectForTesting->m_pxGlassClient->m_iTextureIndex = iNewTexture;
			}
		}
	}
}


void Tools_Entity_Glass_Object::RemoveTexture()
{
	Asura_Assert(s_pxThisObjectForTesting,"");
	if (s_pxThisObjectForTesting)
	{
		if (s_pxThisObjectForTesting->m_pxGlassServer)
		{
			s_pxThisObjectForTesting->m_pxGlassServer->m_xTextureName.MakeBlank();
		}

		if (s_pxThisObjectForTesting->m_pxGlassClient)
		{
			s_pxThisObjectForTesting->m_pxGlassClient->m_iTextureIndex = ASURA_TEXTURE_NONE;
		}
	}
}



bool Tools_Entity_Glass_Object::CanRemoveTexture()
{
	if (s_pxThisObjectForTesting && s_pxThisObjectForTesting->m_pxGlassServer)
	{
		return !s_pxThisObjectForTesting->m_pxGlassServer->m_xTextureName.IsBlank();
	}

	return false;
}




void Tools_Entity_Glass_Object::OnSelection()
{
    PARENT::OnSelection();
    s_pxThisObjectForTesting = this;
}

void Tools_Entity_Glass_Object::OnDeselection()
{
    PARENT::OnDeselection();
    s_pxThisObjectForTesting = NULL;
}

void Tools_Entity_Glass_Object::UpdateWhileSelected()
{
	if (Changed)
	{
		UpdatePositionInAsuraData(false);
	}

	PARENT::UpdateWhileSelected();
	Asura_Shard_System::Update();

	if(m_pxGlassServer)
	{
		m_pxGlassServer->SetDestructible( m_bIsDestructible );
		m_pxGlassServer->SetHealth(m_fHealth);
	}
}


void Tools_Entity_Glass_Object::UpdatePositionInAsuraData(bool)
{
	Asura_Assert(m_pxPaneObject && m_pxPaneObject->Pane, "");
	Asura_Assert(m_pxGlassServer && m_pxGlassClient, "");

	if (m_pxGlassServer)
	{
		m_pxGlassServer->m_uColour = m_xToolsColour.ToUIntARGB();
		m_pxGlassServer->m_xPane = *m_pxPaneObject->Pane;
		m_pxGlassServer->m_bUseEnvironmentMap = m_bUseTextureAsEnvironmentMap;

		// Need to update dynamics block too.
		m_pxGlassServer->SetCornerPosition(m_pxGlassServer->m_xPane.CornerPosition);
		m_pxGlassServer->SetOrientation(m_pxGlassServer->m_xPane.Orientation);

		Changed = true; // Make sure we prompt for saving when we exit the mode.

		if (m_pxGlassServer->ToolsData)
		{
			// May as well make sure toolsdata position gets updated
			m_pxGlassServer->ToolsData->Position = m_pxGlassServer->m_xPane.CalculateCentre();
		}
	}

	if (m_pxGlassClient)
	{
		m_pxGlassClient->m_uColour = m_xToolsColour.ToUIntARGB();
		m_pxGlassClient->m_xPane = *m_pxPaneObject->Pane;
		m_pxGlassClient->m_bUseEnvironmentMap = m_bUseTextureAsEnvironmentMap;
	}

	if (m_pxGlassServer && m_pxGlassClient)
	{
		for (int i=0;i<4;i++)
		{
			if (i % 2)
			{
				m_pxGlassClient->m_afU[i] = m_pxGlassServer->m_afU[i] = m_fBottomRightU;
			}
			else
			{
				m_pxGlassClient->m_afU[i] = m_pxGlassServer->m_afU[i] = m_fTopLeftU;
			}

			if (i < 2)
			{
				m_pxGlassClient->m_afV[i] = m_pxGlassServer->m_afV[i] = m_fTopLeftV;
			}
			else
			{
				m_pxGlassClient->m_afV[i] = m_pxGlassServer->m_afV[i] = m_fBottomRightV;
			}
		}
	}
}

bool Tools_Entity_Glass_Object::HandlesThisMessage(int messageID)
{
    switch (messageID)
    {
    case ASURA_MSG_GLASS_SMASH:
        // handled if we have an animation and a skin
        return true;
    default:
        return false;
    }
	
}



void Tools_Entity_Glass_Object::Render()
{
	PARENT::Render();
	if (IsSelected())
	{
		Asura_Shard_System::Render();
	}
	RenderGlass();
}

Asura_String Tools_Entity_Glass_Object::GetTextureNameForExport()
{
	Asura_Assert(m_pxGlassServer, "Expected this not to be NULL");
	return m_pxGlassServer->m_xTextureName;
}



void Tools_Entity_Glass_Object::RenderGlass()
{
	// Render the client entity..
	Asura_Assert(m_pxGlassClient, "");
	if (m_pxGlassClient)
	{
		m_pxGlassClient->Render();
	}
}


void Tools_Entity_Glass_Object::AddOverlayControls(Asura_Overlay* pxNewOverlay, Asura_Vector_2& xOffset)
{
	Tools_Entity_Object::AddOverlayControls(pxNewOverlay, xOffset);
	Asura_Dialog* pxNewDialog;

	pxNewDialog = new Asura_Function_Dialog("Edit glass pane (E)", xOffset, EditWorldSpaceRectangle);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Tickbox_Dialog("Use texture as environment map", xOffset, &m_bUseTextureAsEnvironmentMap, &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Function_Dialog("Choose texture", xOffset, ChooseTexture);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Function_Dialog("Remove texture", xOffset, RemoveTexture, 0, CanRemoveTexture);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Top left - U", xOffset, &m_fTopLeftU, -7.5f, 7.5f, 0.1f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Top left - V", xOffset, &m_fTopLeftV, -7.5f, 7.5f, 0.1f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Bottom Right - U", xOffset, &m_fBottomRightU, -7.5f, 7.5f, 0.1f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Bottom Right - V", xOffset, &m_fBottomRightV, -7.5f, 7.5f, 0.1f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Red", xOffset, &m_xToolsColour.m_fR, 0.0f, 1.0f, 0.001f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Green", xOffset, &m_xToolsColour.m_fG, 0.0f, 1.0f, 0.001f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Blue", xOffset, &m_xToolsColour.m_fB, 0.0f, 1.0f, 0.001f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Alpha", xOffset, &m_xToolsColour.m_fA, 0.0f, 1.0f, 0.001f, "%.3f", &Changed);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;
	
	pxNewDialog = new Asura_Function_Dialog("------------------------------", xOffset, DoNothing);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Test Smash - X Coord", xOffset, &m_fTestSmashXCoord, 0, 1, 0.01f, "%.01f");
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog("Test Smash - Y Coord", xOffset, &m_fTestSmashYCoord, 0, 1, 0.01f, "%.01f");
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;
	
	pxNewDialog = new Asura_Numerical_Dialog("Test Smash - Force", xOffset, &m_fTestSmashForce, 0, 1, 0.01f, "%.01f");
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Function_Dialog("Smash pane at position", xOffset, SmashPaneAtPosition, 0, CanTestCurrentGlass);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;
	
	pxNewDialog = new Asura_Numerical_Dialog("Test Blast - Force", xOffset, &m_fTestBlastForce, 0, 1, 0.01f, "%.01f");
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Tickbox_Dialog("Test Blast - Direction", xOffset, &m_bBlastPaneDirection);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Function_Dialog("Blast pane", xOffset, BlastPane, 0, CanTestCurrentGlass);
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Dialog( "------------------------------", xOffset );
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Numerical_Dialog( "Health", xOffset, &m_fHealth, 0.0f, 999.9f, 0.1f, "%3.1f" );
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;

	pxNewDialog = new Asura_Tickbox_Dialog("Destructible", xOffset, &m_bIsDestructible );
	pxNewOverlay->AddDialog(pxNewDialog);
	xOffset.y += 1.5f;
}


void Tools_Entity_Glass_Object::SmashPaneAtPosition()
{
	Asura_Assert(s_pxThisObjectForTesting, "");
	Asura_Assert(s_pxThisObjectForTesting->m_pxGlassClient, "");
	
	if (s_pxThisObjectForTesting && s_pxThisObjectForTesting->m_pxGlassClient)
	{
		Asura_Vector_2 Coordinates(s_pxThisObjectForTesting->m_fTestSmashXCoord, s_pxThisObjectForTesting->m_fTestSmashYCoord);

		const Asura_Euler_3 * pxOri = Asura_Camera::GetOriEuler();
		Asura_Vector_3 xVec(0.0f, 0.0f, 0.0f);
		xVec.x += Asura_Maths::Sine(pxOri->y);
		xVec.z += Asura_Maths::Cosine(pxOri->y);
		xVec.y += Asura_Maths::Sine(pxOri->x);
		xVec.Normalise();
		Asura_SFX_GlassSmash::Create(*s_pxThisObjectForTesting->m_pxGlassClient, s_pxThisObjectForTesting->m_fTestSmashForce, Coordinates, xVec);
	}
}



void Tools_Entity_Glass_Object::BlastPane()
{
	Asura_Assert(s_pxThisObjectForTesting, "");
	Asura_Assert(s_pxThisObjectForTesting->m_pxGlassClient, "");

	if (s_pxThisObjectForTesting && s_pxThisObjectForTesting->m_pxGlassClient)
	{
		Asura_SFX_GlassSmash::Create(*s_pxThisObjectForTesting->m_pxGlassClient, s_pxThisObjectForTesting->m_fTestBlastForce, s_pxThisObjectForTesting->m_bBlastPaneDirection);
	}
}


bool Tools_Entity_Glass_Object::CanTestCurrentGlass()
{
	if (!s_pxThisObjectForTesting) return false;
	if (!s_pxThisObjectForTesting->m_pxGlassClient)	return false;
	if (!s_pxThisObjectForTesting->m_pxPaneObject) return false;
	if (!s_pxThisObjectForTesting->m_pxPaneObject->Pane) return false;
	
	if (s_pxThisObjectForTesting->m_pxPaneObject->Pane->Dimensions.x == 0.0f ||
		s_pxThisObjectForTesting->m_pxPaneObject->Pane->Dimensions.y == 0.0f)
	{
		return false;
	}

	return true;
}

void Tools_Entity_Glass_Object::Copy(const Tools_Object* pxObject)
{
	//get the glass object pointer of the object being copied from
	const Tools_Entity_Glass_Object* pxFromObject = s_xList.FindEntity(pxObject->GetGuid());
	if(!pxFromObject) return;

	//get the entities to copy from and to
	const Asura_ServerEntity_Glass* pxFromServer = pxFromObject->m_pxGlassServer;
	Asura_ServerEntity_Glass* pxToServer = m_pxGlassServer;

	const Asura_ClientEntity_Glass* pxFromClient = pxFromObject->m_pxGlassClient;
	Asura_ClientEntity_Glass* pxToClient = m_pxGlassClient;

	//copy between server entities
	if(Tools_Object_System::GetCopyType() == TOOLS_COPYOBJECT_DUPLICATE)
	{
		pxToServer->m_xPane = pxFromServer->m_xPane;
		pxToServer->m_xCollisionPane = pxFromServer->m_xCollisionPane;
	}
	for(int i=0;i<4;i++)
	{
		pxToServer->m_afU[i] = pxFromServer->m_afU[i];
		pxToServer->m_afV[i] = pxFromServer->m_afV[i];
	}
	pxToServer->m_uColour = pxFromServer->m_uColour;
	pxToServer->m_xTextureName = pxFromServer->m_xTextureName;
	pxToServer->m_uGlassFlags = pxFromServer->m_uGlassFlags;


	//copy between client entities
	if(Tools_Object_System::GetCopyType() == TOOLS_COPYOBJECT_DUPLICATE)
	{
		pxToClient->m_xPane = pxFromClient->m_xPane;
	}
	for(int i=0;i<4;i++)
	{
		pxToClient->m_afU[i] = pxFromClient->m_afU[i];
		pxToClient->m_afV[i] = pxFromClient->m_afV[i];
	}
	pxToClient->m_uColour = pxFromClient->m_uColour;
	pxToClient->m_iTextureIndex = pxFromClient->m_iTextureIndex;

	pxToClient->m_xBB = pxFromClient->m_xBB;
	pxToClient->m_xCentre = pxFromClient->m_xCentre;
	pxToClient->m_fRadius = pxFromClient->m_fRadius;
	pxToClient->m_iLastKnownModule = pxFromClient->m_iLastKnownModule;


	//copy between tools objects
	m_xToolsColour = pxFromObject->m_xToolsColour;
	m_bUseTextureAsEnvironmentMap = pxFromObject->m_bUseTextureAsEnvironmentMap;
	m_fTopLeftU = pxFromObject->m_fTopLeftU;
	m_fTopLeftV = pxFromObject->m_fTopLeftV;
	m_fBottomRightU = pxFromObject->m_fBottomRightU;
	m_fBottomRightV = pxFromObject->m_fBottomRightV;
	m_bIsDestructible = pxFromObject->m_bIsDestructible;
	m_fHealth = pxFromObject->m_fHealth;

	if(Tools_Object_System::GetCopyType() == TOOLS_COPYOBJECT_DUPLICATE)
	{
		if (m_pxPaneObject && pxFromObject->m_pxPaneObject)
		{
			m_pxPaneObject->Position = pxFromObject->m_pxPaneObject->Position;
			m_pxPaneObject->Orientation = pxFromObject->m_pxPaneObject->Orientation;
			m_pxPaneObject->SetObjectToPosition(this);
		}
	}

	//Need to set the mesh again , since it will have changed as a result of the parent copying
	Mesh = Asura_Mesh_System::GetMesh("ToolsShape_CutsceneTrackPoint");


}

Tools_Object* Tools_Entity_Glass_Object::CreateObjectOfThisType() const
{

	Tools_Object* pxOldSelection = Tools_Object_System::SelectedObject;
	Tools_Entity_Glass_Object::Project_Create(*Asura_Camera::GetPosition(), *Asura_Camera::GetOrientation(), Asura_Vector_2(1.0f, 1.0f));
	Tools_Object* pxNewSelection = Tools_Object_System::SelectedObject;


	return (pxOldSelection!=pxNewSelection) ? pxNewSelection : 0;
	
}
