/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Modul_8_Dhaf;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import Modul_6_Dhaf.*;

public class TestSprite extends JPanel implements Runnable, MouseListener, KeyListener {
    private Thread th;
    private ImageManager imsMgr;
    private boolean showBound = false;
    private boolean showHelp = true;
    private boolean pause = true;
    private PlayerSprite player;
    private boolean fireEnable;
    private int enemyMaxSize = 5;
    private BufferedImage HelpImage;
    private String[] enemySprite = { "adHeli", "navyHeli", "stHeli", "tigerHeli", "whiteHeli" };
    private long shootSpaceTime;
    private long reSpawnTime;
    private ArrayList<EnemySprite> enemySprites;
    private ArrayList<BulletSprite> playerBullet = new ArrayList<BulletSprite>();
    private ArrayList<BulletSprite> enemyBullet = new ArrayList<BulletSprite>();
    private Random rand = new Random();
    private Graphics2D g2d;
    private BufferedImage bufImg;
    private boolean running;
    
    public TestSprite() {
        setPreferredSize(new Dimension(800, 600));
        imsMgr = new ImageManager();
        th = new Thread(this);
        running = true;
        init();
        
        HelpImage=imsMgr.getImage("HeliHelp");
        addMouseListener(this);
    }
    
    public void init() {
      imageLoad();
      initPlayer();
      initEnemy();
    }
    
    public void imageLoad() {
        imsMgr = new ImageManager();
        imsMgr.setPath("Jeni7/images");
        imsMgr.loadSingleImage("HeliWarBackground.png");
        imsMgr.loadStripImages("playerHeli.png", 4, 1);
        imsMgr.loadStripImages("playerHeliFire.png", 4, 1);
        imsMgr.loadStripImages("playerHeliAwake.png", 4, 4);
        imsMgr.loadStripImages("adHeli.png", 4, 1);
        imsMgr.loadStripImages("navyHeli.png", 4, 1);
        imsMgr.loadStripImages("stHeli.png", 4, 1);
        imsMgr.loadStripImages("tigerHeli.png", 4, 1);
        imsMgr.loadStripImages("whiteHeli.png", 4, 1);
        imsMgr.loadStripImages("adHeliFire.png", 4, 1);
        imsMgr.loadStripImages("navyHeliFire.png", 4, 1);
        imsMgr.loadStripImages("stHeliFire.png", 4, 1);
        imsMgr.loadStripImages("tigerHeliFire.png", 4, 1);
        imsMgr.loadStripImages("whiteHeliFire.png", 4, 1);
        imsMgr.loadSingleImage("redPlasma.png");
        imsMgr.loadSingleImage("greenPlasma.png");
        imsMgr.loadSingleImage("HeliHelp.png");
        imsMgr.loadStripImages("explosion.png", 4, 4);
        imsMgr.loadStripImages("explosion2.png", 4, 2);
        imsMgr.loadStripImages("explosion3.png", 5, 2);
    }
    
    public void initPlayer() {
        player = new PlayerSprite(200, 400, imsMgr, "playerHeli");
        player.loopImage(50, 0.5, true);
        player.setStep(0, 0);
        player.addBoundingBox(new Rectangle(40, 0, 15, 95));
        player.addBoundingBox(new Rectangle(30, 5, 35, 35));
        player.repositionBoundingBoxs();
    }

    public void initEnemy() {
        enemySprites = new ArrayList<EnemySprite>();
        for (int i = 0; i < enemyMaxSize; i++) {
            EnemySprite em = new EnemySprite(rand.nextInt(700), -rand.nextInt(100), imsMgr, enemySprite[rand.nextInt(5)], enemySprites, enemyBullet);
                  em.loopImage(50, 0.5, true);
                  em.setStep(rand.nextInt(2) - rand.nextInt(2), 1 +rand.nextInt(2));
                  em.addBoundingBox(new Rectangle(40, 0, 15, 95));
                  em.addBoundingBox(new Rectangle(30, 50, 35, 35));
                  em.repositionBoundingBoxs();
                  em.setTarget(player);
                  enemySprites.add(em);
            }
      }
    
      public void start() {
            th.start();
      }
      
      public void stop() {
            running = false;
      }
      
      public void run() {
            while (running) {
                  try {
                        Thread.sleep(20);
                  } catch (Exception e) {
                  }
                  update();
                  render();
                  repaint();
            }
      }
      
