#include "stdafx.h"

#include "Projectile.h"
#include "DxWrapper.h"
#include <math.h>
#include "ray.h"
#include "TimePilot.h"

// statics initialisieren:
const float Projectile::SCALE_FACTOR				= 0.5;
const float Projectile::CALIBRATION_ANGLE_X			= 0.0f;         // grund-rotation des models
const float Projectile::CALIBRATION_ANGLE_Y			= 0.0f;         // grund-rotation des models
const float Projectile::CALIBRATION_ANGLE_Z			= 0.0f;         // grund-rotation des models
const unsigned int Projectile::TIME_TO_LIVE			= 2500;			// the number of milliseconds the Projectile will stay active after firing
Model Projectile::s_Model = Model();           //als leeres Model initialisieren, geladen wird später

Projectile::Projectile(void)
{
    Initialize();    
}

Projectile::Projectile(LPCTSTR file, LPCTSTR path, float calibrationAngleX, float calibrationAngleY, float calibrationAngleZ): GameObject3D(file, path, calibrationAngleX, calibrationAngleY, calibrationAngleZ)
{
    Initialize();
}

Projectile::Projectile(const Model &model) : GameObject3D(model)
{
    Initialize();
}


void Projectile::Initialize()
{
    GameObject3D::Initialize();
    m_Active = false;
    m_DamagePoints = 1;

    m_ScaleFactorX = Projectile::SCALE_FACTOR;
    m_ScaleFactorY = Projectile::SCALE_FACTOR;
    m_ScaleFactorZ = Projectile::SCALE_FACTOR;
    InitializeBoundingBoxByModel();
}


Projectile::~Projectile(void)
{
}


void Projectile::Cycle(float deltaMs)
{
    UpdatePosition(deltaMs);

    //std::cout << "lastPosition=" << m_LastPosition.x << ","  << m_LastPosition.y << "   m_Position=" << m_Position.x << "," << m_Position.y << std::endl; 
     
    CheckTimeToLive(deltaMs);

    /* 
    std::ostringstream s(std::ostringstream::out);
    s << " Mesh=" << model.Mesh << "   posX=" << this->posX << "   posY=" << this->posY << "   distanceTraveled=" << distanceTraveled << std::endl;
    DxWrapper::Instance()->WriteLog(s.str());
    */  
}

void Projectile::CheckTimeToLive(float deltaMs)
{
    timeTraveledMs += deltaMs;

    if (timeTraveledMs > timeToLive)
    {
        m_Active = false;        
    }
}

void Projectile::Fire( GameObject3D& shootingObj, float speed)
{
    this->m_pShootingObj = &shootingObj;
    this->m_Position.x = shootingObj.m_Position.x;
    this->m_Position.y = shootingObj.m_Position.y;
    this->m_Position.z = shootingObj.m_Position.z;
    this->m_RotX = shootingObj.m_RotX;
    this->m_RotY = shootingObj.m_RotY;
    this->m_RotZ = shootingObj.m_RotZ;
    this->m_Velocity.x = shootingObj.m_Velocity.x + (speed * sin(D3DXToRadian(shootingObj.m_RotZ)));
    this->m_Velocity.y = shootingObj.m_Velocity.y + (speed * cos(D3DXToRadian(shootingObj.m_RotZ)));
    this->m_Velocity.z = 0.0;
    this->timeTraveledMs = 0.0;
	this->timeToLive = Projectile::TIME_TO_LIVE;
    this->m_Active = true;
}

void Projectile::Destroy()
{
    m_Active = false;
}

/** returns the standard model of the projéctile
* forceLoad = true  erzwingt das erneute Laden des Modells, vielleicht nützlich nach einem lost d3d device.. funzt aber scheinbar nicht,
* die Modelle werden trotzdem nicht gerendert :/
*/
const Model& Projectile::GetStandardModel(bool forceLoad)
{
	DxWrapper::Instance()->LogWrite("Projectile::GetStandardModel()");
    if (!s_Model.Mesh || forceLoad)
    {
        DxWrapper::LoadModel(&s_Model, FILENAME_MODEL_PROJECTILE, FILEPATH_RESOURCES);
		s_Model.calibrationAngleX = Projectile::CALIBRATION_ANGLE_X;
        s_Model.calibrationAngleY = Projectile::CALIBRATION_ANGLE_Y;
        s_Model.calibrationAngleZ = Projectile::CALIBRATION_ANGLE_Z;
    }
    return s_Model;   
}