/*=========================================================================
File Name:		COPYPASTE.CPP
Purpose:
	Implements tdoCopyBuffer, tdoPasteSubMaterialModif and tdoInstanciateSubMaterialModif classes

Author:			Benoit Germain
Date:			June 1997
==========================================================================*/
#include "stdafx.h"
#include "Acp_Base.h"
#include "itf.h"
#include "gmt.h"

#include "GMatObj.hpp"
#include "CopyPaste.hpp"
#include "inctex.h"
#include "_interf.hpp"
#include "diameca.hpp"
#include "diacol.hpp"
#include "diasound.hpp"

extern Material_Interface *gs_p_oMaterialInterface;

/*=========================================================================
implementation of tdoCopyBuffer
==========================================================================*/

void tdoCopyBuffer::m_vInvalidateAllHandlesAtConstruct()
{
	m_eType = E_cbt_None;

	DNM_fn_vInvalidateMatCharacteristics(&m_hMechanicsMaterialToPaste);
	m_hCollideMaterialToPaste = GMT_C_InvalidCollideMaterial;
	m_hSoundMaterialToPaste = GMT_C_InvalidSoundMaterial;
}

/*=========================================================================
==========================================================================*/
tdoCopyBuffer::tdoCopyBuffer(DNM_tdxHandleToMecMatCharacteristics _hMechanicsMaterial)
{
	m_vInvalidateAllHandlesAtConstruct();

	m_eType = E_cbt_Mechanics;

	//create a copy of the material for paste operations
	m_hMechanicsMaterialToPaste = DNM_fn_xMatCharacteristicsCreate();
	if ( DNM_fn_bIsMatCharacteristicsValid(_hMechanicsMaterial) )
		DNM_fn_vMatCharacteristicsCopy(m_hMechanicsMaterialToPaste, _hMechanicsMaterial);
}

tdoCopyBuffer::tdoCopyBuffer(GMT_tdxHandleToCollideMaterial _hCollideMaterial)
{
	m_vInvalidateAllHandlesAtConstruct();

	m_eType = E_cbt_Collide;

	//create a copy of the material for paste operations
	m_hCollideMaterialToPaste = GMT_fn_hCreateCollideMaterial();
	if ( _hCollideMaterial != GMT_C_InvalidCollideMaterial )
		GMT_fn_vCopyCollideMaterial(m_hCollideMaterialToPaste, _hCollideMaterial);
}

tdoCopyBuffer::tdoCopyBuffer(SND_tdxHandleToSoundMaterial _hSoundMaterial)
{
	m_vInvalidateAllHandlesAtConstruct();

	m_eType = E_cbt_Sound;

	//create a copy of the material for paste operations
	m_hSoundMaterialToPaste = _hSoundMaterial;
}

/*=========================================================================
==========================================================================*/
tdoCopyBuffer::~tdoCopyBuffer()
{
	//destroy the buffers we created for copy

	//mechanics
	if ( DNM_fn_bIsMatCharacteristicsValid(m_hMechanicsMaterialToPaste) )
	{
		DNM_fn_vMatCharacteristicsDestroy(m_hMechanicsMaterialToPaste);
		DNM_fn_vInvalidateMatCharacteristics(&m_hMechanicsMaterialToPaste);
	}

	//collide
	if ( m_hCollideMaterialToPaste != GMT_C_InvalidCollideMaterial )
	{
		GMT_fn_vDestroyCollideMaterial(&m_hCollideMaterialToPaste);
	}

	//sound
	m_hSoundMaterialToPaste = GMT_C_InvalidSoundMaterial;
}

/*=========================================================================
==========================================================================*/
BOOL tdoCopyBuffer::m_bDoPaste(
	GMT_tdxHandleToGameMaterial _hTargetGameMaterial
)
{
	switch ( m_eType )
	{
	case E_cbt_Mechanics:
		{
			//get the mechanics material of the target game material																													
			DNM_tdxHandleToMecMatCharacteristics hTargetMechanicsMaterial;
			hTargetMechanicsMaterial = GMT_fn_hGetMechanicsMaterial(_hTargetGameMaterial);
			//and copy the contents of the source
			DNM_fn_vMatCharacteristicsCopy(hTargetMechanicsMaterial, m_hMechanicsMaterialToPaste);
		}
		break;

	case E_cbt_Collide:
		{
			//get the collide material of the target game material																													
			GMT_tdxHandleToCollideMaterial hTargetCollideMaterial;
			hTargetCollideMaterial = GMT_fn_hGetCollideMaterial(_hTargetGameMaterial);
			//and copy the contents of the source
			GMT_fn_vCopyCollideMaterial(hTargetCollideMaterial, m_hCollideMaterialToPaste);
		}
		break;

	case E_cbt_Sound:
		GMT_fn_vSetSoundMaterial(_hTargetGameMaterial, m_hSoundMaterialToPaste);
		break;

	default:
		ASSERT(FALSE);
		return FALSE;
	}
	return TRUE;
}

/*=========================================================================
==========================================================================*/
/*=========================================================================
implementation of tdoPasteSubMaterialModif class
==========================================================================*/
/*=========================================================================
==========================================================================*/

