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

public class PlayerControl : EntityBehaviour
{
	public float dischargeTime = 0.5f;
	public bool sharedInventory = false;

	Rigidbody body;
	Item activeItem;
	InventoryDictionary oldInventory;

	public static PlayerControl current { get; private set; }

	public enum ChargeState { Idle, Charging, Cooldown };

	public ChargeState chargeState { get; private set; }
	public float chargeAmount { get; private set; }

	void OnEnable() {
		// Throw out our old local inventory and share
		// the one in the savegame.
		if (sharedInventory && oldInventory == null) {
			oldInventory = entity.inventory;
			entity.inventory = SaveGame.current.inventory;
		}

		UIWrangler.target = this;
		UIWrangler.selectedItem = entity.carrying?.GetComponent<Item>();
		body = GetComponent<Rigidbody>();
		chargeState = ChargeState.Idle;
		current = this;
	}

	void OnDisable() {
		if (UIWrangler.target == this) {
			UIWrangler.selectedItem = null;
			UIWrangler.target = null;
		}

		if (sharedInventory) {
			entity.inventory = oldInventory;
			oldInventory = null;
		}
		if (current == this)
			current = null;
	}

	void FixedUpdate() {
		if (Game.inCutscene || UIWrangler.ui.gamePaused)
			return;

		// Should we enter a roll?
		if (!entity.onGround 
			&& entity.airTime < 0.3f 
			&& entity.groundDist > 0.7f 
			&& Vector3.ProjectOnPlane(body.velocity, Vector3.up).magnitude > 1.5f
			&& !entity.isRolling) {
			entity.Roll(Vector3.zero);
		}

		Vector2 move = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
		if (move.magnitude > 1)
			move.Normalize();

		// Rotate into world space.
		Transform cam = Game.camera.transform;
		Vector3 fwd = new Vector3(cam.forward.x, 0.0f, cam.forward.z).normalized;
		Vector3 moveVec = cam.right*move.x + fwd*move.y;

		entity.Move(moveVec);
		entity.Turn(moveVec);
	}
	
	void Update() {
		if (activeItem != UIWrangler.selectedItem) {
			activeItem = UIWrangler.selectedItem;
			if (activeItem && activeItem.carried != Item.CarryMode.NotCarried)
				entity.CarryObject(activeItem);
		}

		if (Game.inCutscene || UIWrangler.ui.gamePaused)
			return;

		if (Input.GetButtonDown("Fire1")) {
			UseCheck();
		}

		if (Input.GetButtonDown("Fire2")) {
			if (chargeState != ChargeState.Cooldown)
				chargeState = ChargeState.Charging;
		}

		UpdateCharge();
	}

	void UpdateCharge() {
		bool discharge = false;

		switch (chargeState) {
			case ChargeState.Idle:
				break;
			case ChargeState.Charging:
				if (Input.GetButton("Fire2") && entity.carrying) {
					// Wait till we're charged.
					bool ready = true;
					if (entity.carrying.chargeTime > 0) {
						chargeAmount += Time.deltaTime / entity.carrying.chargeTime;
						if (chargeAmount < 1.0f)
							ready = false;
						else
							chargeAmount = 1.0f;
					}

					// Do it.
					if (ready) {
						chargeState = ChargeState.Cooldown;
						entity.carrying.SendMessage("OnFire", entity, SendMessageOptions.DontRequireReceiver);
					}
				} else {
					discharge = true;
				}
				break;
			case ChargeState.Cooldown:
				discharge = true;
				break;
		}

		if (discharge) {
			chargeAmount -= Time.deltaTime / dischargeTime;
			if (chargeAmount <= 0) {
				chargeState = ChargeState.Idle;
				chargeAmount = 0;
			}
		}
	}

	void UseCheck() {
		// Find the thing we're pointing at.
		Entity nearest = entity.FindUseTarget();
		if (nearest) {
			Debug.Log($"Player used {nearest.name}.");
			nearest.Use(entity);
		}
	}
}
