package bullithell.objects;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;

import main.Joystick;
import bullithell.images.Images;
import bullithell.objects.missiles.Ball;
import bullithell.objects.missiles.Missile;
import bullithell.objects.missiles.PlayerMissile;
import bullithell.particles.Fireball;

public class Player extends Ship implements KeyListener{
	private double movedirvert, movedirhor;
	private int health, score, shieldpower;
	private ArrayList<Fireball> particle;
	private ArrayList<PlayerMissile> missiles;
	private boolean launchmissiles;
	private long lastFired;
	Joystick joystick;
	
	public Player(int x, int y) {
		super(Images.player,x,y);
		new Thread(joystick = new Joystick());
		reset();
	}
	
	@Override public void keyTyped(KeyEvent e) {}
	@Override
	public void keyReleased(KeyEvent e) {
		if(((e.getKeyChar() == 'd' ||  e.getKeyCode() == KeyEvent.VK_RIGHT) && movedirvert == 1) || ((e.getKeyChar() == 'a' || e.getKeyCode() == KeyEvent.VK_LEFT) && movedirvert == -1)){
			movedirvert = 0;
		}else if(((e.getKeyChar() == 'w' ||  e.getKeyCode() == KeyEvent.VK_UP) && movedirhor == -1) || ((e.getKeyChar() == 's' || e.getKeyCode() == KeyEvent.VK_DOWN) && movedirhor == 1)){
			movedirhor = 0;
		}else if(e.getKeyChar() == ' ' || e.getKeyCode() == KeyEvent.VK_ENTER){
			launchmissiles = false;
		}
	}
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyChar() == 'd' || e.getKeyCode() == KeyEvent.VK_RIGHT){
			movedirvert = 1;
		}else if(e.getKeyChar() == 'a' || e.getKeyCode() == KeyEvent.VK_LEFT){
			movedirvert = -1;
		}else if(e.getKeyChar() == 'w' || e.getKeyCode() == KeyEvent.VK_UP){
			movedirhor = -1;
		}else if(e.getKeyChar() == 's' || e.getKeyCode() == KeyEvent.VK_DOWN){
			movedirhor = 1;
		}else if(e.getKeyChar() == ' ' || e.getKeyCode() == KeyEvent.VK_ENTER){
			launchmissiles = true;
		}
	}
	public void setLives(int health){
		this.health = health;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	public int getHealth() {
		return health;
	}	
	public int getShieldpower() {
		return shieldpower;
	}
	public void setShieldpower(int shieldpower) {
		this.shieldpower = shieldpower;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public void reset(){
		particle = new ArrayList<Fireball>();
		missiles = new ArrayList<PlayerMissile>();
		health = 120;
		shieldpower = 100;
		score = 0;
	}
	public void draw(Graphics2D g2){
		if(shieldpower > 0){
			g2.setPaint(new RadialGradientPaint(new Point((int)(border.getX() + border.getWidth()/2),(int)(border.getY() + border.getHeight()/2)), (int)(border.getHeight()), new float[]{0.3f,0.9f,1f}, new Color[]{new Color(0,0,0,0),new Color(130,208,250,shieldpower*2),new Color(0,0,0,0) }));
			g2.fillRect((int)(border.getX()-100), (int)(border.getY()-100), (int)(border.getWidth()+200),(int)(border.getHeight()+200));
		}
		super.draw(g2);
		try{
			Iterator<PlayerMissile> i = missiles.iterator();
			while(i.hasNext()){
				PlayerMissile m = i.next();
				m.draw(g2);
			}
			Iterator<Fireball> j = particle.iterator();
			while(j.hasNext()){
				Fireball b = j.next();
				b.draw(g2);
			}
		}catch(ConcurrentModificationException e){e.printStackTrace();}
	}
	
	public void reCalculate(){
		movedirvert = (joystick.getxAxisPercentage()-50)*0.15;
		movedirhor = (joystick.getyAxisPercentage()-50)*-0.15;
		
		Iterator<PlayerMissile> i = missiles.iterator();
		while(i.hasNext()){
			PlayerMissile m = i.next();
			if(m.outOfScreen(0, 0, 800, 800)){
				i.remove();
			}else{
				m.recalculate();
			}
		}
		Iterator<Fireball> j = particle.iterator();
		while(j.hasNext()){
			Fireball b = j.next();
			if(b.color.getBlue() < 160){
				j.remove();
			}else{
				b.update();
			}
		}
		if(movedirvert != 0 || movedirhor != 0){
			border.setLocation((int)(border.getX()+movedirvert*12), (int)(border.getY()+movedirhor*12));
			for(int k = 0; k < 120; k++){
				particle.add(new Fireball((int)(border.getX()+(border.getWidth()/2)+(Math.random()*10)-5), (int)(border.getMaxY()+(Math.random()*10)), (int)((border.getX() + border.getMaxX()) / 2)));
			}
		}
		if(launchmissiles && System.currentTimeMillis() - lastFired > 200){
			lastFired = System.currentTimeMillis();
			missiles.add(new PlayerMissile(getX()+10, getY(), 20));
			missiles.add(new PlayerMissile(getX()+45, getY(), 20));
		}
	}
	
	public boolean missileIntersect(Missile m){
		Iterator<PlayerMissile> i = missiles.iterator();
		while(i.hasNext()){
			PlayerMissile pm = i.next();
			if(pm.intersect(m)){
				i.remove();
				return true;
			}
		}
		return false;
	}
	public boolean intersect(ArrayList<Missile> missiles){
		boolean tempreturn = false;
		for(Missile m:missiles){
			Ellipse2D shield = new Ellipse2D.Double((int)(border.getX()+border.getWidth()/2-60), (int)(border.getY()+border.getHeight()/2)-50, (int)(border.getHeight())+50, (int)border.getWidth()+50);
			if(shieldpower > 0 && shield.intersects(m.getBorder())){
				if(m.type == Missile.Missiletype.BALL){
					Ball ball = (Ball)m;
					if(!ball.isReturned()){
						m.setYspeed(m.getYspeed()*-1.5);
						shieldpower -= 10;
						ball.setReturned(true);
					}

				}
			}else if(m.intersect(getBorder())){
				health -= 10;
				m.explode(true);
				return true;
			}

		}
		return tempreturn;
	}
}
