using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public abstract class Actions {
	//==============================================================================
	//Template
	//==============================================================================

	/*
	public static void template(NetworkReader message) {
		TemplateBuffer buffer = message.ReadMessage<TemplateBuffer>();
		template(buffer);
	}

	public static void template(NonExistingBuffer buffer) {
		//TODO
	}
	*/

	//==============================================================================
	//Message
	//==============================================================================

	public static void writeMessage(NetworkReader message) {
		MessageBuffer buffer = message.ReadMessage<MessageBuffer>();
		writeMessage(buffer);
	}

	public static void writeMessage(MessageBuffer buffer) {
		Debug.Log(buffer.message);
	}

	//==============================================================================
	//Move
	//==============================================================================

	public static void move(NetworkReader message) {
		MoveBuffer buffer = message.ReadMessage<MoveBuffer>();
		move(buffer, false);
	}

	public static void move(MoveBuffer buffer, bool isSelf = true) {
		GameObject gameObject = GameController.sharedGameObjects[buffer.id];
		Vector3 newPos = new Vector3(buffer.position.x, buffer.position.y, -1);

		//if (isSelf) {
			if ((gameObject.transform.localPosition - newPos).magnitude > 0.2f)
				gameObject.transform.localPosition = newPos;
			gameObject.GetComponentInChildren<Rigidbody2D>().velocity = buffer.speed;
			gameObject.GetComponentInChildren<Rigidbody2D>().rotation = buffer.rotation;

		/*}
		else {
			if ((gameObject.transform.localPosition - newPos).magnitude > 0.2f)
				gameObject.transform.localPosition = newPos;
			gameObject.GetComponent<Moving>().speed = buffer.speed;
			gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, buffer.rotation));
		}*/
	}

	//==============================================================================
	//EVA
	//==============================================================================

	public static void EVA(NetworkReader message) {
		EVABuffer buffer = message.ReadMessage<EVABuffer>();
		EVA(buffer);
	}

	public static void EVA(EVABuffer buffer) {
		GameObject character = GameController.sharedGameObjects[buffer.id];

		//TODO: change player controller
		if (character.GetComponent<SharedGameObject>().type == ObjectType.Character) { // char -> eva
			Debug.Assert(character.GetComponent<CharController>() != null);

			bool self = (GameController.player.characterController == character.GetComponent<CharController>());
			GameObject eva = GameController.instantiate(buffer.id, TemplateManager.getTemplate(ObjectType.EVA, 0), character.transform.position, character.transform.rotation.eulerAngles.z,
				character.GetComponent<CharController>().spaceShipInternals.transform.parent.FindChild("Collider").GetComponent<Rigidbody2D>().velocity);
			eva.GetComponent<EVAController>().enabled = self;
			GameController.updateNewSharedGameObject(eva);

			if (self)
				GameController.player.characterController = eva.GetComponent<EVAController>();
		}
		else { // eva -> char
			Debug.Assert(character.GetComponent<EVAController>() != null);

			bool self = (GameController.player.characterController == character.GetComponent<EVAController>());
			GameObject chara = GameController.instantiate(buffer.id, TemplateManager.getTemplate(ObjectType.Character, 0), character.transform.position, character.transform.rotation.eulerAngles.z);
			chara.GetComponent<CharController>().enabled = self;
			GameController.updateNewSharedGameObject(chara);

			if (self)
				GameController.player.characterController = chara.GetComponent<CharController>();
		}
	}

	//==============================================================================
	//Spawn
	//==============================================================================

	public static void spawn(NetworkReader message) {
		SpawnBuffer buffer = message.ReadMessage<SpawnBuffer>();
		spawn(buffer);
	}

	public static void spawn(SpawnBuffer buffer) {
		GameObject obj = GameController.instantiate(buffer.id, TemplateManager.getTemplate(buffer.type, buffer.index), buffer.position, buffer.rotation);
		if (buffer.type == ObjectType.Character) {
			Debug.Assert(buffer.parentSpaceShipID != -1);
		}
		else if (buffer.type == ObjectType.LargeSpaceShip) {
			GameController.largeSpaceShips.Add(obj);
		}

		if (buffer.parentSpaceShipID != -1) {
			obj.transform.parent = GameController.largeSpaceShips[buffer.parentSpaceShipID].transform.FindChild("Internals/Characters");
			obj.GetComponent<CharController>().largeSpaceShipID = buffer.parentSpaceShipID;
		}

		GameController.registerNewSharedGameObject(obj);
	}

	//==============================================================================
	//Change Controller
	//==============================================================================

	public static void changeController(NetworkReader message) {
		ControllerChangeBuffer buffer = message.ReadMessage<ControllerChangeBuffer>();
		changeController(buffer);
	}

	public static void changeController(ControllerChangeBuffer buffer) {
		GameController.players[buffer.playerID].currentController.enabled = false;

		Controller controller = GameController.sharedGameObjects[buffer.gameObjectID].GetComponent<SharedGameObject>().internalControllers[buffer.internalControllerID];
		GameController.players[buffer.playerID].currentController = controller;

		if (buffer.playerID == GameController.player.id) {
			controller.enabled = true;
		}
	}

	//==============================================================================
	//New Player
	//==============================================================================

	public static void newPlayer(NetworkReader message) {
		NewPlayerBuffer buffer = message.ReadMessage<NewPlayerBuffer>();
		newPlayer(buffer);
	}

	public static void newPlayer(NewPlayerBuffer buffer) {
		Player player = new Player();
		player.id = buffer.playerID;
		player.characterController = GameController.sharedGameObjects[buffer.characterID].GetComponent<CharController>();
		player.currentController = player.characterController;

		GameController.players[player.id] = player;

		if (buffer.isSelf) {
			Debug.Assert(GameController.player == null);
			GameController.player = player;
			player.characterController.enabled = true;
		}
		else {
			//GameController.sharedGameObjects[buffer.characterID].AddComponent<Moving>();
			//GameController.sharedGameObjects[buffer.characterID].GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
		}
	}
}
