#ifndef COLL_DETECT_HPP
#define COLL_DETECT_HPP

#include "collision_body.hpp"

#include "types.hpp"
#include <vector>

class Collision_body;

// evil globals - set these to tweak the collision detection
extern bool coll_detect_use_one_coll_per_edge_for_body;

// provide some functions for managing collision detection

struct Collision_info
{
  Collision_info() {}
  Collision_info(Collision_body * body0, Collision_body * body1,
                 const Vector3 & dir_to_0, const Position & position,
                 Scalar penetration_depth) : 
      body0(body0), body1(body1),
      dir_to_0(dir_to_0),
      position(position), penetration_depth(penetration_depth) {}

  // body 0 is alsways set
  Collision_body * body0;
  // body 1 may be zero, if it's a body-terrain collision
  Collision_body * body1;

  // normalised direction in world space pointing towards body 0 from the other body/terrain
  Vector3 dir_to_0;

  //==============================================================
  // The following properties may get modified when this collision
  // info is updated.
  //==============================================================
  // collision point, in world space (i.e. sensible place to apply a restoring force)
  Position position;

  // depth of the penetration. Can be -ve, indicating penetration isn't happening
  Scalar penetration_depth;

  /// Set/Used by Physics in process/preprocess_collision
  Position R0; // position relative to body 0 (in world space)
  Position R1; // position relative to body 1 (if there is a body1)
  Scalar vr_extra; // extra speed (in dir_to_0) for restoring deviation
  Scalar elasticity;
  Scalar static_friction;
  Scalar dynamic_friction;
  Scalar denominator;
};

/// detects all collisions between active bodies and other active/frozen bodies. 
/// Appends the result to collisions.
/// brute force approach for now ;-)
void detect_all_collisions(const std::vector<Collision_body *> & collision_bodies,
                           std::vector<Collision_info> & collisions);

/// detects all collisions between a single bodies and other frozen/immovable bodies.
/// Appends the result to collisions.
/// brute force approach for now ;-)
/// collision_body should not be in collision_bodies
void detect_frozen_collisions_with_body(Collision_body * collision_body,
                                        const std::vector<Collision_body *> & collision_bodies,
                                        std::vector<Collision_info> & collisions);

#endif
