using FalcoEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class controller_s : MonoBehaviour
{
	public Prefab ball;
	private ball_s[] all_balls;
	private string check_color;
	private string pre_check_color;
	private int color_count;
	private GameObject[] balls_to_destroy=new GameObject[100];
	private int destroy_count;
	private GameObject first_point;
	public int collapse;
	private ball_s[] all_balls2;
	private int auto_collapse;
	private Text score_text;
	public int score;
	
	public Prefab exp_red;
	public Prefab exp_green;
	public Prefab exp_blue;
	public Prefab exp_purple;
	public Prefab exp_yellow;
	
	public Prefab sound_exp;
	public float speed_incr;
	public int game_end;
	private Text best_score_text;
	
	void Start()
	{
		score_text=GameObject.Find("score_text").GetComponent<Text>();
		first_point=GameObject.Find("first_point");
		
		for(int i=0;i<20;i++)
		{
			GameObject new_ball=ball.Instantiate(first_point.transform.position,transform.rotation);
			ball_s ball_s=new_ball.GetComponent<ball_s>();
			ball_s.pos=-0.03f*i;
			ball_s.index=i;
		}
		
		best_score_text=GameObject.Find("best_score_text").GetComponent<Text>();
		best_score_text.text="Best Score: "+PlayerPrefs.GetInt("best_score").ToString();
	}
	
	void FixedUpdate()
	{
		if(game_end==0)
		{
			speed_incr+=0.00000001f;
			score_text.text="Score: "+score.ToString();
			
			if(collapse==0)
			{
				auto_collapse++;
				if(auto_collapse==50)
				{
					auto_collapse=0;
					try_collapse();
				}
			}
			
			Debug.Log("1");
			
			ball_s[] sort_balls = FindObjectsOfType<ball_s>();
			int[] all_index = new int[10000];
			int index_count=0;
			
			for(int i=0;i<sort_balls.Length;i++)
			{
				all_index[index_count]=sort_balls[i].index;
				index_count++;
			}
			
			int a=0;
			
			Debug.Log("2");
			
			for(int i=0;i<index_count-1;i++)
			{
				for(int j=0;j<index_count-1;j++)
				{		
					if(all_index[j]>all_index[j+1])
					{
						a=all_index[j];
						all_index[j]=all_index[j+1];
						all_index[j+1]=a;
					}
				}
			}
			
			Debug.Log("3");
			
			ball_s[] all_balls = new ball_s[index_count];
			ball_s[] all_balls2=FindObjectsOfType<ball_s>();

			int sort_count=0;
			
			for(int i=0;i<index_count;i++)
			{
				for(int j=0;j<all_balls2.Length;j++)
				{
					if(all_balls2[j].index==all_index[i])
					{
						all_balls[sort_count]=all_balls2[j];
						sort_count++;
					}
				}
			}
			
			Debug.Log("4");
			
			int index=10000;
			int ball_min_index=0;
			
			for(int i=0;i<all_balls.Length;i++)
			{
				if(all_balls[i].index<=index)
				{
					index=all_balls[i].index;
					ball_min_index=i;
				}
				
				if(all_balls[i].pos<-1.1f)
				{
					game_end++;
					GameObject.Find("end_gui").enabled=true;
				}
			}
			
			if(all_balls[ball_min_index].pos<-0.03f)
			{
				GameObject new_ball=ball.Instantiate(first_point.transform.position,transform.rotation);
				ball_s ball_s=new_ball.GetComponent<ball_s>();
				ball_s.pos=0f;
				ball_s.index=ball_min_index;
				
				for(int i=0;i<all_balls.Length;i++)
				{
					if(all_balls[i].gameObject!=new_ball)
					{
						all_balls[i].index++;
					}
				}
			}
			
			if(collapse>0)
			{
				collapse++;
				
				for(int i=0;i<all_balls.Length;i++)
				{
					all_balls[i].pos=Mathf.Lerp(all_balls[i].pos,-0.03f*i,0.1f);
				}
				
				if(collapse==50)
				{
					collapse=0;
					
					for(int i=0;i<all_balls.Length;i++)
					{
						all_balls[i].index=i;
					}
				}
			}
		}
		
		if(game_end>0)
		{
			game_end++;
			
			if(game_end==2)
			{
				if(score>PlayerPrefs.GetInt("best_score"))
				{
					PlayerPrefs.SetInt("best_score",score);
					FalcoEngine.PlayerPrefs.Save();
				}
			}
		}
	}
	
	public void try_collapse()
	{
		ball_s[] sort_balls = FindObjectsOfType<ball_s>();
		int[] all_index = new int[10000];
		int index_count=0;

		for(int i=0;i<sort_balls.Length;i++)
		{
			all_index[index_count]=sort_balls[i].index;
			index_count++;
		}

		int a=0;
		
		for(int i=0;i<index_count-1;i++)
		{
			for(int j=0;j<index_count-1;j++)
			{		
				if(all_index[j]>all_index[j+1])
				{
					a=all_index[j];
					all_index[j]=all_index[j+1];
					all_index[j+1]=a;
				}
			}
		}

		ball_s[] all_balls = new ball_s[index_count];
		ball_s[] all_balls2=FindObjectsOfType<ball_s>();

		int sort_count=0;
		
		for(int i=0;i<index_count;i++)
		{
			for(int j=0;j<all_balls2.Length;j++)
			{
				if(all_balls2[j].index==all_index[i])
				{
					all_balls[sort_count]=all_balls2[j];
					sort_count++;
				}
			}
		}

		color_count=0;
		destroy_count=0;

		for(int i=0;i<all_balls.Length;i++)
		{
			if(i==0)
			{
				pre_check_color=all_balls[0].color;
				check_color=all_balls[0].color;
			}
			
			balls_to_destroy[destroy_count]=all_balls[i].gameObject;
			destroy_count++;
			
			check_color=all_balls[i].color;
			
			if(check_color==pre_check_color)
			{
				color_count++;
				
				if(color_count>=3)
				{
					for(int j=0;j<destroy_count;j++)
					{
						score+=10;
						
						ball_s this_ball = balls_to_destroy[j].GetComponent<ball_s>();
						
						if(this_ball.color=="red")
						{
							exp_red.Instantiate(balls_to_destroy[j].transform.position,Quaternion.Euler(0,0,0));
						}

						if(this_ball.color=="green")
						{
							exp_green.Instantiate(balls_to_destroy[j].transform.position,Quaternion.Euler(0,0,0));
						}

						if(this_ball.color=="blue")
						{
							exp_blue.Instantiate(balls_to_destroy[j].transform.position,Quaternion.Euler(0,0,0));
						}

						if(this_ball.color=="purple")
						{
							exp_purple.Instantiate(balls_to_destroy[j].transform.position,Quaternion.Euler(0,0,0));
						}

						if(this_ball.color=="yellow")
						{
							exp_yellow.Instantiate(balls_to_destroy[j].transform.position,Quaternion.Euler(0,0,0));
						}
						
						Destroy(balls_to_destroy[j]);
						collapse=1;
					}
					
					sound_exp.Instantiate(new Vector3(0,0,0),Quaternion.Euler(0,0,0));
				}
			}
			else
			{
				color_count=1;
				destroy_count=1;
				balls_to_destroy[0]=all_balls[i].gameObject;
			}
			pre_check_color=check_color;
		}
	}
	
	void Update()
	{
		if(game_end>0)
		{
			if(Input.GetKeyDown(ScanCode.Space))
			{
				FalcoEngine.SceneManager.LoadScene("game.scene");
			}
		}
	}
}
