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


public class MainBoard : MonoBehaviour 
{
	public static int m_iSizeX = 6;
	public static int m_iSizeY = 14;
	public static int m_iSize{get; private set;}
	public Switcher m_tTheSwitcher;

	public static MainBoard m_tMainBoard;

	static float m_fMovmentSpeed;
	static float m_fFallSpeed;
	static float m_fPointsRatio;
	static float m_fSpawnInterval;
	static int m_iPointsPerBlock;

	public float m_fBaseMovmentSpeed;
	public float m_fBaseFallSpeed;
	public float m_fBasePointsRatio;
	public float m_fBaseSpawnInterval;
	public int m_iBasePointsPerBlock;

	public static float m_fBaseMovSpBuf;
	public static float m_fBaseFallSpBuf;
	public static float m_fBasePntsRatBuf;
	public static float m_fBaseSpawnIntBuf;
	public static int m_iBasePointsPerBlockBuf;

	float m_fCurrentMultiplicator = 1;
	int m_iCurrentScore = 0;
	public TextMesh m_ScoreText;
	public TextMesh m_MultiplicatorText;
	public SpeedManager m_tSpeedManager;
	public static bool m_bColorBlindActive = false;

	float m_fSpawnStartTime;

	public AudioSource m_aExplode;
	public List<int> m_iCellToDelete;

	//explode patch
	public SpriteExplode m_explosionSprite;


	//temp vars 
	float m_fLastSlideTime;
	public float m_fSlideEachTime;

	public Block[]	m_eBoard = new Block[m_iSizeX * m_iSizeY];

	bool m_bGameOver = false;

	public static void SetPointsPerBlocks(int iPointsPerBlock)
	{
		m_iPointsPerBlock = iPointsPerBlock;
	}

	public static void SetMovementSpeedRatio(float fRatio)
	{
		m_fMovmentSpeed = m_fMovmentSpeed * fRatio;
	}

	public static void SetFallSpeedRatio(float fRatio)
	{
		Debug.Log("pre" + m_fFallSpeed);
		m_fFallSpeed = m_fFallSpeed * fRatio;
		Debug.Log("post" + m_fFallSpeed);
	}

	public static void SetPointsRatio(float fPointsRatio)
	{
		m_fPointsRatio = fPointsRatio;
	}

	public static void SetSpawnInterval(float fSpawnInterval)
	{
		m_fSpawnInterval = fSpawnInterval;
	}

	public static void ReinitializeRatios()
	{
		m_fMovmentSpeed = m_fBaseMovSpBuf;
		m_fFallSpeed = m_fBaseFallSpBuf;
		m_fPointsRatio = m_fBasePntsRatBuf;
		m_fSpawnInterval = m_fBaseSpawnIntBuf;
		m_iPointsPerBlock = m_iBasePointsPerBlockBuf;
	}