tdoPasteSubMaterialModif::tdoPasteSubMaterialModif(tdoCopyBuffer *_p_oCopyBuffer)
: CPA_Modif(0, "")
{
	m_hTargetGameMaterial = gs_p_oMaterialInterface->m_p_oGetEditedMaterial()->m_hGetEngineMaterial();
	m_p_oCopyBufferForDo = _p_oCopyBuffer;

	switch ( _p_oCopyBuffer->m_eGetType() )
	{
	case E_cbt_Mechanics:
		{
			//create a copy buffer which contains the submaterial info of the target material
			DNM_tdxHandleToMecMatCharacteristics hTargetMechanicsMaterial;
			hTargetMechanicsMaterial = GMT_fn_hGetMechanicsMaterial(m_hTargetGameMaterial);
			m_p_oCopyBufferForUndo = new tdoCopyBuffer(hTargetMechanicsMaterial);
			SetName("Mechanics Material Paste");
		}
		break;

	case E_cbt_Collide:
		{
			//create a copy buffer which contains the submaterial info of the target material
			GMT_tdxHandleToCollideMaterial hTargetCollideMaterial;
			hTargetCollideMaterial = GMT_fn_hGetCollideMaterial(m_hTargetGameMaterial);
			m_p_oCopyBufferForUndo = new tdoCopyBuffer(hTargetCollideMaterial);
			SetName("Collide Material Paste");
		}
		break;

	case E_cbt_Sound:
		{
			//create a copy buffer which contains the submaterial info of the target material
			SND_tdxHandleToSoundMaterial hTargetSoundMaterial;
			hTargetSoundMaterial = GMT_fn_hGetSoundMaterial(m_hTargetGameMaterial);
			m_p_oCopyBufferForUndo = new tdoCopyBuffer(hTargetSoundMaterial);
			SetName("Sound Material Paste");
		}
		break;
	default:
		ASSERT(FALSE);
		break;
	}
}

/*=========================================================================
==========================================================================*/
tdoPasteSubMaterialModif::~tdoPasteSubMaterialModif()
{
	delete m_p_oCopyBufferForUndo;
	//do not delete the Do() buffer if we are not done, because the dialog
	//may use it again...
	if ( HasBeenDone() )
		delete m_p_oCopyBufferForDo;
}

/*=========================================================================
==========================================================================*/
BOOL tdoPasteSubMaterialModif::Do()
{
	if ( m_p_oCopyBufferForDo->m_bDoPaste(m_hTargetGameMaterial) )
	{
		tdoEditorGameMaterial *p_oTargetGameMaterial = (tdoEditorGameMaterial *) 
		gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(m_hTargetGameMaterial);
		//if the edited material is the submaterial's owner game material, update display
		switch ( m_p_oCopyBufferForDo->m_eGetType() )
		{
		case E_cbt_Mechanics:
			gs_p_oMaterialInterface->m_p_oGetMecaView()->m_p_oCopyBuffer = NULL;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetMecaView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			//tell the editor object responsible for the submaterial that it has to be saved
			DNM_tdxHandleToMecMatCharacteristics hTargetMechanicsMaterial;
			hTargetMechanicsMaterial = GMT_fn_hGetMechanicsMaterial(m_hTargetGameMaterial);
			gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hTargetMechanicsMaterial)->fn_vNotifySave();
			break;

		case E_cbt_Collide:
			gs_p_oMaterialInterface->m_p_oGetCollView()->m_p_oCopyBuffer = NULL;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetCollView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			//tell the editor object responsible for the submaterial that it has to be saved
			GMT_tdxHandleToCollideMaterial hTargetCollideMaterial;
			hTargetCollideMaterial = GMT_fn_hGetCollideMaterial(m_hTargetGameMaterial);
			gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hTargetCollideMaterial)->fn_vNotifySave();
			break;

		case E_cbt_Sound:
			gs_p_oMaterialInterface->m_p_oGetSoundView()->m_p_oCopyBuffer = NULL;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetSoundView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			//tell the editor object responsible for the submaterial that it has to be saved
			//SND_tdxHandleToSoundMaterial hTargetSoundMaterial; //until sound materials need an editor object...
			//hTargetSoundMaterial = GMT_fn_hGetSoundMaterial(m_hTargetGameMaterial);
			//gs_p_oMaterialInterface->m_p_oGetEditorSoundMaterialForEngine(hTargetsoundMaterial)->fn_vNotifySave();
			break;

		default:
			ASSERT(FALSE);
			return FALSE;
		}
	}
	return TRUE;
}

/*=========================================================================
==========================================================================*/
BOOL tdoPasteSubMaterialModif::Undo()
{
	if ( m_p_oCopyBufferForUndo->m_bDoPaste(m_hTargetGameMaterial) )
	{
		tdoEditorGameMaterial *p_oTargetGameMaterial = (tdoEditorGameMaterial *) 
			gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(m_hTargetGameMaterial);
		//if the edited material is the submaterial's owner game material, update display
		//note that the paste operation already marked the materials for save, so it is not necessary
		//to notify the change again
		switch ( m_p_oCopyBufferForDo->m_eGetType() )
		{
		case E_cbt_Mechanics:
			gs_p_oMaterialInterface->m_p_oGetMecaView()->m_p_oCopyBuffer = m_p_oCopyBufferForDo;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetMecaView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			break;

		case E_cbt_Collide:
			gs_p_oMaterialInterface->m_p_oGetCollView()->m_p_oCopyBuffer = m_p_oCopyBufferForDo;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetCollView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			break;

		case E_cbt_Sound:
			gs_p_oMaterialInterface->m_p_oGetSoundView()->m_p_oCopyBuffer = m_p_oCopyBufferForDo;
			if ( gs_p_oMaterialInterface->m_p_oGetEditedMaterial() == p_oTargetGameMaterial )
				gs_p_oMaterialInterface->m_p_oGetSoundView()->m_fn_vShowMaterial(m_hTargetGameMaterial);
			break;

		default:
			ASSERT(FALSE);
			return FALSE;
		}
	}
	return FALSE;
}
