#include "disk.hpp"

//constructeur
disk::disk()
{
    _radius = 15;
    _floor = 0;
    _ceil = -7;
}

//ajouter un model
void disk::addShell(const shell& s)
{
    _collection.push_back(s);
}

//placer une copie de model
void disk::placeShell(int i, const point& p)
{
    assert(i<_collection.size());
    _world.push_back(_collection[i]);
    _world.back().add(p);
}

//modifier une copie de model dejà placé
void disk::set(int i, const shell& s)
{
    assert(i<_world.size());
    _world[i] = s;
}

//modifier la taille du monde
void disk::setRadius(float r)
{
    _radius = r;
}

//modifier la hauteur du plancher
void disk::setFloor(float h)
{
    _floor = h;
}

//modifier la hauteur du plafond
void disk::setCeil(float h)
{
    _ceil = h;
}

void disk::scale(float scalar)
{
    for (int i=0;i<_world.size();i++)
        _world[i].setCenter(_world[i].getCenter()*scalar);
    _floor *= scalar;
    _ceil *= scalar;
    _radius *= scalar;
}

//obtenir une copie de modele déja placé
const shell& disk::get(int i)const
{
    assert(i<_world.size());
    return _world[i];
}

//obtenir le nombre de copie de model placé
int disk::size()const
{
    return _world.size();
}

//obtenir un model dans la collection
const shell& disk::model(int i)const
{
    assert(i<_collection.size());
    return _collection[i];
}

//obtenir le nombre de model different
int disk::numModel()const
{
    return _collection.size();
}

float disk::getRadius()const
{
    return _radius;
}

//detection de collision
//les piece d'un meme monde
bool disk::worldWillCollide(int i,const point& mov)const
{
    assert(i<_world.size());
    shell tmp = _world[i];
    tmp.add(mov);
    for (int j=0;j<_world.size();j++)
        if (i!=j && _world[j].collide(tmp))
            return true;
    return false;
}

//piece exterieur et le monde
bool disk::willCollide(const shell& spr ,const point& dir)const
{
    shell tmp = spr;
    tmp.add(dir);
    for (int j=0;j<_world.size();j++)
        if (_world[j].collide(tmp))
            return true;
    return false;
}

//piece qui sort du monde
bool disk::gettingOutOfTheWorld(const shell& spr,const point& dir)const
{
    shell tmp = spr;
    tmp.add(dir);
    return tmp.getCenter().magSQ() > _radius*_radius;
}

//piece qui traverse le planché
bool disk::gettingBelowTheFloor(const shell& spr,const point& dir)const
{
    shell tmp = spr;
    tmp.add(dir);
    return tmp.getCenter().getY() > _floor;
}

//piece qui dépasse la hauteur maximale
bool disk::gettingOverTheTop(const shell& spr,const point& dir)const
{
    shell tmp = spr;
    tmp.add(dir);
    return tmp.getCenter().getY() < _ceil;
}