	// Use this for initialization
	void Start () 
	{
		m_tMainBoard = this;

		m_iSize = m_iSizeX * m_iSizeY;

		m_fBaseMovSpBuf = m_fBaseMovmentSpeed;
		m_fBaseFallSpBuf = m_fBaseFallSpeed;
		m_fBasePntsRatBuf = m_fBasePointsRatio;
		m_fBaseSpawnIntBuf = m_fBaseSpawnInterval;
		m_iBasePointsPerBlockBuf = m_iBasePointsPerBlock;

		m_fMovmentSpeed = m_fBaseMovSpBuf;
		m_fFallSpeed = m_fBaseFallSpBuf;
		m_fPointsRatio = m_fBasePntsRatBuf;
		m_fSpawnInterval = m_fBaseSpawnIntBuf;
		m_iPointsPerBlock = m_iBasePointsPerBlockBuf;

		m_fCurrentMultiplicator = 1;
		m_iCurrentScore = 0;

		m_fSpawnStartTime = Time.time;
		m_bGameOver = false;

//		MainBoard.m_tMainBoard.SwitchToNormalColor();
		MainBoard.m_bColorBlindActive = false;

		CharacterManager.m_Instance.ActivateCharacterByIndex(0);


		//initialize randomly
		
		for (int i = 0; i < m_iSize; i++) 
		{
			/*			if(i<30)
			{
				GlobalVars.BrickType _Type = ( GlobalVars.BrickType ) UnityEngine.Random.Range(0,(int)GlobalVars.BrickType.COLOR_COUNT);
				SpawnBlock(i, _Type);
			}
			else
			{
*/				GlobalVars.BrickType _Type = GlobalVars.BrickType.EMPTY;
			SpawnBlock(i, _Type);
			//			}
			//			Debug.Log( m_eBoard[i] );
		}
		
		DrawManager.DrawBoard( this );
		
		//init switcher
		m_tTheSwitcher.Init();
		
		//init slid time
		m_fLastSlideTime = Time.time;

		m_tSpeedManager.Init();

	}

	 
	public bool CheckVerticalCellMove(int iIndex)
	{
		if(m_eBoard[iIndex].GetBlockType() != GlobalVars.BrickType.EMPTY)
		{
			if(! m_eBoard[iIndex].m_bHaveReacheNearTarget )
				return false;
			Vec2 _Pos = GetPosByIndex(iIndex);
			if( _Pos.y > 0 && m_eBoard[GetIndexByPos(new Vec2(_Pos.x, _Pos.y - 1))].GetBlockType() == GlobalVars.BrickType.EMPTY)
			{
				//m_eBoard[iIndex].m_TargetPos = new Vector3(m_eBoard[iIndex].m_TargetPos.x, _Pos.y - 1 * DrawManager.m_tDrawManager.m_fBlocSize, 0) + DrawManager.m_tDrawManager.m_tWorldPosition;
				m_eBoard[iIndex].m_TargetPos = new Vector3(m_eBoard[iIndex].m_TargetPos.x, _Pos.y - 1 * DrawManager.m_tDrawManager.m_fBlocSize, 0);
				Block _buffer = m_eBoard[GetIndexByPos(new Vec2(_Pos.x, _Pos.y - 1))];
				m_eBoard[iIndex].m_bHaveReacheNearTarget = false;				
				m_eBoard[iIndex].m_bIsMoving = true;				
				m_eBoard[GetIndexByPos(new Vec2(_Pos.x, _Pos.y - 1))] = m_eBoard[iIndex];
				m_eBoard[iIndex] = _buffer;
				m_eBoard[iIndex].m_Pos = new Vector3(_Pos.x, _Pos.y * DrawManager.m_tDrawManager.m_fBlocSize, 0);
				m_eBoard[iIndex].m_TargetPos = m_eBoard[iIndex].m_Pos;
				m_eBoard[iIndex].m_bHaveReacheNearTarget = false;				 

				return true;
			}
		}
		return false;
	}

	public void CheckAllVerticalCellMove()
	{
		for(int i =0; i < m_iSize; i++)
		{

				CheckVerticalCellMove(i);
		}
	}

	public void CheckCell( Vec2 pos, GlobalVars.BrickType tType, ref int cpt  )
	{
		int index = GetIndexByPos( pos );	
//		Debug.Log(index + "Trying to check" + m_eBoard[ index ].m_bHaveBeenChecked + " " + m_eBoard[ index ].GetBlockType() );
		if( index >=0 && index < m_iSize )
		{
			if( tType == m_eBoard[ index ].GetBlockType() && !m_eBoard[ index ].m_bHaveBeenChecked )
			{
//				Debug.Log(index + "CHECKED " + m_eBoard[ index ].GetBlockType());
				cpt++;
//				Debug.Log("+1 - " + cpt );
				m_eBoard[ index ].m_bHaveBeenChecked = true;
				m_iCellToDelete.Add( index );
				if( pos.x+1 < m_iSizeX )
				CheckCell( new Vec2( pos.x+1, pos.y ),tType, ref cpt);
				if( pos.x-1 >= 0 )			
				CheckCell( new Vec2( pos.x-1, pos.y ),tType, ref cpt);
				if( pos.y+1 < m_iSizeY )			
				CheckCell( new Vec2( pos.x, pos.y+1 ),tType, ref cpt);
				if( pos.y-1 >= 0 )			
				CheckCell( new Vec2( pos.x, pos.y-1 ),tType, ref cpt);
			}
		}

	}