      public void update() {
            if (!pause) {
                  collsionCheck();
                  //
                  player.updateSprite();
                  if (fireEnable)
                        fire();
                  // try{
                  for (int i = 0; i < enemySprites.size(); i++) {
                        EnemySprite es = enemySprites.get(i);
                        if (i == enemySprites.size())
                              break;
                        es.updateSprite();
                        es.updateMovement();
                        es.updateState();
                        if (es.getXPosn() <= 0 || es.getXPosn()+es.getWidth()>=800)
                              es.setStep(-es.getXStep(), es.getYStep());
                        if (es.getYPosn()>= 800)
                              es.setPosition(es.getXPosn(), -100);
                  }
                  // }catch(Exception e){System.out.println("hehehe
                  // "+e.getMessage());}
                  for (int i = 0; i < enemyBullet.size(); i++) {
                        BulletSprite bp = enemyBullet.get(i);
                        bp.updateSprite();
                        if (bp.getYPosn() <= 0 || bp.getYPosn() >= 600) {
                              enemyBullet.remove(bp);
                        }
                  }
                  
                  for (int i = 0; i < playerBullet.size(); i++) {
                        BulletSprite bp = playerBullet.get(i);
                        bp.updateSprite();
                        if (bp.getYPosn() <= 0 || bp.getYPosn() >= 600) {
                              playerBullet.remove(bp);
                        }
                  }
                  
                  if (System.currentTimeMillis() >= reSpawnTime)
                        reSpawnEnemy();
            }
      }
      
      public void collsionCheck() {
            for (int i = 0; i < enemySprites.size(); i++) {
                  EnemySprite em = enemySprites.get(i);
                  if (player.isCollidedWith(em)&& (player.getState()!=HeliSprite.STATE_EXPLODING && em.getState() !=HeliSprite.STATE_EXPLODING)) {
                        player.explode();
                        fireEnable=false;
                        em.explode();
                  }
            }
            
            for (int i = 0; i < enemyBullet.size(); i++) {
                  BulletSprite bp = enemyBullet.get(i);
                  if (bp.getState()==BulletSprite.STATE_NORMAL && player.isCollidedWith(bp)) {
                        //enemyBullet.remove(bp);
                        bp.explode();
                        //System.out.println("Player got Shooted");
                  }
            }
            
            for (int i = 0; i < enemySprites.size(); i++) {
                  EnemySprite em = enemySprites.get(i);
                  for (int j = 0; j < playerBullet.size(); j++) {
                        BulletSprite bp = playerBullet.get(j);
                        if (bp.getState()==BulletSprite.STATE_NORMAL && em.getState() !=  HeliSprite.STATE_EXPLODING)
                              if (em.isCollidedWith(bp)) {
                                    //playerBullet.remove(bp);
                                    bp.explode();
                                    em.explode();
                              }
                  }
            }
            
            for (int i = 0; i < playerBullet.size(); i++) {
                  BulletSprite bpp = playerBullet.get(i);
                  for (int j = 0; j < enemyBullet.size(); j++) {
                        BulletSprite bpe = enemyBullet.get(j);
                        if ((bpe.getState()==BulletSprite.STATE_NORMAL && bpp.getState()==BulletSprite.STATE_NORMAL) && bpp.getBoundingBox().intersects(bpe.getBoundingBox())) {
                              //playerBullet.remove(bpp);
                              //enemyBullet.remove(bpe);
                              bpp.explode();
                              bpe.explode();
                        }
                  }
            }
      }
      
      public void fire() {
            if (System.currentTimeMillis() >= shootSpaceTime) {
                  BulletSprite leftBullet = new BulletSprite(player.getXPosn()+ 30,player.getYPosn(), imsMgr,"redPlasma",playerBullet);
                  leftBullet.setStep(0, -6);
                  leftBullet.setOwner(player);
                  BulletSprite rightBullet = new BulletSprite(player.getXPosn()+ 57,player.getYPosn(), imsMgr,"redPlasma",playerBullet);
                  rightBullet.setStep(0, -6);
                  rightBullet.setOwner(player);
                  playerBullet.add(rightBullet);
                  playerBullet.add(leftBullet);
                  shootSpaceTime = System.currentTimeMillis() + 100;
            }
      }
      
      public void reSpawnEnemy() {
            for (int i = 0; i < enemyMaxSize - enemySprites.size(); i++) {
                  EnemySprite es = new EnemySprite(rand.nextInt(700), -rand.nextInt(100), imsMgr,enemySprite[rand.nextInt(5)],enemySprites, enemyBullet);
                  es.loopImage(50, 0.5, true);
                  es.setStep(rand.nextInt(2) - rand.nextInt(2), 1 +rand.nextInt(2));
                  es.addBoundingBox(new Rectangle(40, 0, 15, 95));
                  es.addBoundingBox(new Rectangle(30, 50, 35, 35));
                  es.repositionBoundingBoxs();
                  es.setTarget(player);
                  enemySprites.add(es);
                  reSpawnTime = System.currentTimeMillis() +rand.nextInt(2000);
            }
      }
      
