4/25/21

 

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

public class Spoke_Handler : MonoBehaviour
{
    public bool setLastHeld = false;
    public bool isInFulgurite = false;  
    public bool isBeingHeld = false;

    private Vector3     targetPos;
    private Quaternion  targetRot;
    
    // +x,+y,+z,-x,-y,-z
    public List<Spoke_AllShape> spoke_AS = new List<Spoke_AllShape>();
    public Rigidbody rb;

    private AF_Instance af_Instance;

    public SphereCollider sphereCollider;

    public AF_Network_Grabable netGrabbable;

    public Touch_Lighting_and_Sound tls;

    public Spoke_AllShape SAS1 { get; private set; }
    public Spoke_AllShape SAS2 { get; private set; }

    private GameObject AllShape_1;
    private GameObject AllShape_2;
    private GameObject objectToStay;
    private GameObject objectToMove;

    private float tAccum_ST = 0f;
    private float tDurr_ST = 1.5f;
    private float tweenVAL = 0f;

    private Vector3[] axisFLIPPER = {  new Vector3 { x = 1,  y = 0,  z = 0 },
                                       new Vector3 { x = 0,  y = 1,  z = 0 },
                                       new Vector3 { x = 0,  y = 0,  z = 1 },
                                       new Vector3 { x = -1, y = 0,  z = 0 },
                                       new Vector3 { x = 0,  y =-1,  z = 0 },
                                       new Vector3 { x = 0,  y = 0,  z = -1},
                                    };

    public void Awake()
    {
        af_Instance = AF_Instance.Instance;
    }

    void Start()
    {
        tls = GetComponent<Touch_Lighting_and_Sound>();
        //TAG Spokes to access target transforms
        for (int i = 0; i<spoke_AS.Count; i++)
        {
            spoke_AS[i].SetParent_AllShape(this, i);
            tls.initializeColors_in_Spoke(spoke_AS[i]);
        }

        //TEST
        //for (int i = 0; i < spoke_AS.Count; i++)
        //{
        //    tls.Light_Occupied(spoke_AS[i],true);
        //}
    }
    //HANDLE IT HERE
    public void SpokeTriggered(int idx, Spoke_AllShape sourceSpoke)
    {
        //Am I in a Fulgurite? - Is the other in a Fulgurite?
        //
        //Last Held?
        //

        // DETERMINE ACTION BY CASE GOES HERE

        Form_Bond(spoke_AS[idx], sourceSpoke);
        //af_Instance.fulgurites[0].Create_New_Bond(spoke_AS[idx], sourceSpoke);
    }

    public void Form_Bond(Spoke_AllShape sas1, Spoke_AllShape sas2)
    {
        GameObject AS1 = sas1.myALL_SHAPE.gameObject;
        Transform targ1 = sas1.targTransform;
        GameObject AS2 = sas2.myALL_SHAPE.gameObject;
        Transform targ2 = sas2.targTransform;

        Determine_Target_Movement(AS1, targ1, AS2, targ2);
    }



    public void setOccupied(int spokeIDX, bool bOccupied, Spoke_AllShape connectedSpoke)
    {
        spoke_AS[spokeIDX].bOccupied = bOccupied;
        tls.Light_Occupied(spoke_AS[spokeIDX], bOccupied);

        spoke_AS[spokeIDX].connectedSpoke = connectedSpoke;
    }

