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

import ddf.minim.*; 

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 Cyberroids_X extends PApplet {


Minim minim;
AudioSample shoot;
AudioSample explosion;
AudioSample hit;
AudioSample music;






float posx = 400;
float posy = 400;
float speed = 12;
float score = 0;
float _score = 100;
float frametimer = 0;
float frametimer2 = 0;
float frametimer3 = 0;
float speedtimer = 0;
float limit = 40;
player guy;
projectile temp;
enemy douche;
boolean[] keys;
float sx;
float sy;
float abs;
boolean blowit = false;
float pspeed = 15;
boolean _temp;
int enemyamount = 1;
float _rand;
float _rand2;
float _x;
float _y;
float _abs;
float _tempx;
float _temp2x;
float _tempy;
float _temp2y;
boolean _bool;
boolean damaged = false;
float damage = 0;
float enemyspeed = 7;
int playercolour = color(255, 255, 255);
float xposmouse;
float regentimer = 0;

ArrayList shots;
ArrayList mob;
ArrayList parts;
float finalscore;

float _musictime;
float musictime;
public void setup() {
  size(800, 800);  
  guy = new player(); 
  keys = new boolean[4];
  keys[0] = false;
  keys[1] = false;
  keys[2] = false;
  keys[3] = false;
  shots = new ArrayList();
  mob = new ArrayList();
  parts = new ArrayList();

  minim = new Minim(this);
  shoot = minim.loadSample("Blip_Shoot.wav", 512);
  explosion = minim.loadSample("Explosion.wav", 512);
  hit = minim.loadSample("Hit_Hurt.wav", 512);
  music = minim.loadSample("Strategy_Game_Loo.mp3", 512);
  music.trigger();
} // Setup End



public void draw() {
  musictime ++;

  if ( musictime > 5760) {
    music.trigger();
    musictime = 0;
  }

  if (limit < 15) {

    limit = 15;
  }
  background(0); 







  //println(damaged);
  if ( damage > 0) {
    regentimer++;
  }
  if (regentimer > 30 ) {
    regentimer = 0;
    damage--;
  }



  frametimer2++; 
  if (frametimer2 > 100) {
    score++ ;
    _score++; 
    frametimer2 = 0;
  }
  if (damaged == true) {
    frametimer3++; 
    playercolour = color(255, 0, 0);
  }
  else {
    playercolour = color(255, 255, 255);
  }
  if (frametimer3 > 50 && damaged == true) {
    damaged = false; 
    frametimer3 = 0;
  }




  rectMode(CORNERS);

  rect(300, 50, 700-damage, 75);
  fill(0, 255, 0);
  textSize(24);
  text("LIFE", 300, 40);
  stroke(0, 255, 0);




  if (_score > 40) {





    limit--;

    _score = _score - 40;
    speedtimer++;
    if (speedtimer > 2) {

      enemyspeed++;
      speedtimer = 0;
    }
  }



  text("Score: "+ score, 50, 50);
  text("Enemy Speed : " + (enemyspeed-6), 50, 100);
  //text("Enemies: " + mob.size(), 50, 150);
  guy.disp();
  guy.shoot();
  guy.move();
  for (int i = shots.size()-1; i >=0; i--) {
    projectile temp = (projectile) shots.get(i);
    temp.fire();  
    _temp = temp.check();
    if (_temp == true) {
      shots.remove(i);
    }
  }
  guy.spawn();

  for (int i = mob.size()-1; i >=0; i--) {
    enemy douche = (enemy) mob.get(i);
    douche.move();
  }

  // %%%%% COLLISSIONSSKIT%%%%

  for (int i = mob.size()-1; i>=0; i--) {
    enemy douche = (enemy) mob.get(i);
    _temp2x = douche.sendx(); // 
    _temp2y = douche.sendy();
    if ( posx < _temp2x+10 && posx > _temp2x-10 && posy > _temp2y-10 && posy < _temp2y+10 && damaged == false) {
      damaged = true;
      damage = damage +80;
      hit.trigger();
    }
  }

  for (int i = shots.size()-1; i>=0; i--) {
    projectile temp = (projectile) shots.get(i);
    _tempx = temp.sendx();
    _tempy = temp.sendy();

    for (int i2 = mob.size()-1; i2 >=0; i2--) {
      enemy douche = (enemy) mob.get(i2);
      _temp2x = douche.sendx(); // 
      _temp2y = douche.sendy();



      if ( _tempx < _temp2x+10 && _tempx > _temp2x-10 && _tempy > _temp2y-10 && _tempy < _temp2y+10) { //\u00e4r current projektil i current fiende?
        _bool = douche.damage();
        if (_bool == true) {
          score = score + 10;
          _score = _score +10 ;

          if (damage > 0) {
            damage = damage - 5;
          }
          mob.remove(i2);
          explosion.trigger();
          //skapa ny particle med initialhastighet och riktning
          for (int i3 = PApplet.parseInt(random(20, 60)); i3 >= 0; i3--) {

            parts.add(new particles(_temp2x, _temp2y, random(-2, 2), random(-20, 0)));  //SKAPELSE AV PARTIKLAR
          } 


          //parts heter vektorn

          // particle.live(_temp2x, _temp2y);
        } 
        shots.remove(i);
      }
    }
  }



  // %%%%%%%%   COLLISIONSSKIT   END   %%%%%%


  for (int i = parts.size()-1; i>=0; i--) { // R\u00d6RELSE AV PARTIKLAR
    particles temp = (particles) parts.get(i); 
    temp.live();

    _bool = temp.die();

    if (_bool == true) {
      parts.remove(i);
    }
  }


  if (damage < 400) {
    finalscore = score;
  }

  if (damage > 400) {

    background(0);
    textSize(64);
    text("GAME OVER", 200, 400); 
    text ("Final Score: " + finalscore, 200, 500);
    textSize(24);
    text("Music by Electrolord99 (Newgrounds)", 100, 600);
    text("Sounds by bfxr.net", 100, 700);
    text("Made by Oats.", 100, 750);
    shoot.close();
    explosion.close();
    hit.close();
  }
} //Draw End



class player {

  player() {
  }  



  public void spawn() {
    frametimer++;
    if (frametimer > limit) { // var hundrade score skapas en ny fiendeinstans
      _rand = random(0, 100); // randomar vilken edge



      if (_rand < 25) { // Mobspawn

        //v\u00e4nster
        _rand2 = random(0, height);

        _x = posx + 10; // vilken direction?
        _y = posy-_rand2;
        _abs = sqrt(_y*_y + _x*_x);
        mob.add(new enemy(-10, _rand2, _x/_abs, _y/_abs));
      }


      if (_rand >= 25 && _rand < 50) {


        _rand2 = random(0, width);

        _x = posx-_rand2; // vilken direction?
        _y = posy+10;
        _abs = sqrt(_y*_y + _x*_x);
        mob.add(new enemy(_rand2, -10, _x/_abs, _y/_abs));
        //upp
      }
      if (_rand >= 50 && _rand < 75) {
        _rand2 = random(0, height);

        _x = posx - (width +10); // vilken direction?
        _y = posy-_rand2;
        _abs = sqrt(_y*_y + _x*_x);
        mob.add(new enemy(width+10, _rand2, _x/_abs, _y/_abs));
        //h\u00f6ger
      }
      if (_rand >= 75) {
        _rand2 = random(0, width);

        _x = posx- _rand2; // vilken direction?
        _y = posy-(width+10);
        _abs = sqrt(_y*_y + _x*_x);
        mob.add(new enemy(_rand2, width+10, _x/_abs, _y/_abs));
        //ned
      }


      frametimer = 0;
    } // Mobspawn end
  }

  public void move() {
    if (keys[0] == true) {
      posy = posy-speed;
    }
    if (keys[1] == true) {
      posy = posy+speed;
    }
    if (keys[2] == true) {
      posx = posx-speed;
    }
    if (keys[3] == true) {
      posx = posx+speed;
    }


    if (posx > width-8) {
      posx = width-8;
    }
    if (posx < 8) {
      posx = 8;
    }
    if (posy > height-8) {
      posy = height-8;
    }
    if (posy < 8) {
      posy = 8;
    }
  } // move End

  public void shoot() {
    if (mousePressed == true) {


      sx = mouseX-posx;
      sy = mouseY-posy;
      abs = sqrt(sy*sy + sx*sx);
      //temp = new projectile(posx, posy, 10);
      //temp.fire();
      shots.add(new projectile(posx, posy, sx/abs, sy/abs)); 
      //shoot.trigger();  
      //posx = posx + speed*sx/abs;
      //posy = posy + speed*sy/abs;
      //skapa enhetsvektor fr\u00e5n pos till mouse
    }


    //skapa partikel vid spelare med hastighet riktad mot musen
  } // shoot End

  public void disp() {

    fill(playercolour);
    ellipse(posx, posy, 20, 20);
  } //disp End
} // player End



class projectile {
  float px;
  float py;
  float dirx; 
  float diry;

  projectile(float _px, float _py, float _dirx, float _diry) {
    px = _px;
    py = _py;
    dirx = _dirx;
    diry = _diry;
  }


  public float sendx() {

    return px;
  }
  public float sendy() {

    return py;
  }


  public void fire() {


    px = px + pspeed*dirx;
    py = py + pspeed*diry;
    ellipse(px, py, 5, 5);
  } // fire End

  public boolean check() {
    if ( px > width || px < 0 || py > height || py < 0) {
      return true;
    }
    else {
      return false;
    }
  }// check End
} // projectile End

class enemy {
  float px;
  float py;
  float dirx; 
  float diry;
  float life = 2;

  enemy(float _px, float _py, float _dirx, float _diry) {
    px = _px;
    py = _py;
    dirx = _dirx;
    diry = _diry;
  }

  public boolean damage() {
    life-- ;
    if (life <= 0) {

      return true;
    }
    else {
      return false;
    }
  }

  public float sendx() {

    return px;
  }
  public float sendy() {

    return py;
  }





  //spawn() {

  //beroende p\u00e5 score s\u00e5 skapar nya instanser av fiender.
  // d\u00f6r en fiende s\u00e5 tas den bort
  //}


  public void disp() {
  }



  public void move() {
    rectMode(RADIUS);
    rect(px, py, 10, 10);
    px = px + enemyspeed*dirx;
    py = py + enemyspeed*diry;
  }


  public void coll() {
  }
} //enemy End

class particles {
  float px;
  float py;
  float vy;
  float vx;
  float ax;

  particles(float _px, float _py, float _vx, float _vy) {
    py = _py;
    px = _px;

    vx = _vx;
    vy = _vy;
  }

  public void live() { 
    ax = ax + 0.2f ;
    py = py + vy + ax;
    px = px + vx;
    // tar bort initalacc
    ellipse(px, py, 1, 1);
  }

  public boolean die() {
    if ( py > height+20) {
      return true;
    }
    else {

      return false;
    }
  }
}



//%%%%%%%%% KEYPRESSING SHIT %%%%%%%%%%%%%%%%%%%%

public void keyPressed() {
  if  (key == 'W' || key == 'w') {

    keys[0] = true;
  }
  if  (key == 'S' || key == 's') {

    keys[1] = true;
  }
  if  (key == 'A' || key == 'a') {

    keys[2] = true;
  }
  if  (key == 'D' || key == 'd') {

    keys[3] = true;
  }
}

public void keyReleased() {

  if  (key == 'W' || key == 'w') {

    keys[0] = false;
  }
  if  (key == 'S' || key == 's') {

    keys[1] = false;
  }
  if  (key == 'A' || key == 'a') {

    keys[2] = false;
  }
  if  (key == 'D' || key == 'd') {

    keys[3] = false;
  }
}

public void stop()
{
  shoot.close();
  explosion.close();
  hit.close();
  minim.stop();
  super.stop();
}

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "Cyberroids_X" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
