5/10/21

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ArgosTweenSpacePuppy;
using BNG;

public class AF_Instance : MonoBehaviour
{
    public bool bDEBUG_ALL_SHAPE_ON = false;

    public enum FULG_MODE
    {
        SLERP_LERP,
        GRIP_LOCK,
    };

    public FULG_MODE fUlG_Mode = FULG_MODE.SLERP_LERP;

    public class AF_Bond
    {
        public Spoke_Handler spokeHandler_Moved;
        public Spoke_Handler spokeHandler_Stayed;
        public int fin_Moved_IDX;
        public int fin_Stayed_IDX;
        public int fulgurite_ID;

        public bool bRemoved = false;
    }
    public int ID_FULG_COUNTER = 0;
    public Grabber rightHand_Grabber;
    public Grabber leftHand_Grabber;
    private bool bTwoHand_Grab = false;

    [Range(0f, 1f)]
    public float sLERP_Amount;

    public static AF_Instance Instance = null;

    public List<AF_Bond> AF_Bonds = new List<AF_Bond>();

    public List<GameObject> allShape_List = new List<GameObject>();

    public GameObject grabbed_ITEM = null;

    void Awake()
    {
        if (Instance == null)
            Instance = this;
        else if (Instance != this)
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);//HERE IS THE DON'T DESTROY ON LOAD method for new scenes        

