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

public class RangeHighlighter : MonoBehaviour {
    
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    public Transform m_highlightPrefab;
    private static List<Transform> ms_highlightObjects;

    private static readonly Color MOVE_COLOR = new Color(0.8f, 0.8f, 0.1f, 0.4f);
    private static readonly Color ACTION_COLOR = new Color(0.7f, 0.3f, 0.1f, 0.4f);
    private static readonly Color AOE_COLOR = new Color(1.0f, 0.1f, 0.1f, 0.5f);
    
    public static void ClearHighlights()
    {
        if (ms_highlightObjects != null)
        {
            foreach (Transform obj in ms_highlightObjects)
            {                
                Destroy(obj.gameObject);
            }
            ms_highlightObjects = null;
        }
    }

    public void AddHighlight( GridCoord pos, Color color )
    {
        UnityEngine.Object newObj = Instantiate(m_highlightPrefab, pos.GetUnityPos() + new Vector3(0.0f, GridManager.UNITY_CHARACTER_DEPTH, 0.0f), Quaternion.identity);
        Transform objTrans = newObj as Transform;
        objTrans.localScale = new Vector3(GridManager.UNITY_GRID_SIZE, GridManager.UNITY_CHARACTER_DEPTH / 2.0f, GridManager.UNITY_GRID_SIZE);

        // Highlight GridObject's are NOT added to the GridManager, since they have no collision. They're just used for easy mouseclick lookups
        objTrans.GetComponent<GridObject>().UpdatePosition(pos, true);
        objTrans.GetComponent<Renderer>().material.color = color;

        ms_highlightObjects.Add(objTrans);
    }


    static public List<CoordChoice> GetPossibleMoves()
    {
        GridCoord playerPos = PlayerObject.Instance.GetComponent<GridObject>().GridPosition;

        List<CoordChoice> possMoves = new List<CoordChoice>();
        foreach (Transform highlight in ms_highlightObjects)
        {
            GridObject gridObj = highlight.GetComponent<GridObject>();
            GridObject characterGridObj;
            if (GridManager.Instance.TestCollision(gridObj.GridPosition, out characterGridObj, true) == false)
            {
                CoordChoice choice;
                choice.m_pos = gridObj.GridPosition;
                choice.m_stepsFromPlayer = GridCoord.GetStepsBetween(choice.m_pos, playerPos);
                possMoves.Add(choice);
            }
        }
        return possMoves;
    }

    public List<CharacterObject> GetAffectedAOE()
    {
        List<CharacterObject> affected = new List<CharacterObject>();

        foreach (Transform highlight in ms_highlightObjects)
        {
            GridObject gridObj = highlight.GetComponent<GridObject>();
            if (gridObj.m_canBeSelectedByAction)
            {
                GridObject characterGridObj;
                if ( GridManager.Instance.TestCollision(gridObj.GridPosition, out characterGridObj, false) )
                {
                    //Debug.Log("Hit: ");
                    if ( characterGridObj != null )
                    {
                        //Debug.Log("Hit2: ");
                        CharacterObject charObj = characterGridObj.GetComponent<CharacterObject>();
                        if ( charObj != null )
                        {
                            //Debug.Log("Hit3: " + charObj.Info.m_name);
                            affected.Add(charObj);
                        }
                    }
                }
            }
        }

        return affected;
    }   
  
    public void ShowMoveHighlight(GridCoord startPos, int numMoves)
    {
        ClearHighlights();

        GridObject gridObj = GetComponent<GridObject>();
        if (gridObj == null)
        {
            return;
        }
        
        Dictionary<GridCoord, int> canMoveTo = GridManager.Instance.GetValidMoves(gridObj, startPos, numMoves);

        ms_highlightObjects = new List<Transform>();
        foreach (KeyValuePair<GridCoord, int> posAndCost in canMoveTo)
        {
            AddHighlight(posAndCost.Key, MOVE_COLOR);
        }
    }

    public void ShowActionHighlight(bool allowMelee, int maxDist, bool colorMelee)
    {
        ClearHighlights();

        GridObject gridObj = GetComponent<GridObject>();
        if (gridObj == null)
        {
            return;
        }

        GridCoord startPos = gridObj.GridPosition;

        Dictionary<GridCoord, int> canMoveTo = GridManager.Instance.GetActionRange( startPos, allowMelee, maxDist);

        ms_highlightObjects = new List<Transform>();
        foreach (KeyValuePair<GridCoord, int> posAndCost in canMoveTo)
        {
            Color actionColor = ACTION_COLOR;
            if ( colorMelee )
            {
                if ( BaseTurn.IsAttackMelee( startPos, posAndCost.Key ) )
                {
                    actionColor = AOE_COLOR; // Maybe change this?
                }
            }

            AddHighlight(posAndCost.Key, actionColor);
        }
    }

    public void SetCanBeSelectedByAction( bool onlyEnemies )
    {
        //Debug.Log(onlyEnemies + " Scan");

        // Use GridPosition instead of CommittedGridPosition for player/enemies, since they haven't done their turn yet
        foreach (Transform highlight in ms_highlightObjects )
        {
            GridObject gridObj = highlight.GetComponent<GridObject>();
            if (onlyEnemies)
            {
                foreach ( Transform enemy in EnemyManager.Instance.m_enemies )
                {
                    if (enemy.GetComponent<GridObject>().GridPosition == gridObj.CommitedGridPosition)
                    {
                        //Debug.Log(onlyEnemies + " Can be selected: " + enemy.GetComponent<CharacterObject>().Info.m_name);
                        gridObj.SetCanBeSelectedByAction();
                    }
                }
            }
            else
            {
                // Only player
                if (PlayerObject.Instance.GetComponent<GridObject>().GridPosition == gridObj.CommitedGridPosition)
                {
                    //Debug.Log(onlyEnemies + " Can be selected: " + PlayerObject.Instance.GetComponent<CharacterObject>().Info.m_name);
                    gridObj.SetCanBeSelectedByAction();    
                }
            }
        }
    }

    public void ShowAOEHighlight(GridCoord pos, int aoeSize)
    {
        ClearHighlights();

        GridObject gridObj = GetComponent<GridObject>();
        if (gridObj == null)
        {
            return;
        }

        Dictionary<GridCoord, int> canMoveTo;

        if (aoeSize <= 1)
        {
            canMoveTo = new Dictionary<GridCoord, int>();
            canMoveTo.Add(pos, 1);
        }
        else
        {
            canMoveTo = GridManager.Instance.GetActionRange(pos, true, aoeSize - 1);
        }

        ms_highlightObjects = new List<Transform>();
        foreach (KeyValuePair<GridCoord, int> posAndCost in canMoveTo)
        {
            AddHighlight(posAndCost.Key, AOE_COLOR);
        }
    }

}
