#ifndef ENGINE_H
#define ENGINE_H

#define SIGN(x)((x)<0 ? 1 : -1)

//#include <stdio.h>
//#include <stdlib.h>
//#include <iostream>
//#include <cstdlib>
//#include <cstdio>
#include <string>
//#include <iomanip>
#include <fstream>

using namespace std;

class Planet
{
public:

    SDL_Rect pl_rect;
    SDL_Surface *image;
    int id,x,y,count1,count2,count3,count4,count5,price1,price2,price3,price4,price5;
    int PLx,PLy;
    string name,tovar1,tovar2,tovar3,tovar4,tovar5;

    Planet(SDL_Surface *temp, string path)
    {
        id=x=y=count1=count2=count3=count4=count5=price1=price2=price3=price4=price5 = NULL;
        image = temp;
        read(path.c_str());
        PLx = x; PLy = y;
        pl_rect.x = x * grid_x - Camera.x;
        pl_rect.y = y * grid_y - Camera.y;
    }

    void read(string path)
    {
        ifstream fin(path.c_str());
        if(!fin.is_open())
        {
            printf("Text file: %s not fount\n", path.c_str());
        }
        else
        {
            while(!fin.eof())
            {
                fin>>id;
                fin>>x>>y;
                fin>>name;

                fin>>tovar1;
                fin>>count1;
                fin>>price1;

                fin>>tovar2;
                fin>>count2;
                fin>>price2;

                fin>>tovar3;
                fin>>count3;
                fin>>price3;

                fin>>tovar4;
                fin>>count4;
                fin>>price4;

                fin>>tovar5;
                fin>>count5;
                fin>>price5;
            }
            fin.close();
        }
    }

    void set(int x, int y)
    {
        pl_rect.x = x * grid_x - Camera.x;
        pl_rect.y = y * grid_y - Camera.y;
    }

    void update()
    {
        set(PLx,PLy);
        draw();
    }

    void draw()
    {
        SDL_BlitSurface(image,NULL,screen,&pl_rect);
    }

    int getX()
    {
        return PLx;
    }

    int getY()
    {
        return PLy;
    }

    int getID()
    {
        return id;
    }

};

class game
{
public:
    