	public void CheckCellBlindColor( Vec2 pos, GlobalVars.BrickType tType, ref int cpt  )
	{
		int index = GetIndexByPos( pos );	
		//		Debug.Log(index + "Trying to check" + m_eBoard[ index ].m_bHaveBeenChecked + " " + m_eBoard[ index ].GetBlockType() );
		if( index >=0 && index < m_iSize )
		{
			GlobalVars.BrickType block = m_eBoard[ index ].GetBlockType();
			if( ( (tType == GlobalVars.BrickType.YELLOW  || tType == GlobalVars.BrickType.GREEN) && (block == GlobalVars.BrickType.YELLOW  || block == GlobalVars.BrickType.GREEN) )  && !m_eBoard[ index ].m_bHaveBeenChecked )
			{
				//				Debug.Log(index + "CHECKED " + m_eBoard[ index ].GetBlockType());
				cpt++;
				//				Debug.Log("+1 - " + cpt );
				m_eBoard[ index ].m_bHaveBeenChecked = true;
				m_iCellToDelete.Add( index );
				if( pos.x+1 < m_iSizeX )
					CheckCellBlindColor( new Vec2( pos.x+1, pos.y ),tType, ref cpt);
				if( pos.x-1 >= 0 )			
					CheckCellBlindColor( new Vec2( pos.x-1, pos.y ),tType, ref cpt);
				if( pos.y+1 < m_iSizeY )			
					CheckCellBlindColor( new Vec2( pos.x, pos.y+1 ),tType, ref cpt);
				if( pos.y-1 >= 0 )			
					CheckCellBlindColor( new Vec2( pos.x, pos.y-1 ),tType, ref cpt);
			}
			else if( tType == m_eBoard[ index ].GetBlockType() && !m_eBoard[ index ].m_bHaveBeenChecked )
			{
				//				Debug.Log(index + "CHECKED " + m_eBoard[ index ].GetBlockType());
				cpt++;
				//				Debug.Log("+1 - " + cpt );
				m_eBoard[ index ].m_bHaveBeenChecked = true;
				m_iCellToDelete.Add( index );
				if( pos.x+1 < m_iSizeX )
					CheckCellBlindColor( new Vec2( pos.x+1, pos.y ),tType, ref cpt);
				if( pos.x-1 >= 0 )			
					CheckCellBlindColor( new Vec2( pos.x-1, pos.y ),tType, ref cpt);
				if( pos.y+1 < m_iSizeY )			
					CheckCellBlindColor( new Vec2( pos.x, pos.y+1 ),tType, ref cpt);
				if( pos.y-1 >= 0 )			
					CheckCellBlindColor ( new Vec2( pos.x, pos.y-1 ),tType, ref cpt);
			}
		}
		
	}

	public static int GetIndexByPos(Vec2 Position)
	{
		int _ReturnValue = ( m_iSizeX * (int)Position.y ) + (int)Position.x;
		return _ReturnValue;
	}

	public static Vec2 GetPosByIndex( int iIndex )
	{
		int _PosY = iIndex/m_iSizeX;
		int _PosX = iIndex - (_PosY*m_iSizeX);
		return new Vec2( _PosX, _PosY);
	}


	public GlobalVars.BrickType GetBrickTypeByIndex( int iIndex )
	{
		if( iIndex >= 0 && iIndex < m_iSize  )
		{
			return m_eBoard[iIndex].GetBlockType();
		}
		return GlobalVars.BrickType.INVALID;
	}

	public void SpawnRandomPattern(int iSize, int iSpawnX)
	{
/*		if(iSize > 1 && iSpawnX >= m_iSizeX - 2)
		{
			iSpawnX = 0;
		}*/
		Vec2 _SpawnPos;
		for(int i = 0; i <= iSize; i++)
		{
			if(i < 2)
			{
				_SpawnPos = new Vec2(iSpawnX + i, m_iSizeY - 1);
				if(GetIndexByPos(_SpawnPos) < m_iSize )
				{
//					Debug.Log(_SpawnPos.x + "  " + _SpawnPos.y);
					SpawnAndCreateMesh(GetIndexByPos(_SpawnPos), ( GlobalVars.BrickType ) UnityEngine.Random.Range(0,(int)GlobalVars.BrickType.COLOR_COUNT));
				}
			}
			else
			{
				_SpawnPos =  new Vec2(iSpawnX + i - 2, m_iSizeY - 2);
				if(GetIndexByPos(_SpawnPos) < m_iSize )
				{
//					Debug.Log(_SpawnPos.x + "  " + _SpawnPos.y);
					SpawnAndCreateMesh(GetIndexByPos( _SpawnPos), ( GlobalVars.BrickType ) UnityEngine.Random.Range(0,(int)GlobalVars.BrickType.COLOR_COUNT));
				}
			}

		}
	}


