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

public class GodHand : MonoBehaviour {

	// Use this for initialization
	void Start () {
        GetComponent<CameraController>().DesiredZoomLevel = 1;
        ShowTip(null);
        HelicopterTargeter.SetActive(false);
        SetActivePower(ActivePower.Tractor);
    }

    private enum InputState
    {
        WaitingForInput,
        MouseDownWaitingForDrag,
        MouseDownDragging,
    }

    private enum ActivePower
    {
        None,
        Tractor,
        Helicopter,
        Airplane,
        Ignite
    }

    private Vector3 mouseDownScreenLocation;

    private InputState currentInputState = InputState.WaitingForInput;
    private ActivePower currentActivePower = ActivePower.None;

    private Vector3 AirplaneStartPoint = Vector3.zero;
    private int AirplanePowerAwaitingclick = 0;

    private void SetActivePower(ActivePower newPower)
    {
        if (currentActivePower == ActivePower.Helicopter)
        {
            HelicopterTargeter.SetActive(false);
        }
        if (currentActivePower == ActivePower.Airplane)
        {
            AirplaneTargeter.SetActive(false);
        }

        currentActivePower = newPower;

        if (currentActivePower == ActivePower.Helicopter)
        {
            HelicopterTargeter.SetActive(true);
        }
        if (currentActivePower == ActivePower.Airplane)
        {
            AirplaneTargeter.SetActive(true);
        }

        UpdateHintText();
    }
	
    private void ProcessClickLogic()
    {
        if (currentActivePower == ActivePower.Tractor)
        {
            // Figure out what object you've clicked
            RaycastHit hitInfo;
            Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo);
            if (hitInfo.collider != null)
            {
                Tree clickedTree = hitInfo.collider.gameObject.GetComponent<Tree>();
                if (clickedTree != null && clickedTree.burningState == BurnState.Waiting)
                {
                    clickedTree.SetSelectedAsTractorTarget(!clickedTree.SelectedAsTractorTarget);
                }
            }
        }
        if (currentActivePower == ActivePower.Helicopter)
        {
            Vector3 targetDest = GetWorldPositionFromScreenPosition(Input.mousePosition);
            GetComponent<HelicopterProcessor>().ReleaseHelicopter(targetDest);
            HelicopterButton.GetComponent<CooldownTracker>().UsedCharges++;

            // set us back to tractor mode and clean up
            SetActivePower(ActivePower.Tractor);
            GameObject confirmObject = GameObject.Instantiate(HelicopterConfirmer, targetDest, Quaternion.identity);
            Destroy(confirmObject, 4.0f);
        }

        if (currentActivePower == ActivePower.Airplane)
        {
            Vector3 clickPos = GetWorldPositionFromScreenPosition(Input.mousePosition);
            if (AirplanePowerAwaitingclick == 0)
            {
                // The first click is the start click
                // Set the position
                AirplaneStartPoint = clickPos;
                AirplanePowerAwaitingclick = 1;
            }
            else
            {
                Vector3 EndPos = GetAirplaneEndpointFromPosition(AirplaneStartPoint, clickPos);
                GetComponent<AirplaneProcessor>().ReleasePlane(AirplaneStartPoint, EndPos);
                AirplaneButton.GetComponent<CooldownTracker>().UsedCharges++;

                SetActivePower(ActivePower.Tractor);
            }

        }
    }

    public float AirplaneDropLength = 4.0f;
    private Vector3 GetAirplaneEndpointFromPosition(Vector3 start, Vector3 end)
    {
        Vector3 dir = (end - start).normalized;
        if (dir == Vector3.zero)
            dir = Vector3.forward;
        return start + dir * GetComponent<AirplaneProcessor>().SplooshLength;
    }

    private Vector3 GetWorldPositionFromScreenPosition(Vector3 screenPos)
    {
        Plane Ground = new Plane(Vector3.up, 0.0f);
        Vector3 result = Vector3.zero;
        float distance = 0.0f;
        if (Ground.Raycast(Camera.main.ScreenPointToRay(screenPos), out distance))
        {
            result = Camera.main.ScreenPointToRay(Input.mousePosition).GetPoint(distance);
        }
        return result;
    }

    public GameObject HelicopterTargeter = null;
    public GameObject AirplaneTargeter = null;
    public GameObject HelicopterConfirmer = null;

    // Update is called once per frame
    void Update () {

#if UNITY_EDITOR
        RaycastHit debugHoverInfo;
        Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out debugHoverInfo);
        if (debugHoverInfo.collider != null)
        {
            Combustible combustible = debugHoverInfo.collider.gameObject.GetComponent<Combustible>();
            if (combustible != null)
            {
                DebugHUD.TrackData("Fuel", combustible.Fuel);
                DebugHUD.TrackData("Temperature", combustible.CurrentTemperature);
            }
        }
