﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;

[PrimaryObject]
public class PotionScript : ItemScript {

	[HideInInspector]
	public GameObject potionPrefab;
	public Potion potion;
	[HideInInspector]
	public List<Material> potionMats;
	[HideInInspector]
	public List<GameObject> potionParts;
	[HideInInspector]
	public MeshRenderer inside;
	string potionName;

	// Use this for initialization
	void Start () {
		base.Awake ();
        stackable = true;
		stackNumber = 1;
	}

	// Update is called once per frame
	new void Update () {
		base.Update ();

		if (isActive)
			UpdateActivePotion ();
	}

	new void OnDrawGizmosSelected () {
		base.OnDrawGizmosSelected ();
	}

	void OnTriggerEnter (Collider col) {
		if (col.gameObject.tag == "Player"){
			if (col.gameObject.GetPhotonView () && !col.gameObject.GetPhotonView ().IsMine && PhotonNetwork.IsConnected)
				return;
			col.gameObject.GetComponent<PlayerBase> ().itemUI.AssignUIPotion (this);
		}
	}

	void OnTriggerStay (Collider col) {
		if (col.gameObject.tag == "Player"){
			if (col.gameObject.GetPhotonView() && !col.gameObject.GetPhotonView().IsMine && PhotonNetwork.IsConnected)
				return;

			if (Input.GetKeyDown (KeyCode.E)) {
				if (col.gameObject.GetComponent<PlayerBase> ().itemUI.displayObj == gameObject) {
					col.gameObject.GetComponent<PlayerBase> ().itemUI.displayObj = null;
				}
				InitializePotion (col.gameObject);

				if (photonView && PhotonNetwork.IsConnected) {
                    PhotonDebugger.IncrementNumberOfMessages("pick up potion");
                    photonView.RPC("PickUpOrAddPotion", RpcTarget.OthersBuffered, col.gameObject.GetComponent<PlayerBase>().photonView.Owner.ActorNumber, photonView.ViewID);
                }
			}
		}
	}

	void OnTriggerExit (Collider col) {
		if (col.gameObject.tag == "Player"){
			if (col.gameObject.GetPhotonView () && !col.gameObject.GetPhotonView ().IsMine && PhotonNetwork.IsConnected)
				return;
			if (col.gameObject.GetComponent<PlayerBase> ().itemUI.displayObj == gameObject) {
				col.gameObject.GetComponent<PlayerBase> ().itemUI.displayObj = null;
			}
		}
	}

	public bool CheckPotionNumber () {
		if (stackNumber == potion.maxStackNumber)
			return false;
		else if (stackNumber < 1)
			return false;
		else
			return true;
	}

	void InitializePotion (GameObject player) {
		myOwner = player;
		playerBase = myOwner.GetComponent<PlayerBase> ();

		// set bools
		pickedUp = true;
		isActive = true;
		gameObject.GetComponent<SphereCollider> ().enabled = false;

		// set the active potion
		if (potion.type == PotionType.Health)
			playerBase.activePotionObj = playerBase.healthPotion;
		else
			playerBase.activePotionObj = playerBase.shieldPotion;
        

        // check for other items or potions
        bool isLocalPlayer = (PhotonNetwork.IsConnected ? playerBase.photonView.IsMine : true);
		if (playerBase.activeItem != null) {
            PotionScript potionScript = playerBase.activeItem.GetComponent<PotionScript>();
            if (potionScript)
                if (potionScript.potion.type == potion.type && potionScript.potion.size == potion.size)
                    if (potionScript.CheckPotionNumber())
                        AddPotion(potionScript, isLocalPlayer);
                    else
                        SwapItems(true, isLocalPlayer);
                else
                    SwapItems(true, isLocalPlayer);
            else
                SwapItems(true, isLocalPlayer);
        }
		else
			SwapItems (false, isLocalPlayer);
	}

	void UpdateActivePotion () {
		if (potion.type == PotionType.Health)
			playerBase.activePotionObj = playerBase.healthPotion;
		else
			playerBase.activePotionObj = playerBase.shieldPotion;
		playerBase.activePotion = this;
	}

    void AddPotion(PotionScript pScript, bool localPlayer = true) {
        int OwnerID;
        if (PhotonNetwork.IsConnected)
            OwnerID = playerBase.photonView.Owner.ActorNumber;
        else
            OwnerID = 1;
		if (pScript.stackNumber + stackNumber > potion.maxStackNumber) {
            stackNumber -= potion.maxStackNumber - pScript.stackNumber;
			pScript.stackNumber = potion.maxStackNumber;
			pickedUp = false;
			isActive = false;
			myOwner = null;
			playerBase = null;
		} else {
			pScript.stackNumber += stackNumber;
			if (PhotonNetwork.IsConnected) {
                if (localPlayer) {
                    PhotonDebugger.IncrementNumberOfMessages("pickup potion");
                    photonView.RPC("PickUpOrAddPotion", RpcTarget.OthersBuffered, OwnerID, pScript.photonView.ViewID);
                }
                if (PhotonNetwork.IsMasterClient) {
                    StartCoroutine(WaitAndDestroyPhoton());
                }
			} else if (!PhotonNetwork.IsConnected) {
				Destroy (gameObject);
			}
		}
        if (localPlayer)
            ItemDisplays.itemDisplay.UpdateAmount(pScript);
    }