    public void Determine_Target_Movement(GameObject AS1, Transform targ1, GameObject AS2, Transform targ2)
    {
        //Debug.Log("DETERMINE:");

        AllShape_1 = AS1;
        AllShape_2 = AS2;

        AF_Network_Grabable gbl_AS1 = AS1.GetComponent<Spoke_Handler>().netGrabbable;
        AF_Network_Grabable gbl_AS2 = AS2.GetComponent<Spoke_Handler>().netGrabbable;

        gbl_AS2.DropItem(null, true, true);
        gbl_AS1.DropItem(null, true, true);

        //gbl_AS1.enabled = false;
        //gbl_AS2.enabled = false;

        //AS1.GetComponent<Spoke_Handler>().SetAllActive_Colliders(false);
        //AS2.GetComponent<Spoke_Handler>().SetAllActive_Colliders(false);
        //Debug.Log("SetAllActive_Colliders(false)");

        //Quaternion qRota;
        //qRota = Quaternion.Euler(90, 0, 0);

        //Two calls - only take this one
        if (AS1 == af_Instance.last_Held_AllShape /*|| (AS1.GetComponent<Spoke_Handler>().isBeingHeld)*/)
        {
            objectToMove = AS1;
            objectToStay = AS2;

            //AS1.GetComponent<Rigidbody>().isKinematic = true;
            //AS2.GetComponent<Rigidbody>().isKinematic = true;

            AS2.GetComponent<Spoke_Handler>().SetAllActive_Colliders(false, false);
            AS2.GetComponent<Spoke_Handler>().SetAllActive_Colliders(false, false);

            //af_Instance.Set_All_Active_Colliders(false,false);

            Set_Target_Transform(targ2);

            tAccum_ST = 0.0f;
            Debug.Log("Start COROUTINE:" + Time.time.ToString("F3"));
            StartCoroutine(Move_to_Connect());

            //transform.position  = targ2.position;
            //transform.rotation  = targ2.rotation;
            //transform.rotation *= qRota;
        }
        else
        {
            //objectToMove = AS2;
            //objectToStay = AS1;

            //Set_Target_Transform(targ1);

            ////transform.position = targ1.position;
            ////transform.rotation = targ1.rotation;
            ////transform.rotation *= qRota;
        }

        //tAccum_ST = 0.0f;
        //Debug.Log("Start COROUTINE start:" + Time.time.ToString("F3"));
        //StartCoroutine(Move_to_Connect());
    }

    public void Set_Target_Transform(Transform targ)
    {
        Vector3 center = (objectToMove.transform.position + objectToStay.transform.position) / 2f;
        int idx1 = objectToMove.GetComponent<Spoke_Handler>().Closest_Fin(center);
        int idx2 = objectToStay.GetComponent<Spoke_Handler>().Closest_Fin(center);

        Vector3 vin = objectToStay.GetComponent<Spoke_Handler>().spoke_AS[idx2].trans_to.vIN[idx1];
        Vector3 vup = objectToStay.GetComponent<Spoke_Handler>().spoke_AS[idx2].trans_to.vUP[idx1];

        Vector3 vInTrans = objectToStay.transform.TransformDirection(vin);
        Vector3 vUpTrans = objectToStay.transform.TransformDirection(vup);

        targetPos = targ.position;
        targetRot = Quaternion.LookRotation(vInTrans, vUpTrans);

        //Debug.Log("MOVE fin:" + idx1.ToString() + "STAY fin:" + idx2.ToString());
        //Debug.Log("vin = " + vin.ToString("F1") + "vup = " + vup.ToString("F1"));
        //Debug.Log("vin TRANs = " + vInTrans.ToString("F1") + "vup TRANs = " + vUpTrans.ToString("F1"));

        //Flip it - for minimal rotation to bonding FIN
        if (Vector3.Dot(vUpTrans, objectToMove.transform.up) < 0 || Vector3.Dot(vInTrans, objectToMove.transform.forward) < 0)
        {
            Quaternion qRota = Quaternion.AngleAxis(180, axisFLIPPER[idx1]);
            targetRot *= qRota;
        }
    }

