#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 d(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
#define KEY 6
#define LITAK_W 14
#define LITAK_H 9
const PROGMEM byte litak[] = {
 B10000000, B00000000,
 B11100000, B00000000,
 B11011111, B11100000,
 B01000000, B00011000,
 B01111111, B11111100,
 B00000111, B10000000,
 B00000111, B00000000,
 B00000110, B00000000,
 B00001100, B00000000,
};
const PROGMEM byte litak2[] = {
  B00000000,B00000100,
  B00000000,B00011100,
  B00011111,B11101100,
  B01100000,B00001000,
  B11111111,B11111000,
  B00000111,B10000000,
  B00000011,B10000000,
  B00000001,B10000000,
  B00000000,B11000000,
};
#define TANK_W 16
#define TANK_H 7
#define TANK_Y (SCREEN_HEIGHT-TANK_H)
const PROGMEM byte tank[] = {
 B00001111, B10000000,
 B00010000, B01111111,
 B10100000, B00100000,
 B11111111, B11111000,
 B11111111, B11111000,
 B10000000, B00010000,
 B01111111, B11100000,
};
const PROGMEM byte tank2[] = {
 B00000001, B11110000,
 B11111110, B00001000,
 B00000100, B00000101,
 B00011111, B11111111,
 B00011111, B11111111,
 B00001000, B00000001,
 B00000111, B11111110,
};
#define BOMB_W 5
#define BOMB_H 6
const PROGMEM byte bomb[] = {
  B11111000,
  B01110000,
  B10001000,
  B10001000,
  B01110000,
  B00100000,
};
#define LITAK_MAXY (SCREEN_HEIGHT-LITAK_H-TANK_H-20)
float tankX=0, tankSpeed=3;
float litakX=0, litakY=0, litakSX=5, litakSY=0;
float bombX=60, bombY=SCREEN_HEIGHT, bombSX=2, bombSY=0;
int wait_time=0;
void setup() {
  Serial.begin(115200);
  pinMode(KEY, INPUT_PULLUP);
  d.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  d.clearDisplay();
  //d.drawBitmap(10, 0, litak, LITAK_W, LITAK_H, 1);
  //d.drawBitmap(10, 30, tank, TANK_W, TANK_H, 1);
  //d.drawBitmap(10, 30, bomb, BOMB_W, BOMB_H, 1);
  d.display();
  randomSeed( analogRead(A0) );
}
void show_tank() {
  if ( tankSpeed > 0 )
    d.drawBitmap(tankX, TANK_Y, tank, TANK_W, TANK_H, 0);
  else   
    d.drawBitmap(tankX, TANK_Y, tank2, TANK_W, TANK_H, 0);
  tankX += tankSpeed;
  if ( (tankX >= SCREEN_WIDTH) || ( tankX < -TANK_W ) ) {
    tankSpeed = (float) random( 5, 25 ) / 10.0;
    if ( random(6) > 2 ) tankSpeed = -tankSpeed;
    if ( tankSpeed < 0 ) tankX = SCREEN_WIDTH;
    else tankX = -TANK_W;
  }
  if ( tankSpeed > 0 ) 
    d.drawBitmap(tankX, TANK_Y, tank, TANK_W, TANK_H, 1);
  else   
    d.drawBitmap(tankX, TANK_Y, tank2, TANK_W, TANK_H, 1);
}
void show_litak(){
  if ( litakSX > 0 ) d.drawBitmap(litakX, litakY, litak, LITAK_W, LITAK_H, 0);
  else d.drawBitmap(litakX, litakY, litak2, LITAK_W, LITAK_H, 0);
  litakX += litakSX;
  litakY += litakSY;
  if ( litakX >= SCREEN_WIDTH ) { // вилетіли вправо за екран
    litakSX = (float) random( 30, 50 ) / 10.0;
    if ( random(2) == 0 ) litakSX = -litakSX;
    litakY = (float) random( 0, LITAK_MAXY  );
    if ( litakSX > 0 ) litakX = -LITAK_W;
    else litakX = SCREEN_WIDTH;
  }
  if ( litakX < -LITAK_W ) { // вилетіли вліво за екран
    litakSX = (float) random( 30, 50 ) / 10.0;
    if ( random(2) == 0 ) litakSX = -litakSX;
    litakY = (float) random( 0, LITAK_MAXY  );
    if ( litakSX > 0 ) litakX = -LITAK_W;
    else litakX = SCREEN_WIDTH;
  }
  if ( litakSX > 0 ) d.drawBitmap(litakX, litakY, litak, LITAK_W, LITAK_H, 1);
  else d.drawBitmap(litakX, litakY, litak2, LITAK_W, LITAK_H, 1);
}
void show_bomb(){
  if ( bombY <= SCREEN_HEIGHT ) {
    d.drawBitmap(bombX, bombY, bomb, BOMB_W, BOMB_H, 0 );
    bombX += bombSX;
    bombY += bombSY;
    bombSY += 1.5;
    if ( bombSY >= TANK_H ) bombSY = TANK_H - 1;
    d.drawBitmap(bombX, bombY, bomb, BOMB_W, BOMB_H, 1 );
  }
}
void new_bomb(){
  if ( bombY >= SCREEN_HEIGHT ) {
    bombY = litakY + LITAK_H;
    if ( litakSX > 0 ) bombX = litakX;
    else bombX = litakX + LITAK_W - BOMB_W;
    bombSY = 0;
    bombSX = litakSX;
  }
}
void check_hit(){ // контроль попадання бомби в танк
  if ( bombY < SCREEN_HEIGHT ) {
    if ( bombX + BOMB_W > tankX ) {
      if ( bombX < tankX + TANK_W ) {
        //Serial.println("X in tank!");
        if (bombY + BOMB_H >= TANK_Y) {
          //Serial.println("Hit!");
          //delay(5000);
          tankSpeed = 0;
          bombY = SCREEN_HEIGHT;
          wait_time = 10;
          int x = bombX+BOMB_W/2;
          int y = bombY+BOMB_H;
          d.drawBitmap(bombX, bombY, bomb, BOMB_W, BOMB_H, 0 );
          if ( tankSpeed > 0 )
            d.drawBitmap(tankX, TANK_Y, tank, TANK_W, TANK_H, 0);
          else   
            d.drawBitmap(tankX, TANK_Y, tank2, TANK_W, TANK_H, 0);
          d.drawLine(x,y, x-5, y-15, 1 );
          d.drawLine(x,y, x+5, y-15, 1 );
          d.drawLine(x,y, x, y-20, 1 );
        }
      }
    }
  }
  if ( wait_time > 0 ) {
    wait_time -= 1;
    if ( wait_time == 0 ) {
      d.clearDisplay();
      tankX = SCREEN_WIDTH;
    } 
  }
}
void loop() {
  if ( digitalRead(KEY) == 0 ) {
    new_bomb();
  }
  show_tank();
  show_litak();
  show_bomb();
  d.display();
  check_hit();
}