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

[PrimaryObject]
public class WandScript : ItemScript {

	[HideInInspector]
	public GameObject wandPrefab;
	[HideInInspector]
	public int auraCount = 1;
	public Wand wand;
	public Transform magicOrigin;

	// Use this for initialization
	void Start () {
		base.Awake ();
        HideParticleEffects();
    }

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

		if (isActive)
			UpdateActiveWand ();
	}

	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.AssignUIWand (this);
		}
	}

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

	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;
				}

				InitializeWand (col.gameObject);
				ItemDisplays.itemDisplay.AssignItem (wandPrefab, gameObject.GetComponent<MeshRenderer>().material, gameObject.GetComponent<WandScript>()); // need to check what this does

                if (photonView && PhotonNetwork.IsConnected) {
                    PhotonDebugger.IncrementNumberOfMessages("pickup wand");
                    photonView.RPC("PickUpWand", 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;
			}
		}
	}

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

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

		// set transform variables
		transform.parent = playerBase.rightHand;
		transform.localPosition = Vector3.zero;
		transform.localScale = Vector3.one;
		transform.localEulerAngles = new Vector3 (-90f, 0f, 0f);

		// set external script variables
		playerBase.activeWandObj = gameObject;
		playerBase.spawnPoint = magicOrigin;

        TurnOnParticleEffects();

        // handle player base list
        if (playerBase.activeItem != null) {
			if (photonView && PhotonNetwork.IsConnected) {
                PhotonDebugger.IncrementNumberOfMessages("drop wand");
				photonView.RPC ("DropItem", RpcTarget.OthersBuffered, playerBase.photonView.Owner.ActorNumber, (playerBase.activeItem.GetPhotonView ()) ? playerBase.activeItem.GetPhotonView ().ViewID : -1, 0f, Vector3.zero);
            }
            playerBase.DropItem(playerBase.activeItem);
        }
		if(playerBase.photonView && !playerBase.photonView.IsMine && PhotonNetwork.IsConnected) {
            playerBase.inventory.Add(gameObject);
        }
        else {
            playerBase.inventory[playerBase.activeItemNum] = gameObject;
        }
		playerBase.activeItem = gameObject;
	}

	void UpdateActiveWand () {
		playerBase.activeWandObj = gameObject;
		playerBase.spawnPoint = magicOrigin;
	}

    void TurnOnParticleEffects() {
        for (int i = 0; i < transform.childCount; i++) {
            transform.GetChild(i).gameObject.SetActive(true);
        }
    }

    // if anything else becomes a child of the wands this will create a problem
    public void HideParticleEffects() {
        for(int i = 0; i < transform.childCount; i++) {
            transform.GetChild(i).gameObject.SetActive(false);
        }
    }


	void OnValidate () {
		
		int checkAuras = 0;
		for(int i = 0; i < transform.childCount; i++){
			if (transform.GetChild (i).tag == "Aura") {
				checkAuras++;
			}
		}

		auraCount = checkAuras;
		SetAuras (auraCount);

		if (wand.rarity == Rarity.Basic) {
			wand.iconColor = new Color (0.541f, 0.565f, 0.580f, 1.000f);
			wand.baseDamage = 2f;
			wand.maxDamage = 20f;
		} else if (wand.rarity == Rarity.Normal) {
			wand.iconColor = new Color (0.314f, 0.620f, 0.008f, 1.000f);
			wand.baseDamage = 4f;
			wand.maxDamage = 40f;
		} else if (wand.rarity == Rarity.Unique) {
			wand.iconColor = new Color (0.000f, 0.576f, 0.725f, 1.000f);
			wand.baseDamage = 6f;
			wand.maxDamage = 60f;
		} else if (wand.rarity == Rarity.Super) {
			wand.iconColor = new Color (0.675f, 0.306f, 0.831f, 1.000f);
			wand.baseDamage = 8f;
			wand.maxDamage = 80f;
		} else {
			wand.iconColor = new Color (0.855f, 0.518f, 0.239f, 1.000f);
			wand.baseDamage = 10f;
			wand.maxDamage = 100f;
		}

		if (wand.type == WandType.Scatter) {
			wand.spellNum = 15;

		} else if (wand.type == WandType.Burst) {
			wand.spellNum = 3;
		} else {
			wand.spellNum = 1;
		}

		if (wand.damage < wand.baseDamage)
			wand.damage = wand.baseDamage;
		else if (wand.damage > wand.maxDamage)
			wand.damage = wand.maxDamage;

		SetSpeelSpeed ();
	}

	void SetSpeelSpeed () {
		if (wand.rarity == Rarity.Basic) {
			if (wand.type == WandType.Scatter) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = wand.minSpeed = 20f;
			} else if (wand.type == WandType.Orb) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = 25f;
				wand.minSpeed = 20f;
			} else if (wand.type == WandType.Burst) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 25f;
				wand.maxSpeed = 35f;
			} else if (wand.type == WandType.Beam) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 30f;
				wand.maxSpeed = 50f;
			}
		} else if (wand.rarity == Rarity.Normal) {
			if (wand.type == WandType.Scatter) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = wand.minSpeed = 20f;
			} else if (wand.type == WandType.Orb) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = 30f;
				wand.minSpeed = 20f;
			} else if (wand.type == WandType.Burst) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 30f;
				wand.maxSpeed = 40f;
			} else if (wand.type == WandType.Beam) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 37.5f;
				wand.maxSpeed = 62.5f;
			}
		} else if (wand.rarity == Rarity.Unique) {
			if (wand.type == WandType.Scatter) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = wand.minSpeed = 25f;
			} else if (wand.type == WandType.Orb) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = 40f;
				wand.minSpeed = 30f;
			} else if (wand.type == WandType.Burst) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 40f;
				wand.maxSpeed = 50f;
			} else if (wand.type == WandType.Beam) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 50f;
				wand.maxSpeed = 75f;
			}
		} else if (wand.rarity == Rarity.Super) {
			if (wand.type == WandType.Scatter) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = wand.minSpeed = 25f;
			} else if (wand.type == WandType.Orb) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = 50f;
				wand.minSpeed = 35f;
			} else if (wand.type == WandType.Burst) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 50f;
				wand.maxSpeed = 65f;
			} else if (wand.type == WandType.Beam) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 62.5f;
				wand.maxSpeed = 87.5f;
			}
		} else if (wand.rarity == Rarity.Extraordinary) {
			if (wand.type == WandType.Scatter) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = wand.minSpeed = 30f;
			} else if (wand.type == WandType.Orb) {
				wand.baseSpeed = wand.spellSpeed = wand.maxSpeed = 60f;
				wand.minSpeed = 40f;
			} else if (wand.type == WandType.Burst) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 60f;
				wand.maxSpeed = 80f;
			} else if (wand.type == WandType.Beam) {
				wand.baseSpeed = wand.spellSpeed = wand.minSpeed = 75f;
				wand.maxSpeed = 100f;
			}
		}
	}

	void SetAuras (int auras) {
		if (!transform.GetChild (0))
			return;

		if (!transform.GetChild (0).GetComponent<ParticleSystem> ())
			return;
		
		magicOrigin = transform.GetChild (0);
		wand.aura1 = transform.GetChild (0);
		var ps1 = wand.aura1.GetComponent<ParticleSystem> ().main;
		ps1.startColor = wand.aura1Color;


		if (auras == 2) {
			wand.aura2 = transform.GetChild (1);
			var ps2 = wand.aura2.GetComponent<ParticleSystem> ().main;
			ps2.startColor = wand.aura2Color;
		} else if (auras == 3) {
			wand.aura3 = transform.GetChild (2);
			var ps3 = wand.aura3.GetComponent<ParticleSystem> ().main;
			ps3.startColor = wand.aura3Color;
		}
	}

    [PunRPC]
    public void PickUpWand(int ownerID, int wandID) {
        if (photonView.ViewID != wandID) {
            return;
        }
        GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
        foreach (GameObject player in players) {
            if (player.GetComponent<PlayerBase>().photonView.Owner.ActorNumber == ownerID) {
                InitializeWand(player);
            }
        }
    }
}


