#include "levels.h"
#include "timer.h"

// Level Type One (Levels 1,3,5,7)

Level_TypeOne::Level_TypeOne(int speed) : Level()
{
    dir = 2;
    disty = 0;
    distx = 0;
    y_speed = speed;
}

Level_TypeOne::~Level_TypeOne()
{
}

void Level_TypeOne::Move()
{
    switch(stage)
    {
	case 1:
	    AddX(2);
	    break;
	default:
	    distx++;
	    if(distx > 0 && distx <= 300) AddX(2);
	    if(distx > 300 && distx <= 500);
	    if(distx > 500 && distx <= 600) AddX(4);
	    if(distx > 600) distx = 0;
	    break;
    }

    if(frame_count%y_speed == 0) { AddY(dir); disty++; }
    if(disty >= 90) { dir = -dir; disty = 0; }

    XWrap();
    YWrap();
}

void Level_TypeOne::Generate()
{
    for(int i=0; i<3; ++i)
     {
	 for(int j=0; j<5; ++j)
	 {
	     Anim a;
	     a = base;
	     a.SetX((j*134)+32 - SCREEN_W);
	     a.SetY((i*36));

	     if(i == 1)   a.SetX(a.X() - 67);

	     group.push_back(a);
	 }
     }
}

void Level_TypeOne::Reset(int stage)
{
    Level::Reset(stage);

    group.clear();
    Generate();

    dir = 2;
    disty = 0;

    SetPoints( (stage == 1) ? Points() : 4000);
}

void Level_TypeOne::ResetPos()
{
    Level::ResetPos();

    if(group.size() > 0)
    {
	for(int i=0; i<3; ++i)
	{
	     for(int j=0; j<5; ++j)
	     { 
		 group[j + (i*5)].SetX((j*134)+32 - SCREEN_W);
		 group[j + (i*5)].SetY((i*36));

		 if(i == 1)   group[j + (i*5)].SetX(group[j + (i*5)].X() - 67);
	     }
	} 
    }

    disty = 0;
    distx = 0; 
}

const Level_TypeOne &Level_TypeOne::operator=(const Level_TypeOne &src)
{
    if(this != &src)
    {
	Level::operator=(src);
	dir = src.dir;
	disty = src.disty;
	y_speed = src.y_speed;
    }

    return *this;
}

// Level Type Two (Levels 2,4)

Level_TypeTwo::Level_TypeTwo() : Level()
{
    dir = 2;
    disty = 0;
    distx = 0;
}

Level_TypeTwo::~Level_TypeTwo()
{
}

void Level_TypeTwo::XWrap()
{
//    EnemyGroup::XWrap();
    for(unsigned int i=0; i<group.size(); ++i)
    {
	if(group[i].X() > SCREEN_W + group[i].W())
	{
	    group[i].SetX(-group[i].W());
	}
    }

    for(unsigned int i=0; i<group.size(); ++i)
    {
	if(group[i].X() < -group[i].W())
	{
	    group[i].SetX(SCREEN_W + group[i].W());
	}
    }
}

void Level_TypeTwo::Move()
{
    switch(stage)
    {
	case 1:
	    if(disty > 0 && disty < 20) AddY(2);
	    if(disty > 40 && disty < 60) AddY(2);
	    break;
	default:
	    AddY(stage);
	    break;
    }

    distx++;
    disty++;
    if(distx > 300)
    {
	dir = -dir;
	disty = 0;
	distx = 0;
    }
    AddX(dir);

    XWrap();
    YWrap();
}

void Level_TypeTwo::Generate()
{
    for(int i=0; i<6; ++i)
     {
	 for(int j=0; j<3; ++j)
	 {
	     Anim a;
	     a = base;
	     a.SetX((j*100) + (i * 100));
	     a.SetY((i*60) - SCREEN_H + 150);

	     group.push_back(a);
	 }
     }
     XWrap();
}

void Level_TypeTwo::Reset(int stage)
{
    Level::Reset(stage);

    group.clear();
    Generate();

    dir = 2;
    disty = 0;
    distx = 0;

    SetPoints( (stage == 1) ? Points() : 4000);
}

void Level_TypeTwo::ResetPos()
{
    if(group.size() > 0)
    {
       for(int i=0; i<6; ++i)
	{
	    for(int j=0; j<3; ++j)
	    {
		group[j + (3*i)].SetX((j*100) + (i * 100));
		group[j + (3*i)].SetY((i*60) - SCREEN_H + 150);
	    }
	}
    }
    XWrap();
}

const Level_TypeTwo &Level_TypeTwo::operator=(const Level_TypeTwo &src)
{
    if(this != &src)
    {
	Level::operator=(src);
	dir = src.dir;
	disty = src.disty;
	distx = src.distx;
    }

    return *this;
}
