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

public class DragRotation : MonoBehaviour
{
    private float modelAngleX = 0f; //rotation of model along X
    private float modelAngleZ = 0f; //rotation of model along Y
    private float modelOffsetX = 0f; //translation along X
    private float modelOffsetZ = 0f; //translation along Y
    private Vector3 previousPosition;
    private Vector3 currentPosition;
    private Ray ray;
    private float speed = 40f/100f;
    private float timeButtonDown;
    private Matrix4x4 viewMatrix;
    private Matrix4x4 worldMatrix;
    private Vector3 zeroPoint = new Vector3(0, 0, 0); //translation of coordinate system origin
    private Vector3 camPos;
    private float difference, difference2;


    [SerializeField] private RoscanModelUnity model; 
    [SerializeField] private Toggle onOffToggle; //toggle to able to measure
    [SerializeField] private Renderer renModel;
    //[SerializeField] private Shader shader;


    // Start is called before the first frame update
    void Start()
    {
        camPos = Camera.main.transform.localPosition;
        //Camera.main.transform.Translate(new Vector3(0, -camPos.z, 0));
        //Camera.main.transform.Rotate(new Vector3(-90, 0, 0), Space.World);
        previousPosition = Input.mousePosition;
    }

    // Update is called once per frame
    void Update()
    {
        if (EventSystem.current.IsPointerOverGameObject())
            return;

        // When the user click, put (measurement) point on model
        if (onOffToggle.isOn)
        {
            if (Input.GetMouseButtonDown(0))
            {
                timeButtonDown = Time.time;
            }
            if (Input.GetMouseButtonUp(0))
            {
                if ((Time.time - timeButtonDown) <= 0.2f)  // find out if it is mouse hold or mouse click
                {
                    ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                    RaycastHit[] hits;
                    hits = Physics.RaycastAll(ray);
                    model.LeftMouseClick(ray, hits);
                }
            }
            if (Input.GetMouseButtonDown(1))
            {
                ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit[] hits;
                hits = Physics.RaycastAll(ray);
                model.RightMouseClick(ray, hits);
            }
        }

        if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
        {
            if (Input.GetKey(KeyCode.LeftArrow)) //move left
            {
                modelOffsetZ = 0;
                modelOffsetX = speed;
                Translation();
            }
            if (Input.GetKey(KeyCode.RightArrow)) //move right
            {
                modelOffsetZ = 0;
                modelOffsetX = -speed;
                Translation();
            }
            if (Input.GetKey(KeyCode.UpArrow)) //move up
            {
                modelOffsetX = 0;
                modelOffsetZ = speed;
                Translation();
            }
            if (Input.GetKey(KeyCode.DownArrow)) //move down
            {
                modelOffsetX = 0;
                modelOffsetZ = -speed;
                Translation();
            }
            if (Input.GetMouseButtonDown(0)) // get position of mouse before start moving
            {
                previousPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            }
            else if (Input.GetMouseButton(0)) // move the model by mouse 
            {
                currentPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
                modelOffsetX = 0;
                modelOffsetZ = 0;
                modelOffsetX = 300f * (-currentPosition.x + previousPosition.x);
                modelOffsetZ = 300f * (currentPosition.y - previousPosition.y);
                Translation();

                previousPosition = currentPosition;
            }
        }
        else // not pressed SHIFT
        {
            if (Input.GetKey(KeyCode.LeftArrow))//rotate left
            {
                modelAngleX = 0;
                modelAngleZ = speed;
                Rotation();
            }
            if (Input.GetKey(KeyCode.RightArrow)) //rotate right
            {
                modelAngleX = 0;
                modelAngleZ = -speed;
                Rotation();
            }
            if (Input.GetKey(KeyCode.UpArrow)) //rotate up
            {
                modelAngleZ = 0;
                modelAngleX = -speed;
                Rotation();
            }
            if (Input.GetKey(KeyCode.DownArrow)) //rotate down
            {
                modelAngleZ = 0;
                modelAngleX = speed;
                Rotation();
            }

            if (Input.GetMouseButtonDown(0)) //get position before the dragging the model
            {
                previousPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            }
            else if (Input.GetMouseButton(0)) // drag the model by mouse
            {

                currentPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
                modelAngleX = 0;
                modelAngleZ = 0;
                modelAngleZ = 300f * (-currentPosition.x + previousPosition.x);
                modelAngleX = 300f * (-currentPosition.y + previousPosition.y);
                Rotation();

                previousPosition = currentPosition;
            }
        }

        //zoom camera with mouse wheel
        Camera.main.fieldOfView -= Input.GetAxis("Mouse ScrollWheel") * speed*10;        


        if (Input.GetKey(KeyCode.Q)) //zoom in
            Camera.main.fieldOfView += speed;           
        if (Input.GetKey(KeyCode.A)) //zoom out
        {
            Camera.main.fieldOfView -=  speed;
        }

        /*if (modelScale < 0.0001f) //scale saturation
            modelScale = 0.0001f;*/

    }

    /// <summary> make a rotation of the object</summary>
    private void Rotation()
    {
        transform.Rotate(new Vector3(modelAngleX, 0, modelAngleZ));
    }

    /// <summary> make a translation of the object</summary>
    private void Translation()
    {
        transform.Translate(new Vector3(modelOffsetX, 0, modelOffsetZ));
    }

    /// <summary> Reset view of camera after every new load of model</summary>
    public void prepareCamera()
    {
        Camera.main.transform.localPosition = new Vector3(30, camPos.z, 0);
        Camera.main.transform.localEulerAngles = new Vector3(-90, 0, 0);
        Camera.main.transform.DetachChildren();
    }

}
