using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;

namespace Slayter
{
    public partial class Map : Background, IDrawable, IClickable
    {
        bool FirstClick;
        public List<int[]> path;
        int[] position=new int[2]{-1,-1};
        public void Click(MouseState state)
        {
            int[] temp = new int[2];
            temp[0] = (state.X + TopX) / 40;
            temp[1] = (state.Y + TopY) / 40;
            if (!forbidden.Contains<int>(map[temp[1], temp[0]]))
            {
                if (position[0] == temp[0] && position[1] == temp[1] && !(last[1]== temp[1] && last[0] == temp[0]))
                {
                    WalkingPath = new List<int[]>(DrawingPath);
                    FirstClick = false;
                    hero.heroIsMoving = true;
                    hero.AbleToMove(map[WalkingPath[0][1],WalkingPath[0][0]]);
                }
                else
                {
                    if (last[1] == temp[1] && last[0] == temp[0])
                        path.Clear();
                    else
                        //DeterminePath(hero.CurrentY / 40, hero.CurrentX / 40, temp[1], temp[0]);
                        DeterminePath(last[1], last[0], temp[1], temp[0]);
                    
                    DrawingPath = new List<int[]>(path);
                    position[0] = temp[0];
                    position[1] = temp[1];
                    FirstClick = true;
                    hero.heroIsMoving = false;
                    //for (int i = 0; i < path.Count; i++)
                    //{
                    //    Console.Out.WriteLine(path[i][1]+" "+path[i][0]);
                    //}
                    
                    if (WalkingPath.Count != 0){
                        {
                            WalkingPath.Clear();
                            //WalkingPath.Add(new int[2] { hero.CurrentX / 40, hero.CurrentY / 40 });
                            WalkingPath.Add(last);
                        }
                    }
                }
            }
        }

        private void DeterminePath(int startX, int startY, int endX, int endY)
        {
            Console.Out.WriteLine(startX+" "+startY+" "+endX+" "+endY);
            bool[,] mapVisited = new bool[rows, cols];
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    mapVisited[i, j] = false;
                }
            }
            List<Cell> opened = new List<Cell>();
            List<Cell> list2 = new List<Cell>();
            Cell temp;
            opened.Add(new Cell(startX, startY, 0, 1, null, Direction.Null));
            List<int[]> coor = new List<int[]>();
            while (opened.Count != 0)
            {
                coor.Clear();
                for (int i = 0; i < opened.Count; i++)
                {
                    Cell cell = opened[i];
                    if (cell.Activate())
                    {

                        coor.Add(new int[2] { cell.x, cell.y });

                        if (cell.x > 0 && !mapVisited[cell.x - 1, cell.y] && !forbidden.Contains(map[cell.x - 1, cell.y]))
                        {
                            coor.Add(new int[2] { cell.x - 1, cell.y });
                            temp = new Cell(cell.x - 1, cell.y, cell.path + map[cell.x - 1, cell.y] + 1, map[cell.x - 1, cell.y] + 1, cell, Direction.Up);
                            checkForMatchingCellsAndAdd(list2, temp);
                        }
                        if (cell.y > 0 && !mapVisited[cell.x, cell.y - 1] && !forbidden.Contains(map[cell.x, cell.y - 1]))
                        {
                            temp = new Cell(cell.x, cell.y - 1, cell.path + map[cell.x, cell.y - 1] + 1, map[cell.x, cell.y - 1] + 1, cell, Direction.Left);
                            coor.Add(new int[2] { cell.x, cell.y - 1 });
                            checkForMatchingCellsAndAdd(list2, temp);
                        }
                        if (cell.x < rows - 1 && !mapVisited[cell.x + 1, cell.y] && !forbidden.Contains(map[cell.x + 1, cell.y]))
                        {
                            temp = new Cell(cell.x + 1, cell.y, cell.path + map[cell.x + 1, cell.y] + 1, map[cell.x + 1, cell.y] + 1, cell, Direction.Down);
                            coor.Add(new int[2] { cell.x + 1, cell.y });
                            checkForMatchingCellsAndAdd(list2, temp);

                        }
                        if (cell.y < cols - 1 && !mapVisited[cell.x, cell.y + 1] && !forbidden.Contains(map[cell.x, cell.y + 1]))
                        {
                            temp = new Cell(cell.x, cell.y + 1, cell.path + map[cell.x, cell.y + 1] + 1, map[cell.x, cell.y + 1] + 1, cell, Direction.Right);
                            coor.Add(new int[2] { cell.x, cell.y + 1 });
                            checkForMatchingCellsAndAdd(list2, temp);
                        }
                    }
                    else
                    {
                        list2.Add(cell);
                    }
                }
                for (int i = 0; i < list2.Count; i++)
                {
                    Cell cell = list2[i];
                    if (cell.x == endX && cell.y == endY)
                    {
                        path.Clear();
                        Console.Out.WriteLine(cell.changedDirection);
                        while (!cell.CheckFatherForNull())
                        {
                            path.Add(new int[2] { cell.y, cell.x });
                            cell = cell.father;

                        }
                        path.Reverse();
                        return;
                    }
                }


                for (int i = 0; i < coor.Count; i++)
                {
                    mapVisited[coor[i][0], coor[i][1]] = true;
                }
                opened = new List<Cell>(list2);
                list2.Clear();
            }
        }

        private void checkForMatchingCellsAndAdd(List<Cell> list2, Cell temp)
        {
            if (!list2.Contains(temp))
            {
                list2.Add(temp); ;
                return;
            }
            Cell temp2 = list2.Find(delegate(Cell c)
            {
                return c.Equals(temp);
            });
            if (temp.path < temp2.path)
            {
                list2.Remove(temp2);
                list2.Add(temp);
            }
        }
    }
}