/// <summary>
/// The primary type of a wand: Scatter, Burst, Beam, Orb.
/// </summary>
[System.Serializable]
public enum WandType {Scatter, Burst, Beam, Orb}
/// <summary>
/// The sub type of a wand: None, Auto, Charged.
/// </summary>
[System.Serializable]
public enum WandSubType {None, Auto, Charged}
/// <summary>
/// Defines the rarity of an item: Basic (Gray), Normal (Green), Unique (Blue), Super (Purple), Extraordinary (Gold).
/// </summary>
[System.Serializable]
public enum Rarity {Basic, Normal, Unique, Super, Extraordinary}

/// <summary>
/// Base class for wands.
/// </summary>
[System.Serializable]
public class Wand {

	// Most of the Read only variables will be set as 

	[ReadOnly]
	public Color iconColor;
	public WandType type;
	public WandSubType subType;
	public Rarity rarity;

	[HideInInspector]
	public int range, spellNum;
	[HideInInspector]
	public Color spellColor;
	public Color aura1Color;
	[VariableToggle("auraCount", 2)]
	public Color aura2Color;
	[VariableToggle("auraCount", 3)]
	public Color aura3Color;

	[HideInInspector]
	public Transform aura1, aura2, aura3;

	[HideInInspector]
	public float castCost, chargeCost, chargeRate, baseDamage, maxDamage, baseSpeed, maxSpeed, minSpeed;
	[ReadOnly]
	public float damage, spellSpeed;

}