        //TODO GATHER LIST ASSIGN
        //allShape_List.Add(allShape_1);
        //allShape_List.Add(allShape_2);
        //allShape_List.Add(allShape_3);
        //allShape_List.Add(allShape_4);
        //allShape_List.Add(allShape_5);
    }

    void Start()
    {

    }

    public void Set_FULG_MODE(int fulg_Mode)
    {
        if(fulg_Mode == (int)FULG_MODE.SLERP_LERP)
        {
            fUlG_Mode = FULG_MODE.SLERP_LERP;
        }
        else if (fulg_Mode == (int)FULG_MODE.GRIP_LOCK)
        {
            fUlG_Mode = FULG_MODE.GRIP_LOCK;
        }
    }

    private void CheckDebug()
    {
        if(BNG.InputBridge.Instance.AButtonDown)
        {
            if(!bDEBUG_ALL_SHAPE_ON)
            {
                bDEBUG_ALL_SHAPE_ON = true;
            }
            else
            {
                bDEBUG_ALL_SHAPE_ON = false;
            }
        }

        if(bDEBUG_ALL_SHAPE_ON)
        {
            foreach(GameObject go in allShape_List)
            {
                go.GetComponent<Spoke_Handler>().bDEBUG_ON = true;
            }
        }
        else
        {
            foreach (GameObject go in allShape_List)
            {
                go.GetComponent<Spoke_Handler>().bDEBUG_ON = false;
            }
        }
    }

    private void DO_FULG_Processes()
    {
        if(fUlG_Mode == FULG_MODE.SLERP_LERP)
        {
            Do_Slerp_Lerp();
        }
        else if(fUlG_Mode == FULG_MODE.GRIP_LOCK)
        {
            Do_Grip_Lock();
        }
    }

    public void NewGrab(GameObject grabbedItem)
    {
        grabbed_ITEM = grabbedItem;
        Spoke_Handler spGrabbed = grabbedItem.GetComponent<Spoke_Handler>();
        int fulgID = grabbedItem.GetComponent<Spoke_Handler>().FULG_ID;

        for (int i = 0; i < allShape_List.Count; i++)
        {
            Spoke_Handler sp = allShape_List[i].GetComponent<Spoke_Handler>();

            if (sp == spGrabbed) continue;

            if (sp.FULG_ID == fulgID)//RELATIVE TO GRABBED
            {
                sp.vRel_To_Grabbed = (sp.GetComponent<Transform>().position - spGrabbed.GetComponent<Transform>().position);
                sp.qRel_To_Grabbed = spGrabbed.GetComponent<Transform>().rotation;

                sp.vRel_To_Grabbed = Quaternion.Inverse(sp.qRel_To_Grabbed) * sp.vRel_To_Grabbed;

                sp.qRel_To_Grabbed = sp.qRel_To_Grabbed * Quaternion.Inverse(spGrabbed.transform.rotation);
            }
        }
    }

    private void Do_Grip_Lock()
    {
        if (grabbed_ITEM != null)
        {
            Spoke_Handler spGrabbed = grabbed_ITEM.GetComponent<Spoke_Handler>();
            int fulgID = grabbed_ITEM.GetComponent<Spoke_Handler>().FULG_ID;

            for (int i = 0; i < allShape_List.Count; i++)
            {
                GameObject go = allShape_List[i];

                Spoke_Handler sp = go.GetComponent<Spoke_Handler>();

                if (sp == spGrabbed) continue;

                if (sp.FULG_ID != 0 && sp.FULG_ID == fulgID)//RELATIVE TO GRABBED
                {
                    go.transform.position = spGrabbed.transform.position + spGrabbed.transform.rotation * sp.vRel_To_Grabbed;
                    go.transform.rotation = spGrabbed.transform.rotation * Quaternion.Inverse(sp.qRel_To_Grabbed);
                }
            }
        }
        else
        {
            Do_Slerp_Lerp();
        }
    }

    private void Do_Slerp_Lerp()
    {
        GameObject GO_RH = null;
        GameObject GO_LH = null;

        //LOAD HELD GRABBABLEs if Any 
        bool bHeldGrabbables = Any_Held_Grabbables(GO_RH, GO_LH);

        for (int i = 0; i < AF_Bonds.Count; i++)
        {
            bool lerp_M = true;
            bool lerp_S = true;

            if (!AF_Bonds[i].bRemoved) //LERPING && SLERPING
            {
                GameObject dsGo_M = AF_Bonds[i].spokeHandler_Moved.gameObject;
                GameObject dsGo_S = AF_Bonds[i].spokeHandler_Stayed.gameObject;

                if (bHeldGrabbables)
                {
                    if (GO_RH == dsGo_M || GO_LH == dsGo_M)
                    {
                        lerp_M = false;
                    }
                    if (GO_RH == dsGo_S || GO_LH == dsGo_S)
                    {
                        lerp_S = false;
                    }
                }

                if (lerp_M && !AF_Bonds[i].spokeHandler_Stayed.bLocked)
                {
                    int idxS = AF_Bonds[i].fin_Stayed_IDX;
                    Transform t = AF_Bonds[i].spokeHandler_Stayed.spoke_AS[idxS].trans_to_TB.transform;
                    dsGo_M.transform.position = Vector3.Lerp(dsGo_M.transform.position, t.position, sLERP_Amount);
                    dsGo_M.transform.rotation = Quaternion.Slerp(dsGo_M.transform.rotation, t.rotation, sLERP_Amount);
                }
                if (lerp_S && !AF_Bonds[i].spokeHandler_Moved.bLocked)
                {
                    int idxM = AF_Bonds[i].fin_Moved_IDX;
                    Transform t = AF_Bonds[i].spokeHandler_Moved.spoke_AS[idxM].trans_to_TB.transform;
                    dsGo_S.transform.position = Vector3.Lerp(dsGo_S.transform.position, t.position, sLERP_Amount);
                    dsGo_S.transform.rotation = Quaternion.Slerp(dsGo_S.transform.rotation, t.rotation, sLERP_Amount);
                }
            }
        }
    }



    public void Release_Grabbable(GameObject Grabbable)
    {
        grabbed_ITEM = null;

        //LAST GRABBED HERE IF NEEDED
    }


    public bool Any_Held_Grabbables(GameObject go_RH, GameObject go_LH)
    {
        //LOAD HELD GRABBABLEs if Any 
        bool bHG = false;
        if (rightHand_Grabber.HeldGrabbable != null)
        {
            go_RH = rightHand_Grabber.HeldGrabbable.gameObject;
            bHG = true;
        }
        if (leftHand_Grabber.HeldGrabbable != null)
        {
            go_LH = leftHand_Grabber.HeldGrabbable.gameObject;
            bHG = true;
        }
        return bHG;
    }



    void Update()
    {
        CheckDebug();
        DO_FULG_Processes();

        if (rightHand_Grabber.HeldGrabbable != null && leftHand_Grabber.HeldGrabbable != null)
        {
            //ADD CONDITION WHERE TWO SEPARATE ALL SHAPES ARE HELD
            Debug.Log("Remove BONDS - AT RIGHT HAND");
            for (int i = 0; i < AF_Bonds.Count; i++)
            {
                if (AF_Bonds[i].spokeHandler_Moved == rightHand_Grabber.HeldGrabbable.GetComponent<Spoke_Handler>()
                 || AF_Bonds[i].spokeHandler_Stayed == rightHand_Grabber.HeldGrabbable.GetComponent<Spoke_Handler>())
                {
                    AF_Bonds[i].bRemoved = true;//TODO FULGURITE ACCOUNTING
                }
            }
            rightHand_Grabber.HeldGrabbable.GetComponent<Spoke_Handler>().Disconect_AllShape();
        }
    }

    //public void Disconnect_Grabbable(Grabbable gbl)
    //{
    //    Spoke_Handler sh = ((AF_Network_Grabable)gbl).GetComponent<Spoke_Handler>();

    //    for(int i = 0; i < AF_Bonds.Count; i++)
    //    {
    //        if(sh == AF_Bonds[i].spokeHandler_Moved || sh == AF_Bonds[i].spokeHandler_Stayed)
    //        {

    //        }
    //    }
    //}

    public void Add_Bond(Spoke_Handler spokeHandler_Object_Moved,
                         Spoke_Handler spokeHandler_Object_Stayed,
                         int fin_Moved_IDX,
                         int fin_Stayed_IDX
                          )
    {
        AF_Bond AFB = new AF_Bond();

        int num_occu_in_Moved = spokeHandler_Object_Moved.Get_Num_Occupied();
        int num_occu_in_Stayed = spokeHandler_Object_Stayed.Get_Num_Occupied();

        if(num_occu_in_Moved == 0 && num_occu_in_Stayed == 0)
        {
            //NEW FULGURITE
            ID_FULG_COUNTER++;
            spokeHandler_Object_Moved.FULG_ID = ID_FULG_COUNTER;
            spokeHandler_Object_Stayed.FULG_ID = ID_FULG_COUNTER;
        }
        else
        {
            if(num_occu_in_Moved > num_occu_in_Stayed)
            {
                spokeHandler_Object_Stayed.FULG_ID = spokeHandler_Object_Moved.FULG_ID;
            }
            else
            {
                spokeHandler_Object_Moved.FULG_ID = spokeHandler_Object_Stayed.FULG_ID;
            }
        }
        AFB.fulgurite_ID = spokeHandler_Object_Moved.FULG_ID; //DETERMINE FULGURITE ID WIP

        AFB.spokeHandler_Moved = spokeHandler_Object_Moved;
        AFB.spokeHandler_Stayed = spokeHandler_Object_Stayed;
        AFB.fin_Moved_IDX = fin_Moved_IDX;
        AFB.fin_Stayed_IDX = fin_Stayed_IDX;


        AFB.bRemoved = false;
        AF_Bonds.Add(AFB);
    }

    //public void Remove_Bond(int idx)
    //{
    //    AF_Bonds.RemoveAt(idx);
    //}

    //public void Remove_Bond(FixedJoint fj)
    //{
    //    for(int i = 0; i < AF_Bonds.Count; i++)
    //    {
    //        if(AF_Bonds[i].fj == fj)
    //        {
    //            AF_Bonds.RemoveAt(i);
    //        }
    //    }
    //}
}