/*
	*	FUNCITON: Detect swipes on screen
	*	CALLED BY: Update()
	*/
	void SwipeMovementControl()
	{	
		//check and execute two jump or duck commands simultaneously
		if (bDirectionQueueFlag)
		{
			if(!bInAir && directionQueue == SwipeControlsCS.SwipeDirection.Jump)		//queue JUMP
			{
				bJumpFlag = true;			
				bDirectionQueueFlag = false;
			}//end of jump queue
			if (directionQueue == SwipeControlsCS.SwipeDirection.Duck && !bInDuck)		//queue SLIDE
			{
				duckPlayer();			
				bDirectionQueueFlag = false;
			}//end of duck queue
			
		}//end of direction queue

		//restore the size of the collider after slide ends
		if ( (mecanimEnabled && aPlayerMecAnim.GetAnimatorTransitionInfo(0).nameHash == Animator.StringToHash("Slide -> Run"))
		|| (!mecanimEnabled && !isPlayingDuck() && bInDuck == true) )//is the slide animation playing?
		{
			hSoundManagerCS.playSound(SoundManagerCS.CharacterSounds.Footsteps);
			
			//rotation correction after DIVE
			tPlayerRotation.localEulerAngles = new Vector3(tPlayerRotation.localEulerAngles.x, tPlayerRotation.localEulerAngles.y,0);
			//translation correction after DIVE (to fix mysterious bug :S)
			tBlobShadowPlane.localPosition = new Vector3(0, tBlobShadowPlane.localPosition.y, tBlobShadowPlane.localPosition.z);
					
			bInDuck = false;
			tFrontCollider.localScale = v3BNCDefaultScale;
			tPlayerSidesCollider.localScale = v3BFCDefaultScale;//restore far collider
			if (bDiveFlag)	//do not resume run animation on Dive
				return;
			if (!mecanimEnabled)
				aPlayer.CrossFadeQueued("run", 0.5f, QueueMode.CompleteOthers);
			else
			{
                aPlayerMecAnim.SetBool("DuckAnim", false);
				aPlayerMecAnim.SetBool("RunAnim", true);
			}
		}//end of if end of duck animation
	
		//swipe controls
		var direction = swipeLogic.getSwipeDirection();	//get the swipe direction	
		if (direction != SwipeControlsCS.SwipeDirection.Null)
		{
			bMouseReleased = false;//disallow taps on swipe
			
			if (direction == SwipeControlsCS.SwipeDirection.Jump)	//JUMP
			{
				if(!bInAir)
				{					
					bJumpFlag = true;
				}
				if (bInAir)	//queue the second jump if player swipes up in the middle of a jump
				{
					bDirectionQueueFlag = true;
					directionQueue = SwipeControlsCS.SwipeDirection.Jump;
				}
			}//end of if direction is jump
			if (direction == SwipeControlsCS.SwipeDirection.Right && swipeControlsEnabled == true)	//RIGHT swipe
			{
				if (iLanePosition != 1) 
				{
					iLastLanePosition = iLanePosition;
					iLanePosition++;
					
					strafePlayer(StrafeDirection.Strafe_Right);
					
				}//end of lane check if
			}//end of swipe direction if
			if (direction == SwipeControlsCS.SwipeDirection.Left && swipeControlsEnabled == true)	//LEFT swipe
			{
				if (iLanePosition != -1) 
				{
					iLastLanePosition = iLanePosition;
					iLanePosition--;
					
					strafePlayer(StrafeDirection.Strafe_Left);
					
				}//end of lane check if
			}//end of swipe direction if
			if (direction == SwipeControlsCS.SwipeDirection.Duck && bInDuck)//SLIDE: queue the second duck command if player is in the middle of slide animation
			{
				bDirectionQueueFlag = true;
				directionQueue = SwipeControlsCS.SwipeDirection.Duck;
			}
			if (direction == SwipeControlsCS.SwipeDirection.Duck && !bInAir && !bInDuck)//SLIDE: on ground
			{
				duckPlayer();
			}
			if (direction == SwipeControlsCS.SwipeDirection.Duck && bInAir && !bInDuck)//SLIDE/ DIVE: in air
			{				
				bDiveFlag = true;	//used by Set Transform() to make the character dive
			}//end of slide in air if
			
			//swipeLogic.iTouchStateFlag = 2;
		}//end of if	
		if (Input.GetMouseButtonUp(0))	//allow taps on mouse/ tap release
		{
			bMouseReleased = true;
		}
			
		//keyboard controls (DEBUG)
		if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow))//Up/ jump
		{
			if(!bInAir)
			{					
				bJumpFlag = true;
			}
			if (bInAir)
			{
				bDirectionQueueFlag = true;
				directionQueue = SwipeControlsCS.SwipeDirection.Jump;
			}
		}
		else if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow))//Right
		{
			if (iLanePosition != 1) 
			{
				iLastLanePosition = iLanePosition;
				iLanePosition++;
				
				strafePlayer(StrafeDirection.Strafe_Right);
				
			}//end of lane check if
		}
		else if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow))//Left
		{
			if (iLanePosition != -1) 
			{
				iLastLanePosition = iLanePosition;
				iLanePosition--;
				
				strafePlayer(StrafeDirection.Strafe_Left);
				
			}//end of lane check if
		}
		else if ( (Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && bInDuck)
		{
			bDirectionQueueFlag = true;
			directionQueue = SwipeControlsCS.SwipeDirection.Duck;
		}
		else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && !bInAir && !bInDuck)
		{
			duckPlayer();
		}
		else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && bInAir && !bInDuck)
		{
			bDiveFlag = true;	//used by Set Transform() to make the character dive
		}
		
	}//end of Movement Control function
    /*
     *	FUNCITON: Detect swipes on screen
     *	CALLED BY: Update()
     */
    void SwipeMovementControl()
    {
        //check and execute two jump or duck commands simultaneously
        if (bDirectionQueueFlag)
        {
            if (!bInAir && directionQueue == SwipeControlsCS.SwipeDirection.Jump)                       //queue JUMP
            {
                bJumpFlag           = true;
                bDirectionQueueFlag = false;
            }                                                                      //end of jump queue
            if (directionQueue == SwipeControlsCS.SwipeDirection.Duck && !bInDuck) //queue SLIDE
            {
                duckPlayer();
                bDirectionQueueFlag = false;
            }    //end of duck queue
        }        //end of direction queue

        //restore the size of the collider after slide ends
        if ((mecanimEnabled && aPlayerMecAnim.GetAnimatorTransitionInfo(0).nameHash == Animator.StringToHash("Base.Slide -> Base.Run")) ||
            (!mecanimEnabled && !isPlayingDuck() && bInDuck == true))        //is the slide animation playing?
        {
            hSoundManagerCS.playSound(SoundManagerCS.CharacterSounds.Footsteps);

            //rotation correction after DIVE
            tPlayerRotation.localEulerAngles = new Vector3(tPlayerRotation.localEulerAngles.x, tPlayerRotation.localEulerAngles.y, 0);
            //translation correction after DIVE (to fix mysterious bug :S)
            tBlobShadowPlane.localPosition = new Vector3(0, tBlobShadowPlane.localPosition.y, tBlobShadowPlane.localPosition.z);

            bInDuck = false;
            tFrontCollider.localScale       = v3BNCDefaultScale;
            tPlayerSidesCollider.localScale = v3BFCDefaultScale; //restore far collider

            if (bDiveFlag)                                       //do not resume run animation on Dive
            {
                return;
            }

            if (!mecanimEnabled)
            {
                aPlayer.CrossFadeQueued("run", 0.5f, QueueMode.CompleteOthers);
            }
            else
            {
                aPlayerMecAnim.SetBool("DuckAnim", false);
                aPlayerMecAnim.SetBool("RunAnim", true);
            }
        }        //end of if end of duck animation

        //swipe controls
        var direction = swipeLogic.getSwipeDirection();         //get the swipe direction

        if (direction != SwipeControlsCS.SwipeDirection.Null)
        {
            bMouseReleased = false;                               //disallow taps on swipe

            if (direction == SwipeControlsCS.SwipeDirection.Jump) //JUMP
            {
                if (!bInAir)
                {
                    bJumpFlag = true;
                }
                if (bInAir)                     //queue the second jump if player swipes up in the middle of a jump
                {
                    bDirectionQueueFlag = true;
                    directionQueue      = SwipeControlsCS.SwipeDirection.Jump;
                }
            }                                                                                      //end of if direction is jump
            if (direction == SwipeControlsCS.SwipeDirection.Right && swipeControlsEnabled == true) //RIGHT swipe
            {
                if (iLanePosition != 1)
                {
                    iLastLanePosition = iLanePosition;
                    iLanePosition++;

                    strafePlayer(StrafeDirection.Strafe_Right);
                }                                                                                 //end of lane check if
            }                                                                                     //end of swipe direction if
            if (direction == SwipeControlsCS.SwipeDirection.Left && swipeControlsEnabled == true) //LEFT swipe
            {
                if (iLanePosition != -1)
                {
                    iLastLanePosition = iLanePosition;
                    iLanePosition--;

                    strafePlayer(StrafeDirection.Strafe_Left);
                }                                                            //end of lane check if
            }                                                                //end of swipe direction if
            if (direction == SwipeControlsCS.SwipeDirection.Duck && bInDuck) //SLIDE: queue the second duck command if player is in the middle of slide animation
            {
                bDirectionQueueFlag = true;
                directionQueue      = SwipeControlsCS.SwipeDirection.Duck;
            }
            if (direction == SwipeControlsCS.SwipeDirection.Duck && !bInAir && !bInDuck)            //SLIDE: on ground
            {
                duckPlayer();
            }
            if (direction == SwipeControlsCS.SwipeDirection.Duck && bInAir && !bInDuck) //SLIDE/ DIVE: in air
            {
                bDiveFlag = true;                                                       //used by Set Transform() to make the character dive
            }                                                                           //end of slide in air if

            //swipeLogic.iTouchStateFlag = 2;
        }                              //end of if
        if (Input.GetMouseButtonUp(0)) //allow taps on mouse/ tap release
        {
            bMouseReleased = true;
        }

        //keyboard controls (DEBUG)
        if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow))        //Up/ jump
        {
            if (!bInAir)
            {
                bJumpFlag = true;
            }
            if (bInAir)
            {
                bDirectionQueueFlag = true;
                directionQueue      = SwipeControlsCS.SwipeDirection.Jump;
            }
        }
        else if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow))        //Right
        {
            if (iLanePosition != 1)
            {
                iLastLanePosition = iLanePosition;
                iLanePosition++;

                strafePlayer(StrafeDirection.Strafe_Right);
            }                                                                        //end of lane check if
        }
        else if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) //Left
        {
            if (iLanePosition != -1)
            {
                iLastLanePosition = iLanePosition;
                iLanePosition--;

                strafePlayer(StrafeDirection.Strafe_Left);
            }            //end of lane check if
        }
        else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && bInDuck)
        {
            bDirectionQueueFlag = true;
            directionQueue      = SwipeControlsCS.SwipeDirection.Duck;
        }
        else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && !bInAir && !bInDuck)
        {
            duckPlayer();
        }
        else if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && bInAir && !bInDuck)
        {
            bDiveFlag = true; //used by Set Transform() to make the character dive
        }
    }                         //end of Movement Control function
	void Start()
	{
		//script references
		hPatchesRandomizerCS = (PatchesRandomizerCS)this.GetComponent(typeof(PatchesRandomizerCS));
		//hMissionsControllerCS = (MissionsControllerCS)this.GetComponent(typeof(MissionsControllerCS));
		//hGlobalAchievementControllerCS = (GlobalAchievementControllerCS)this.GetComponent(typeof(GlobalAchievementControllerCS));
		hPlayerSidesColliderScriptCS = (PlayerSidesColliderScriptCS)GameObject.Find("PlayerSidesCollider").GetComponent(typeof(PlayerSidesColliderScriptCS));
		hPlayerFrontColliderScriptCS = (PlayerFrontColliderScriptCS)GameObject.Find("PlayerFrontCollider").GetComponent(typeof(PlayerFrontColliderScriptCS));
		hSoundManagerCS = (SoundManagerCS)GameObject.Find("SoundManager").GetComponent(typeof(SoundManagerCS));
		hInGameScriptCS = (InGameScriptCS)this.GetComponent(typeof(InGameScriptCS));
		hPitsMainControllerCS = (PitsMainControllerCS)this.GetComponent(typeof(PitsMainControllerCS));
		hCheckPointsMainCS = (CheckPointsMainCS)this.GetComponent(typeof(CheckPointsMainCS));
		hPowerupScriptCS = (PowerupsMainControllerCS)this.GetComponent(typeof(PowerupsMainControllerCS));
		//hEnemyControllerCS = (EnemyControllerCS)GameObject.Find("Enemy").GetComponent(typeof(EnemyControllerCS));
		hPowerupScriptCS = (PowerupsMainControllerCS)this.GetComponent(typeof(PowerupsMainControllerCS));
		hCameraControllerCS = (CameraControllerCS)GameObject.Find("Main Camera").GetComponent(typeof(CameraControllerCS));
		swipeLogic = (SwipeControlsCS)transform.GetComponent(typeof(SwipeControlsCS));
        //tPlayerMesh = (Transform)GameObject.Find("fatguy_").GetComponent(typeof(Transform));
		
		//check which type of menu (Custom or NGUI) to work with
		if (hInGameScriptCS.isCustomMenuEnabled())
		{
			//hMenuScriptCS = (MenuScriptCS)GameObject.Find("MenuGroup").GetComponent(typeof(MenuScriptCS));
			HUDCamera = GameObject.Find("HUDCamera").GetComponent<Camera>();
			
			tHUDGroup = GameObject.Find("HUDMainGroup/HUDGroup").transform;
			tPauseButton = GameObject.Find("HUDMainGroup/HUDGroup/HUDPause").transform;
		}
		
		tPlayer = transform;
		tPlayerRotation = transform.Find("PlayerRotation");
		
		//get the animation component of the player character
		if (this.transform.Find("PlayerRotation/PlayerMesh/Prisoner"))
		{
			mecanimEnabled = false;
			aPlayer = (Animation)this.transform.Find("PlayerRotation/PlayerMesh/Prisoner").GetComponent(typeof(Animation));			
			StartCoroutine("playIdleAnimations");//start playing idle animations
		}
		else if (this.transform.Find("PlayerRotation/PlayerMesh/Prisoner(MecAnim)"))//check for mecanim animated character
		{
			mecanimEnabled = true;
			aPlayerMecAnim = (Animator)this.transform.Find("PlayerRotation/PlayerMesh/Prisoner(MecAnim)").GetComponent(typeof(Animator));
			
			v3DefaultPlayerAnimPosition = aPlayerMecAnim.transform.localPosition;//get the default player position
			v3DefaultPlayerAnimRotation = aPlayerMecAnim.transform.localEulerAngles;//get the default player rotation		
		}
			
		tBlobShadowPlane = transform.Find("BlobShadowPlane");//get the shadow
		
		tPlayerSidesCollider = GameObject.Find("PlayerSidesCollider").transform;//get the sides collider to detect stumbles
		tFrontCollider = GameObject.Find("PlayerFrontCollider").transform;//get the front collider to detect collisions
		
		v3BNCDefaultScale = tFrontCollider.localScale;	
		v3BFCDefaultScale = tPlayerSidesCollider.localScale;
		
		bInAir = false;
		fCurrentDistanceOnPath = 50.0f;	//inital distance with respect to spline
		fCurrentDistance = 0.0f;
		fCurrentMileage = 0.0f;
		tCurrentAngle = 0.0f;	
		fPitFallLerpValue = 0.0f;
		fPitFallForwardSpeed = 0.0f;
		fPitPositionX = 0.0f;
		fDeathAnimStartTime = 0;
		bGroundhit = false;	
		bJumpFlag = false;
		bInJump = false;
		fCurrentUpwardVelocity = 0;
		fCurrentHeight = 0;
		
		bDirectionQueueFlag = false;
		directionQueue = SwipeControlsCS.SwipeDirection.Null;
		iLanePosition = 0;	//set current lane to mid	
		fCurrentWalkSpeed = fStartingWalkSpeed;
		
		//get the type of controls (swipe or gyro) set by user
		if (PlayerPrefs.HasKey("ControlsType"))
			swipeControlsEnabled = PlayerPrefs.GetInt("ControlsType") == 1 ? true : false;
		else
			PlayerPrefs.SetInt("ControlsType", (swipeControlsEnabled == true ? 1 : 0));
			
		//stop footsteps sound if playing
		hSoundManagerCS.stopSound(SoundManagerCS.CharacterSounds.Footsteps);
        stumbledXtimes = 0;
	}//end of Start()
    void Start()
    {
        //script references
        hPatchesRandomizerCS           = (PatchesRandomizerCS)this.GetComponent(typeof(PatchesRandomizerCS));
        hMissionsControllerCS          = (MissionsControllerCS)this.GetComponent(typeof(MissionsControllerCS));
        hGlobalAchievementControllerCS = (GlobalAchievementControllerCS)this.GetComponent(typeof(GlobalAchievementControllerCS));
        hPlayerSidesColliderScriptCS   = (PlayerSidesColliderScriptCS)GameObject.Find("PlayerSidesCollider").GetComponent(typeof(PlayerSidesColliderScriptCS));
        hPlayerFrontColliderScriptCS   = (PlayerFrontColliderScriptCS)GameObject.Find("PlayerFrontCollider").GetComponent(typeof(PlayerFrontColliderScriptCS));
        hSoundManagerCS       = (SoundManagerCS)GameObject.Find("SoundManager").GetComponent(typeof(SoundManagerCS));
        hInGameScriptCS       = (InGameScriptCS)this.GetComponent(typeof(InGameScriptCS));
        hPitsMainControllerCS = (PitsMainControllerCS)this.GetComponent(typeof(PitsMainControllerCS));
        hCheckPointsMainCS    = (CheckPointsMainCS)this.GetComponent(typeof(CheckPointsMainCS));
        hPowerupScriptCS      = (PowerupsMainControllerCS)this.GetComponent(typeof(PowerupsMainControllerCS));
        hEnemyControllerCS    = (EnemyControllerCS)GameObject.Find("Enemy").GetComponent(typeof(EnemyControllerCS));
        hPowerupScriptCS      = (PowerupsMainControllerCS)this.GetComponent(typeof(PowerupsMainControllerCS));
        hCameraControllerCS   = (CameraControllerCS)GameObject.Find("Main Camera").GetComponent(typeof(CameraControllerCS));
        swipeLogic            = (SwipeControlsCS)transform.GetComponent(typeof(SwipeControlsCS));

        //check which type of menu (Custom or NGUI) to work with
        if (hInGameScriptCS.isCustomMenuEnabled())
        {
            hMenuScriptCS = (MenuScriptCS)GameObject.Find("MenuGroup").GetComponent(typeof(MenuScriptCS));
            HUDCamera     = GameObject.Find("HUDCamera").GetComponent <Camera>();

            tHUDGroup    = GameObject.Find("HUDMainGroup/HUDGroup").transform;
            tPauseButton = GameObject.Find("HUDMainGroup/HUDGroup/HUDPause").transform;
        }

        tPlayer         = transform;
        tPlayerRotation = transform.Find("PlayerRotation");

        //get the animation component of the player character
        if (this.transform.Find("PlayerRotation/PlayerMesh/Prisoner"))
        {
            mecanimEnabled = false;
            aPlayer        = (Animation)this.transform.Find("PlayerRotation/PlayerMesh/Prisoner").GetComponent(typeof(Animation));
            StartCoroutine("playIdleAnimations");                                    //start playing idle animations
        }
        else if (this.transform.Find("PlayerRotation/PlayerMesh/Prisoner(MecAnim)")) //check for mecanim animated character
        {
            mecanimEnabled = true;
            aPlayerMecAnim = (Animator)this.transform.Find("PlayerRotation/PlayerMesh/Prisoner(MecAnim)").GetComponent(typeof(Animator));

            v3DefaultPlayerAnimPosition = aPlayerMecAnim.transform.localPosition;            //get the default player position
            v3DefaultPlayerAnimRotation = aPlayerMecAnim.transform.localEulerAngles;         //get the default player rotation
        }

        tBlobShadowPlane = transform.Find("BlobShadowPlane");                    //get the shadow

        tPlayerSidesCollider = GameObject.Find("PlayerSidesCollider").transform; //get the sides collider to detect stumbles
        tFrontCollider       = GameObject.Find("PlayerFrontCollider").transform; //get the front collider to detect collisions

        v3BNCDefaultScale = tFrontCollider.localScale;
        v3BFCDefaultScale = tPlayerSidesCollider.localScale;

        bInAir = false;
        fCurrentDistanceOnPath = 50.0f;         //inital distance with respect to spline
        fCurrentDistance       = 0.0f;
        fCurrentMileage        = 0.0f;
        tCurrentAngle          = 0.0f;
        fPitFallLerpValue      = 0.0f;
        fPitFallForwardSpeed   = 0.0f;
        fPitPositionX          = 0.0f;
        fDeathAnimStartTime    = 0;
        bGroundhit             = false;
        bJumpFlag = false;
        bInJump   = false;
        fCurrentUpwardVelocity = 0;
        fCurrentHeight         = 0;

        bDirectionQueueFlag = false;
        directionQueue      = SwipeControlsCS.SwipeDirection.Null;
        iLanePosition       = 0;        //set current lane to mid
        fCurrentWalkSpeed   = fStartingWalkSpeed;

        //get the type of controls (swipe or gyro) set by user
        if (PlayerPrefs.HasKey("ControlsType"))
        {
            swipeControlsEnabled = PlayerPrefs.GetInt("ControlsType") == 1 ? true : false;
        }
        else
        {
            PlayerPrefs.SetInt("ControlsType", (swipeControlsEnabled == true ? 1 : 0));
        }

        //stop footsteps sound if playing
        hSoundManagerCS.stopSound(SoundManagerCS.CharacterSounds.Footsteps);
    }    //end of Start()