using System;
using UnityEngine;

public class UltimateOrbitCamera : MonoBehaviour
{
	private void Awake()
	{
		this.targetDistance = this.distance;
		if (this.invertAxisX)
		{
			this.invertXValue = -1;
		}
		else
		{
			this.invertXValue = 1;
		}
		if (this.invertAxisY)
		{
			this.invertYValue = -1;
		}
		else
		{
			this.invertYValue = 1;
		}
		if (this.invertAxisZoom)
		{
			this.invertZoomValue = -1;
		}
		else
		{
			this.invertZoomValue = 1;
		}
		if (this.autoRotateOn)
		{
			this.autoRotateReverseValue = -1;
		}
		else
		{
			this.autoRotateReverseValue = 1;
		}
		this._transform = base.transform;
		Rigidbody component = base.GetComponent<Rigidbody>();
		if (component != null)
		{
			component.freezeRotation = true;
		}
		this.SetTransform(this.target.position, new Vector2(this.initialAngleX, this.initialAngleY), this.distance);
	}

	private void OnEnable()
	{
		if (!GameMain.Instance.VRMode)
		{
			UICamera.fallThrough = base.gameObject;
		}
	}

	private void OnDisable()
	{
		if (!GameMain.Instance.VRMode)
		{
			UICamera.fallThrough = null;
		}
	}

	private void OnHover(bool isOver)
	{
		if (!GameMain.Instance.VRMode)
		{
			this.m_bFallThrough = isOver;
		}
	}

	public void SetTransform(Vector3 f_vecTargetPosWorld, Vector2 f_vecRot, float f_fDistance)
	{
		Transform transform = this.target;
		this.mVelocity = f_vecTargetPosWorld;
		transform.position = f_vecTargetPosWorld;
		this._transform.rotation = Quaternion.identity;
		this._transform.Rotate(new Vector3(0f, f_vecRot.x, this.m_fRotZ), Space.World);
		this._transform.Rotate(new Vector3(f_vecRot.y, 0f, this.m_fRotZ), Space.Self);
		this.xNowRotate = (this.x = f_vecRot.x);
		this.yNowRotate = (this.y = f_vecRot.y);
		this.xVelocity = (this.yVelocity = 0f);
		this.position = this._transform.rotation * new Vector3(0f, 0f, -f_fDistance) + this.target.position;
		this._transform.position = this.position;
	}

	public void SetOffset(Vector3 f_posOffset, bool is_animation)
	{
		this.offsetTarget = f_posOffset;
		this.isForceMove = !is_animation;
	}

	public void SetTargetPos(Vector3 f_vecTargetPosWorld)
	{
		Transform transform = this.target;
		this.mVelocity = f_vecTargetPosWorld;
		transform.position = f_vecTargetPosWorld;
	}

	public void SetAroundAngle(Vector2 f_vecAngle)
	{
		this.SetTransform(this.target.position, f_vecAngle, this.distance);
	}

	public Vector2 GetAroundAngle()
	{
		return new Vector2(this.xNowRotate, this.yNowRotate);
	}

	public void SetDistance(float f_fDistance)
	{
		this.distance = f_fDistance;
		this.targetDistance = f_fDistance;
	}

