#include "common.h"
#include "includes.h"
#include "gamebasics.h"
#include "dat.h"

//-------------------------------------------------------------------------
// FUNÇÕES PRINCIPAIS
void gameloop(void);
void menu(void);
void pause(void);
void endgame(void);
void help(void);
double start_bg_x = 0;


int main(int argc, char **argv)
{
	if (!begin())
	{
		closing();
		return -1;
	}
	buffer = create_bitmap(MAX_X, MAX_Y);

    menu();
    Tiro::load();
    Explosao::load();
	gameloop();

	closing();
	return 0;

}
END_OF_MAIN()

void gameloop(void)
{
    DATAFILE *data;
    packfile_password("password");
    data = load_datafile("./dat1.dat");
    packfile_password(NULL);
    unsigned long long int vel_control = counter;
    unsigned long long int time_arraste;
    long double distance = 0;
    long double max_distance = 0;
	Nave nave("nave_branca.bmp", makecol(255,255,255),2), nave2("nave_preta.bmp",makecol(0,0,0),2);
	Bloco barra(makecol(0,0,0), new Ponto(0, MAX_Y/2 - 20), new Ponto(MAX_X, MAX_Y/2 + 20));
	nave2.setPonto(new Ponto(0 , MAX_Y-50));
	BITMAP *background = (BITMAP*) data[BACKGROUND_BMP].dat;//load_bitmap("background.bmp", NULL);
	BITMAP *heart = load_bitmap("heart.bmp", NULL);
	double tiro_x_1, tiro_y_1, tiro_x_2, tiro_y_2;
	double bg_x = 0;
	double arraste = 0.5;
    vector<Bloco *> blocos;
    vector<Explosao *> explosao;
    vector<Tiro *> deck1, deck2;
    bool morreu = false, acabou = false;

    for(register unsigned short int i = 0; i < 10; ++i) {
        clear(buffer);
        textprintf_centre_ex(buffer, font, MAX_X/2, MAX_Y/2, makecol(255,255,255), -1 , "Loading...");
        textprintf_centre_ex(buffer, font, MAX_X/2, MAX_Y/2 + 10, makecol(255,255,255), -1 , "Creating some random shit!");
        blit(buffer, screen, 0, 0, 0, 0, MAX_X, MAX_Y);
        Bloco *temp, *temp2, *temp3, *temp4;
        int y, y2, y3, y4;
        y = rand()%(MAX_Y/2 - 70);
        y3 = rand()%(MAX_Y/2 - 70);
        y2 = MAX_Y/2 + rand()%(MAX_Y - (MAX_Y/2 + 20) - 50);
        y4 = MAX_Y/2 + rand()%(MAX_Y - (MAX_Y/2 + 20) - 50);
        while(y + 50 > barra.getUpperY() || y3 + 50 > barra.getUpperY() || y2 < barra.getLowerY() || y4 < barra.getLowerY() || (!((y + 50 < y3) || (y > y3 + 50))) || (!((y2 + 50 < y4) || (y2 > y4 + 50)))) {
            y = rand()%(MAX_X/2 - 70);
            y3 = rand()%(MAX_X/2 - 70);
            y2 = MAX_Y/2 + rand()%(MAX_Y - (MAX_Y/2 + 20) - 50);
            y4 = MAX_Y/2 + rand()%(MAX_Y - (MAX_Y/2 + 20) - 50);
        }
        temp = new Bloco(makecol(255,255,255), new Ponto(200*i + 400,y), new Ponto(200*i + 420,y + 50));
        temp2 = new Bloco(makecol(0,0,0), new Ponto(200*i + 400,y3), new Ponto(200*i + 420,y3 + 50));
        temp3 = new Bloco(makecol(0,0,0), new Ponto(200*i + 400,y2), new Ponto(200*i + 420,y2 + 50));
        temp4 = new Bloco(makecol(255,255,255), new Ponto(200*i + 400,y4), new Ponto(200*i + 420,y4 + 50));
        blocos.push_back(temp);
        blocos.push_back(temp2);
        blocos.push_back(temp3);
        blocos.push_back(temp4);
        max_distance = 200*i + 400;
    }
    rest(1500);

    	// Looping do Jogo-------------------------------
	do
	{

		if (counter >= vel_control)
		{
            blit(background, buffer, 0, 0, (int)(1280-bg_x), 0, MAX_X, MAX_Y);
            blit(background, buffer, (int)bg_x, 0, 0, 0, MAX_X, MAX_Y);
            for(register unsigned short int i = 0; i < blocos.size(); ++i) {
                Bloco *b_ = blocos.at(i);
                rectfill(buffer, (int)b_->getUpperLeft()->getX(), (int)b_->getUpperLeft()->getY(), (int)b_->getLowerRight()->getX(), (int)b_->getLowerRight()->getY(), b_->getColor());
                rect(buffer, (int)b_->getUpperLeft()->getX(), (int)b_->getUpperLeft()->getY(), (int)b_->getLowerRight()->getX(), (int)b_->getLowerRight()->getY(), makecol(0,0,0));
                b_->desloca(arraste);
                if(b_->getRightX() < 0) blocos.erase(blocos.begin() + i);
            }
            rectfill(buffer, (int)barra.getLeftX(), (int)barra.getUpperY(), (int)barra.getRightX(), (int)barra.getLowerY(), barra.getColor());
            draw_sprite(buffer, nave.getImg(), (int)nave.getX(), (int)nave.getY());
            draw_sprite(buffer, nave2.getImg(), (int)nave2.getX(), (int)nave2.getY());
            for(register unsigned short int i = 0; i < Nave::getVidas(); ++i) {
                draw_sprite(buffer, heart, (int)(barra.getLeftX() + 15*(i+1)), (int)(barra.getUpperY() + 5));
            }
            textprintf_ex(buffer, font, (int)(barra.getLeftX() + 15), (int)(barra.getUpperY() + 30), makecol(255,255,255),-1,"Distance traveled: %Lg m.", distance);
            if(nave.morreu() || nave2.morreu()) {
                time_arraste = vel_control;
                arraste = 0;
                morreu = true;
            }
            if((vel_control - time_arraste > 10) && morreu) {
                arraste = 0.5;
                morreu = false;
            }
			nave.setX(nave.getX()-arraste);
			nave2.setX(nave2.getX()-arraste);
            if(key[KEY_LEFT] /*&& !nave.colidiu(b)*/) nave.setX(nave.getX()-nave.getVelocidade());
            if(key[KEY_RIGHT] /*&& !nave.colidiu(b)*/) nave.setX(nave.getX()+nave.getVelocidade());
            if(key[KEY_UP] /*&& !nave.colidiu(b)*/) nave.setY(nave.getY()-nave.getVelocidade());
            if(key[KEY_DOWN] /*&& !nave.colidiu(b)*/ && !nave.colidiu(barra)) nave.setY(nave.getY()+nave.getVelocidade());
			if(key[KEY_A]) nave2.setX(nave2.getX()-2);
			if(key[KEY_D]) nave2.setX(nave2.getX()+2);
			if(key[KEY_W] && !nave2.colidiu(barra)) nave2.setY(nave2.getY()-2);
			if(key[KEY_S]) nave2.setY(nave2.getY()+2);
			if(key[KEY_RSHIFT]) {
			    nave.atirar();
			    tiro_x_1 = nave.getX() + nave.getWidth();
			    tiro_y_1 = nave.getY() + nave.getHeight()/2;
			    nave.addTiro(tiro_x_1,tiro_y_1,3);
			}
			if(key[KEY_LSHIFT]) {
			    nave2.atirar();
			    tiro_x_2 = nave2.getX() + nave2.getWidth();
			    tiro_y_2 = nave2.getY() + nave2.getHeight()/2;
			    nave2.addTiro(tiro_x_2,tiro_y_2,3);
			}
			if(nave.getTiro()) {
			    nave.atira(buffer);
			}
			if(nave2.getTiro()) {
			    nave2.atira(buffer);
			}
			for(register unsigned short int i = 0; i < nave.getTiros().size(); ++i) {
			    deck1 = nave.getTiros();
			    for(register unsigned short int j = 0; j < blocos.size(); ++j) {
                    if(deck1.at(i)->colide(blocos.at(j))) {
                        nave.removeTiro(i);
                        if(blocos.at(j)->getColor() == nave.getCor()) {
                            Explosao *temp = new Explosao(new Ponto((blocos.at(j)->getLeftX() + blocos.at(j)->getRightX())/2,(blocos.at(j)->getUpperY() + blocos.at(j)->getLowerY())/2));
                            temp->setFrame(vel_control);
                            explosao.push_back(temp);
                            blocos.erase(blocos.begin() + j);
                        }
                    }
			    }
			}
			for(register unsigned short int i = 0; i < nave2.getTiros().size(); ++i) {
			    deck2 = nave2.getTiros();
			    for(register unsigned short int j = 0; j < blocos.size(); ++j) {
                    if(deck2.at(i)->colide(blocos.at(j))) {
                        nave2.removeTiro(i);
                        if(blocos.at(j)->getColor() == nave2.getCor()) {
                            Explosao *temp = new Explosao(new Ponto((blocos.at(j)->getLeftX() + blocos.at(j)->getRightX())/2,(blocos.at(j)->getUpperY() + blocos.at(j)->getLowerY())/2));
                            temp->setFrame(vel_control);
                            explosao.push_back(temp);
                            blocos.erase(blocos.begin() + j);
                        }
                    }
			    }
			}
			for(register unsigned short int i = 0; i < explosao.size(); ++i) {
                explosao.at(i)->desenha();
                if(vel_control - explosao.at(i)->getFrame() > 15) {
                    explosao.erase(explosao.begin() + i);
                }
			}
			bg_x += arraste;
			distance += 0.1;
			if(bg_x > background->w) bg_x = 0;
            if(!explosao.empty()) {
                cout << explosao.at(0)->getFrame() << endl;
            }
			vel_control = counter + 1;
			if(blocos.size() == 0) {
                arraste = 0;
                distance-= 0.1;
                acabou = true;
			}
            if(acabou) {
                nave.setX(nave.getX() + 2.5);
                nave2.setX(nave2.getX() + 2.5);
                textprintf_ex(buffer, font, (int)(barra.getLeftX() + 315), (int)(barra.getUpperY() + 30), makecol(255,255,255),-1,"Voce venceu! Aperte ESC para sair.");
            }
            vsync();
            blit(buffer, screen, 0, 0, 0, 0,MAX_X,MAX_Y);
            clear_to_color(buffer, makecol(255,255,255));
		}
		if (key[KEY_ESC])    break;
	}while(1);
}
END_OF_FUNCTION(gameloop);

