import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class Gurik_Space_Invaders extends PApplet {

 
Player spaceship;

ArrayList<Enemy> enemies = new ArrayList<Enemy>();

int numEnemy = 30;
int score;

public void setup () {
  
  
  score= 0;
  
  spaceship = new Player(250, 400);
  
  for (int i = 0; i < numEnemy; i++) {
    
  }
}  

public void draw() {
  background(219, 0, 26);
  
  if (spaceship.lives == 0) {
    rect(0, 0, width, height);
    fill(219);
    text("Game Over", width / 2, height / 2);
    noLoop();
  }
  
  spaceship.update();
  
  for (int i = 0; i < enemies.size(); i++) {
    Enemy e = enemies.get(i);
    e.update();
 }
 
 if (enemies.size() < numEnemy) {
   respawn();
 }
 
 text("Lives: " + spaceship.lives, 50, 50);
 text("Score:" + score, 50, 100);
 
}

public void keyPressed() {
 if (key == ' ') {
   spaceship.fire();
   
 }
}  

public void respawn() {
  enemies.add(new Enemy((int)random(0, width), (int) random(-200, 0)));
}
class Bullet {
  
  int x;
  int y;
  int bHeight;
  int bWidth;
  
  Bullet(int xPos, int yPos) {
    this.x = xPos;
    this.y = yPos;
    this.bWidth = 20;
    this.bHeight = 20;
 }
 
 public void update() {
   draw();
   move();
 }  
 

public void draw() {
  fill(0);
  ellipse(x, y, bWidth, bHeight);
}

public void move(){
  y = y - 5;
 }
 
 public boolean hit(Enemy e) {
   return abs(x - e.x) < (bWidth + e.eWidth) / 2 && abs(y - e.y) < (bHeight + e.eHeight)/2;
 }
 } 
class Enemy {

  int x;
  int y;
  int eWidth;
  int eHeight;
  
  Enemy(int xPos, int yPos) {
    this.x = xPos;
    this.y = yPos;
    this.eWidth = 20;
    this.eHeight = 20;
  }

  public void update(){
    draw();
    move();
  }

  public void draw() {
    fill(52, 164, 183);
     rect(x, y, eWidth, eHeight);
   
  }  
  
  public void move () {
    y = y + 5;
    
    if (y > height) {
      y = (int)random(-200, -50);
      x = (int)random(0, width -50);
    }
  } 
}  
    
  
  
  
  
class Player {
  
 int x;
 int y;
 int pWidth;
 int pHeight;
 int lives;
 
 ArrayList<Bullet> bullets = new ArrayList<Bullet>();
 
 
  Player(int xPos, int yPos) {
    this.x = xPos;
    this.y = yPos;
    this.pWidth = 30;
    this.pHeight = 30;
    this.lives = 3;
  }
  
  public void fire() {
    bullets.add(new Bullet(x + 15, y));
  }
  
  public void hit() {
    for (int i = 0; i < enemies.size(); i++) {
      Enemy e  = enemies.get(i);
      if (abs(x - e.x) < (pWidth + e.eWidth)/2 && abs(y - e.y) < (pHeight + e.eHeight)/2) {
        enemies.remove(i);
        lives--; 
      }
    }
  }
  
    public void update() {
      draw();
      move();
      hit();
    
      for (int i = 0; i < bullets.size(); i ++) {
        Bullet b = bullets.get(i);
        b.update();
        
        if (b.y < 0) {
          bullets.remove(i); 
          }
          for (int j = 0; j < enemies.size(); j++) {
            Enemy e = enemies.get(j);
            if (b.hit(e)) {
            enemies.remove(j);
            bullets.remove(i);
            score ++;
            }
          }
       }
    } 
    

public void draw() {
  
  fill(0);  
     rect(x, y, pWidth, pHeight);
     
  }
  
  public void move() {
     if (keyPressed) {
       if (keyCode == LEFT) {
         x = x - 5 ;
       }
       
       if (keyCode == RIGHT){
         x = x + 5;
       }
     }
   } 
} 
  
  public void settings() {  size(500, 500); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "Gurik_Space_Invaders" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
