private void AddEditSpot(HexagonTile tile, double x, double y)
        {
            tile.X = (int)x;
            tile.Y = (int)y;

            hexagonList.Add(tile, GetEditTile(x,y));
        }
 public HexagonTileSerializable(HexagonTile source)
 {
     this.Id        = source.Id;
     this.X         = source.X;
     this.Y         = source.Y;
     this.TileType  = source.TileType;
     this.TileValue = source.TileValue;
     this.Fortress  = source.Fortress;
 }
 public HexagonTileSerializable(HexagonTile source)
 {
     this.Id = source.Id;
     this.X = source.X;
     this.Y = source.Y;
     this.TileType = source.TileType;
     this.TileValue = source.TileValue;
     this.Fortress = source.Fortress;
 }
        public void InitNewLevel()
        {
            Board.Children.Clear();
            CrossSections.Children.Clear();

            hexagonList.Clear();

            startTile = new HexagonTile()
            {
                TileType = TileType.none,
                TileValue = 0,
            };
            hexagonList.Add(startTile, GetEditTile(0,0));
        }
 private void AddPosibility(List<HexagonTile> posibilities, HexagonTile tile)
 {
     if (tile != null && !posibilities.Contains(tile))
     {
         posibilities.Add(tile);
     }
 }
        private List<HexagonTile> FindPosibilities(HexagonTile search, List<HexagonTile> posibilities)
        {
            AddPosibility(posibilities, FindPotentialLine(search, f => f.North));
            AddPosibility(posibilities, FindPotentialLine(search, f => f.NorthWest));
            AddPosibility(posibilities, FindPotentialLine(search, f => f.NorthEast));
            AddPosibility(posibilities, FindPotentialLine(search, f => f.South));
            AddPosibility(posibilities, FindPotentialLine(search, f => f.SouthEast));
            AddPosibility(posibilities, FindPotentialLine(search, f => f.SouthWest));

            return posibilities;
        }
        private void MapUpTile(HexagonTile tile)
        {
            if (tile.North == null)
            {
                tile.North = FindTileAt((int)tile.X + 0, (int)tile.Y - yFull);
                if (tile.North != null)
                {
                    tile.North.South = tile;
                }
            }

            if (tile.South == null)
            {
                tile.South = FindTileAt((int)tile.X + 0, (int)tile.Y + yFull);
                if (tile.South != null)
                {
                    tile.South.North = tile;
                }
            }

            if (tile.NorthWest == null)
            {
                tile.NorthWest = FindTileAt((int)tile.X - xMarge, (int)tile.Y - yMarge);
                if (tile.NorthWest != null)
                {
                    tile.NorthWest.SouthEast = tile;
                }
            }

            if (tile.NorthEast == null)
            {
                tile.NorthEast = FindTileAt((int)tile.X + xMarge, (int)tile.Y - yMarge);
                if (tile.NorthEast != null)
                {
                    tile.NorthEast.SouthWest = tile;
                }
            }

            if (tile.SouthWest == null)
            {
                tile.SouthWest = FindTileAt((int)tile.X - xMarge, (int)tile.Y + yMarge);
                if (tile.SouthWest != null)
                {
                    tile.SouthWest.NorthEast = tile;
                }
            }

            if (tile.SouthEast == null)
            {
                tile.SouthEast = FindTileAt((int)tile.X + xMarge, (int)tile.Y + yMarge);
                if (tile.SouthEast != null)
                {
                    tile.SouthEast.NorthWest = tile;
                }
            }
        }
        private void ReplaceBoardTile(HexagonTile tile)
        {
            hexagonList[tile].MouseRightButtonDown -= RemoveHexagonTile;
            hexagonList[tile].MouseLeftButtonDown -= AddNewColour;
            hexagonList[tile].MouseLeftButtonDown += AddHexagonTile;

            tile.TileType = TileType.none;
            tile.TileValue = 0;
            hexagonList[tile].SetTileType(TileType.none);
        }
        public void LoadSaveData(BoardSerializable boardData)
        {
            int id = 0;

            Dictionary<HexagonTileSerializable, HexagonTile> mapping = new Dictionary<HexagonTileSerializable, HexagonTile>();

            this.hexagonList.Clear();

            foreach (HexagonTileSerializable serializedTile in boardData.ActiveTileList)
            {
                HexagonTile tile = new HexagonTile()
                {
                    Id = serializedTile.Id,
                    TileType = serializedTile.TileType,
                    X = serializedTile.X,
                    Y = serializedTile.Y,
                };

                if (tile.TileType != TileType.none)
                {
                    mapping.Add(serializedTile, tile);
                    this.hexagonList.Add(tile);
                }
            }

            foreach (HexagonTile tile in hexagonList)
            {
                MapUpTile(tile);
            }

            this.SetTurn();
        }
        private HexagonTile FindColorInLine(HexagonTile search, Func<HexagonTile, HexagonTile> GetNext)
        {
            TileType found = TileType.none;

            HexagonTile next = GetNext(search);

            if (next == null || next.TileType == search.TileType || next.TileType == TileType.board || next.TileType == TileType.none)
            {
                return null;
            }

            while (next != null && next.TileType != TileType.board && next.TileType != TileType.none && next.TileType != search.TileType)
            {
                found = next.TileType;
                next = GetNext(next);

                // endboard => end search
                if (next == null || next.TileType == TileType.none)
                {
                    return null;
                }
            }

            if (next.TileType == search.TileType)
            {
                if (this.firstCapture == TileType.none)
                {
                    this.firstCapture = found;
                }
                return next;
            }
            return null;
        }
        private bool MappingExists(HexagonTile a, HexagonTile b)
        {
            if (mappings.ContainsKey(a) && mappings[a].Contains(b))
            {
                return true;
            }

            if (mappings.ContainsKey(b) && mappings[b].Contains(a))
            {
                return true;
            }

            if (a.TileType == TileType.none || b.TileType == TileType.none)
            {
                return true;
            }

            return false;
        }
        private void CreateMappings(HexagonTile tile)
        {
            if (tile.TileType != TileType.none)
            {
                if (!mappings.ContainsKey(tile))
                {
                    mappings.Add(tile, new List<HexagonTile>());
                }

                if (tile.North != null)
                {

                    if (tile.North.South != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.North, tile))
                    {
                        mappings[tile].Add(tile.North);

                        CreateMappings(tile.North);
                    }
                }

                if (tile.South != null)
                {
                    if (tile.South.North != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.South, tile))
                    {
                        mappings[tile].Add(tile.South);

                        CreateMappings(tile.South);
                    }
                }

                if (tile.NorthEast != null)
                {
                    if (tile.NorthEast.SouthWest != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.NorthEast, tile))
                    {
                        mappings[tile].Add(tile.NorthEast);

                        CreateMappings(tile.NorthEast);
                    }
                }

                if (tile.NorthWest != null)
                {
                    if (tile.NorthWest.SouthEast != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.NorthWest, tile))
                    {
                        mappings[tile].Add(tile.NorthWest);

                        CreateMappings(tile.NorthWest);
                    }
                }

                if (tile.SouthEast != null)
                {
                    if (tile.SouthEast.NorthWest != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.SouthEast, tile))
                    {
                        mappings[tile].Add(tile.SouthEast);

                        CreateMappings(tile.SouthEast);
                    }
                }

                if (tile.SouthWest != null)
                {
                    if (tile.SouthWest.NorthEast != tile)
                    {
                        throw new Exception("mapping incomplete");
                    }

                    if (!MappingExists(tile.SouthWest, tile))
                    {
                        mappings[tile].Add(tile.SouthWest);

                        CreateMappings(tile.SouthWest);
                    }
                }
            }
        }
        private void CreateMappings()
        {
            foreach (HexagonTile t in hexagonList)
            {
                if (t.TileType != TileType.none)
                {
                    this.startTile = t;
                    break;
                }
            }


            mappings.Clear();
            CreateMappings(this.startTile);

            CrossSections.Children.Clear();

            foreach (HexagonTile key in mappings.Keys)
            {
                foreach (HexagonTile tile in mappings[key])
                {
                    CreateLine(key, tile);
                }
            }
        }
        private bool CanBeRemoved(HexagonTile tile)
        {
            if (tile.TileType != TileType.none)
            {
                return false;
            }

            HexagonTile[] neighbours =
                new[]{
                    tile.North,
                    tile.NorthEast,
                    tile.NorthWest,
                    tile.South,
                    tile.SouthEast,
                    tile.SouthWest,
                };

            foreach (HexagonTile neighbour in neighbours)
            {
                if (neighbour != null && neighbour.TileType != TileType.none)
                {
                    return false;
                }
            }


            return true;
        }
        private void DetachTile(HexagonTile removeTile)
        {
            if (removeTile.North != null)
            {
                removeTile.North.South = null;
                removeTile.North = null;
            }

            if (removeTile.NorthEast != null)
            {
                removeTile.NorthEast.SouthWest = null;
                removeTile.NorthEast = null;
            }

            if (removeTile.NorthWest != null)
            {
                removeTile.NorthWest.SouthEast = null;
                removeTile.NorthWest = null;
            }

            if (removeTile.South != null)
            {
                removeTile.South.North = null;
                removeTile.South = null;
            }

            if (removeTile.SouthEast != null)
            {
                removeTile.SouthEast.NorthWest = null;
                removeTile.SouthEast = null;
            }

            if (removeTile.SouthWest != null)
            {
                removeTile.SouthWest.NorthEast = null;
                removeTile.SouthWest = null;
            }
        }
        private HexagonTile FindPotentialLine(HexagonTile search, Func<HexagonTile, HexagonTile> GetNext)
        {
            HexagonTile next = GetNext(search);

            // skip first
            if (next == null || next.TileType == search.TileType || next.TileType == TileType.board || next.TileType == TileType.none)
            {
                return null;
            }

            while (next.TileType != TileType.board)
            {
                if (next.TileType == search.TileType)
                {
                    return null;
                }
                next = GetNext(next);

                // endboard => end search
                if (next == null || next.TileType == TileType.none)
                {
                    return null;
                }
            }

            return next;
        }
        private void TurnTilesToCurrentColor(HexagonTile chosenTile)
        {
            bool first = (this.firstCapture == TileType.none);

            if (FindColorInLine(chosenTile, f => f.North) != null)
            {
                TurnColorInLine(chosenTile, f => f.North);
            }

            if (FindColorInLine(chosenTile, f => f.NorthEast) != null)
            {
                TurnColorInLine(chosenTile, f => f.NorthEast);
            }

            if (FindColorInLine(chosenTile, f => f.NorthWest) != null)
            {
                TurnColorInLine(chosenTile, f => f.NorthWest);
            }

            if (FindColorInLine(chosenTile, f => f.South) != null)
            {
                TurnColorInLine(chosenTile, f => f.South);
            }

            if (FindColorInLine(chosenTile, f => f.SouthWest) != null)
            {
                TurnColorInLine(chosenTile, f => f.SouthWest);
            }

            if (FindColorInLine(chosenTile, f => f.SouthEast) != null)
            {
                TurnColorInLine(chosenTile, f => f.SouthEast);
            }

            if (first)
            {
                switch (this.firstCapture)
                {
                    case TileType.red:
                        turnOrder[1] = TileType.red;
                        turnOrder[2] = TileType.blue;
                        break;
                    case TileType.blue:
                        turnOrder[1] = TileType.blue;
                        turnOrder[2] = TileType.red;
                        break;
                }
            }

            var boardtiles = from p in hexagonList
                             where p.TileType == TileType.board
                             select p;
        }
        private void CreateLine(HexagonTile a, HexagonTile b)
        {
            double dx1 = a.X + 30.0;
            double dy1 = a.Y + 26;

            double dx2 = b.X + 30.0;
            double dy2 = b.Y + 26.0;

            Line l1 = new Line()
            {
                X1 = dx1,
                Y1 = dy1,
                X2 = dx2,
                Y2 = dy2,
                Stroke = new SolidColorBrush(Colors.Purple)
            };

            l1.Opacity = 0.9;
            l1.StrokeDashArray = new DoubleCollection() { 1, 2 };
            this.CrossSections.Children.Add(l1);
        }
 private void TurnColorInLine(HexagonTile search, Func<HexagonTile, HexagonTile> GetNext)
 {
     HexagonTile next = GetNext(search);
     while (next.TileType != search.TileType)
     {
         next.TileType = search.TileType;
         next = GetNext(next);
     }
 }
        public void LoadSaveData(BoardSerializable boardData)
        {
            Dictionary<HexagonTileSerializable, HexagonTile> mapping = new Dictionary<HexagonTileSerializable, HexagonTile>();

            this.hexagonList.Clear();
            this.Board.Children.Clear();

            this.Fortresses.Text = boardData.FortressesPerPlayer.ToString();

            foreach (HexagonTileSerializable serializedTile in boardData.ActiveTileList)
            {
                HexagonTile tile = new HexagonTile()
                {
                    Id = serializedTile.Id,
                    TileType = serializedTile.TileType,
                    X = serializedTile.X,
                    Y = serializedTile.Y,
                    TileValue = serializedTile.TileValue,
                    Fortress = serializedTile.Fortress,
                };

                mapping.Add(serializedTile, tile);

                BoardHexagon board = null;

                switch (tile.TileType)
                {
                    case TileType.none:
                        board = (BoardHexagon)this.GetEditTile(serializedTile.X, serializedTile.Y);
                        board.SetTileType(tile.TileType);
                        board.SetTileValue(tile.TileValue);
                        board.ShowFortress(tile.Fortress);
                        this.hexagonList.Add(tile, board);
                        break;
                    case TileType.board:
                        board = (BoardHexagon)this.GetBoardTile(serializedTile.X, serializedTile.Y);
                        board.SetTileType(tile.TileType);
                        this.hexagonList.Add(tile, board);
                        board.SetTileValue(tile.TileValue);
                        board.ShowFortress(tile.Fortress);
                        break;
                    case TileType.blue:
                    case TileType.red:
                    case TileType.yellow:
                        board = (BoardHexagon)this.GetBoardTile(serializedTile.X, serializedTile.Y, tile.TileType);
                        board.SetTileType(tile.TileType);
                        board.SetTileValue(tile.TileValue);
                        board.ShowFortress(tile.Fortress);
                        this.hexagonList.Add(tile, board);
                        break;
                }
            }

            foreach (HexagonTile tile in hexagonList)
            {
                MapUpTile(tile);
            }

            foreach (HexagonTile tile in hexagonList)
            {
                hexagonList[tile].SetLinkCount(tile.LinkCount);
            }

            CreateMappings();
        }
        private void ReplaceBoardWithColour(HexagonTile tile)
        {
            hexagonList[tile].MouseLeftButtonDown -= AddNewColour;
            hexagonList[tile].MouseLeftButtonDown += AddPropertyToColour;
            hexagonList[tile].MouseRightButtonDown -= RemoveHexagonTile;
            hexagonList[tile].MouseRightButtonDown += RemoveColouredTile;

            tile.TileType = this.currentSelection.TileType;
            hexagonList[tile].SetTileType(this.currentSelection.TileType);
        }
        private void ReplaceEditSpot(HexagonTile tile)
        {
            BoardHexagon control = hexagonList[tile];

            control.MouseLeftButtonDown -= AddHexagonTile;
            control.MouseLeftButtonDown += AddNewColour;
            control.MouseRightButtonDown += RemoveHexagonTile;

            tile.TileType = TileType.board;
            tile.TileValue = defaultTileValue;
            control.SetTileType(TileType.board);
        }