/* DEL133TS  É USAR EGABGI By TC II (Tempo Carlos II)
 * Isto é do TEMPO dos afonsinhos!
 *
 *
 *  */
#include<stdio.h>
#include<time.h>
#include<graphics.h> /* this lib is ugly and does not work */
#include<dos.h>
#include<conio.h>
#include<stdlib.h>
#define TamanhoBike 100
#define WINDOWS 1
float octave[7] = { 130.81, 146.83, 164.81, 174.61, 196, 220, 246.94 };
/* Criar matriz com a junção de quatro COORDENADAS
 * 
 */
int msg=70; /* coordenada da mensagem */
int veri;
int walls[1][2];
int raios=0;
int verify(int *x, int *y);
int incremento(int *x, int *y);
int incrementox(int *x);
int incrementoy(int *y, int u); /* u 1 = subir, u 0 = descer */
int Thick = NORM_WIDTH, Style = SOLID_LINE;
void wait (int seconds );
int cenario(int *y);
int bike(int *x, int *y, int scale);
#ifdef NIX
gint
main (void)
{
#else
int main (void)
{
#endif
        void *Bike;
        int gd = DETECT, gm, maxx, x,y;
        int key; /* g33z! DuDe! 0x100 in NIX r00LS! */
        int finish=0; /* fsck. FECHAR?! BREKA CICLOS? */
        int Tamanho; /* DE QUE?  */
        int adn;
        int lost=0;
        y=0;
        x=100;
        gm=VGAMED; /* this is 133talhada VGA! */
#ifdef NIX
        initgraph(&gd, &gm, NULL);
#else
        initgraph(&gd, &gm, "c:\\tc\\bgi");
#endif
        /* DEMO ASCII CODE */
        while(!lost)
        {
        setbkcolor(0);
      adn=random(7);
#ifdef SOUNDWORKS
      while(!kbhit()){
        sound(octave[adn]*10);
      delay(190);
        }

#endif
        bike(&x, &y, 5);
        outtextxy((getmaxx()/2)-20,(getmaxy()/2)-100,"Para Jogar prima qualquer tecla ");

        /* Inicio a interfa */
        getch();
        cleardevice();
        setbkcolor(0);

        maxx = getmaxx();
        x=0;
        y=250;
        setcolor(4);

        setfillstyle(1,YELLOW);

        outtextxy(20, 20, " FreeRider Game - dev by kOp");
        outtextxy(20,40, "This game run over 16 colors ");
        outtextxy(20, 60, "W = ANDAR RAPIDO");
        outtextxy(20, 80, "E = ANDAR PARA CIMA E PARA A FRENTE RAPIDO");
        outtextxy(20, 100, "H = ANDAR PARA BAIXO E PARA A FRENTE RAPIDO");
        outtextxy(20, 120, "Q = QUIT ");
        rectangle(10, 30, getmaxx()/2+50, getmaxy()/2-40);
        arc(10,30, 0, 90, 50);
        setfillstyle(1,YELLOW);
        cenario(&y);
        fflush(stdin);
        bike(&x,&y,1);
        Tamanho = imagesize(x, y, x+TamanhoBike, y + TamanhoBike);
        Bike = malloc(Tamanho);
        getimage(x, y, x+TamanhoBike, y+TamanhoBike, Bike);
        finish=0;
        while (!finish)
        {
                key=0;
                fflush(stdin);
                putimage(x, y, Bike, XOR_PUT); /* apagar a bike que EXISTE! FSSSSCCCCKkkkk! JEWS did RIDES ROR */
                x = x + 1;
                if (kbhit())
                        key=toupper(getch());
                switch(key)
                {
                        case 'W': incrementoy(&y,1);  break;
                        case 'E': x=x+1; y=y-1; break;
                        case 'H': x=x+1; incrementoy(&y,0); break;
                        case 'S': incrementoy(&y,0); break;
                        case 'Q': finish=1; break;
                }
                if (verify(&x,&y))
                {
                        finish=1;
                        lost=1;
                }


                if (x >= maxx) x = 0;
                putimage(x, y, Bike, XOR_PUT);
                delay(10);

        }
        if (finish==1)
        {
                fflush(stdin);
                clearviewport();
                setfillstyle(1,1);
                setcolor(RED);
                 bike(&x,&y,2);
                 setfillstyle(1,WHITE );
                 setcolor(RED);
                bar(getmaxx()/2-80, getmaxy()/2-80, getmaxx()/2+200, getmaxy()/2);
                if (lost==0)
                outtextxy(getmaxx()/2-30, getmaxy()/2-30, "Desejas sair do jogo? Y=sair");
                else
                {
                outtextxy(getmaxx()/2-30, getmaxy()/2-60, "GAMEOVER!");
                outtextxy(getmaxx()/2-30, getmaxy()/2-30, "Desejas sair do jogo? Y=sair");

                }
                fflush(stdin);
                delay(2000);
                key=toupper(getch());
                fflush(stdin);
                if (key=='Y')
                {

                        setfillstyle(1, RED);
                        setcolor(BLUE);
                        outtextxy(getmaxx()/2, getmaxy()-60, "Espere... cl0sing! ");
                        delay(2000);
                        exit(1);

                }
                else
                        lost=0;
        }
        }
        wait(8);
        getch();
        free(Bike);
        closegraph();
        return (0);
}
void wait (int seconds )
{
         clock_t endwait;
          endwait = clock () + seconds;
           while (clock() < endwait) {}
}

int cenario(int *y)
{
        /* preencher o walls[4][4] - pontos gameover */
        int rampa[6];
        walls[0][0]=getmaxx()/2+30;
        walls[0][1]=getmaxy()-200;
        /* IMPORTANTE: definir Viewports */
        rampa[0]=getmaxx()/2-30;
        rampa[1]=getmaxy()-120;
        rampa[2]=getmaxx()/2-30;
        rampa[3]=getmaxy()-140;
        rampa[4]=getmaxx()/2;
        rampa[5]=getmaxy()-160;
        setfillstyle(1,6);
        /* 1º obstaculos */
        fillpoly(3,rampa);
        fillellipse(20, getmaxy()-90,89,89);
        setfillstyle(1,6);
        /* Terreno  - tentativa de junção de cores */
        bar(0,getmaxy()-100, getmaxx(), getmaxy());
        setfillstyle(10,6);
        bar(0,getmaxy()-100, getmaxx(), getmaxy());
        /* obstaculos para fazer bunny hop por cima com KEY a definir  - may be H 0x666 fsck*/
        setfillstyle(1,RED);
        setcolor(RED);
        setviewport (0,0 , getmaxx(),  getmaxy()-90, 1);
        fillellipse(getmaxx()/2, getmaxy()-95, 30,30);
        fillellipse(getmaxx()-20, getmaxy()-160, 50,50);
        setviewport (0,0 , getmaxx(),  getmaxy(), 0);
        fillpoly(3,rampa);

        return 0;
}
int bike(int *x, int *y, int scale)
{
        int passed=0;
        int selin[10];
        /* TESTE das funções getimage() - BUGGED! 
         * Preencher o quadro da cor de funcao set by setbk com clearviewport(). setbkcolor() - BUGGED 
         * */


        /* preencher array */
        selin[0]=*x+28*scale;
        selin[1]=*y+60*scale;
        selin[2]=*x+26*scale;
        selin[3]=*y+59*scale;
        selin[4]=*x+28*scale;
        selin[5]=*y+58*scale;
        selin[6]=*x+31*scale;
        selin[7]=*y+58*scale;
        selin[8]=*x+34*scale;
        selin[9]=*y+59*scale;
        setfillstyle(1,BLACK);
        bar(*x, *y, *x+TamanhoBike, *y + TamanhoBike);
        /* FIM DO TESTE */
        setcolor(RED);
        setfillstyle(1,8);
        /* rodas */
        fillellipse(*x+10*scale,*y+78*scale,10*scale,10*scale);
        fillellipse(*x+65*scale,*y+78*scale,10*scale,10*scale);
        setfillstyle(1,4);
        Thick ^= 2;
        setlinestyle (0, 0, 3);
        /* parte de tras */
        line(*x+8*scale,*y+78*scale, *x + 30*scale, *y+78*scale);/* linha horizontal */
        line(*x + 30*scale, *y+60*scale, *x+30*scale, *y+78*scale); /* linha vertical*/
        line(*x+8*scale, *y+78*scale, *x+30*scale, *y+65*scale); /* linha diagonal */
        /* quadro, parte da frente */
        setcolor(YELLOW);
        setfillstyle(1,YELLOW);
        line(*x+28*scale, *y+60*scale, *x+34*scale, *y+60*scale); /* selin */
        fillpoly(5, selin);/* selin */
        setfillstyle(1,4);
        setcolor(RED);

        line(*x+30*scale, *y+65*scale, *x+65*scale, *y+59*scale); /*  linha semi horizontal */
        line(*x+67*scale, *y+80*scale, *x +64*scale, *y+55*scale); /* forqueta */
        line(*x+66*scale, *y+80*scale, *x +62*scale, *y+55*scale); /* forqueta */
        line(*x+30*scale, *y+78*scale, *x+58*scale, *y+65*scale);/*quadro diagonal baixo */
        /* CASSETES da bike = rodas dentadas  !! */
        setfillstyle(1,0);
        setcolor(BLACK);

        setlinestyle (0, 0, 0);

        circle(*x+10*scale, *y+78*scale, 5*scale);
        circle(*x+10*scale, *y+78*scale, 4*scale);
        circle(*x+10*scale, *y+78*scale, 3*scale);
        circle(*x+10*scale, *y+78*scale, 2*scale);

        /* raios - futura implementação dos raios a andar
         * quando conseguir fazer alterações em tempo real da bike 
         *  */

        if (raios==0)
        {
                line(*x+0*scale,*y+80*scale,*x+20*scale, *y+75*scale);
                line(*x+0*scale,*y+73*scale,*x+20*scale, *y+83*scale);
                passed=1;
        }
        else if (raios==1)
        {
                line(*x+0*scale,*y+65*scale,*x+10*scale, *y+75*scale);
                line(*x+10*scale,*y+65*scale,*x+10*scale, *y+83*scale);
                raios==0;
        }
        if (passed==1) raios=1;
        /* Desenhar JOGADOR */
        setfillstyle(1, 4);
        setcolor(RED);
        bar(*x+25*scale,*y+30*scale, *x+35*scale, *y+55*scale);
        line(*x+60*scale, *y+55*scale, *x+65*scale, *y+65*scale);
        setfillstyle(1,YELLOW);
        fillellipse(*x+33*scale,*y+22*scale,5*scale,5*scale);
        return 0;
}
int incrementox(int *x)
{
        return 0;
}

/* ESTA FUNCAO E DO DEMO !!!!!!!!!!!! */
int incrementoy(int *y, int u)
{

        if ((u==1)) /* SOBE IN DA GAME FR 0.0.0.0.0.1 */
        {
        if (*y<(90))
                return 1;
        else
                *y=*y-1;
        }
        else
        {
                if (*y > (getmaxy()-185))
                        return 1;
                else
                        *y=*y+1;
        }
        return 0;
}
int verify(int *x, int *y)
{
        int ii, k;
        /* Verificar se existem obstaculos */
        for (ii = 0; ii<1; ii++)
                for (k=0; k<2; k++)
                {
                       if ((*y>=walls[ii][k]) && (*x>=walls[ii][k]))
                       {
                        setcolor(4);
                        setfillstyle(1,YELLOW);
                        if (msg > getmaxy()/2)
                                outtextxy(20, msg, " *GAME* *OVER* - w00t?");
                                msg=msg+20;
                                return 1;
                        }
                }



        /* game over */
        return 0;
}
int incremento(int *x, int *y)
{
        return 0;
}