#include "uLCD_4DGL.h"
#include "bullet.h"
#include "game_synchronizer.h"
#include "globals.h"
#include "math.h"
#include "playSound.h"
#include "wave_player.h"

extern Serial pc;
extern Game_Synchronizer sync;
extern uLCD_4DGL uLCD;
extern wave_player player;  
// Initialize the bullet. Don't have to do much here.
// Keep a pointer to this bullet's tank.
// Set the speed, and default the bullet to not in_flight.
Bullet::Bullet(Tank* t) {
    tank = t;
    speed = 300;
    in_flight = false;
}

// If in_flight, do nothing. Otherwise,
// set the in_flight flag, and initialize values needed for
// the trajectory calculations. (x0, y0), (vx0, vy0), time
// Hint: tank->barrel_end(...) is useful here.
void Bullet::shoot(void) {
    if(!in_flight){
        in_flight = true;
        tank->barrel_end(&x0,&y0,&tx,&ty);
        x = x0;
        y = y0;
        time = 0;
        vx0 = speed*cos(tank->barrel_theta);
        vy0 = speed*sin(tank->barrel_theta);
    
    }


}

// If the bullet is in flight, calculate its new position
// after a time delta dt.
void Bullet::update_position(float dt) {
    time = time + dt;
    x = x0 + vx0*time;
    y = y0 + vy0*time - 0.5*980*time*time;
}

int Bullet::time_step(float dt) {
    //wait(1);

    if (in_flight){
    int oldx = x;
    int oldy = y;

//            uLCD.locate(5,5);
//            uLCD.printf("x: %d y:%d time %f",x,y,dt);
//        uLCD.locate(2,2);
//        uLCD.printf("color: %d ",sync.pixel_eq(sync.read_pixel(x,y),SKY_COLOR));
            update_position(dt);
            //sync.pixel(x,y,BLACK);
            sync.pixel(x,y,BLACK);
            
    //check if the bullet is off the screen
    if ((x < 0 )||(x > 128)|| (y < 0)||(y > 105)){
            //explosion effect
            playSound("/sd/wavfiles/explosion.wav");
            in_flight = false;
            
            //erase the bullet
            sync.pixel(oldx,oldy,SKY_COLOR);
            sync.update();
            
            //explosion effect
            sync.filled_circle(oldx,oldy,2,RED);
            wait(0.8);
            sync.update();
            sync.filled_circle(oldx,oldy,4,RED);
            wait(0.8);
            sync.update();
            sync.filled_circle(oldx,oldy,4,SKY_COLOR);
            sync.update();
            return  BULLET_OFF_SCREEN;
    } else if (x == oldx && y == oldy){//check if the bullet stay at the same place, if yes do nothing
        return BULLET_NO_COLLISION;
    }else if (!(sync.pixel_eq(sync.read_pixel(x,y),SKY_COLOR))){//check if the bullet hit something
            playSound("/sd/wavfiles/explosion.wav");
            in_flight = false;
            int col = sync.read_pixel(x,y);
            sync.update();
            //erase the bullet
            sync.pixel(oldx,oldy,SKY_COLOR);
            sync.update();
            //explosion effect
            sync.filled_circle(oldx,oldy,2,RED);
            wait(0.8);
            sync.update();
            sync.filled_circle(oldx,oldy,4,RED);
            wait(0.8);
            sync.update();
            sync.filled_circle(oldx,oldy,4,SKY_COLOR);
            sync.update();
            return col;
        
        }
            sync.update();
            sync.pixel(oldx,oldy,SKY_COLOR);
    //uLCD.printf("x: %d y:%d",x,y);

    return BULLET_NO_COLLISION;
    }
    return BULLET_NO_COLLISION;

    // If the bullet hasn't hit anything, 
    // redraw the bullet at its new location. 
    // If it has hit something (obstacle, tank, edge of the screen), 
    // set the in_flight flag back to false, explode the nearby area,
    // and return one of the following codes.
    //
    // return codes:
    //      BULLET_NO_COLLISION: no collision
    //      BULLET_OFF_SCREEN:   off the side of the screen
    //      Otherwise, return the color you've hit in 16bpp format. 
}