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

public class ThingToOrbit{
	private Transform transform;
	private Rigidbody rigidbody;
	private OrbitObject orbitObject;
	public ThingToOrbit(GameObject thing){
		transform = thing.transform;
		rigidbody = thing.GetComponent<Rigidbody>();
		orbitObject = thing.GetComponent<OrbitObject>();
	}
	public Vector3 Position(){
		return transform.position;
	}
	public float Mass(){
		return rigidbody.mass;
	}
	public Vector3 Velocity(){
		return rigidbody.velocity;
	}
	public bool IsBeingThrown(){
		return orbitObject.beingThrown && OrbitObject.thingsToOrbit.Length > 1;
	}
}

public class OrbitObject : MonoBehaviour {
	private float gravityCutoffDistance = 4f;
	public float orbitForceMulti = 1f;
	public Vector3 initialVelocity;
	private Rigidbody myRigid;
	public bool beingThrown; 
	public static ThingToOrbit[] thingsToOrbit;
	public AudioSource screaming;
	void Start () {
		planetAS = gameObject.GetComponent<AudioSource>();
		myRigid = this.GetComponent<Rigidbody>();
		findThingsToOrbit();
		myRigid.AddForce(orbitForce(), ForceMode.VelocityChange);
		myRigid.mass = Random.Range(myRigid.mass*1.1f, myRigid.mass*0.9f);
	}
	
	void FixedUpdate() {
		OrbitObjects();
	}

	Vector3 cacheVectorFromMeToOrbitObject = new Vector3(); // Don't be wasteful, reuse your variables and GC will love you
	float cacheGravityForce = 0; // Don't be wasteful, reuse your variables and GC will love you
	void OrbitObjects(){
		for (int i = 0; i < thingsToOrbit.Length; i++)
		{
			cacheVectorFromMeToOrbitObject = (thingsToOrbit[i].Position() - transform.position);
			if(!thingsToOrbit[i].IsBeingThrown() && cacheVectorFromMeToOrbitObject.magnitude < gravityCutoffDistance){
				cacheGravityForce = thingsToOrbit[i].Mass() * Mathf.Sqrt(cacheVectorFromMeToOrbitObject.magnitude);
				myRigid.AddForce(cacheVectorFromMeToOrbitObject.normalized * cacheGravityForce * orbitForceMulti * Time.deltaTime, ForceMode.Force);
			}
		}
	}
	Vector3 orbitForce(){
		Vector3 forceVect = new Vector3();
		int numberOfThings = 0;
		for (int i = 0; i < thingsToOrbit.Length; i++)
		{
			cacheVectorFromMeToOrbitObject = (thingsToOrbit[i].Position() - transform.position);
			if(!thingsToOrbit[i].IsBeingThrown() && cacheVectorFromMeToOrbitObject.magnitude < gravityCutoffDistance){
				numberOfThings++;
				
				cacheGravityForce = thingsToOrbit[i].Mass() * Mathf.Sqrt(cacheVectorFromMeToOrbitObject.magnitude);
				forceVect = cacheVectorFromMeToOrbitObject.normalized;
				return (Quaternion.Euler(0f, 90f, 0f) * forceVect) * cacheGravityForce * 0.01f;
			}
		}
		return new Vector3();
	}

	public void onPickUp(){
		beingThrown = true;
		gameObject.GetComponent<TrailRenderer>().time = 0.3f;
		planetAS.clip = pickupClip[Random.Range(0, pickupClip.Length)];
		planetAS.Play();
		if(screaming!= null) screaming.Play();
	}
	public void onDetachFromHand(){
		gameObject.GetComponent<TrailRenderer>().time = 10f;
		beingThrown = false;
		planetAS.clip = putDownClip;
		planetAS.Play();
		if(screaming!= null) screaming.Stop();
		
		if(Sun.isHandOnFire){
			Sun.isHandOnFire = false;

			ParticleSystem[] temp = Valve.VR.InteractionSystem.InteractableButtonEvents.lastHandUsed.GetComponentsInChildren<ParticleSystem>();
			
			for (int i = 0; i < temp.Length; i++)
			{
				if(temp[i]!=null) temp[i].Stop();
			}
			
			Destroy(gameObject);
		}
	}
	public static void findThingsToOrbit(){
		if(thingsToOrbit != null) return;
		GameObject[] objects = GameObject.FindGameObjectsWithTag("GravityBody");
		thingsToOrbit = new ThingToOrbit[objects.Length];
		for (int i = 0; i < objects.Length; i++)
		{
			thingsToOrbit[i] = new ThingToOrbit(objects[i]);
		}
	}
	public ParticleSystem crashParticles;
	public ParticleSystem fireParticles;
	 AudioSource planetAS;

	public AudioClip crashClip;
	public AudioClip[] pickupClip;
	public AudioClip putDownClip;
	void OnCollisionEnter(Collision collision)
    {
		if(crashParticles!=null)
			crashParticles.Play();
		if(planetAS!=null && collision.gameObject.name.ToLower() != "headcollider" && collision.gameObject.name.ToLower() != "sun"){
			planetAS.clip = crashClip;
			planetAS.Play();
		}
		if(collision.gameObject.name.ToLower() == "sun"){
			if(fireParticles!=null)
				fireParticles.Play();
		}
    }
}
