/*
 * KartPhysicsComponent.cpp
 *
 *  Created on: Aug 19, 2020
 *      Author: fredrick
 */

#include "KartPhysicsComponent.h"

namespace JamSpook {

KartPhysicsComponent::KartPhysicsComponent(mat4 transform,
                                           shared_ptr<BroadcastObservable<shared_ptr<Message> > > entity,
                                           weak_ptr<BroadcastObservable<const milliseconds> > physicsSystem,
                                           weak_ptr<BroadcastObservable<shared_ptr<CollisionStateChangeMessage> > > physicsCollisionSubSystem,
                                           weak_ptr<BroadcastObservable<shared_ptr<ColliderQueryMessage> > > physicsColliderQuerySubSystem,
                                           shared_ptr<Collider> collider):
        PhysicsComponent(transform,
                         entity,
                         physicsSystem,
                         physicsCollisionSubSystem,
                         physicsColliderQuerySubSystem,
                         collider)
{}

KartPhysicsComponent::~KartPhysicsComponent()
{}

void KartPhysicsComponent::update(const milliseconds dtms)
{
//    Log::write(LogLevel::trace, "CollectablePhysicsComponent - update");
    PhysicsComponent::update(dtms);

    if (getPosition().y < -100.0f)
    {
    	setPosition(vec3(getFloatInRange(-10.0f, 10.0f),
                		 10, /// above the ball
						 getFloatInRange(-10.0f, 10.0f)));
    }

    if (glm::length(mDirection) > 0)
    {
        // Forward or backwards force
        mCollider->applyForce(mat3(mTransform) * vec3(0, 0, mDirection.z * 500),
                              vec3(0, 0, 0));

        // Turning torque

    }
}

void KartPhysicsComponent::onICCMessage(shared_ptr<Message> message)
{
    PhysicsComponent::onICCMessage(message);

    // DirectionChangeMessage
    if (message->getMessageType() == IDCache::get("DirectionChangeMessage"))
    {
        Log::write(LogLevel::debug, "KartPhysicsComponent - onICCMessage - DirectionChangeMessage - getNewDirection: " + glm::to_string(mDirection));

        shared_ptr<DirectionChangeMessage> msg = dynamic_pointer_cast<DirectionChangeMessage>(message);
        mDirection = msg->getNewDirection();
    }

    // Jump message, make the kart jump
    if (message->getMessageType() == IDCache::get("JumpMessage"))
    {
        Log::write(LogLevel::debug, "KartPhysicsComponent - onICCMessage - JumpMessage");

        // shared_ptr<JumpMessage> msg = dynamic_pointer_cast<JumpMessage>(message);
        // Does not use any data in message, skip casting, but leave code as reference

        mCollider->applyImpulse(vec3(0, 1000, 0), vec3(0, 0, 0));
    }
}

void KartPhysicsComponent::onCollision(const string& tag)
{
    if (tag == "goal")
    {
        ICCBroadcast(make_shared<Message>(IDCache::get("GroundCollisionMessage")));
    }
}

void KartPhysicsComponent::onSeparation(const string& tag)
{
    if (tag == "goal")
    {
        ICCBroadcast(make_shared<Message>(IDCache::get("GroundSeparationMessage")));
    }
}

} // namespace JamSpook