    void load_imgs()
    {
        space = load_image("data/space.png");
        if(space == NULL)
        {
            printf("Unable to load space.png\n");
            //return;
        }

        space_2 = load_image("data/space_2.png");
        if(space_2 == NULL)
        {
            printf("Unable to load space_2.png");
        }
            
        player_up = load_image("data/player/player_up.png");
        if(player_up == NULL)
        {
            printf("Unable to load player_up.png\n");
            //return;
        }

        player_rt = load_image("data/player/player_rt.png");
        if(player_rt == NULL)
        {
            printf("Unable to load player_rt.png\n");
        }

        player_dn = load_image("data/player/player_dn.png");
        if(player_dn == NULL)
        {
            printf("Unable to load player_dn.png\n");
        }

        player_lt = load_image("data/player/player_lt.png");
        if(player_lt == NULL)
        {
            printf("Unable to load player_lt.png\n");
        }

        ship_up = load_image("data/enemies/enemy_1_up.png");
        if(ship_up == NULL)
        {
            printf("Unable to load enemies/enemy_1_up.png\n");
            //return;
        }

        ship_rt = load_image("data/enemies/enemy_1_rt.png");
        if(ship_rt == NULL)
        {
            printf("Unable to load enemies/enemy_1_rt.png\n");
        }

        ship_dn = load_image("data/enemies/enemy_1_dn.png");
        if(ship_dn == NULL)
        {
            printf("Unable to load enemies/enemy_1_dn.png\n");
        }

        ship_lt = load_image("data/enemies/enemy_1_lt.png");
        if(ship_lt == NULL)
        {
            printf("Unable to load enemies/enemy_1_lt.png\n");
        }

        ship_2 = load_image("data/sputnik_1.png");
        if(ship_2 == NULL)
        {
            printf("Unable to load ship_2.png\n");
            //return;
        }

        planet_1 = load_image("data/planet_1.png");
        if(planet_1 == NULL)
        {
            printf("Unable to load planet_1.png\n");
            //return;
        }

        planet_2 = NULL;
        if(planet_2 == NULL)
        {
            printf("Unable to load planet_2.png\n");
            //return;
        }

        sputnik_1 = load_image("data/sputnik_1.png");
        if(sputnik_1 == NULL)
        {
            printf("Unable to load sputnik_1.png\n");
            //return;
        }

        sputnik_2 = NULL;
        if(sputnik_2 == NULL)
        {
            printf("Unable to load sputnik_2.png\n");
            //return;
        }

        arrow_up = load_image("data/enemies/arrow_1.png");
        if(arrow_up == NULL)
        {
            printf("Unable to load enemies/arrow_1.png\n");
            //return;
        }

        arrow_rt = load_image("data/enemies/arrow_2.png");
        if(arrow_rt == NULL)
        {
            printf("Unable to load enemies/arrow_2.png\n");
            //return;
        }

        arrow_dn = load_image("data/enemies/arrow_3.png");
        if(arrow_dn == NULL)
        {
            printf("Unable to load enemies/arrow_3.png\n");
            //return;
        }

        arrow_lt = load_image("data/enemies/arrow_4.png");
        if(arrow_lt == NULL)
        {
            printf("Unable to load enemies/arrow_4.png\n");
            //return;
        }

        menu = load_image("data/menu.png");
        if(menu == NULL)
        {
            printf("Unable to load menu.png\n");
        }

        inv = load_image("data/inv.png");
        if(inv == NULL)
        {
            printf("Unable to load inv.png\n");
        }

        battle = load_image("data/battle.png");
        if(battle == NULL)
        {
            printf("Unable to load battle.png\n");
        }

        p_beam = load_image("data/player/p_beam.png");
        if(p_beam == NULL)
        {
            printf("Unable to load player/p_beam.png\n");
        }

        e_beam = load_image("data/enemies/e_beam.png");
        if(e_beam == NULL)
        {
            printf("Unable to load enemies/e_beam.png");
        }

        p_rocket = load_image("data/player/p_rocket.png");

        boom_1 = load_image("data/player/boom_1.png");

        boom_2 = load_image("data/player/boom_2.png");
        boom_3 = load_image("data/player/boom_3.png");
        boom_4 = load_image("data/player/boom_4.png");
        boom_5 = load_image("data/player/boom_5.png");
        boom_6 = load_image("data/player/boom_6.png");
        boom_7 = load_image("data/player/boom_7.png");
        boom_8 = load_image("data/player/boom_8.png");
        boom_9 = load_image("data/player/boom_9.png");
        boom_10 = load_image("data/player/boom_10.png");

        //music
        music = Mix_LoadMUS( "data/music/music_is_my_galaxy.ogg" );//music = Mix_LoadMUS( "beat.wav" );
        if(music == NULL)
        {
            printf("Unable to load music/music_is_my_galaxy.ogg\n");
        }
    }

    void clean()
    {
        SDL_FreeSurface(screen);
        SDL_FreeSurface(space);
        SDL_FreeSurface(space_2);

        SDL_FreeSurface(player);
        SDL_FreeSurface(player_up);
        SDL_FreeSurface(player_rt);
        SDL_FreeSurface(player_dn);
        SDL_FreeSurface(player_lt);

        SDL_FreeSurface(ship_up);
        SDL_FreeSurface(ship_rt);
        SDL_FreeSurface(ship_dn);
        SDL_FreeSurface(ship_lt);

        SDL_FreeSurface(ship_2);
        SDL_FreeSurface(planet_1);
        SDL_FreeSurface(planet_2);
        SDL_FreeSurface(sputnik_1);
        SDL_FreeSurface(sputnik_2);
        SDL_FreeSurface(arrow_up);
        SDL_FreeSurface(arrow_rt);
        SDL_FreeSurface(arrow_dn);
        SDL_FreeSurface(arrow_lt);
        SDL_FreeSurface(p_beam);
        SDL_FreeSurface(e_beam);

        SDL_FreeSurface(boom_1);
        SDL_FreeSurface(boom_2);
        SDL_FreeSurface(boom_3);
        SDL_FreeSurface(boom_4);
        SDL_FreeSurface(boom_5);
        SDL_FreeSurface(boom_6);
        SDL_FreeSurface(boom_7);
        SDL_FreeSurface(boom_8);
        SDL_FreeSurface(boom_9);
        SDL_FreeSurface(boom_10);
        SDL_FreeSurface(p_rocket);

        SDL_FreeSurface(menu);
        SDL_FreeSurface(inv);
        SDL_FreeSurface(battle);


        Mix_FreeMusic(music);
        
        Mix_CloseAudio();
        TTF_Quit();
        SDL_Quit();
    }

