package menus;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.jln.ld.Game;
import com.jln.ld.GameAnimation;
import com.jln.ld.Shared;

import MapItem.MessagePoint;
import MapItem.Powerup;
import Ship.BasicShip;
import Ship.Hunter01;
import Ship.Hunter02;
import Ship.SupplySpaceship;
import enemis.Asteroid;
import enemis.Destroyer;
import enemis.MegaDestroyer;
import enemis.SmallDestroyer;
import enemis.SmallExtraDestroyer;
import shoot.BasicShoot;
import space.Space;

public class GameMenu {

	private GameHud hud;
	private Space space;
	private BasicShip hunter01;
	private BasicShip hunter02;
	private BasicShip supply;
	private List<BasicShoot> shoots;
	private List<BasicShoot> enemyshoots;
	private List<GameAnimation> animations;
	private List<Asteroid> asteroids;
	private List<Powerup> powerups;
	private List<MessagePoint> messages;
	private List<Destroyer> enemis;
	private int points;
	private String strPoints;
	private int timer = 0;
	private int tic = 0;
	private boolean gameover = false;
	private boolean goToTitle = false;

	public boolean updateAsteroid = false;
	public boolean updateEnemis = false;


	public GameMenu() {
		hud = new GameHud();
	}

	public void initGame(){
		hunter01 = new Hunter01(160,150,true);
		hunter02 = new Hunter02(70,70,false);
		supply = new SupplySpaceship(70,260,false);

		space = new Space();
		shoots = new ArrayList<>();
		enemyshoots = new ArrayList<>();
		asteroids = new ArrayList<>();
		animations = new ArrayList<>();
		powerups = new ArrayList<>();
		messages = new ArrayList<>();
		enemis = new ArrayList<>();
		
		asteroids.add(new Asteroid(Asteroid.MEDIUM1,true));
		asteroids.add(new Asteroid(Asteroid.MEDIUM1,true));
		asteroids.add(new Asteroid(Asteroid.MEDIUM1,true));
		asteroids.add(new Asteroid(Asteroid.MEDIUM1,true));
		goToTitle = false;
		gameover = false;
		hud.initGameHud();

		points = 0;
		timer = 0;
		tic = 0;
		calculateStrPoints();
		Shared.MUSIC_01.play();
		Shared.MUSIC_01.setLooping(true);
	}