#endif

        if (currentActivePower == ActivePower.Helicopter)
        {
            HelicopterTargeter.transform.position = GetWorldPositionFromScreenPosition(Input.mousePosition);
        }

        if (currentActivePower == ActivePower.Airplane)
        {
            float SplooshRadius = GetComponent<AirplaneProcessor>().SplooshRadius;
            if (AirplanePowerAwaitingclick == 0)
            {
                AirplaneTargeter.transform.position = GetWorldPositionFromScreenPosition(Input.mousePosition);
                AirplaneTargeter.transform.localScale = new Vector3(SplooshRadius, 1.0f, SplooshRadius);
            }
            else
            {
                AirplaneTargeter.transform.position = AirplaneStartPoint;
                Vector3 mouseWorldPos = GetWorldPositionFromScreenPosition(Input.mousePosition);
                Vector3 dir = (mouseWorldPos - AirplaneStartPoint).normalized;
                if (dir == Vector3.zero)
                    dir = Vector3.forward;
                Vector3 endPoint = GetAirplaneEndpointFromPosition(AirplaneStartPoint, mouseWorldPos);
                AirplaneTargeter.transform.rotation = Quaternion.LookRotation(dir);
                AirplaneTargeter.transform.localScale = new Vector3(SplooshRadius, 1.0f, GetComponent<AirplaneProcessor>().SplooshLength);
            }
        }

        if (currentInputState == InputState.WaitingForInput)
        {
            if (Input.GetMouseButtonDown(0) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
            {
                currentInputState = InputState.MouseDownWaitingForDrag;
                mouseDownScreenLocation = Input.mousePosition;
            }
        }
        else if (currentInputState == InputState.MouseDownWaitingForDrag)
        {
            if (Input.GetMouseButton(0))
            {
                if ((Input.mousePosition - mouseDownScreenLocation).sqrMagnitude > 25.0f)
                {
                    currentInputState = InputState.MouseDownDragging;
                }
            }
            else
            {
                ProcessClickLogic();
                currentInputState = InputState.WaitingForInput;
            }
        }
        else if (currentInputState == InputState.MouseDownDragging)
        {
            if (Input.GetMouseButton(0))
            {
                Vector3 dragVector = mouseDownScreenLocation - Input.mousePosition;
                dragVector.x /= Screen.width;
                dragVector.y /= Screen.height;
                GetComponent<CameraController>().DesiredCameraPan = new Vector3(dragVector.x, 0.0f, dragVector.y);
                mouseDownScreenLocation = Input.mousePosition;
            }
            else
            {
                currentInputState = InputState.WaitingForInput;
            }
        }

        if (Input.GetMouseButton(1))
        {
            SetActivePower(ActivePower.Tractor);
        }

        UpdateUI();
    }

    private void UpdateUI()
    {

        HelicopterButton.transform.Find("ChargeMeter").GetComponent<Slider>().value = HelicopterButton.GetComponent<CooldownTracker>().PercentTowardsNextCharge;
        HelicopterButton.transform.Find("ChargeMeter").Find("Fill Area").Find("Fill").GetComponent<Image>().color = (HelicopterButton.GetComponent<CooldownTracker>().Ready&& !GetComponent<HelicopterProcessor>().HelicopterActive) ? Color.green : Color.yellow;

        AirplaneButton.transform.Find("ChargeMeter").GetComponent<Slider>().value = AirplaneButton.GetComponent<CooldownTracker>().PercentTowardsNextCharge;
        AirplaneButton.transform.Find("ChargeMeter").Find("Fill Area").Find("Fill").GetComponent<Image>().color = (AirplaneButton.GetComponent<CooldownTracker>().Ready && !GetComponent<AirplaneProcessor>().AirplaneActive) ? Color.green : Color.yellow;

        // Update sprite backgrounds
        TractorButton.GetComponent<Image>().sprite = (currentActivePower == ActivePower.Tractor) ? ButtonSpriteSelected : ButtonSpriteReady;
        HelicopterButton.GetComponent<Image>().sprite = (currentActivePower == ActivePower.Helicopter) ? ButtonSpriteSelected : ((HelicopterButton.GetComponent<CooldownTracker>().Ready && !GetComponent<HelicopterProcessor>().HelicopterActive)? ButtonSpriteReady : ButtonSpriteInactive);
        AirplaneButton.GetComponent<Image>().sprite = (currentActivePower == ActivePower.Airplane) ? ButtonSpriteSelected : ((AirplaneButton.GetComponent<CooldownTracker>().Ready && !GetComponent<AirplaneProcessor>().AirplaneActive) ? ButtonSpriteReady : ButtonSpriteInactive);
    }


    public GameObject TractorButton = null;
    public GameObject HelicopterButton = null;
    public GameObject AirplaneButton = null;
    public GameObject TipPanel = null;
    public TMPro.TextMeshProUGUI ActiveTip = null;

    public void TractorButtonHandler()
    {
        SetActivePower(ActivePower.Tractor);
    }

    public void HelicopterButtonHandler()
    {
        if (HelicopterButton.GetComponent<CooldownTracker>().Ready && !GetComponent<HelicopterProcessor>().HelicopterActive)
        {
            SetActivePower(ActivePower.Helicopter);
        }
    }

    public void AirplaneButtonHandler()
    {
        if (AirplaneButton.GetComponent<CooldownTracker>().Ready && !GetComponent<AirplaneProcessor>().AirplaneActive)
        {
            SetActivePower(ActivePower.Airplane);
            AirplaneStartPoint = Vector3.zero;
            AirplanePowerAwaitingclick = 0;

        }
    }

    public Sprite ButtonSpriteReady = null;
    public Sprite ButtonSpriteInactive = null;
    public Sprite ButtonSpriteSelected = null;

    public void UpdateHintText()
    {
        switch(currentActivePower)
        {
            case ActivePower.Tractor:
                ShowTip(TractorButton.GetComponent<HelpText>()?.Text);
                break;
            case ActivePower.Helicopter:
                ShowTip(HelicopterButton.GetComponent<HelpText>()?.Text);
                break;
            case ActivePower.Airplane:
                ShowTip(AirplaneButton.GetComponent<HelpText>()?.Text);
                break;
        }
    }

    private void ShowTip(string text)
    {
        if (text != null && text != "")
        {
            TipPanel.SetActive(true);
            ActiveTip.SetText(text.Replace("\\n", "\n"));
        }
        else
        {
            TipPanel.SetActive(false);
        }
    }
}