void menu(void) {
    unsigned long long int vel_control = counter;
    BITMAP *bg = load_bitmap("menu_bg.bmp", NULL);
    BITMAP *title = load_bitmap("title5.bmp", NULL);
    do {
        if(counter >= vel_control) {
            blit(bg, buffer, 0, 0, (int)(bg->w-start_bg_x), 0, MAX_X, MAX_Y);
            blit(bg, buffer, (int)start_bg_x, 0, 0, 0, MAX_X, MAX_Y);
            draw_sprite(buffer, title, (MAX_X-title->w)/2, (MAX_Y-title->h)/2);
            textprintf_centre_ex(buffer, font, 320, 400, makecol(255,255,0), -1, "PRESS ENTER TO START");
            textprintf_centre_ex(buffer, font, 320, 420, makecol(255,255,0), -1, "PRESS H FOR HELP");
            textprintf_centre_ex(buffer, font, 320, 440, makecol(255,255,0), -1, "PRESS ESC TO QUIT");

            if(key[KEY_ENTER]) {
                return;
            }
            if(key[KEY_ESC]) {
                closing();
                exit(0);
            }
            if(key[KEY_H]) {
                help();
            }
            blit(buffer, screen, 0, 0, 0, 0, MAX_X, MAX_Y);
            clear(buffer);
            vel_control = counter + 1;
            if(start_bg_x > bg->w) start_bg_x = 0;
            start_bg_x += 0.5;
        }

    } while (1);
}
END_OF_FUNCTION(menu);

