package com.syntacticsugar.vooga.gameplayer.manager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EventListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.syntacticsugar.vooga.gameplayer.attribute.HealthAttribute;
import com.syntacticsugar.vooga.gameplayer.attribute.IAttribute;
import com.syntacticsugar.vooga.gameplayer.attribute.ScoreAttribute;
import com.syntacticsugar.vooga.gameplayer.attribute.movement.MovementControlAttribute;
import com.syntacticsugar.vooga.gameplayer.attribute.weapon.BasicWeaponAttribute;
import com.syntacticsugar.vooga.gameplayer.conditions.ConditionType;
import com.syntacticsugar.vooga.gameplayer.engine.GameEngine;
import com.syntacticsugar.vooga.gameplayer.event.ICollisionEvent;
import com.syntacticsugar.vooga.gameplayer.event.IGameEvent;
import com.syntacticsugar.vooga.gameplayer.event.implementations.HealthChangeEvent;
import com.syntacticsugar.vooga.gameplayer.event.implementations.LevelChangeEvent;
import com.syntacticsugar.vooga.gameplayer.game.Game;
import com.syntacticsugar.vooga.gameplayer.objects.GameObject;
import com.syntacticsugar.vooga.gameplayer.objects.GameObjectType;
import com.syntacticsugar.vooga.gameplayer.objects.IGameObject;
import com.syntacticsugar.vooga.gameplayer.universe.IGameUniverse;
import com.syntacticsugar.vooga.gameplayer.view.GameViewController;
import com.syntacticsugar.vooga.xml.data.GameData;
import com.syntacticsugar.vooga.xml.data.ObjectData;
import com.syntacticsugar.vooga.xml.data.UniverseData;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Duration;

public class GameManager implements IGameManager{

	private Game myGame;
	private IGameUniverse currentLevel;
	// private List<IGameCondition> myConditions;
	// private GameInformation myInformation;
	private Timeline myGameTimeline;
	private GameEngine myGameEngine;

	private IEventManager myEventManager;
	
	private GameViewController myViewController;
	
	// engine stage
	private Stage myStage;
	private double frameLength;
	
	private List<EventListener> myListeners; // Will go in game players

	public GameManager(EventHandler<WindowEvent> onClose, double gameSize, GameData data, double frameRate) {
		this.frameLength = frameRate;
		myStage = new Stage();
		myStage.setOnCloseRequest(onClose);

		myEventManager = new EventManager();
		myEventManager.registerListener(this);

		myGame = new Game(data);
		currentLevel = myGame.getLevel(1);

		myViewController = new GameViewController(gameSize);
		myViewController.displayLevel(currentLevel);
		currentLevel.registerListeners(myEventManager);
		myGameEngine = new GameEngine(currentLevel, myViewController);

		stageInit();
	}

	private void stageInit() {
		Scene gameScene = new Scene(getGameView());
		initializeAnimation(frameLength);
		gameScene.addEventFilter(KeyEvent.KEY_PRESSED, e -> receiveKeyPressed(e.getCode()));
		gameScene.addEventFilter(KeyEvent.KEY_RELEASED, e -> receiveKeyReleased(e.getCode()));
		gameScene.setOnKeyPressed(e -> receiveKeyPressed(e.getCode()));
		gameScene.setOnKeyReleased(e -> receiveKeyReleased(e.getCode()));
		myStage.setScene(gameScene);
		myStage.show();
	}

	@Override
	public void restartGame() {
		myGameEngine.resetUniverse(currentLevel);
	}

	@Override
	public void updateGame() {
		myGameEngine.update();
		
	}
	
	public void pause() {
		myGameTimeline.pause();
	}
	

	@Override
	public void switchLevel(ConditionType type) {
		pause();
		if (type.equals(ConditionType.WINNING)) {
			System.out.println("WINNER");
			nextLevel();
		} else if (type.equals(ConditionType.LOSING)) {
			System.out.println("YOU LOSE");
			restartGame();
			startGame();
		}

	}
	
