#include "snake.h"

bodypart null_part(100, 100);

body::body(int _length)
{
    // assume length > 0 && length <= MAX_LENGTH

    alive = 1;
    
    length = _length;
    head = 0;
    tail = 0;

    dir = 0;
    speed = DEFAULT_SPEED;
    
    for (int i = tail; i <= head; i++)
    {
	snake[i] = null_part;
    }
}

void body::crash()
{
    alive = 0;

    // for each bodypart add a 'dead_part' bonus to the bonus list
    for (int i = tail; i < head; i++)
    {
	add_bonus(get(i));
    }
}

int body::cut(int index)
{
    int ret;
    int i;
    
    // for each bodypart add a 'dead_part' bonus to the bonus list
    for (i = tail; i < index - 2; i++)
    {
	add_bonus(get(i));
    }

    ret = index - tail + 2;
    
    tail = i;
    length = head - tail + 1;

    return ret;
}

bodypart &body::operator[](int index)
{
    return get(index);
}

// this function gets UNMODIFIED indices!
bodypart &body::get(int index)
{
    return snake[index % MAX_LENGTH];
}

void body::set_dir(int _dir)
{
    dir = _dir;

    while (dir < 0)       // don't trust % behaviour on negative numbers
	dir += 360;
    
    dir = dir % 360;
}

void body::turn(int angle)
{
    dir += angle;

    while (dir < 0)       // don't trust % behaviour on negative numbers
	dir += 360;

    dir = dir % 360;
}

double body::cosinus(int deg)
{
    double rad;

    rad = deg * 2 * M_PI;
    rad /= 360.0;

    return cos(rad);
}

double body::sinus(int deg)
{
    double rad;

    rad = deg * 2 * M_PI;
    rad /= 360.0;

    return sin(rad);
}

bodypart body::calc_new_pos()
{
    bodypart bp;

    // top and bottom are switched : a right turn has to stay
    // a right turn so mirror the y component

    bp.x = (int)(get(head).x + speed * cosinus(dir));
    bp.y = (int)(get(head).y - speed * sinus(dir));

    return bp;
}

void body::move(bodypart const &other, int burrow)
{
    // check if our length is larger than head - tail + 1
    // if so, we need to grow, and we just move the head
    // if not, we also move the tail.

    if (length == head - tail + 1)
    {
	// move the tail
	tail++;
    }

    head++;
    get(head).x = other.x;
    get(head).y = other.y;
    get(head).burrow = burrow;
}

void body::init_pos(int _x, int _y, int _angle)
{
    get(head).x = _x;
    get(head).y = _y;
    dir = _angle;
}
