using UnityEngine;
using System.Collections;

public class Woodpecker : MonoBehaviour
{
	public float DistanceToCamera	= 3.0f;
	public float TimeHitting		= 0.3f;
	public float TimeDisturbing		= 12;
	public float Speed				= 0.5f;

	private bool m_started			= false;
	private bool m_jump				= false;
	private bool m_hitting			= false;

	private Vector3 m_startPos		= new Vector3();
	private Vector3 m_nextPos		= new Vector3();
	private GameObject m_curBranch	= null;
	private float m_stayTime		= 0;
	private float m_startTime		= 0;
	private float m_totTime			= 0;
	private float m_disturbTime		= 0;

	public void Begin()
	{
		if ( m_started )
		{
			return;
		}

		GameObject Terr = GameObject.Find("Terrain");

		if ( null != Terr )
		{
			TerrainGenerator Gen = Terr.GetComponent<TerrainGenerator>();

			if ( null != Gen )
			{
				GameObject NearestBranch = Gen.GetNearestBranch( gameObject );
				transform.position = new Vector3( NearestBranch.transform.position.x, NearestBranch.transform.position.y, transform.position.z );
				m_started = true;

				//Debug.Log( "Nearest branch " + transform.position.ToString() );
			}
		}
	}

	void Update()
	{
		if ( !m_started )
		{
			return;
		}

		GameObject CamObj = GameObject.Find( "MainCamera" );

		if ( null != CamObj )
		{
			if ( !m_jump )
			{
				Camera Cam = CamObj.GetComponent<Camera>();

				if ( Cam.transform.position.y + DistanceToCamera > transform.position.y )
				{
					m_jump = true;
					//Debug.Log( "Started Jumping" );
				}
			}
			else
			{
				m_disturbTime += Time.deltaTime;

				if ( m_disturbTime < TimeDisturbing )
				{
					if ( m_hitting )
					{
						StayInBranch();
					}
					else
					{
						Jumping();
					}
				}
				else
				{
					transform.position = new Vector3( transform.position.x + Time.deltaTime * 4, transform.position.y, transform.position.z );

					if ( !renderer.isVisible )
					{
						DestroyObject( gameObject );
					}
				}
			}
		}
		else
		{
			Debug.Log( "null Cam" );
		}
	}

	void StayInBranch()
	{
		m_stayTime += Time.deltaTime;

		if ( m_stayTime >= TimeHitting )
		{
			m_hitting	= false;
			m_stayTime	= 0;

			if ( null != m_curBranch && null != m_curBranch.gameObject.rigidbody )
			{
				m_curBranch.gameObject.rigidbody.isKinematic = false;
				m_curBranch.gameObject.rigidbody.useGravity = true;
			}
			else if ( null != m_curBranch )
			{
				Debug.Log( "Branch: " + m_curBranch.name + " no rigidbody" );
			}
		}
	}

	void Jumping()
	{
		if ( m_nextPos.x == 0 )
		{
			FindClosestBranch();
		}

		if ( m_nextPos.x != 0 )
		{
			InterpolateJump();
		}
	}

	float LinearInterpolation( float t, float b, float c, float d )
	{
		return b + t * c / d;
	}

	void InterpolateJump()
	{
		transform.position = new Vector3(
			LinearInterpolation( m_stayTime, m_startPos.x, m_nextPos.x - m_startPos.x, m_totTime ),
			LinearInterpolation( m_stayTime, m_startPos.y, m_nextPos.y - m_startPos.y, m_totTime ),
			transform.position.z
		);

		m_stayTime += Time.deltaTime;

		if ( m_stayTime >= m_totTime )
		{
			transform.position = new Vector3( m_nextPos.x, m_nextPos.y, m_nextPos.z );

			m_nextPos = new Vector3();
			m_startPos = new Vector3();

			m_hitting	= true;

			m_stayTime	= 0;
			m_totTime	= 0;
		}
	}

	void FindClosestBranch()
	{
		GameObject Terr = GameObject.Find("Terrain");

		if ( null != Terr )
		{
			TerrainGenerator Gen = Terr.GetComponent<TerrainGenerator>();

			if ( null != Gen )
			{
				GameObject Obj = Gen.GetSecondNearestBranch( gameObject );

				if ( null != Obj )
				{
					m_curBranch = Obj;

					m_startTime = Time.time;
					m_stayTime	= 0;
					m_startPos	= new Vector3( transform.position.x, transform.position.y, transform.position.z );
					m_nextPos	= new Vector3( Obj.transform.position.x, Obj.transform.position.y, transform.position.z );

					m_totTime = ( Vector2.Distance( new Vector2( m_startPos.x, m_startPos.y ), new Vector2( m_nextPos.x, m_nextPos.y ) ) / 10 ) * Speed;
				}
			}
		}
	}

	void OnTriggerEnter( Collider collisionInfo )
	{
		if ( collisionInfo.name.Contains( "obj_banana" ) )
		{
			DestroyObject( gameObject );
			DestroyObject( collisionInfo.gameObject );
		}
	}
}