    IEnumerator WaitAndDestroyPhoton() {
        yield return new WaitForSecondsRealtime(0.5f);
        PhotonNetwork.Destroy(photonView);
    }

    void SwapItems (bool itemToDrop, bool localPlayer = true) {
        if (itemToDrop) {
			if (photonView && PhotonNetwork.IsConnected) {
                if (!playerBase.activeItem.GetComponent<ItemScript>().stackable) {
                    PhotonDebugger.IncrementNumberOfMessages("drop potion");
                    photonView.RPC("DropItem", RpcTarget.OthersBuffered, playerBase.photonView.Owner.ActorNumber, playerBase.activeItem.GetPhotonView().ViewID, 0f, Vector3.zero);
                }
                else {
                    PhotonDebugger.IncrementNumberOfMessages("drop potion stack");
                    photonView.RPC("DropItemStack", RpcTarget.OthersBuffered, playerBase.photonView.Owner.ActorNumber, playerBase.activeItem.GetPhotonView().ViewID, 0f, Vector3.zero, stackNumber);
                }
            }
			playerBase.DropItem (playerBase.activeItem);
		}

        if (localPlayer) {
            if (potion.type == PotionType.Health)
                ItemDisplays.itemDisplay.AssignItem(potionPrefab, potionMats[0], gameObject.GetComponent<PotionScript>());
            else
                ItemDisplays.itemDisplay.AssignItem(potionPrefab, potionMats[1], gameObject.GetComponent<PotionScript>());
        }

		if(playerBase.photonView && !playerBase.photonView.IsMine && PhotonNetwork.IsConnected)
			playerBase.inventory.Add(gameObject);
		else
			playerBase.inventory[playerBase.activeItemNum] = gameObject;
		transform.SetParent (playerBase.transform);
		foreach (GameObject part in potionParts) {
			part.SetActive (false);
		}
		playerBase.activeItem = gameObject;
	}

	[PunRPC]
	public void PickUpOrAddPotion (int ownerID, int potionID) {
		if (photonView.ViewID != potionID) {
			return;
		}
		GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
		foreach (GameObject player in players) {
			if (player.GetComponent<PlayerBase>().photonView.Owner.ActorNumber == ownerID) {
				InitializePotion(player);
			}
		}
	}
		
	void OnValidate () {
		if (potion.size == PotionSize.Mini) {
			potion.potionRarity = Rarity.Normal;
			potion.iconColor = new Color (0.314f, 0.620f, 0.008f, 1.000f);
			potion.value = 10f;
			potion.maxStackNumber = 5;
			if (gameObject.activeInHierarchy)
				potionName = "Mini";
		} else if (potion.size == PotionSize.Quarter) {
			potion.potionRarity = Rarity.Unique;
			potion.iconColor = new Color (0.000f, 0.576f, 0.725f, 1.000f);
			potion.value = 25f;
			potion.maxStackNumber = 3;
			if (gameObject.activeInHierarchy)
				potionName = "Quarter";
		} else if (potion.size == PotionSize.Half) {
			potion.potionRarity = Rarity.Super;
			potion.iconColor = new Color (0.675f, 0.306f, 0.831f, 1.000f);
			potion.value = 50f;
			potion.maxStackNumber = 2;
			if (gameObject.activeInHierarchy)
				potionName = "Half";
		} else {
			potion.potionRarity = Rarity.Extraordinary;
			potion.iconColor = new Color (0.855f, 0.518f, 0.239f, 1.000f);
			potion.value = 100f;
			potion.maxStackNumber = 1;
			if (gameObject.activeInHierarchy)
				potionName = "Full";
		}

		if (potion.type == PotionType.Health)
			inside.material = potionMats [0];
		else
			inside.material = potionMats [1];
		
		if (gameObject.name != potionName + " Potion" && gameObject.activeInHierarchy) {
			gameObject.name = potionName + " Potion";
		}
	}
}

[System.Serializable]
public enum PotionSize {Mini, Quarter, Half, Full}

[System.Serializable]
public enum PotionType {Health, Shield}

[System.Serializable]
public class Potion {
	[ReadOnly]
	public Color iconColor;
	[HideInInspector]
	public PotionType type = PotionType.Health;
	public PotionSize size;
	[ReadOnly]
	public float value;
	[HideInInspector]
	public int maxStackNumber = 1;
	[HideInInspector]
	public Rarity potionRarity;
}
