#include "game.hpp"

game::game()
{
	_world = loadDisk("../data/battleflight.disk");
    _arwing = fly(loadShell("../data/arwing.shell"));
    _arwing.setPos(point(0,-1,0));

    _cam.setRadius(15);
	_thirdPerson = true;

    _bulletModel = loadShell("../data/bullet.shell");

    tank t = tank(loadShell("../data/tank.shell"));
    t.setPos(point(2,0,2));
    _enemy.push_back(t);
}

void game::update()
{
        //reinitialiser l'arriere plan
        _bg = color(0,0,0);

		//bouger l'avion avec sa detection de collision
		if(_world.gettingOutOfTheWorld(_arwing.getShell(), _arwing.getDir()*_arwing.speed()))
		{
            //_arwing.loop();
            _arwing.turnLeft(pi/10);
		}
        if(_world.willCollide(_arwing.getShell(), _arwing.getDir()*-0.1))
            _bg = color(128, 0, 0);
		_arwing.forward(_arwing.speed());

        _cam.addShell(_arwing.getShell());

        if(_thirdPerson)
        {
            _cam.moveTo(point(0,0.3,2).rotY(_arwing.getRadY()) - _arwing.getPos());
            _cam.turnY(-_arwing.getRadY());
            _cam.turnX(0);
        }
        else
        {
            _cam.moveTo(point(0,6,0)-_arwing.getPos());
            _cam.turnX(pi/2);
            _cam.turnY(0);
        }
        //render bullet
        for(list<bullet>::iterator it= _bulletList.begin(); it!=_bulletList.end(); it=it->next())
        {
            if(_world.willCollide(it->data().getShell(),point()) ||
               _world.gettingBelowTheFloor(it->data().getShell(),point()) ||
               _world.gettingOverTheTop(it->data().getShell(), point()) ||
               _world.gettingOutOfTheWorld(it->data().getShell(), point()))
                it->data().setExpire(0);

            if(_arwing.getShell().collide(it->data().getShell()))
            {
                _bg = color(255, 255, 0);
                it->data().setExpire(0);
            }

            if(it->data().update())
                _cam.addShell(it->data().getShell());
            else
                it = it->remove();
        }
        //render world
		for (int i=0;i<_world.size();i++)
		{
            shell tmp(_world.get(i));
            _cam.addShell(tmp);
		}
		//render enemy
		for (int i=0;i<_enemy.size();i++)
		{
		    if(_enemy[i].watch(_arwing))
		    {
		        _bulletList.push_back(_enemy[i].shoot(_arwing,_bulletModel));
		    }
		    _cam.addShell(_enemy[i].getShell());
		}
}

void game::left()
{
    _arwing.turnLeft(pi/200);
}

void game::right()
{
	_arwing.turnRight(pi/200);
}

void game::down()
{
    if (!_world.gettingOverTheTop(_arwing.getShell(), point(0,-0.015,0)))
        _arwing.climb(0.015);
}

void game::up()
{
    if (!_world.gettingBelowTheFloor(_arwing.getShell(), point(0,0.015,0)))
        _arwing.descent(0.015);
}

void game::space()
{
//    if ((++_bulletSlower%=20)==0)
    if(_arwing.cool())
        _bulletList.push_back(_arwing.shoot(_bulletModel));
}

void game::shift()
{
    if(_arwing.cool())
        _arwing.boost(0);
}


const color& game::getBg()
{
    return _bg;
}

bool game::thereIsLineToDraw()
{
    return !_cam.bufferEmpty();
}

const camera::draw game::nextLineToDraw()
{
    camera::draw tmp = _cam.currentLine();
    _cam.unmountBuffer();
    return tmp;
}
