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


public enum GameState
{
    handFree,
    menu,
    cableInHand
}

public class CursorBehaviour : MonoBehaviour {

    [ReadOnly] public GameState currentState;

    [HideInInspector] public CableGrabSphere currentlyGrabbedCableSphere;

    public static CursorBehaviour instance;

    private EventSystem mainEventSystem;

    public LayerMask cableInHandLayerMask;
    public LayerMask cableInHandClickLayerMask;
    public LayerMask handFreeLayerMask;
    public LayerMask menuLayerMask;

    private Camera mainCam;

    private void Awake ()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this);
        }
        mainCam = Camera.main;
    }
    private void Start ()
    {
        mainEventSystem = EventSystem.current;
    }
    void Update ()
    {
        DoRaycast();
	}

    public void DoRaycast ()
    {
        bool mouseClicked = Input.GetMouseButtonUp(0);
        bool mouseClickedDown = Input.GetMouseButtonDown(0);
        bool rightMouseClicked = Input.GetMouseButtonUp(1);
        bool rightMouseClickedDown = Input.GetMouseButtonDown(1);

        Ray camRay = mainCam.ScreenPointToRay(Input.mousePosition);

        if (currentState == GameState.cableInHand)
        {
            RaycastHit cablePlaneHit;
            if (Physics.Raycast(camRay, out cablePlaneHit, Mathf.Infinity, cableInHandLayerMask, QueryTriggerInteraction.Collide))
            {
                if (currentlyGrabbedCableSphere != null)
                {
                    currentlyGrabbedCableSphere.MoveToPosition(cablePlaneHit.point);
                }
            }

            if (mouseClicked)
            {
                RaycastHit freeHandHit;
                if (Physics.Raycast(camRay, out freeHandHit, Mathf.Infinity, cableInHandClickLayerMask, QueryTriggerInteraction.Collide))
                {
                    if (currentlyGrabbedCableSphere != null)
                    {
                        TopSocket castedTopSocket = freeHandHit.collider.GetComponent<TopSocket>();
                        if (castedTopSocket != null && castedTopSocket.connectedCableSphere == null)
                        {
                            currentlyGrabbedCableSphere.joinToTopSocket(castedTopSocket);
                            setCurrentState(GameState.handFree);
                        }
                    }
                }
            }
            if (rightMouseClicked)
            {
                if (currentlyGrabbedCableSphere != null)
                {
                    currentlyGrabbedCableSphere.SetGrabbed(false);
                }
                setCurrentState(GameState.handFree);
            }
        }
        else if (currentState == GameState.handFree)
        {
            if (mouseClicked)
            {
                RaycastHit freeHandHit;
                if (Physics.Raycast(camRay, out freeHandHit, Mathf.Infinity, handFreeLayerMask, QueryTriggerInteraction.Collide))
                {
                    if (currentlyGrabbedCableSphere == null)
                    {
                        CableGrabSphere sphereToGrab = freeHandHit.collider.GetComponent<CableGrabSphere>();
                        if (sphereToGrab != null)
                        {
                            sphereToGrab.SetGrabbed(true);
                            currentlyGrabbedCableSphere = sphereToGrab;
                            setCurrentState(GameState.cableInHand);
                        }
                        else
                        {
                            Diary clickedDiary = freeHandHit.collider.GetComponent<Diary>();
                            if (clickedDiary != null && clickedDiary.isActive)
                            {
                                clickedDiary.setShowing(true);
                                setCurrentState(GameState.menu);
                            }
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Cable grabbed already, weird scenario detected");
                    }
                }
            }
        }
        else if (currentState == GameState.menu)
        {
            if (!mainEventSystem.IsPointerOverGameObject())
            {            
                if (mouseClicked)
                {
                    Diary.instance.setShowing(false);
                    setCurrentState(GameState.handFree);
                }
            }
            if (!mouseClicked && rightMouseClicked)
            {
                Diary.instance.setShowing(false);
                setCurrentState(GameState.handFree);
            }
        }
    }

    public void setCurrentState (GameState nextState)
    {
        switch (nextState)
        {
            case GameState.menu:
            {
                ClearSelection();
                break;
            }
            case GameState.handFree:
            {

                ClearSelection();
                break;
            }
            case GameState.cableInHand:
            {
                break;
            }
        }
        currentState = nextState;
    }

    public void ClearSelection ()
    {
        if (currentlyGrabbedCableSphere != null)
        {
            currentlyGrabbedCableSphere = null;
        }
    }

    public LayerMask maskForState (GameState state)
    {
        switch (state)
        {
            case GameState.menu:
            {
                return menuLayerMask;
            }
            case GameState.handFree:
            {
                return handFreeLayerMask;
            }
            case GameState.cableInHand:
            {
                return cableInHandLayerMask;
            }
        }
        return handFreeLayerMask;
    }

    [ContextMenu("Force State set to Menu")]
    public void forceSetMenu ()
    {
        setCurrentState(GameState.menu);
    }

    [ContextMenu("Force State set to hand Free")]
    public void forceSetFree ()
    {
        setCurrentState(GameState.handFree);
    }
}
