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

public class Rotation : BaseDeformation
{
    public override string DeformationName { get; protected set; } = "Scale/Rotation";
    

    public override string Description { get; set; } = "Enables rotating and scaling the model";
    public override float Intensity
    {
        get
        {
            return 1;
        }

        set
        {
            // cannot change intensity of rotation
        }
    }

    public override void InitializeDeformation(DeformationManager deformationManager)
    {
        DeformationManager = deformationManager;
    }

    private Vector3 lastPositionLeft;
    private Vector3 currentPositionLeft;

    private Vector3 lastPositionRight;
    private Vector3 currentPositionRight;

    private void Update()
    {
        if (IsDeforming)
        {
            lastPositionLeft = currentPositionLeft;
            currentPositionLeft = VRTK_DeviceFinder.GetControllerLeftHand().transform.position;
            lastPositionRight = currentPositionRight;
            currentPositionRight = VRTK_DeviceFinder.GetControllerRightHand().transform.position;

            RotateModelWithBothControllers(lastPositionLeft, currentPositionLeft, lastPositionRight, currentPositionRight);



            //RotateModelWithOneController(DeformationManager.GlobalLastPosition, DeformationManager.GlobalCurrentPosition);
        }
    }

    public override void AddUndoStep(UndoStack undoStack)
    {

    }

    public override void StartDeforming()
    {
        if (IsDeforming)
        {
            return;
        }
        currentPositionLeft = VRTK_DeviceFinder.GetControllerLeftHand().transform.position;
        lastPositionLeft = currentPositionLeft;

        currentPositionRight = VRTK_DeviceFinder.GetControllerRightHand().transform.position;
        lastPositionRight = currentPositionRight;
        IsDeforming = true;
    }

    public override void StopDeforming()
    {
        IsDeforming = false;
    }

    public void RotateModelWithOneController(Vector3 lastPosition, Vector3 currentPosition)
    {
        Vector3 modelPosition = DeformationManager.ObjectToDeform.transform.position;

        Vector3 modelToLastPosition = lastPosition - modelPosition;
        Vector3 modelToCurrentPosition = currentPosition - modelPosition;
        float angle = Vector3.Angle(modelToCurrentPosition, modelToLastPosition);
        Vector3 normalToRotateAround = Vector3.Cross(modelToCurrentPosition, modelToLastPosition);


        DeformationManager.ObjectToDeform.transform.Rotate(normalToRotateAround, -angle, Space.World);

        // scale
        float distance = Vector3.Distance(lastPosition, currentPosition);

        int scaleUpDown = 1;
        if (modelToLastPosition.magnitude > modelToCurrentPosition.magnitude)
        {
            scaleUpDown = -1;
        }
        Vector3 scale = DeformationManager.ObjectToDeform.transform.localScale;
        scale += Vector3.one * distance * scaleUpDown;
        DeformationManager.ObjectToDeform.transform.localScale = scale;
    }


    public void RotateModelWithBothControllers(Vector3 lastPositionLeft, Vector3 currentPositionLeft, Vector3 lastPositionRight, Vector3 currentPositionRight)
    {
        Vector3 modelPosition = DeformationManager.ObjectToDeform.transform.position;


        Vector3 lastDirection = lastPositionLeft - lastPositionRight;
        Vector3 currentDirection = currentPositionLeft - currentPositionRight;
        float angle = Vector3.Angle(lastDirection, currentDirection);
        //Debug.Log(angle);

        Vector3 normalToRotateAround = Vector3.Cross(lastDirection, currentDirection);


        DeformationManager.ObjectToDeform.transform.Rotate(normalToRotateAround, angle, Space.World);
    
        
        Vector3 lastYPosition = (lastPositionLeft + lastPositionRight) / 2;
        Vector3 currentYPosition = (currentPositionLeft + currentPositionRight) / 2;

        float yDifference = currentYPosition.y - lastYPosition.y;

        
        
        Vector3 modelToLastCenter = lastYPosition - modelPosition;
        Vector3 modelToCurrentCenter = currentYPosition - modelPosition;

        angle = Vector3.Angle(modelToCurrentCenter, modelToLastCenter);
        normalToRotateAround = Vector3.Cross(modelToCurrentCenter, modelToLastCenter);


        DeformationManager.ObjectToDeform.transform.Rotate(normalToRotateAround, -angle, Space.World);
        


        float distance = currentDirection.magnitude - lastDirection.magnitude;

        Vector3 scale = DeformationManager.ObjectToDeform.transform.localScale;
        scale += Vector3.one * distance * 3;
        DeformationManager.ObjectToDeform.transform.localScale = scale;


    }

}