    void draw_map()
    {
        for(int i = -H; i < H; i++)
            for(int j = -W; j < W; j++)
            {
                img_draw(space_2,j*600-Camera.x,i*450-Camera.y);
                //img_draw(space,j*grid_x/*-camX*/,i*grid_y/*-camY*/);
            }
    }
};

class Player
{
public:
    int dx,dy,dir,money,ch_m,ch_m_x,rockets,h,hp,m_hp;
    int LvL,dmg,laser,rDmg,exp;
    SDL_Surface *temp;
    Player() {}
    ~Player() {}

    Player(SDL_Surface *image, int xx, int yy)
    {
        {
            Px = xx; Py = yy;
            dx = 1; dy = 1;
            player = image;
            temp   = image;
            ch_m   = 0;
            ch_m_x = 0;
            LvL = 1;
            exp = 0;
            laser = 10;
            dmg = laser*LvL;
            rDmg = 30;
        }
        {
            h       = 3;
            hp      = 150;
            m_hp    = 150;
            item[2] = 2;
            money   = 1000;
            rockets = 3;
            item[1] = 1;
        }
        p_rect.x = xx * grid_x - Camera.x;
        p_rect.y = yy * grid_y - Camera.y;
    }

    void Set(int xx, int yy)
    {
        p_rect.x = xx * grid_x - Camera.x;
        p_rect.y = yy * grid_y - Camera.y;
    }

    bool update(int dir)
    {
        switch(Eturn)
        {
            case 0:
                switch(dir)
                {
                case up:

                    if(upp == false)
                    {
                        upp = true;
                        //if(collision() == true) return false;    
                        Py -= dy;
                        //Set(Px,Py);
                        Camera.y -= 64;
                        player = player_up;
                        Eturn = true;
                    }
                    return true;
                    break;
                case rt:
                    if(rp == false)
                    {
                        rp = true;
                        //if(collision() == true) return false;
                        Px += dx;
                        //Set(Px,Py);
                        Camera.x += 64;
                        player = player_rt;
                        Eturn = true;
                    }
                    return true;
                    break;
                case down:
                    if(dp == false)
                    {
                        dp = true;
                        //if(collision() == true) return false;
                        Py += dy;
                        //Set(Px,Py);
                        Camera.y += 64;
                        player = player_dn;
                        Eturn = true;
                    }
                    return true;
                    break;
                case lt:
                    if(lp == false)
                    {
                        lp = true;
                        //if(collision() == true) return false;
                        Px -= dy;
                        //Set(Px,Py);
                        Camera.x -= 64;
                        player = player_lt;
                        Eturn = true;
                    }
                    return true;
                    break;
                }
                break;
            case 1: break;
        }
        return false;        
    }

    bool collision()
    {
        if ( p_rect.x < 0 ) {
            p_rect.x = 0;
            return true;
        }
        else if ( p_rect.x > SCREEN_X-step ) {
            p_rect.x = SCREEN_X-step;
            return true;
        }
        if ( p_rect.y < 0 ) {
            p_rect.y = 0;
            return true;
        }
        else if ( p_rect.y > SCREEN_Y-step ) {
            p_rect.y = SCREEN_Y-step;
            return true;
        }
        return false;
    }

    void draw()
    {
        SDL_BlitSurface(player,NULL,screen,&p_rect);
    }

};

class Ship
{
public:

    SDL_Rect sh_rect;
    SDL_Surface *image, *tftemp;
    int Sx,Sy,dx,dy,hp,Edmg,Elvl;
    bool life;

