/** 
 * \file Sheep.cpp
 * \brief CSheep class member functions implementation. CSheep holds model's position and facing.
 * 
 * \author Petar Bajic, MPE (C) All Rights Reserved, Homepage: www.mystic-peanut.com
 * \date January, 16 2007.
 */

#include "Sheep.h"

#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )

/**
 * \brief Standard constructor.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
CSheep::CSheep()
{
	m_Model = NULL;
	m_MovingSound1 = NULL;
	m_MovingSound2 = NULL;
	m_DyingSound = NULL;
	m_Position = D3DXVECTOR3(0.0f,0.3f,0.0f);
	m_Facing = 0.0f;
	m_BeingCarriedAway = false;
	m_Alive = true;
	m_Moved = false;
}

/**
 * \brief Extended constructor. Takes preloaded skinned model to avoid multiple loading for many sheep.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
CSheep::CSheep(CXFileEntity* model)
{
	if (model != NULL)
	{
		m_Model = new CXFileEntity();
		//Clone Animation Controler
		HRESULT hr = model->m_animController->CloneAnimationController(
			model->m_animController->GetMaxNumAnimationOutputs(),
			model->m_animController->GetMaxNumAnimationSets(),
			model->m_animController->GetMaxNumTracks(),
			model->m_animController->GetMaxNumEvents(),
			&(m_Model->m_animController));
		m_Model->m_currentTime = 0;

		//Other parameters we just copy
		m_Model->m_boneMatrices = model->m_boneMatrices;
		m_Model->m_currentAnimationSet = model->m_currentAnimationSet;
		m_Model->m_currentTrack = model->m_currentTrack;
		m_Model->m_firstMesh = model->m_firstMesh;
		m_Model->m_frameRoot = model->m_frameRoot;
		m_Model->m_maxBones = model->m_maxBones;
		m_Model->m_numAnimationSets = model->m_numAnimationSets;
		m_Model->m_speedAdjust = model->m_speedAdjust;
		m_Model->m_sphereCentre = model->m_sphereCentre;
		m_Model->m_sphereRadius = model->m_sphereRadius;

	}
	else
	{
			m_Model = NULL;
	}

	m_MovingSound1 = NULL;
	m_MovingSound2 = NULL;
	m_DyingSound = NULL;
	m_Position = D3DXVECTOR3(0.0f,0.3f,0.0f);
	m_Facing = 0.0f;
	m_BeingCarriedAway = false;
	m_Moved = false;
}

/**
 * \brief Standard destructor.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
CSheep::~CSheep()
{
	if(m_Model != NULL)
		delete m_Model;
}

/**
 * \brief Init function loads skinned model (CXFileEntity) and sheep specific sounds.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
bool CSheep::Init(HWND hWnd, LPDIRECT3DDEVICE9 pd3dDevice, IDirectSound8* pDS)
{
	m_Model = new CXFileEntity(); // Create our entity class
	// Load an x file to start with
	WCHAR strFullPath[MAX_PATH];
	GetCurrentDirectory(MAX_PATH,strFullPath);
	StringCchCat(strFullPath, 255, L"//Media//Models//sheep.x");
	HRESULT hr = m_Model->LoadXFile(pd3dDevice,strFullPath);
	if (FAILED(hr))
	{
		MessageBox(hWnd,L"Could not load Media/Models/sheep.x file",L"Error",MB_OK);
		return false;
	}
	//Init Sounds
	m_MovingSound1 = new CSound();
	if (!m_MovingSound1->Init(pDS, L"Media/Sounds/sheep_move_1.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_move_1.wav file",L"Error",MB_OK);
		return false;
	}
	m_MovingSound2 = new CSound();
	if (!m_MovingSound2->Init(pDS, L"Media/Sounds/sheep_move_2.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_move_2.wav file",L"Error",MB_OK);
		return false;
	}
	m_DyingSound = new CSound();
	if (!m_DyingSound->Init(pDS, L"Media/Sounds/sheep_die.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_die.wav file",L"Error",MB_OK);
		return false;
	}
	return true;
}

/**
 * \brief Create sounds for dwarf instance.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
bool CSheep::InitSounds(HWND hWnd, IDirectSound8* pDS)
{
	//Init Sounds
	m_MovingSound1 = new CSound();
	if (!m_MovingSound1->Init(pDS, L"Media/Sounds/sheep_move_1.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_move_1.wav file",L"Error",MB_OK);
		return false;
	}
	m_MovingSound2 = new CSound();
	if (!m_MovingSound2->Init(pDS, L"Media/Sounds/sheep_move_2.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_move_2.wav file",L"Error",MB_OK);
		return false;
	}
	m_DyingSound = new CSound();
	if (!m_DyingSound->Init(pDS, L"Media/Sounds/sheep_die.wav"))
	{
		MessageBox(hWnd,L"Could not load Media/Sounds/sheep_die.wav file",L"Error",MB_OK);
		return false;
	}
	return true;
}

/**
 * \brief Move animated model.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
void CSheep::OnFrameMove(LPDIRECT3DDEVICE9 pd3dDevice, float fElapsedTime, D3DXMATRIXA16* matWorld)
{
	if(m_Alive)
		m_Model->OnFrameMove(pd3dDevice, fElapsedTime, matWorld);
}

/**
 * \brief Render skinned model.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
void CSheep::OnRender(LPDIRECT3DDEVICE9 pd3dDevice)
{
	if(m_Alive)
		m_Model->Render(pd3dDevice);
}

/**
 * \brief Restart sheep (position, facing, etc..)
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
void CSheep::Restart()
{
	m_Position = D3DXVECTOR3(0.0f,0.3f,0.0f);
	m_Facing = 0.0f;
}

/**
 * \brief Play sound when pushing sheep.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
void CSheep::PlaySoundMove()
{
	int random_sound = (rand() % 2);// 0 to 2;
	if(random_sound > 0)
	{
		//m_MovingSound1->Stop();
		//m_MovingSound1->Reset();
		m_MovingSound1->Play();
	}
	else
	{
		//m_MovingSound2->Stop();
		//m_MovingSound2->Reset();
		m_MovingSound2->Play();
	}
}

/**
 * \brief Play sound when sheep dies.
 * \author Petar Bajic 
 * \date January, 16 2007.
 */
void CSheep::PlaySoundDeath()
{
	m_DyingSound->Stop();
	m_DyingSound->Reset();
	m_DyingSound->Play();
}