	private void Update()
	{
		if (this.target != null)
		{
			Camera component = base.GetComponent<Camera>();
			if (this.autoRotateOn)
			{
				this.xVelocity += this.autoRotateSpeed * (float)this.autoRotateReverseValue * Time.deltaTime;
			}
			if (this.mouseControl && this.m_bFallThrough && 0f <= Input.mousePosition.x && Input.mousePosition.x < (float)Screen.width && 0f <= Input.mousePosition.y && Input.mousePosition.y < (float)Screen.height)
			{
				if (!this.clickToRotate || (this.leftClickToRotate && NInput.GetMouseButton(0)) || (this.rightClickToRotate && NInput.GetMouseButton(1)))
				{
					this.xVelocity += NInput.GetAxis(this.mouseAxisX) * this.xSpeed * (float)this.invertXValue;
					this.yVelocity -= NInput.GetAxis(this.mouseAxisY) * this.ySpeed * (float)this.invertYValue;
					this.spinning = false;
				}
				this.zoomVelocity -= NInput.GetAxis(this.mouseAxisZoom) * this.zoomSpeed * (float)this.invertZoomValue;
			}
			if (this.mouseControl && NInput.GetMouseButton(2) && this.m_bFallThrough)
			{
				Vector3 vector = new Vector3(-NInput.GetAxis(this.mouseAxisX), -NInput.GetAxis(this.mouseAxisY), 0f);
				Transform transform = this.target.transform;
				Transform transform2 = base.transform;
				this.mVelocity += (transform2.right * vector.x + transform2.up * vector.y) * this.moveSpeed;
				this.spinning = false;
			}
			if (this.mouseControl && NInput.GetMouseButton(2))
			{
				if (Input.GetKey(KeyCode.W))
				{
					this.mVelocity += component.transform.TransformDirection(Vector3.forward) * this.moveSpeed;
				}
				if (Input.GetKey(KeyCode.A))
				{
					this.mVelocity += component.transform.TransformDirection(Vector3.left) * this.moveSpeed;
				}
				if (Input.GetKey(KeyCode.S))
				{
					this.mVelocity += component.transform.TransformDirection(Vector3.back) * this.moveSpeed;
				}
				if (Input.GetKey(KeyCode.D))
				{
					this.mVelocity += component.transform.TransformDirection(Vector3.right) * this.moveSpeed;
				}
			}
			if (this.SpinEnabled && ((this.mouseControl && this.clickToRotate) || this.keyboardControl))
			{
				if ((this.spinUseAxis && NInput.GetAxis(this.spinAxis) != 0f) || (!this.spinUseAxis && Input.GetKey(this.spinKey)))
				{
					this.spinning = true;
					this.spinSpeed = Mathf.Min(this.xVelocity, this.maxSpinSpeed);
				}
				if (this.spinning)
				{
					this.xVelocity = this.spinSpeed;
				}
			}
			if (this.limitX)
			{
				if (this.x + this.xVelocity < this.xMinLimit + this.xLimitOffset)
				{
					this.xVelocity = this.xMinLimit + this.xLimitOffset - this.x;
				}
				else if (this.x + this.xVelocity > this.xMaxLimit + this.xLimitOffset)
				{
					this.xVelocity = this.xMaxLimit + this.xLimitOffset - this.x;
				}
				this.x += this.xVelocity;
				this._transform.Rotate(new Vector3(0f, this.xVelocity, 0f), Space.World);
			}
			else
			{
				this._transform.Rotate(new Vector3(0f, this.xVelocity, this.m_fRotZ - this.m_fBefRotZ), Space.World);
				this.m_fBefRotZ = this.m_fRotZ;
			}
			if (this.limitY)
			{
				if (this.y + this.yVelocity < this.yMinLimit + this.yLimitOffset)
				{
					this.yVelocity = this.yMinLimit + this.yLimitOffset - this.y;
				}
				else if (this.y + this.yVelocity > this.yMaxLimit + this.yLimitOffset)
				{
					this.yVelocity = this.yMaxLimit + this.yLimitOffset - this.y;
				}
				this.y += this.yVelocity;
				this._transform.Rotate(new Vector3(this.yVelocity, 0f, 0f), Space.Self);
			}
			else
			{
				this._transform.Rotate(new Vector3(this.yVelocity, 0f, this.m_fRotZ - this.m_fBefRotZ), Space.Self);
				this.m_fBefRotZ = this.m_fRotZ;
			}
			this.xNowRotate += this.xVelocity;
			this.yNowRotate += this.yVelocity;
			if (this.targetDistance + this.zoomVelocity < this.minDistance)
			{
				this.zoomVelocity = this.minDistance - this.targetDistance;
			}
			else if (this.targetDistance + this.zoomVelocity > this.maxDistance)
			{
				this.zoomVelocity = this.maxDistance - this.targetDistance;
			}
			this.targetDistance += this.zoomVelocity;
			this.distance = Mathf.Lerp(this.distance, this.targetDistance, this.smoothingZoom);
			this.target.position = Vector3.Lerp(this.target.position, this.mVelocity, this.smoothingMove);
			if (this.cameraCollision)
			{
				this.ray = new Ray(this.target.position, (this._transform.position - this.target.position).normalized);
				if (Physics.SphereCast(this.ray.origin, this.collisionRadius, this.ray.direction, out this.hit, this.distance))
				{
					this.distance = this.hit.distance;
				}
			}
			if (this.isForceMove)
			{
				this.offsetNow = this.offsetTarget;
				this.isForceMove = false;
			}
			else
			{
				this.offsetNow = Vector3.Lerp(this.offsetNow, this.offsetTarget, this.smoothingMove);
			}
			this.position = this._transform.rotation * new Vector3(0f, 0f, -this.distance) + this.target.position;
			this._transform.position = this.position;
			Vector3 vector2 = component.WorldToScreenPoint(this.target.position);
			Vector3 a = component.ScreenToWorldPoint(new Vector3(vector2.x, vector2.y, vector2.z));
			Vector3 b = component.ScreenToWorldPoint(new Vector3((float)Screen.width / 2f + this.offsetNow.x, (float)Screen.height / 2f, vector2.z));
			this._transform.position += a - b;
			if (!this.SpinEnabled || !this.spinning)
			{
				this.xVelocity *= this.dampeningX;
			}
			this.yVelocity *= this.dampeningY;
			this.zoomVelocity = 0f;
		}
		else
		{
			Debug.LogWarning("Orbit Cam - No Target Given");
		}
	}

