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

public class Generator : MonoBehaviour {
	public float LeadDistance;
	public float GenerationInterval;
	public float WallSize = 1.28f;
	public float LeftWallX = -3.863529f;
	public float RightWallX = 3.863529f;


	private float lastGeneratedPoint = 0;
	private List<Transform> eligibleWaves = new List<Transform>();
	private GameController gc;
	private Transform player;

	// Use this for initialization
	void Start () {
		GameObject go = GameObject.Find ("GameController");
		gc = go.GetComponent<GameController>();

		GameObject pgo = GameObject.Find("Player");
		if(pgo!=null)
			player = pgo.transform;
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		if(player == null)
		{
			GameObject pgo = GameObject.Find("Player");
			if(pgo!=null)
				player = pgo.transform;
			else
				return;
		}
		if(lastGeneratedPoint - player.position.y < LeadDistance)
		{
			GenerateInterval();
		}
	}

	private void GenerateInterval()
	{
		Debug.Log ("Generating Content at " + lastGeneratedPoint);
		PlaceWalls();
		PlaceWaves();
		PlaceBackground();
	}

	private void PlaceWaves()
	{
		ComputeEligibleWaves();
		int stdcount = gc.rand.Next(4,7);
		int spicecount = gc.rand.Next(1,4);

		for(int i=0; i<stdcount; i++)
		{
			float portion = ((float)i/(float)stdcount);
			PlaceWave( portion*GenerationInterval + lastGeneratedPoint );
		}

		for(int j=0; j<spicecount; j++)
		{
			
		}

	}

	private void PlaceWave(float ypos)
	{
		Transform wavepf = gc.DrawFromAtRandom (eligibleWaves);
		Transform wave = (Transform)GameObject.Instantiate(wavepf);
		wave.position = new Vector3(0, ypos, 0);
	}

	private void ComputeEligibleWaves()
	{
		eligibleWaves.Clear();
		foreach(WaveDepths d in gc.Waves)
		{
			if(d.FirstDepth <= gc.DifficultyLevel && d.LastDepth >= gc.DifficultyLevel)
				eligibleWaves.Add(d.WavePrefab);
		}

	}

	private void PlaceWalls()
	{
		float limit = lastGeneratedPoint + GenerationInterval;
		float placed = lastGeneratedPoint;

		do {
			placed += WallSize*2f;
			PlaceWallPair(placed);
		}
		while(placed < limit);
		lastGeneratedPoint = placed;
	}

	private void PlaceWallPair(float ypos)
	{
		Transform leftpf = gc.DrawFromAtRandom (gc.WallPrefabs);
		Transform rightpf = gc.DrawFromAtRandom (gc.WallPrefabs);

		Transform left = (Transform)GameObject.Instantiate(leftpf);
		left.position = new Vector3(LeftWallX, ypos, 0);
		left.localScale = new Vector3(1,2,0);

		Transform right = (Transform)GameObject.Instantiate(leftpf);
		right.position = new Vector3(RightWallX, ypos, 0);
		right.localScale = new Vector3(-1,2,0);
	}

	private void PlaceBackground()
	{
		int bgcount = gc.rand.Next(1,4);
		for(int i=0; i<bgcount; i++)
		{
			float portion = ((float)i/(float)bgcount);
			PlaceOneBackground( portion*GenerationInterval + lastGeneratedPoint);
		}
	}

	private void PlaceOneBackground(float ypos)
	{
		Transform bgpf = gc.DrawFromAtRandom (gc.BackgroundPrefabs);
		Transform bg = (Transform)GameObject.Instantiate(bgpf);
		float x = ((float)gc.rand.NextDouble()*5f) - 3f;
		float y = ypos + ((float)gc.rand.NextDouble()*2f) - 1f;
		bg.position = new Vector3(x, y, 0);
		bg.eulerAngles = new Vector3(0, 0, gc.rand.Next(0,4) * 90f);
	}

}