	public void SpawnAndCreateMesh( int iIndex, GlobalVars.BrickType Type  )
	{
		Vec2 _tPos = MainBoard.GetPosByIndex( iIndex );
		
		if(m_eBoard[iIndex] == null)
		{
			m_eBoard[iIndex] = new Block();
		}
		if(m_eBoard[iIndex].GetBlockType() != GlobalVars.BrickType.EMPTY)
		{
			m_bGameOver = true;
			GameStateManager.m_Instance.SetStateGameOver();
		}
		else
		{
			m_eBoard[iIndex].Init(new Vector2(_tPos.x, _tPos.y), Type);
			Transform _Instance = (Transform) Instantiate( DrawManager.m_tDrawManager.m_tGameModels[ (int)Type ],new Vector3( _tPos.x * DrawManager.m_tDrawManager.m_fBlocSize, _tPos.y * DrawManager.m_tDrawManager.m_fBlocSize,0 ) + DrawManager.m_tDrawManager.m_tWorldPosition, Quaternion.identity ) as Transform;
			_Instance.gameObject.name = "brique_" + iIndex ;
			m_eBoard[iIndex].SetModel(_Instance);



			//switch color to black and white
			if( MainBoard.m_bColorBlindActive )
				/*if( this.m_eBoard[iIndex].m_Model && (  this.m_eBoard[iIndex].GetBlockType() == GlobalVars.BrickType.RED ))
					this.m_eBoard[iIndex].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[0];
			else if( this.m_eBoard[iIndex].m_Model && (  this.m_eBoard[iIndex].GetBlockType() == GlobalVars.BrickType.BLUE ))
				this.m_eBoard[iIndex].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[1];
			else */if( this.m_eBoard[iIndex].m_Model && (  this.m_eBoard[iIndex].GetBlockType() == GlobalVars.BrickType.YELLOW ))
				this.m_eBoard[iIndex].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[2];
			else if( this.m_eBoard[iIndex].m_Model && (  this.m_eBoard[iIndex].GetBlockType() == GlobalVars.BrickType.GREEN ))
				this.m_eBoard[iIndex].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[3];

		}

		m_fCurrentMultiplicator = 1;
	}

	public void SpawnBlock( int iIndex, GlobalVars.BrickType Type  )
	{
		Vec2 _tPos = MainBoard.GetPosByIndex( iIndex );

		if(m_eBoard[iIndex] == null)
		{
			m_eBoard[iIndex] = new Block();
		}
		m_eBoard[iIndex].Init(new Vector2(_tPos.x, _tPos.y), Type);

/*		if(m_eBoard[iIndex].GetBlockType() != GlobalVars.BrickType.EMPTY)
		{
			m_eBoard[iIndex].m_Model.renderer.enabled = true;
		}
		else
		{
			m_eBoard[iIndex].m_Model.renderer.enabled = false;
		}
*/
//		Transform _Instance = (Transform) Instantiate( m_tDrawManager.m_tGameModels[ (int)_BrickType ],new Vector3( _tPos.x * m_tDrawManager.m_fBlocSize, _tPos.y * m_tDrawManager.m_fBlocSize,0 ) + m_tDrawManager.m_tWorldPosition, Quaternion.identity ) as Transform;
		//		Board.m_[iIndex].Init(_tPos, _Instance);
	}