      public void render() {
            if (bufImg == null) {
                  bufImg = (BufferedImage) createImage(800, 600);
                  if (bufImg == null) {
                         System.out.println("dbImage is null");
                         return;
                  } else
                         g2d = (Graphics2D) bufImg.getGraphics();//getGraphics();
            }
            
            g2d.setColor(Color.black);
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.drawImage(imsMgr.getImage("HeliWarBackground"), 0, 0, null);
            player.drawSprite(g2d);
            
            for (int i = 0; i < enemySprites.size(); i++)
                  enemySprites.get(i).drawSprite(g2d);
            
            for (int i = 0; i < playerBullet.size(); i++)
                  playerBullet.get(i).drawSprite(g2d);
            
            for (int i = 0; i < enemyBullet.size(); i++)
                  enemyBullet.get(i).drawSprite(g2d);
            
            if (showBound)
                  drawSpriteBound(g2d);
            
            if (showHelp)
                  g2d.drawImage(HelpImage, (getWidth()/2)-HelpImage.getWidth()/2, (getHeight()/2)-HelpImage.getHeight()/2, null);
      }
      
      public void drawSpriteBound(Graphics2D g2d) {
            g2d.setColor(Color.yellow);
            if (player.getBoundingBoxs().size() > 0)
                  for (int i = 0; i < player.getBoundingBoxs().size(); i++)
                         g2d.draw((Shape) player.getBoundingBoxs().get(i));
            else
                  g2d.draw((Shape) player.getBoundingBox());
            
            for (int i = 0; i < enemySprites.size(); i++) {
                  enemySprites.get(i).drawSprite(g2d);
                  ArrayList bound = enemySprites.get(i).getBoundingBoxs();
                  if (bound.size() > 0) {
                         for (int j = 0; j < bound.size(); j++) {
                               g2d.draw((Shape) bound.get(j));
                         }
                         
            } else {
                  g2d.draw((Shape) enemySprites.get(i).getBoundingBox());
            }
      }
            
      for (int i = 0; i < enemyBullet.size(); i++)
            g2d.draw((Shape) enemyBullet.get(i).getBoundingBox());
            
      for (int i = 0; i < playerBullet.size(); i++)
            g2d.draw((Shape) playerBullet.get(i).getBoundingBox());
}
      
public void paint(Graphics g) {
      g.drawImage(bufImg, 0, 0, null);
}

public static void main(String[] arg) {
      TestSprite ttPanel = new TestSprite();
      ttPanel.start();
      JFrame app = new JFrame("Sprite and Collision");
      app.getContentPane().add(ttPanel, BorderLayout.CENTER);
      app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      app.addKeyListener(ttPanel);
      app.pack();
      app.setResizable(false);
      app.setVisible(true);
}
public void mouseClicked(MouseEvent e) {
      // TODO Auto-generated method
}
public void mouseEntered(MouseEvent arg0) {
      // TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
      // TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
      // TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
      // TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
      int keyCode = e.getKeyCode();
      switch (keyCode) {
      case KeyEvent.VK_ESCAPE:
            stop();
            System.exit(0);
            break;
      case KeyEvent.VK_H:
            pause = !pause;
            showHelp = !showHelp;
            break;
      }
      if(!pause)
      switch (keyCode) {
      case KeyEvent.VK_B:
            showBound = !showBound;
            break;
      }
      if(!pause && player.getState()!= HeliSprite.STATE_EXPLODING){
            switch (keyCode) {
            case KeyEvent.VK_CONTROL:
                   if (!fireEnable) {
                          fireEnable = true;
                          player.fire();
                   }
                   break;
            case KeyEvent.VK_LEFT:
                   player.setStep(-4, 0);
                   break;
            case KeyEvent.VK_RIGHT:
                   player.setStep(4, 0);
                   break;
            case KeyEvent.VK_UP:
                   player.setStep(0, -4);
                   break;
            case KeyEvent.VK_DOWN:
                   player.setStep(0, 4);
                   break;
            }
      }
}
public void keyReleased(KeyEvent e) {
      int keyCode = e.getKeyCode();
      if(!pause && player.getState()!= HeliSprite.STATE_EXPLODING){
            switch (keyCode) {
            case KeyEvent.VK_CONTROL:
                   fireEnable = false;
                   player.normal();
                   break;
            case KeyEvent.VK_LEFT:
                   player.setStep(0, 0);
                   break;
            case KeyEvent.VK_RIGHT:
                   player.setStep(0, 0);
                   break;
              case KeyEvent.VK_UP:
                    player.setStep(0, 0);
                    break;
              case KeyEvent.VK_DOWN:
                    player.setStep(0, 0);
                    break;
        }
        }
  }
  public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
  }
  public void mouseDragged(MouseEvent arg0) {
        // TODO Auto-generated method stub
  }
  public void mouseMoved(MouseEvent arg0) {
        // TODO Auto-generated method stub
  }
}