    private void Set_Occupied()
    {
        Vector3 center = (objectToMove.transform.position + objectToStay.transform.position) / 2f;
        int idx1 = objectToMove.GetComponent<Spoke_Handler>().Closest_Fin(center);
        int idx2 = objectToStay.GetComponent<Spoke_Handler>().Closest_Fin(center);

        objectToMove.GetComponent<Spoke_Handler>().setOccupied(idx1, true, objectToStay.GetComponent<Spoke_Handler>().spoke_AS[idx2]);
        objectToStay.GetComponent<Spoke_Handler>().setOccupied(idx2, true, objectToMove.GetComponent<Spoke_Handler>().spoke_AS[idx1]);
    }

    private IEnumerator Move_to_Connect()
    {
        int i = 0; //Sanity check for infinite loops

        float linProg = tAccum_ST / tDurr_ST;

        while (i < 180 && linProg < 1)
        {
            tAccum_ST += Time.deltaTime;
            linProg = tAccum_ST / tDurr_ST;
            Mathf.Clamp(tAccum_ST, 0, tDurr_ST);

            tweenVAL = EaseMethods.ExpoEaseInOut(tAccum_ST, 0, 1, tDurr_ST);
            Move_AllShape_Into_Place(tweenVAL);

            yield return true;
            i++;
        }
        tAccum_ST = tDurr_ST;
        tweenVAL = 1;

        Move_AllShape_Into_Place(tweenVAL);

        Set_Occupied();

        //Create_Fulgurite_Container();   //CHECK WHETHER ITs the FIRST ONE
        //AddFixedJoint(AllShape_1);
        //AddFixedJoint(AllShape_2);

        //Reset Active Colliders - Need an RPC call here perhaps
        AllShape_1.GetComponent<Spoke_Handler>().SetAllActive_Colliders(true, false);
        AllShape_2.GetComponent<Spoke_Handler>().SetAllActive_Colliders(true, false);

        //TEMPORARY
        //af_Instance.SetGrab_Colliders(true);
        //af_Instance.Set_All_Active_Colliders(true,false);

        //Debug.Log("FINISHED COROUTINE start:" + Time.time.ToString("F3"));
        StopCoroutine("Move_to_Connect");
    }

    private void Move_AllShape_Into_Place(float val)
    {
        objectToMove.transform.position = Vector3.Lerp(objectToMove.transform.position, targetPos, val);
        objectToMove.transform.rotation = Quaternion.Slerp(objectToMove.transform.rotation, targetRot, val);
    }

    public int Closest_Fin(Vector3 testPos)
    {
        int idxMin = 0;
        float minDistance = 1000000f;
        float dist;
        for (int i = 0; i < spoke_AS.Count; i++)
        {
            dist = (spoke_AS[i].fin_LOC.position - testPos).sqrMagnitude;
            if(dist<minDistance)
            {
                idxMin = i;
                minDistance = dist;
            }
        }
        return idxMin;
    }

    public void SetAllColliders(bool bOn)
    {
        sphereCollider.enabled = bOn;
        rb.isKinematic = true; //MORE CONSIDERATIONS HERE
        for (int i = 0; i < spoke_AS.Count; i++)
        {
            spoke_AS[i].bOccupied = false;
            spoke_AS[i].enableCollider(bOn);          
        }
    }

    public void SetAllActive_Colliders(bool bOn, bool bSphereCollider)
    {
        sphereCollider.enabled = bSphereCollider;
        rb.isKinematic = true; //MORE CONSIDERATIONS HERE
        for (int i = 0; i < spoke_AS.Count; i++)
        {
            if (spoke_AS[i].bOccupied)
            {
                spoke_AS[i].enableCollider(false);
            }
            else
            {
                spoke_AS[i].enableCollider(bOn);
            }
        }
    }

    public void Reset_Spokes_On_Grab()
    {
        for (int i = 0; i < spoke_AS.Count; i++)
        {
            if (spoke_AS[i].bOccupied)
            {
                spoke_AS[i].setOccupied(false);
            }
        }
    }

    void Update()
    {
        if(setLastHeld)
        {
            af_Instance.last_Held_AllShape = this.gameObject;
            setLastHeld = false;
        }
    }
}