	/**
	 * ==========================================
	 * == MISE A JOUR DE L'OBJET               ==
	 * ==========================================
	 */
	public void update(Game game){

		if(Shared.CPT_DECAL>0){
			Shared.CPT_DECAL--;
			if(Shared.CPT_DECAL<=0){
				if(Shared.CPT_DECALBIS>0){
					Shared.CPT_DECALBIS--;
					Shared.DECAL_X=-Shared.DECAL_X;
					Shared.DECAL_Y=-Shared.DECAL_Y;
					Shared.CPT_DECAL = 3;
				}else{
					Shared.DECAL_X=0;
					Shared.DECAL_Y=0;
				}

			}
		}
		hud.update(this);
		if(!hud.isOnPause()){
			space.update();
			hunter01.update(this);
			hunter02.update(this);
			supply.update(this);


			if(!shoots.isEmpty()){
				Iterator<BasicShoot> it = shoots.iterator();
				while(it.hasNext()){
					BasicShoot s = it.next();
					if(s.isDestroy()){
						it.remove();
					}else{
						s.update(this);
					}
				}
			}
			if(!enemyshoots.isEmpty()){
				Iterator<BasicShoot> it2 = enemyshoots.iterator();
				while(it2.hasNext()){
					BasicShoot s = it2.next();
					if(s.isDestroy()){
						it2.remove();
					}else{
						s.update(this);
					}
				}
			}

			if(!animations.isEmpty()){
				Iterator<GameAnimation> itA = animations.iterator();
				while(itA.hasNext()){
					GameAnimation a = itA.next();
					if(a.isDestroy()){
						itA.remove();
					}else{
						a.update(this);
					}
				}
			}

			if(!powerups.isEmpty()){
				Iterator<Powerup> itP = powerups.iterator();
				while(itP.hasNext()){
					Powerup p = itP.next();
					if(p.isDestroy()){
						itP.remove();
					}else{
						p.update(this);
					}
				}
			}
			if(!messages.isEmpty()){
				Iterator<MessagePoint> itM = messages.iterator();
				while(itM.hasNext()){
					MessagePoint m = itM.next();
					if(m.isDestroy()){
						itM.remove();
					}else{
						m.update(this);
					}
				}
			}

			if(updateAsteroid){
				updateAsteroid = false;
				Iterator<Asteroid> itAs = asteroids.iterator();
				while(itAs.hasNext()){
					Asteroid as = itAs.next();
					if(as.isDestroy()){
						itAs.remove();
					}else{
						as.update(this);
					}
				}
			}else{
				for (Asteroid asteroid : asteroids) {
					asteroid.update(this);
				}
			}
			if(updateEnemis){
				updateEnemis = false;
				Iterator<Destroyer> itE = enemis.iterator();
				while(itE.hasNext()){
					Destroyer e = itE.next();
					if(e.isDestroy()){
						itE.remove();
					}else{
						e.update(this);
					}
				}
			}else{
				for (Destroyer en : enemis) {
					en.update(this);
				}
			}


			if(points > 4000 && points%50==0){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}

			if(tic >=60){
				tic = 0;
				if(timer<Integer.MAX_VALUE-1){
					timer++;
				}
				if(timer==26){
					addAstroidWave(1);
				}else if(timer == 42){
					addEnemyWave(1);
				}else if(timer == 55){
					addAstroidWave(2);
				}else if(timer == 70){
					addEnemyWave(2);
				}else if(timer == 96){
					addEnemyWave(3);
				}else if(timer == 110){
					addEnemyWave(4);
				}else if(timer == 130){
					addEnemyWave(5);
				}else if(timer == 150){
					addAstroidWave(3);
				}else if(timer == 170){
					addAstroidWave(4);
				}else if(timer == 180){
					for(Asteroid as : asteroids){
						as.setRecreate(false);
					}
				}else if(timer == 185){
					addAstroidWave(5);
				}else if(timer == 215){
					addEnemyWave(6);
				}else if(timer == 230){
					addEnemyWave(7);
				}else if(timer == 240){
					addAstroidWave(6);
				}else if(timer == 270){
					addEnemyWave(8);
				}else if(timer > 310 && timer%15==0){
					addAstroidWave(6);
				}else if(timer >330 && timer%10==0){
					addEnemyWave((int)Math.random()*8);
				}
			}else{
				tic++;
			}
			
			if((hunter01.isDead()||hunter01.getEnergy()<=0) && (hunter02.isDead() || hunter02.getEnergy()<=0) && (supply.isDead() || supply.getEnergy()<=0)){
				gameover = true;
			}

			if(!gameover && (Gdx.input.isKeyJustPressed(Keys.CONTROL_LEFT) || getPlayerShip().isDead())){
				this.switchShipOnControl();
			}

		}

		if(goToTitle){
			Shared.MUSIC_01.stop();
			game.goToTitleMenu(points,strPoints);
		}
	}

	/**
	 * ==========================================
	 * == DESSIN DE L'OBJET                    ==
	 * ==========================================
	 */
	public void render(Game game){
		Shared.GAME_BATCH.begin();
		space.render();

		if(!hunter01.isPlayerOnControl())hunter01.render(this);
		if(!hunter02.isPlayerOnControl())hunter02.render(this);
		if(!supply.isPlayerOnControl())supply.render(this);

		if(hunter01.isPlayerOnControl())hunter01.render(this);
		if(hunter02.isPlayerOnControl())hunter02.render(this);
		if(supply.isPlayerOnControl())supply.render(this);

		for (Asteroid asteroid : asteroids) {
			asteroid.render(this);
		}
		for (Destroyer en : enemis) {
			en.render(this);
		}
		for (Powerup powerup : powerups) {
			powerup.render(this);
		}

		for (BasicShoot s : shoots) {
			s.render(this);
		}
		for (BasicShoot s : enemyshoots) {
			s.render(this);
		}
		for (GameAnimation a : animations) {
			a.render(this);
		}
		for (MessagePoint a : messages) {
			a.render(this);
		}
		Shared.GAME_BATCH.end();

		Shared.MENU_BATCH.begin();
		hud.render(this);
		Shared.MENU_BATCH.end();
	}

