# include "Car.h"

Car::Car()
: m_bodyCar( 0x0 ), m_bodyWheelFwd( 0x0 ), m_bodyWheelBack( 0x0 ),
m_motorAxe( 0x0 ), m_fwdAxe( 0x0 ),
m_imgCar( 0x0 ), m_imgWheel( 0x0 ),
m_cmd( FREE ),
m_currentTorque( 0.0f ), m_currentSpeed( 0.0f ),
m_goTorque( 0.7f ), m_minTorque( 0.0025f ), m_maxSpeed( 60.0f )
{
	// Constructeur
	m_currentTorque = m_minTorque ;
	m_currentSpeed = 0.0f ;
}

Car::~Car()
{
	if ( !m_imgCar )
		SDL_FreeSurface( m_imgCar );

	if ( !m_imgWheel )
		SDL_FreeSurface( m_imgWheel );
}

void Car::init( b2World &world, float32 x, float32 y, float32 angle )
{
	// Images
	m_imgCar = SDL_LoadBMP("Truck.bmp");
    m_imgWheel = SDL_LoadBMP("Wheel.bmp");

    SDL_SetColorKey( m_imgCar, SDL_SRCCOLORKEY, SDL_MapRGBA( m_imgCar->format, 0, 0, 0, 255 ) );
    SDL_SetColorKey( m_imgWheel, SDL_SRCCOLORKEY, SDL_MapRGBA( m_imgWheel->format, 0, 0, 0, 255 ) );

    // Dimensions
    float32 wtruck, htruck, rwheel;
    wtruck = (float32)m_imgCar->w / MULTI / 2 ;
    htruck = (float32)m_imgCar->h / MULTI / 2 ;
    rwheel = (float32)m_imgWheel->h / MULTI / 2 ;

    // Définition body
    b2BodyDef bodyDef;
    b2PolygonShape dynamicBox;
    b2FixtureDef fixtureDef;
    bodyDef.type = b2_dynamicBody;

	// Roue arrière
	bodyDef.userData = m_imgWheel ;
    bodyDef.position.Set( x - wtruck + rwheel, y + htruck + rwheel );

    b2CircleShape dynamicCircle;
    dynamicCircle.m_radius = rwheel ;

    fixtureDef.shape = &dynamicCircle;
    fixtureDef.density = 0.24f;
    fixtureDef.friction = 15.0f;

    m_bodyWheelBack = world.CreateBody(&bodyDef);
    m_bodyWheelBack->CreateFixture(&fixtureDef);

    // Roue avant
    bodyDef.position.Set( x + wtruck - rwheel, y + htruck + rwheel );

    dynamicCircle.m_radius = rwheel ;

    fixtureDef.shape = &dynamicCircle;
    fixtureDef.density = 0.24f;
    fixtureDef.friction = 15.0f;

    m_bodyWheelFwd = world.CreateBody(&bodyDef);
    m_bodyWheelFwd->CreateFixture(&fixtureDef);

    // Carrosserie
    bodyDef.userData = m_imgCar ;
    bodyDef.position.Set( x, y );

    dynamicBox.SetAsBox( wtruck, htruck );

    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.2f;

	m_bodyCar = world.CreateBody( &bodyDef );
	m_bodyCar->CreateFixture( &fixtureDef );

    // Création pivot avant
    b2RevoluteJointDef myJointDef;
    myJointDef.collideConnected = false ;

    myJointDef.Initialize( m_bodyWheelFwd, m_bodyCar, m_bodyWheelFwd->GetPosition() );

    m_fwdAxe = (b2RevoluteJoint*)world.CreateJoint(&myJointDef);

    // Création pivot arrière
    myJointDef.collideConnected = false ;

    myJointDef.Initialize( m_bodyWheelBack, m_bodyCar, m_bodyWheelBack->GetPosition() );

    myJointDef.maxMotorTorque = 0.05f;
    myJointDef.motorSpeed = 0.0f;
    myJointDef.enableMotor = true;

    m_motorAxe = (b2RevoluteJoint*)world.CreateJoint(&myJointDef);

    // Fin
    return ;
}

void Car::drive( command cmd )
{
	m_cmd = cmd ;
}

void Car::update()
{
	// Update state
	if ( m_cmd == FREE )
	{
		m_currentSpeed = 0.0f ;
		m_currentTorque = m_minTorque ;
	}

	else if ( m_cmd == BREAK )
	{
		m_currentSpeed = 0.0f ;
		m_currentTorque = m_goTorque ;
	}

	else if ( m_cmd == GO )
	{
		m_currentSpeed = -m_maxSpeed ;
		m_currentTorque = m_goTorque ;
	}

	else if ( m_cmd == REVERSE )
	{
		m_currentSpeed = m_maxSpeed ;
		m_currentTorque = m_goTorque ;
	}

	// Update motor
	m_motorAxe->SetMotorSpeed( m_currentSpeed );
    m_motorAxe->SetMaxMotorTorque( m_currentTorque );
}

b2Vec2 Car::GetPosition()
{
	return m_bodyCar->GetPosition();
}