	private void nextLevel(){
		currentLevel = myGame.nextLevel();
		myViewController.displayLevel(currentLevel);
		myEventManager = new EventManager();
		myEventManager.registerListener(this);
		currentLevel.registerListeners(myEventManager);
		myGameEngine = new GameEngine(currentLevel, myViewController);
		//myGameTimeline.stop();
		initializeAnimation(frameLength);
		System.out.println("HERRRRRR");
	}

	public void receiveKeyPressed(KeyCode code) {
		if (code.equals(KeyCode.P)) {
			if (myGameTimeline.getCurrentRate() == 0.0) {
				myGameTimeline.play();
			} else {
				myGameTimeline.pause();
			}
		} 
		else if (code.equals(KeyCode.S)) {
			saveGame();
		} 
		else {
			myGameEngine.receiveKeyPressed(code);
		}
	}

	public void receiveKeyReleased(KeyCode code) {
		myGameEngine.receiveKeyReleased(code);
	}

	public Pane getGameView() {
		return myGameEngine.getGameView();
	}

	@Override
	public void startGame() {
		myGameTimeline.play();
	}

	public void initializeAnimation(double fl) {
		KeyFrame frame = new KeyFrame(Duration.seconds(fl), e -> updateGame());
		myGameTimeline = new Timeline();
		myGameTimeline.setCycleCount(Timeline.INDEFINITE);
		myGameTimeline.getKeyFrames().add(frame);
		startGame();
	}

	@Override
	public void onEvent(IGameEvent e) {
		try {
			LevelChangeEvent event = (LevelChangeEvent) e;
			System.out.println("LEVEL SWITCH");
			switchLevel(event.getLevelConditionType());
		}
		catch (ClassCastException ex) {
			
		}
	}
	
	private void saveGame() {
		UniverseData data = currentLevel.saveGame();
		myGame.saveGame(data);
	}

}

@@ -51,542 +51,8 @@
 r;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.Collection;%0Aimport java.util.EventListener;%0Aimport java.util.HashMap;%0Aimport java.util.List;%0Aimport java.util.Map;%0A%0Aimport com.syntacticsugar.vooga.gameplayer.attribute.HealthAttribute;%0Aimport com.syntacticsugar.vooga.gameplayer.attribute.IAttribute;%0Aimport com.syntacticsugar.vooga.gameplayer.attribute.ScoreAttribute;%0Aimport com.syntacticsugar.vooga.gameplayer.attribute.movement.MovementControlAttribute;%0Aimport com.syntacticsugar.vooga.gameplayer.attribute.weapon.BasicWeaponAttribute;
 %0Aimp
@@ -183,74 +183,8 @@
 ne;%0A
-import com.syntacticsugar.vooga.gameplayer.event.ICollisionEvent;%0A
 impo
@@ -309,356 +309,78 @@
 ons.
-HealthChangeEvent;%0Aimport com.syntacticsugar.vooga.gameplayer.event.implementations.LevelChangeEvent;%0Aimport com.syntacticsugar.vooga.gameplayer.game.Game;%0Aimport com.syntacticsugar.vooga.gameplayer.objects.GameObject;%0Aimport com.syntacticsugar.vooga.gameplayer.objects.GameObjectType;%0Aimport com.syntacticsugar.vooga.gameplayer.objects.IGameObject
+LevelChangeEvent;%0Aimport com.syntacticsugar.vooga.gameplayer.game.Game
 ;%0Aim
@@ -567,61 +567,8 @@
 ta;%0A
-import com.syntacticsugar.vooga.xml.data.ObjectData;%0A
 impo
@@ -1375,77 +1375,8 @@
 h;%0A%09
-%0A%09private List%3CEventListener%3E myListeners; // Will go in game players
 %0A%0A%09p

Clean up imports