	public void OnDrawGizmos()
	{
		Gizmos.DrawIcon(this.target.position, "gizmo_eye.png", true);
		if (base.enabled)
		{
			Gizmos.DrawRay(base.gameObject.transform.position, this.target.position - base.gameObject.transform.position);
		}
	}

	public Transform target;

	public float distance = 10f;

	public float maxDistance = 10f;

	public float minDistance = 5f;

	public bool mouseControl = true;

	public string mouseAxisX = "Mouse X";

	public string mouseAxisY = "Mouse Y";

	public string mouseAxisZoom = "Mouse ScrollWheel";

	public bool keyboardControl;

	public string kbPanAxisX = "Horizontal";

	public string kbPanAxisY = "Vertical";

	public bool kbUseZoomAxis;

	public KeyCode zoomInKey = KeyCode.R;

	public KeyCode zoomOutKey = KeyCode.F;

	public string kbZoomAxisName = string.Empty;

	public float initialAngleX;

	public float initialAngleY;

	public bool invertAxisX;

	public bool invertAxisY;

	public bool invertAxisZoom;

	public float xSpeed = 1f;

	public float ySpeed = 1f;

	public float zoomSpeed = 5f;

	public float moveSpeed = 1f;

	public float dampeningX = 0.9f;

	public float dampeningY = 0.9f;

	public float smoothingZoom = 0.1f;

	public float smoothingMove = 0.1f;

	public bool limitY = true;

	public float yMinLimit = -60f;

	public float yMaxLimit = 60f;

	public float yLimitOffset;

	public bool limitX;

	public float xMinLimit = -60f;

	public float xMaxLimit = 60f;

	public float xLimitOffset;

	public bool clickToRotate = true;

	public bool leftClickToRotate = true;

	public bool rightClickToRotate;

	public bool autoRotateOn;

	public bool autoRotateReverse;

	public float autoRotateSpeed = 0.1f;

	public bool SpinEnabled;

	public bool spinUseAxis;

	public KeyCode spinKey = KeyCode.LeftControl;

	public string spinAxis = string.Empty;

	public float maxSpinSpeed = 3f;

	private bool spinning;

	private float spinSpeed;

	public bool cameraCollision;

	public float collisionRadius = 0.25f;

	private float xVelocity;

	private float yVelocity;

	private Vector3 mVelocity;

	private float zoomVelocity;

	private float targetDistance = 10f;

	private float x;

	private float y;

	private Vector3 position;

	private float xNowRotate;

	private float yNowRotate;

	private bool isForceMove;

	public Vector3 offsetTarget;

	private Vector3 offsetNow;

	private bool m_bFallThrough;

	[HideInInspector]
	public int invertXValue = 1;

	[HideInInspector]
	public int invertYValue = 1;

	[HideInInspector]
	public int invertZoomValue = 1;

	[HideInInspector]
	public int autoRotateReverseValue = 1;

	public float m_fRotZ;

	private float m_fBefRotZ;

	private Ray ray;

	private RaycastHit hit;

	private Transform _transform;

	private enum MouseButtonDown
	{
		MBD_LEFT,
		MBD_RIGHT,
		MBD_MIDDLE
	}
}