void help(void) {
    unsigned long long int vel_control = counter;
    BITMAP *bg = load_bitmap("menu_bg.bmp", NULL);
    //BITMAP *title = load_bitmap("title5.bmp", NULL);
    do {
        if(counter >= vel_control) {
            blit(bg, buffer, 0, 0, (int)(bg->w-start_bg_x), 0, MAX_X, MAX_Y);
            blit(bg, buffer, (int)start_bg_x, 0, 0, 0, MAX_X, MAX_Y);
            //draw_sprite(buffer, title, (MAX_X-title->w)/2, (MAX_Y-title->h)/2);
            textprintf_ex(buffer, font, 30, 30, makecol(255,100,100), -1, "Use as teclas W, A, S, D para controlar a nave negra");
            textprintf_ex(buffer, font, 30, 50, makecol(255,100,100), -1, "Use o Shift esquerdo para atirar com a nave negra");
            textprintf_ex(buffer, font, 30, 70, makecol(255,100,100), -1, "Use as setas direcionais para controlar a nave branca");
            textprintf_ex(buffer, font, 30, 90, makecol(255,100,100), -1, "Use o Shift direito para atirar com a nave branca");
            textprintf_centre_ex(buffer, font, 320, 300, makecol(0,0,0), -1, "PRESS BACKSPACE TO GO BACK TO THE MENU");
            textprintf_centre_ex(buffer, font, 320, 400, makecol(255,255,0), -1, "THIS IS THE HELP SCREEN");
            if(key[KEY_BACKSPACE]) {
                return;
            }
            if(key[KEY_ESC]) {
                closing();
                exit(0);
            }
            blit(buffer, screen, 0, 0, 0, 0, MAX_X, MAX_Y);
            clear(buffer);
            vel_control = counter + 1;
            if(start_bg_x > bg->w) start_bg_x = 0;
            start_bg_x += 0.5;
        }

    } while (1);
}
END_OF_FUNCTION(help);