	public int getShipOnControl(){
		if(hunter01.isPlayerOnControl()){
			return 1;
		}else if(hunter02.isPlayerOnControl()){
			return 2;
		}else{
			return 3;
		}
	}


	public void switchShipOnControl(){
		if(hunter01.isPlayerOnControl()){
			if(!hunter02.isDead()){
				hunter02.takeControl(this);
			}else if(!supply.isDead()){
				supply.takeControl(this);
			}else{
				return;
			}
			hunter01.giveControl(this);
		}else if(hunter02.isPlayerOnControl()){
			if(!supply.isDead()){
				supply.takeControl(this);
			}else if(!hunter01.isDead()){
				hunter01.takeControl(this);
			}else{
				return;
			}
			hunter02.giveControl(this);

		}else{
			if(!hunter01.isDead()){
				hunter01.takeControl(this);
			}else if(!hunter02.isDead()){
				hunter02.takeControl(this);
			}else{
				return;
			}
			supply.giveControl(this);
		}
	}

	public BasicShip getPlayerShip(){
		if(hunter01.isPlayerOnControl()){
			return hunter01;
		}else if(hunter02.isPlayerOnControl()){
			return hunter02;
		}else{
			return supply;
		}
	}
	public BasicShip getHunter01() {
		return hunter01;
	}

	public BasicShip getHunter02() {
		return hunter02;
	}

	public BasicShip getSupplyShip() {
		return supply;
	}

	public void addShoot(BasicShoot s){
		this.shoots.add(s);
	}
	public void addEnemyShoot(BasicShoot s){
		this.enemyshoots.add(s);
	}

	public List<BasicShoot> getShoots() {
		return shoots;
	}

	public List<Asteroid> getAsteroids() {
		return asteroids;
	}

	public List<GameAnimation> getAnimations() {
		return animations;
	}
	public List<Destroyer> getEnemis() {
		return enemis;
	}

	public List<Powerup> getPowerups() {
		return powerups;
	}

	public void incPoints(int i){
		this.points += i;
		calculateStrPoints();
	}

	public void incPointsWithMessage(int i, float x, float y){
		this.points += i;
		addMessage(x,y, String.valueOf(i), MessagePoint.TYPE_POINTS);
		calculateStrPoints();
	}

	public void addMessage(float x, float y,String m,int type){
		messages.add(new MessagePoint(x,y, m,type));
	}

	private void calculateStrPoints(){
		this.strPoints = String.valueOf(this.points);
		while(strPoints.length()<6){
			strPoints = "0"+strPoints;
		}
		strPoints = strPoints + " PTS";
	}

	public void addAstroidWave(int number){
		if(gameover){
			return;
		}
		if(number==1){
			for(int i=0;i<8;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}
		}else if(number==2){
			for(int i=0;i<16;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}
		}else if(number==3){
			for(int i=0;i<25;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}
		}else if(number==4){
			for(int i=0;i<35;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}
		}else{
			for(int i=0;i<14;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,false));
			}
			for(int i=0;i<3;i++){
				asteroids.add(new Asteroid(Asteroid.MEDIUM2,true));
			}
		}
	}

	public void addEnemyWave(int number){
		if(gameover){
			return;
		}
		if(number==1){
			enemis.add(new SmallDestroyer());
		}else if(number==2){
			enemis.add(new Destroyer());
		}else if(number==3){
			enemis.add(new Destroyer());
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallDestroyer());
		}else if(number==4){
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new SmallDestroyer());
		}else if(number==5){
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new Destroyer());
		}else if(number == 6){
			enemis.add(new MegaDestroyer());
		}else if(number == 7){
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallExtraDestroyer());
		}else if(number == 8){
			enemis.add(new Destroyer());
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new MegaDestroyer());
			enemis.add(new MegaDestroyer());
		}else{
			enemis.add(new SmallDestroyer());
			enemis.add(new Destroyer());
			enemis.add(new SmallDestroyer());
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new SmallExtraDestroyer());
			enemis.add(new MegaDestroyer());
			enemis.add(new MegaDestroyer());
		}
	}

	public void goToTitle(){
		goToTitle = true;
	}

	public int getPoints(){
		return this.points;
	}

	public String getPointsString(){
		return strPoints;
	}

	public int getTimer(){
		return timer;
	}

	public boolean isGameOver(){
		return gameover;
	}



}
