package;

import game.Game;
import lime.ui.Gamepad;
import lime.ui.GamepadAxis;
import lime.ui.GamepadButton;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import menu.MainMenu;
import openfl.Lib;
import openfl.display.Sprite;
import openfl.events.Event;

class Main extends Sprite {
	static var _instance:Main;

	public static var instance(get, never):Main;

	static function get_instance():Main
		return _instance;

	var _currentState:State;

	var _lastTime:Int;

	public var activeGamepad:Gamepad = null;

	public var lastInputMethod:InputMode = KEYBOARD;

	public function new() {
		super();

		scaleX = scaleY = 10;

		_instance = this;

		Lib.application.window.onKeyDown.add(onKeyDown);
		Lib.application.window.onKeyUp.add(onKeyUp);

		Gamepad.onConnect.add(onGamepadConnect);

		addEventListener(Event.ENTER_FRAME, onEnterFrame);
		addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

		setState(new MainMenu());
	}

	public function setState(state:State) {
		if (_currentState != null) {
			_currentState.pauseSounds();
			removeChild(_currentState);
		}

		_currentState = state;

		addChild(_currentState);

		_currentState.resumeSounds();
	}

	function onAddedToStage(event:Event) {
		_lastTime = Lib.getTimer();
	}

	function onGamepadConnect(gamepad:Gamepad) {
		trace('Gamepad connected: ${gamepad.name}');

		gamepad.onAxisMove.add(onGamepadAxisMove);
		gamepad.onButtonDown.add(onGamepadButtonDown);
		gamepad.onButtonUp.add(onGamepadButtonUp);

		activeGamepad = gamepad;
	}

	function onGamepadButtonDown(button:GamepadButton) {
		if (_currentState != null)
			_currentState.gamepadButtonDown(button);

		lastInputMethod = GAMEPAD;
	}

	function onGamepadButtonUp(button:GamepadButton) {
		if (_currentState != null)
			_currentState.gamepadButtonUp(button);
		lastInputMethod = GAMEPAD;
	}

	function onGamepadAxisMove(axis:GamepadAxis, val:Float) {
		if (_currentState != null)
			_currentState.gamepadAxis(axis, val);

		lastInputMethod = GAMEPAD;
	}

	function onKeyDown(keyCode:KeyCode, modifier:KeyModifier) {
		if (_currentState != null)
			_currentState.keyDown(keyCode, modifier);

		lastInputMethod = KEYBOARD;
	}

	function onKeyUp(keyCode:KeyCode, modifier:KeyModifier) {
		if (_currentState != null)
			_currentState.keyUp(keyCode, modifier);

		lastInputMethod = KEYBOARD;
	}

	function onEnterFrame(event:Event) {
		var _currentTime = Lib.getTimer();

		if (_currentState != null) {
			_currentState.update((_currentTime - _lastTime) / 1000);
			_currentState.render();
		}

		_lastTime = _currentTime;
	}
}
