/*
 * PlayerControls.cs
 * 
 * This class contains all the methods used for the
 * controls of the player
 *  
 * Created for 2011 Global Game Jam
 */

using UnityEngine;
using System.Collections;

public class PlayerControls : MonoBehaviour 
{
	// Inspector Variables
    public int genMovement;					// keeps track of what generation movement we are in
	
    public float smoothness = 30.0f;		// the smoothness of the arror keys
    public float thwompSpeed = 200;			// the speed of the thwomp
    
    public GameObject DragBox;				// the drag box for gen 5
	
    public Transform thwompExplosion;		// the particle effect for the the thwomp explosion
    public Transform colorPixedExplosion;	// the pixelated color particle effect
    public Transform n64Explosion;			// the slightly better particle effect
	
    public Material thwompMaterial;			// the material for the thowmp
	
    public AudioClip thwompNoise;			// the noise the thwmop makes
    public AudioClip thwompExplodeNoise;	// the explosion noise the thwomp makes
    public AudioClip thwompShrinkNoise;		// the shrink sound for the thwmop
	
	// Private Variables
    Vector3 startPos;			// start position of the thomp
    Vector3 moveUp;				// move up speed vector
    Vector3 moveDown;			// move down speed vector
    Vector3 thwompVelocity;		// the vetor that holds the velocit of the thwomp

    private bool thwomping = false;			// flag for determining if thwomp is moving in gen 1
    private bool arrowMoveLeft = false;		// is the left arrow key being held down
    private bool arrowMoveRight = false;	// is the right arror key being held down
    private bool arrorMoveUp = false;		// is the up arrow key being held down
    private bool arrowMoveDown = false;		// is the down arror key being held down
    private bool thwompShrunk = false;		// flag for if the thwomp has finished shrinkinng
    private bool bottomWalled = false;		// if the thwomp is walled in at the bottom
    private bool topWalled = false;			// if the thwomp is walled in at the top
    private bool leftWalled = false;		// if the thwomp is walled in at the left
    private bool rightWalled = false;		// if the thwomp is walled in at the right
	
    private Plane dragPlane = new Plane(Vector3.back, 0);	// used in gen 5 for flinging characters

	// Use this for initialization
	void Start () 
    {
        startPos = transform.position;					// initialize the start position

        moveDown = new Vector3(0, -thwompSpeed, 0);		// set the move down vector
        moveUp = new Vector3(0, thwompSpeed, 0);		// set the move up vector

        thwompVelocity = moveDown;		// set the thwomp velocity
		Screen.showCursor = false;		// disable showing the cursor

        genMovement = 1;	// set the generation of controls
	}
	
	// Update is called once per frame
	void Update () 
    {
		// determine which generation it is.
	    switch(Global.generation)
        {
            case 1:
                gen1Control();
                break;
            case 2:
                gen2Control();
                break;
            case 3:
				Screen.showCursor = true;
                gen3Control();
                break;
            case 4:
                gen4Control();
                break;
            case 5:
                gen5Control();
                break;
            case 6:
				Screen.showCursor = true;
                gen6Control();
                break;
            default:
                break;
        }
	}

    
    // Thwomp action for Any Key
    void gen1Control()
    {
		// just in case the gesture object is active, turn it off
        if (Global.gestureGO.active)
            Global.gestureGO.active = false;

        genMovement = 1;	// make sure gen movement stays at 1
		
		// if the current y valus is equal to the start y value, then stop thwomping
        if (transform.position.y >= startPos.y)
        {
            thwomping = false;
        }
		
		// if we are not thwomping, listen for any key to be pressed
        if (!thwomping && Input.anyKey)
        {
            thwomping = true;				// start thwomping
            thwompVelocity = moveDown;		// set the velocity of the thwomp
        }
		
		// if we are thwomping than move the thwomp down
        if (thwomping)
            rigidbody.velocity = thwompVelocity;
        else
            rigidbody.velocity = Vector3.zero;	// zero out the velocity
    }
	
	// contorls for the arror key movement
    void gen2Control()
    {
        genMovement = 2;	// ensuer generation stays at 2
		
		// if we are not in the middle of a thwomp
        if (!thwomping)
        {
			// check to see if the thwomp has shrunk 
			//NOTE: the mouseObjectPlayer check is to stop a null reference error
            if (!thwompShrunk && gameObject.name != "mouseObjectPlayer")
            {
                this.renderer.material = thwompMaterial;					// change the thomp material
                Camera.main.transform.audio.PlayOneShot(thwompShrinkNoise);	// play the shrinking sound
                animation.Play("thwompShrink");								// play the shrinking animation
                thwompShrunk = true;										// set the flag to be shrunk
            }
			
			// reset the movement values
            float xMovement = 0.0f;
            float yMovement = 0.0f;
			
			// check for left key down and not walled on the left side
            if (Input.GetKeyDown("left") && !leftWalled)
            {
                arrowMoveLeft = true;	// set move left flag
                rightWalled = false;	// unset the right walled flag
            }
			
			// check for the left key to be released or if we are up against the left wall
            if (Input.GetKeyUp("left") || leftWalled)
                arrowMoveLeft = false;	// unset the move left flag
			
			// if the right key is down and not walled on the right wall
            if (Input.GetKeyDown("right") && !rightWalled)
            {
                arrowMoveRight = true;	// set move the right
                leftWalled = false;		// unset left wallled flag
            }
			
			// check for the right key to be release or if we are up against the right wall
            if (Input.GetKeyUp("right") || rightWalled)
                arrowMoveRight = false;	// unset the move right flag
			
			// if the up key is down and not walled on the top wall
            if (Input.GetKeyDown("up") && !topWalled)
            {
                arrorMoveUp = true;		// set the move up flag
                bottomWalled = false;	// unset the bottom walled flag
            }
			
			// check for the up key to be released or if we are up against the top wall
            if (Input.GetKeyUp("up") || topWalled)
                arrorMoveUp = false;	// unset move up flag
			
			// if the down key is down and not walled on the bottom wall
            if (Input.GetKeyDown("down") && !bottomWalled)
            {
                arrowMoveDown = true;	// set the move down flag
                topWalled = false;		// unset the top walled flag
            }
			
			// check for the down key to be released or if we are up against the bottom wall
            if (Input.GetKeyUp("down") || bottomWalled)
                arrowMoveDown = false;	// unset the move down flag

			// if we are moving left
            if (arrowMoveLeft && !arrowMoveRight)
                xMovement = Time.deltaTime * smoothness * -1;
			
			// if we are moving right
            if (arrowMoveRight && !arrowMoveLeft)
                xMovement = Time.deltaTime * smoothness;
			
			// if we are moving up
            if (arrorMoveUp && !arrowMoveDown)
                yMovement = Time.deltaTime * smoothness;
			
			// if we are moving down
            if (arrowMoveDown && !arrorMoveUp)
                yMovement = Time.deltaTime * smoothness * -1;
			
			// translate to the new location
            transform.Translate(xMovement, yMovement, 0);
        }
		// if we are in the middle of a thwomp
        else
		{
            rigidbody.velocity = Vector3.zero;	// zero out the velocity
			thwomping = false;					// stop the thwomp
		}
    }
	