    Ship(SDL_Surface *temp, int xx, int yy)
    {
        Sx = xx; Sy = yy;
        dx=dy=1;
        image = temp;
        tftemp = temp;
        sh_rect.x = xx * grid_x - Camera.x;
        sh_rect.y = yy * grid_y - Camera.y;

        Elvl = tempLVL;
        Ecount++;
        Edmg = 10 + rand()%50*Elvl/2;
        life = true;
        hp = 50*Elvl;
    }

    void set(int xx, int yy)
    {
        sh_rect.x = xx * grid_x - Camera.x;
        sh_rect.y = yy * grid_y - Camera.y;
    }

    void Set(int xx, int yy)
    {
        sh_rect.x = xx;
        sh_rect.y = yy;
    }

    int GetDir(int sh, int pl, int evade)
    {
        if(sh==pl) return 0;

        int i = SIGN(sh-pl);
        if(evade) return (i*(-1));
        else return i;
    }

    int randd(int q)
    {
        int ress = rand()%q;
        return ress;
    }

    void update()
    {
        if(hp<=0) { life = false; states = GAME; }

        if(Eturn == true)
        {
            if(randd(3) == 0)
            {
                dx = 0;
                dy = 0;
            }
            else
            {
                dx = GetDir(Sx, Px, 0);
                dy = GetDir(Sy, Py, 0);
            }

            if(dx == 1 && dy == -1)
            {
                if(randd(2) == 0)
                {
                    dx = 1;
                    dy = 0;
                }
                else 
                {
                    dx = 0;
                    dy = -1;
                }
            }
            else if(dx == 1 && dy == 1)
            {
                if(randd(2) == 0)
                {
                    dx = 1;
                    dy = 0;
                }
                else 
                {
                    dx = 0;
                    dy = 1;
                }
            }
            else if(dx == -1 && dy == 1)
            {
                if(randd(2) == 0)
                {
                    dx = -1;
                    dy = 0;
                }
                else
                {
                    dx = 0;
                    dy = 1;
                }
            }
            else if(dx == -1 && dy == -1)
            {
                if(randd(2) == 0)
                {
                    dx = -1;
                    dy = 0;
                }
                else
                {
                    dx = 0;
                    dy = -1;
                }
            }

            int tempX = 0, tempY = 0;
            tempX = Sx; tempY = Sy;

            Sx += dx; Sy += dy;
            set(Sx,Sy);

            if(Sx == Px && Sy == Py)
            {
                states = BATTLE;
                //life = false;
                Ecount--;
            }
        }

        if(dy == -1) image = ship_up;
        else if(dx == 1) image = ship_rt;
        else if(dy == 1) image = ship_dn;
        else if(dx == -1) image = ship_lt;

        if(sh_rect.x <= 0) image = arrow_lt;
        else if(sh_rect.x >= SCREEN_X) image = arrow_rt;
        else if(sh_rect.y <= 0)    image = arrow_up;
        else if(sh_rect.y >= SCREEN_Y) image = arrow_dn;

        draw();
    }

    void draw()
    {
        
        if(image == arrow_rt || image == arrow_dn)
        {
            SDL_Rect ar;
            ar.x = sh_rect.x - 64;
            ar.y = sh_rect.y - 64;
            SDL_BlitSurface(image,NULL,screen,&ar);
        }
        else { SDL_BlitSurface(image,NULL,screen,&sh_rect); }
    }
    
    int getX()
    {
        return Sx;
    }

    int getY()
    {
        return Sy;
    }
};

class Menu
{
public:
    SDL_Rect m_rect;
    SDL_Surface *image;

    Menu(SDL_Surface *temp)
    {
        image = temp;
        m_rect.x = SCREEN_X / 2 - 300;
        m_rect.y = SCREEN_Y / 2 - 200;
    }

    void draw()
    {
        SDL_BlitSurface(image,NULL,screen,&m_rect);
    }

    void draw(int x, int y)
    {
        SDL_Rect des;
        des.x = x;
        des.y = y;
        m_rect.x = x;
        m_rect.y = y;
        SDL_BlitSurface(image,NULL,screen,&des);
    }
};

#endif