#ifndef _HPP_KUNGFLOW_CHARACTER
#define _HPP_KUNGFLOW_CHARACTER

#include "gaia/gaia.hpp"
using namespace gaia;

#include "../stageentity.hpp"

class KungFlowGame;
class PlayState;
class HumanGamer;
class PlayState;
class Stage;
//class StageEntity;
class CharacterModelView;
class CharacterController;

class Character;

// for distance sort
struct CharacterProximity {
  Character *character;
  float distance;
  bool operator < (const CharacterProximity &comp) const {
    return distance < comp.distance;
  }
};

class Character : public StageEntity {

  public:

    //Character(const KungFlowGame *game, const PlayState *playState, const HumanGamer *humanGamer, int teamID, const Vector2 &position);
    Character(const KungFlowGame *game, const PlayState *playState, e_Team team, const Vector2 &position);
    virtual ~Character();

    //virtual void GetSpriteBounds(Vector2 &center, Vector2 &radius) const override;
    virtual void OnCollide(const StageEntity* entity) override;
    virtual void OnStepPhysicsTime() override;
    virtual void PostStepPhysicsTime() override;
    virtual void Draw(const Viewport &viewport, const Camera &camera) const override;

    virtual Vector2 GetPosition() const override;
    virtual void SetPosition(const Vector2 &newPosition) override;
    void SetQueuedPosition(const Vector2 &newPosition);
    virtual float GetZPosition() const override;
    virtual void SetZPosition(float newZPosition) override;
    void SetQueuedZPosition(float newZPosition);
    virtual Vector2 GetMovement() const override;
    virtual void SetMovement(const Vector2 &newMovement) override;
    void SetQueuedMovement(const Vector2 &newMovement);
    virtual float GetZMovement() const override;
    virtual void SetZMovement(float newZMovement) override;
    void SetQueuedZMovement(float newZMovement);

    virtual float GetWeight() const override { return GetTeam() == e_Team_GoodGuys ? 1.0f : 0.5f; } // todo: use stats
    virtual float GetRadius() const override;
    virtual float GetHeight() const override;

    void SetControllerOwnership(CharacterController *controller); // NOTICE! this object TAKES OVER RESPONSIBILITY OF THE CONTROLLER LIFETIME! (yes, I do realize that's considered bad practice :))
    CharacterController *GetController() const;
    const CharacterController *GetController_const() const;
    CharacterModelView *GetModelView() const;
    const CharacterModelView *GetModelView_const() const;

    void GetSlavePosition(Vector2 &position_ret, float &zPosition_ret) const;
    //void SetSlaveEntity(StageEntity *entity) const { this->slaveEntity = entity; }
    //StageEntity *GetSlaveEntity() const { return slaveEntity; }

  protected:

    const KungFlowGame *game;
    const PlayState *playState;

    CharacterController *controller;
    CharacterModelView *modelView;

    // the mutability of this object is questionable; though the slave object is not a part of this object, the 'holding it' action is.
    // a better solution might be to have a seperate class for the connection between master/slave objects, or to have the playstate force
    // the release of slave objects.
    // *update: indeed, moved to stage as a connection link 'table'
    //mutable StageEntity *slaveEntity; // if the character is holding anything

};

#endif