	// control for the 3 generation movement (mouse over)
    void gen3Control()
    {
        RaycastHit hit;		// the object that is hit by the raycast
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);	// get the raycast of the mouse
		
		// if we hit an object with the mouse
        if (Physics.Raycast(ray, out hit))
        {
            CubeMovement cubeCol = hit.transform.GetComponent<CubeMovement>();	// get the cube movement script on the collision object
			
			// if the script is null return
			if( cubeCol == null ) 
				return;
			
			// perform a mouse over kill
			cubeCol.MouseOverKill();
			
			// create a particle explosion at the object
            if (colorPixedExplosion)
                Instantiate(colorPixedExplosion, hit.transform.position, hit.transform.rotation);
        }
    }
	
	// perform the 4th generation of movement (Mouse Click)
    void gen4Control()
    {
		// if the left mouse button is clicked
        if(Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;		// the object hit by the raycast
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);	// get the raycast from the mouse posistion
			
			// if the raycast hits an object
            if (Physics.Raycast(ray, out hit))
			{
                CubeMovement characterScript = hit.transform.GetComponent<CubeMovement>();	 // get the cube movement script
				
				// if the script exists
                if (characterScript)
                {
					// perform a mouse click kill operation
                    characterScript.MouseClickKill();
					
					// instantiate a particle effect at the object
                    if (n64Explosion)
                        Instantiate(n64Explosion, hit.transform.position, hit.transform.rotation);
                }
            }
        }
    }
	
	// controls for generation 5
    void gen5Control()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);	// get the raycast from the screen
		
        float dist;							// holds the distance of the raycast
        dragPlane.Raycast(ray, out dist);	// get the distance from the drag plan raycast
        DragBox.rigidbody.MovePosition(ray.origin + ray.direction * dist);	// move the dragbox to the mouse location
		
		// if the left mouse button is held down
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;		// the object hit by the raycast
			
			// if the raycast didn't hit anything
            if(!Physics.Raycast(ray, out hit))
                return;

            SpringJoint springJoint = DragBox.GetComponent<SpringJoint>();		// get the spring joint from the drag box object
            springJoint.connectedBody = hit.transform.gameObject.rigidbody;		// connect the spring joint to the mouse and the item clicked
            Screen.showCursor = false;											// disable the mouse cursor
        }
		// if the left mouse button is released
        else if (Input.GetMouseButtonUp(0))
        {
            DragBox.GetComponent<SpringJoint>().connectedBody = null;	// clear the spring joint
            Screen.showCursor = true;									// enable the cursor
        }
    }
	
	// controlled by gesture recognizer
    void gen6Control()
    {

    }
	
	// kill the thwomp after gen 2
    public void killThwomp()
    {
        Camera.main.transform.audio.PlayOneShot(thwompExplodeNoise);	// play the thwomp explosion noise

		// create an explosion particle effect at the location
        if (thwompExplosion)
        {
            Instantiate(thwompExplosion, transform.position, transform.rotation);
        }
		
        Destroy(gameObject);	// destrop the thwomp object
    }
	
	// Event fireed on a collision
    void OnTriggerEnter(Collider collider)
    {
		// if we are in generation 1
        if (genMovement == 1)
        {
			// if we collided with the bottom wall, move up
            if (collider.gameObject.name == "Bottom Wall")
            {
                thwompVelocity = moveUp;								// setup the velocity to move up
                Camera.main.transform.audio.PlayOneShot(thwompNoise);	// play the thwomp noise
            }
        }
		// if we are in generation 3
        else if (genMovement == 2)
        {
            if (collider.gameObject.name == "Bottom Wall")	// against the bottom wall
                bottomWalled = true;
            if (collider.gameObject.name == "Top Wall")		// against the top wall
                topWalled = true;
            if (collider.gameObject.name == "Left Wall")	// against the left wall
                leftWalled = true; ;
            if (collider.gameObject.name == "Right Wall")	// agaonst the right wall
                rightWalled = true;
        }
    }
}