	public void SwitchToColorBlind()
	{
		for(int i = 0; i < MainBoard.m_iSize; i++)
		{
			/*if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.RED ))
			   this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[0];
			else if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.BLUE ))
			   		this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[1];
		    else */if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.YELLOW ))
		       		 this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[2];
		    else if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.GREEN ))
		        	this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tBlindMaterials[3];
			   
		}
	}

	public void SwitchToNormalColor()
	{
		for(int i = 0; i < MainBoard.m_iSize; i++)
		{
			/*if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.RED ))
				this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tNormalMaterials[0];
			else if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.BLUE ))
				this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tNormalMaterials[1];
			else */if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.YELLOW ))
				this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tNormalMaterials[2];
			else if( this.m_eBoard[i].m_Model && (  this.m_eBoard[i].GetBlockType() == GlobalVars.BrickType.GREEN ))
				this.m_eBoard[i].m_Model.renderer.material = DrawManager.m_tDrawManager.m_tNormalMaterials[3];
			
		}
	}

	void CheckCellsToDelete()
	{
		int nbrOfcell;
		int nbrOfWhiteCell;

		for(int i = 0; i < MainBoard.m_iSize; i++)
		{
			
			nbrOfcell = nbrOfWhiteCell = 0;
			m_iCellToDelete.Clear();

			if( !MainBoard.m_bColorBlindActive )
			{
				CheckCell( GetPosByIndex(i), GlobalVars.BrickType.BLUE, ref nbrOfcell );
				CheckCell( GetPosByIndex(i), GlobalVars.BrickType.GREEN, ref nbrOfcell );
				CheckCell( GetPosByIndex(i), GlobalVars.BrickType.RED, ref nbrOfcell );
				CheckCell( GetPosByIndex(i), GlobalVars.BrickType.YELLOW, ref nbrOfcell );
				CheckCell( GetPosByIndex(i), GlobalVars.BrickType.SAND, ref nbrOfcell );
			}
			else
			{
				CheckCellBlindColor( GetPosByIndex(i), GlobalVars.BrickType.BLUE, ref nbrOfcell );
				CheckCellBlindColor( GetPosByIndex(i), GlobalVars.BrickType.GREEN, ref nbrOfWhiteCell );
				CheckCellBlindColor( GetPosByIndex(i), GlobalVars.BrickType.RED, ref nbrOfcell );
				CheckCellBlindColor( GetPosByIndex(i), GlobalVars.BrickType.YELLOW, ref nbrOfWhiteCell );
				CheckCellBlindColor( GetPosByIndex(i), GlobalVars.BrickType.SAND, ref nbrOfcell );
			}
			
			//				if( nbrOfcell>= 4 )
			//					Debug.Log("delete" + nbrOfcell + " try delete : ");
			
			foreach (int item in m_iCellToDelete) {
				
				//					Debug.Log(item);
				
				if( nbrOfcell>= 4 )
				{
					m_eBoard[item].SetType(GlobalVars.BrickType.EMPTY);
					SpriteExplode obj  = m_eBoard[item].m_Model.GetComponent<SpriteExplode>() as SpriteExplode ;
					if( obj )
					{
						obj.Activate();
					}
					//			m_eBoard[item].m_Model.gameObject.renderer.enabled = false;
				}

				if( MainBoard.m_bColorBlindActive && nbrOfWhiteCell >=8)
				{
					m_eBoard[item].SetType(GlobalVars.BrickType.EMPTY);
					SpriteExplode obj  = m_eBoard[item].m_Model.GetComponent<SpriteExplode>() as SpriteExplode ;
					if( obj )
					{
						obj.Activate();
					}
				}

			}
			if( nbrOfcell>= 4 || nbrOfWhiteCell >= 8)
			{
				//play explode sound
				if( m_aExplode )
					m_aExplode.Play();

				//play combo sound
				CharacterManager.m_Instance.PlayComboSound(	(int)m_fCurrentMultiplicator );


				m_fSpawnStartTime = Time.time;
				if(nbrOfcell>= 4)
				{
					m_iCurrentScore += (int)(((nbrOfcell - 4) * (nbrOfcell - 4) * m_iPointsPerBlock + m_iPointsPerBlock) * m_fCurrentMultiplicator);
				}
				else if(nbrOfWhiteCell >= 8)
				{
					m_iCurrentScore += (int)(((nbrOfWhiteCell - 8) * (nbrOfWhiteCell - 8) * m_iPointsPerBlock + m_iPointsPerBlock) * m_fCurrentMultiplicator);
				}
				m_fCurrentMultiplicator += 1;
			}
		}
		for(int i = 0; i < m_iSize; i++)
		{
			m_eBoard[i].m_bHaveBeenChecked = false;
		}
		m_iCellToDelete.Clear();
			

	}




	// Update is called once per frame
	void Update () 
	{

		if( GameStateManager.m_Instance.m_eGameState == GlobalVars.GAME_STATE.GAME_OVER )
			return;

		/*		if( m_fLastSlideTime + m_fSlideEachTime <= Time.time )
		{
			this.Slide( 2, GlobalVars.Direction.RIGHT );
			m_fLastSlideTime = Time.time;
		}
*/	//	DrawManager.UpdateBlocksPos(this);

		if(m_bGameOver)
		{
			Debug.Log("GAME OVER");
		}

/*		if(Input.GetKeyDown(KeyCode.B))
		{
			Debug.Log("SPAWN");
	//		m_eBoard[60].SetType(GlobalVars.BrickType.BLUE);
			SpawnRandomPattern(UnityEngine.Random.Range(1, 4), UnityEngine.Random.Range(0, m_iSizeX));
		}

*/		
		float _localSpawnInterval = m_fSpawnInterval - ( (m_tSpeedManager.m_fGlobalSpeedMultiplier - 1) * m_tSpeedManager.m_fBlockAppearTimeIncrement );
		if( _localSpawnInterval < m_tSpeedManager.m_minBlocAppearDelay )
			_localSpawnInterval = m_tSpeedManager.m_minBlocAppearDelay;

		if( m_fSpawnStartTime + _localSpawnInterval  < Time.time )
		{
			SpawnRandomPattern(UnityEngine.Random.Range(1, 4), UnityEngine.Random.Range(0, m_iSizeX));
			m_fSpawnStartTime = Time.time;
		}


		DrawManager.m_tDrawManager.ManageBlockChangingColors(this);	
		//update fall speed and limit it
		float _fallSpeed = m_fFallSpeed * m_tSpeedManager.m_fGlobalSpeedMultiplier ;
		if( _fallSpeed > m_tSpeedManager.m_fMaxFallSpeed )
			_fallSpeed = m_tSpeedManager.m_fMaxFallSpeed;

		for(int i = 0; i < MainBoard.m_iSize; i++)
		{
			m_eBoard[i].Update( m_fMovmentSpeed ,_fallSpeed ); 
		}

		CheckAllVerticalCellMove();

		bool _CanDeleteCells = true;
		for(int i = 0; i < m_iSize; i++)
		{
			if(m_eBoard[i].m_bIsMoving || !m_eBoard[i].m_bHaveLanded/* || !m_eBoard[i].m_bHaveReacheNearTarget*/)
			{
				_CanDeleteCells = false;
				i = m_iSize;
			}
		}

		if(_CanDeleteCells)
		{
			CheckCellsToDelete();
		}

		m_tTheSwitcher.Update(this);

		if( m_tSpeedManager.NeedToUpdateSpeed( this.m_iCurrentScore ) )
		{
			m_tSpeedManager.m_fGlobalSpeedMultiplier += m_tSpeedManager.m_speedMultiplierStep;

			m_tSpeedManager.m_iScoreAtLastSpeedUp = this.m_iCurrentScore ;
		}

		CharacterManager.m_Instance.UpdateCharacterEnter();

		//Update score
		m_ScoreText.text = "<b>" + m_iCurrentScore + "</b>";
		m_MultiplicatorText.text = "<b>" + "x" + m_fCurrentMultiplicator + " </b>";
	}

	public Block[] GetLine( int iY )
	{
		Block[] _ReturnValue = new Block[MainBoard.m_iSizeX];
		for(int i = 0; i < MainBoard.m_iSizeX; i++)
		{
			_ReturnValue[i] = m_eBoard[GetIndexByPos(new Vec2(i, iY))];
		}
		return _ReturnValue;
	}

	public void Slide( int iLine, GlobalVars.Direction eDirection )
	{
		m_tTheSwitcher.Move( eDirection, GetLine(iLine) );
		m_tTheSwitcher.CopyLineBufferToMainBoard( this.m_eBoard,  iLine);
		
	}

	public bool LineCanMove(int iLine)
	{
		for(int i = 0; i < m_iSizeX; i++)
		{
			if(this.m_eBoard[GetIndexByPos(new Vec2(i, iLine))].m_bIsMoving)
			{
				return false;
			}
		}
		return true;
	}

	public int GetYMax()
	{
		bool _LineEmpty = true;
		int _iHighestLine = 0;
		for(int y = 0; y < m_iSizeY; y++)
		{
			_LineEmpty = true;
			for(int x = 0; x < m_iSizeX; x++)
			{
				if(m_eBoard[GetIndexByPos(new Vec2(x, y))].GetBlockType() != GlobalVars.BrickType.EMPTY)
				{
					_LineEmpty = false;
					x = m_iSizeX;
				}
			}
			if(_LineEmpty) 
			{
				_iHighestLine = y - 1 ;
				if(_iHighestLine < 0) _iHighestLine = 0;
				y = m_iSizeY;
			}
			else
			{
				_iHighestLine = y - 1 ;
				if(_iHighestLine < 0) _iHighestLine = 0;
			}
		}

		return _iHighestLine;
	}

	
	[Serializable]
	public class SpeedManager  {
		
		
	
		public float m_fGlobalSpeedMultiplier {get; set;}
		public float m_fMaxFallSpeed;
		public float m_speedMultiplierStep, m_fBlockAppearTimeIncrement;
		public float m_minBlocAppearDelay;
		public int	m_iScoreStep;
		public int	m_iScoreAtLastSpeedUp {get; set;}
		
		// Use this for initialization
		public void Init () {
			
			m_iScoreAtLastSpeedUp = 0;
			m_fGlobalSpeedMultiplier = 1;

			
		}
		
		// Update is called once per frame
		public bool NeedToUpdateSpeed ( int iScore ) {
			
			if( iScore  - m_iScoreAtLastSpeedUp > m_iScoreStep)	   
			{
				return true;
			}   
			return false;
		}
		
	}

	[Serializable]
	public class Switcher
	{
		int m_iLineSelected = 0;
		Transform m_Model;
		private Vector3 m_tTargetPos;
		public float m_tSelectorSpeed;
		public AudioSource m_aSlide;

		Block[] m_eLineBuffer;

		public void Update(MainBoard Board)
		{
			bool _bSwitched = false;
			if(Inputs.m_bDownJustPressed)
			{
				m_iLineSelected--;
				if(m_iLineSelected < 0)
				{
					m_iLineSelected = Board.GetYMax();
				}
				_bSwitched = true;
			}
			else if(Inputs.m_bUpJustPressed)
			{
				m_iLineSelected++;
				if(m_iLineSelected > Board.GetYMax())
				{
					m_iLineSelected = 0;
				}
				_bSwitched = true;
			}
			if( _bSwitched )
			{
//				Debug.Log(m_iLineSelected);
				m_tTargetPos = new Vector3(m_Model.position.x, m_iLineSelected * DrawManager.m_tDrawManager.m_fBlocSize, m_Model.position.z );
			}

			m_Model.position = Vector3.Lerp( m_Model.position, m_tTargetPos, m_tSelectorSpeed * Time.deltaTime); 

			if((Inputs.m_bLeftJustPressed || Input.GetButtonDown("LB")) && Board.LineCanMove(m_iLineSelected))
			{
				Board.Slide(m_iLineSelected, GlobalVars.Direction.LEFT);
				if( m_aSlide )
					m_aSlide.Play();
				 
			}
			else if((Inputs.m_bRightJustPressed || Input.GetButtonDown("RB")) && Board.LineCanMove(m_iLineSelected))
			{
				Board.Slide(m_iLineSelected, GlobalVars.Direction.RIGHT);
				if( m_aSlide )
					m_aSlide.Play();
			}

		}

		public void Init()
		{
			m_eLineBuffer = new Block[ MainBoard.m_iSizeX ];
			m_Model = GameObject.Find("Selector").transform;
			m_tTargetPos = m_Model.position;
		}

		public void Move( GlobalVars.Direction eDir, Block[] eBaseLineBuffer )
		{
			int _Dir = (int)eDir;
			int _Index;
			for (int i = 0; i <  MainBoard.m_iSizeX; i++) {

				_Index = i+_Dir;
				if(_Index < 0 ) _Index = MainBoard.m_iSizeX - 1;
				else if( _Index > MainBoard.m_iSizeX - 1 ) _Index = 0;

				m_eLineBuffer[ _Index ]  = eBaseLineBuffer[i];

			}

			//print 

			/*Debug.Log( "------------------------------" );
			for(int i = 0; i < MainBoard.m_iSizeX; i++)
			{
				Debug.Log( eBaseLineBuffer[i] );
				Debug.Log( m_eLineBuffer[i] );
				Debug.Log( "-----" );
			}*/

		}

		public void CopyLineBufferToMainBoard( Block[] Board, int iLine )
		{
			for (int i = 0; i <  MainBoard.m_iSizeX; i++) 
			{				
				Board[ MainBoard.GetIndexByPos( new Vec2(i,iLine) )]  = m_eLineBuffer[i]; 
				Board[ MainBoard.GetIndexByPos( new Vec2(i,iLine) ) ].m_TargetPos = new Vector2(i,iLine);
			}
		}



	}


   
}

