using UnityEngine;
using System;

public class CarMouseInput : MonoBehaviour {

    public string DEBUG;
	public float HorizDeadSpot=0.05f;
	public float VertDeadSpot=0.05f;
	
	public bool Online { get; set; } 
		
//	private float HorizSweepSize;
//	private float VertSweepSize;
	private Vector3 mouseOrigin;
	private Engine engine;
	private Brakes brakes;
    private SteeringWheel steeringWheel;
    private Rigidbody2D r2;
	
	// Use this for initialization
	void Start () {
        Online = true;
		engine = GetComponent<Engine>();
		brakes = GetComponent<Brakes>();
        steeringWheel = GetComponent<SteeringWheel>();
        r2 = GetComponent<Rigidbody2D>();
	}
	
	private float Nonlinearize(float x)
	{
		if(x>=0)
			return (float)Math.Max(Math.Pow(x,1.8), x/4);
		else
			return -(float)Math.Max(Math.Pow(Math.Abs(x),1.8), Math.Abs (x)/4);
	}
	
	private Vector3 CleanInput(Vector3 rawInput)
	{
		// Sanitize the input, bounding it in the sweep size and checking the deadzone in center

        float sweepsize = Mathf.Min(Screen.width, Screen.height) / 3f;

		float cleanx = rawInput.x;
		if (Mathf.Abs(cleanx)<HorizDeadSpot)
			cleanx = 0;
        else if (cleanx > sweepsize)
            cleanx = sweepsize;
        else if (cleanx < -sweepsize)
			cleanx = -sweepsize;
		
		// TODO looks like y input is from +1 to -1
		float cleany = rawInput.y;
		if (Mathf.Abs(cleany)<VertDeadSpot)
			cleany = 0;
        else if (cleany > sweepsize)
            cleany = sweepsize;
        else if (cleany < -sweepsize)
            cleany = -sweepsize;
				
		// Nonlinearize dampens smaller inputs for better feel
        //Vector3 clean = new Vector3(Nonlinearize(cleanx / sweepsize), Nonlinearize(cleany / sweepsize), 0);
        Vector3 clean = new Vector3((cleanx / sweepsize), (cleany / sweepsize), 0);
		DEBUG = ("RAW " + rawInput + " CLEAN " + clean);
		return clean;
	}
	
	
	// Update is called once per frame
	void Update () {
		if(!Online)
			return;
		
		// done in update to handle web player res change on full-screen
        mouseOrigin = Camera.main.WorldToScreenPoint(transform.position);  //new Vector3(Screen.width / 2, Screen.height/2);
//		HorizSweepSize = Screen.width / 2;
//		VertSweepSize = Screen.height / 2;	

		//HandleGearShift();
		HandleGasBrakeAndSteering();
	}
	
	private void HandleGearShift()
	{
		if (Input.GetAxis("Mouse ScrollWheel") > 0)
		{
			UpShift();
		}
		if (Input.GetAxis("Mouse ScrollWheel") < 0)
		{
			DownShift();
		}
	}
	
	private void UpShift()
	{
		//Debug.Log("Up-shifting");
		switch(engine.Gear)
		{
			case Engine.EngineGear.Reverse:
				engine.Gear = Engine.EngineGear.Gas;
			break;
		}
	}
	
	private void DownShift()
	{
		//Debug.Log("Down-shifting");
		switch(engine.Gear)
		{
			case Engine.EngineGear.Gas:
				engine.Gear = Engine.EngineGear.Reverse;
			break;
		}
	}
    /*private void SCRAP_HandleGasBrakeAndSteering()
    {
        Vector3 cleanInput = CleanInput(Input.mousePosition - mouseOrigin);
        float gas = cleanInput.y;
        int sign = ((gas >= 0) ? 1 : -1);
        brakes.BrakeFactor = 0;

        if (Input.GetMouseButton(1))
        {
            brakes.BrakeFactor = 1;
            engine.ThrottleFactor = 0;
        }
        else if (Input.GetMouseButton(0))
        {
            engine.TargetSpeed = 999 * sign;
        }
        else{
            engine.TargetSpeed = 0;

            if (gas > 0.6f)
                engine.TargetSpeed = 29;
            else if (gas > 0.25f)
                engine.TargetSpeed = 24.5f;
            else if (gas > 0.2f)
                engine.TargetSpeed = 20;
            else if (gas > 0.15f)
                engine.TargetSpeed = 12.5f;
            else if (gas > 0.1f)
                engine.TargetSpeed = 7.5f;
            else if (gas > 0.05f)
                engine.TargetSpeed = 5;
            else if (gas > 0f)
                engine.TargetSpeed = 2;


            else if (gas < -0.1f)
                engine.TargetSpeed = -15;
            else if (gas < 0f)
                engine.TargetSpeed = -5;
        }


        //steeringWheel.SteeringFactor = cleanInput.normalized.x;
        steeringWheel.SteeringFactor = Mathf.Clamp(1.75f * cleanInput.x, -1f, +1f);
    }
    */
    private void HandleGasBrakeAndSteering()
	{
		//Debug.Log ("Mouse Position is " + Input.mousePosition + " and Origin is " + mouseOrigin);
		Vector3 cleanInput = CleanInput(Input.mousePosition - mouseOrigin);

        // we want to dampen steering a bit at high speeds to prevent jerkiness
        float speedfactor = Mathf.Clamp( ( r2.velocity.magnitude / 25) , 0, 1);

        float steer = cleanInput.x * 0.4f + (1 - speedfactor) * 0.6f * cleanInput.x;

        steeringWheel.SteeringFactor = Mathf.Clamp(steer, -1f, +1f);



        float gasbreak = Mathf.Clamp(cleanInput.y, -1f, +1f); //cleanInput.y;

        if(Input.GetMouseButton(1))
        {
            brakes.BrakeFactor = 1;
            engine.ThrottleFactor = 0;
            return;
        }
        else if(Input.GetMouseButton(0))
        {
            brakes.BrakeFactor = 0;
			engine.ThrottleFactor = 1.5f * ((gasbreak>=0) ? 1 : -1);
        }
		else if(gasbreak > 0)
		{
			//if(engine.Gear != Engine.EngineGear.Gas)
					//Debug.Log ("changing gear to Gas, gasbrake is "+gasbreak+" vel dot facing = " + Vector3.Dot (rigidbody.velocity, transform.forward));

			engine.Gear = Engine.EngineGear.Gas;
			engine.ThrottleFactor = gasbreak;
			brakes.BrakeFactor = 0;
		}
		else if (gasbreak < 0)
		{
			if((Vector3.Dot (r2.velocity, transform.up) > 1) ||
			   (Math.Abs(gasbreak) < 0.2) )
			{
				//Debug.Log ("just braking, gasbrake is "+gasbreak+" vert sweep is " + VertSweepSize + " vel dot facing = " + Vector3.Dot (rigidbody.velocity, transform.forward));
				brakes.BrakeFactor = -gasbreak;
				engine.ThrottleFactor = 0;
			}
			else 
			{
				//if(engine.Gear != Engine.EngineGear.Reverse)
					//Debug.Log ("changing gear to Reverse, gasbrake is "+gasbreak+" vel dot facing = " + Vector3.Dot (rigidbody.velocity, transform.forward));
				engine.Gear = Engine.EngineGear.Reverse;
				engine.ThrottleFactor = gasbreak;
				brakes.BrakeFactor = 0;					
			}
			
		}
				
		
		
		//Debug.Log ("gasbreak " + gasbreak + " and SteeringFactor " + steeringWheel.SteeringFactor);
		
	}
}
