/// <summary>
        /// Places SelectedToolboxItem to the map. If no item is selected, nothing happnes.
        ///
        /// If the map block is occupied, coordinates are out of range, map is null or item type is unknown, exception is raised.
        ///
        /// </summary>
        /// <param name="mapX">X coordinate of map block to place this item.</param>
        /// <param name="mapY">Y coordinate of map block to place this item.</param>
        public void PlaceSelectedToolboxItem(int mapX, int mapY)
        {
            EditorToolboxItem item = SelectedToolboxItem;

            // no item selected => do nothing
            if (item == null)
            {
                return;
            }

            if (GameMap == null)
            {
                throw new Exception("Není herní mapa!");
            }
            else if (mapX < 0 || mapX >= GameMap.Width || mapY < 0 || mapY >= GameMap.Height)
            {
                throw new Exception($"[{mapX},{mapY}] není v rozsahu mapy!");
            }
            else if ((item.ItemType == EditorToolboxItemType.AI_PLAYER || item.ItemType == EditorToolboxItemType.MONSTER) && GameMap.Grid[mapX, mapY].Occupied)
            {
                throw new Exception($"Na pozici [{mapX},{mapY}] už je umístěn hráč, nebo monstrum!");
            }
            else if ((item.ItemType == EditorToolboxItemType.ITEM || item.ItemType == EditorToolboxItemType.ARMOR || item.ItemType == EditorToolboxItemType.WEAPON) && GameMap.Grid[mapX, mapY].Item != null)
            {
                throw new Exception($"Na pozici [{mapX},{mapY}] už je umístěn předmět!");
            }

            int uid = -1;

            switch (item.ItemType)
            {
            case EditorToolboxItemType.HUMAN_PLAYER:
                if (HumanPlayerPlaced)
                {
                    throw new Exception("Na hrací plochu lze umístit pouze jednoho lidského hráče!");
                }
                GameMap.Grid[mapX, mapY].Creature = new HumanPlayer("Human player", GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Creature.UniqueId;
                HumanPlayerPlaced = true;
                break;

            case EditorToolboxItemType.AI_PLAYER:
                GameMap.Grid[mapX, mapY].Creature = AIPlayerFactory.CreateSimpleAIPLayer("Simple AI Player", GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Creature.UniqueId;
                break;

            case EditorToolboxItemType.MONSTER:
                GameMap.Grid[mapX, mapY].Creature = MonsterFactory.CreateRandomMonster(GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Creature.UniqueId;
                break;

            case EditorToolboxItemType.ITEM:
                GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateBasicItem(GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Item.UniqueId;
                break;

            case EditorToolboxItemType.ARMOR:
                GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateLeatherArmor(GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Item.UniqueId;
                break;

            case EditorToolboxItemType.WEAPON:
                GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateAxe(GameMap.Grid[mapX, mapY]);
                uid = GameMap.Grid[mapX, mapY].Item.UniqueId;
                break;

            default:
                throw new Exception($"Neznámý typ umisťovaného předmětu: {item.ItemType}!");
            }
            EditorToolboxItem placedItem = item.Clone();

            placedItem.UID = uid;
            PlacedItems.Add(placedItem);

            OnPropertyChanged("PlacedItems");
        }
        public void TestSerializeMaze()
        {
            int w   = 4;
            int h   = 4;
            Map map = MapGeneratorFactory.CreateSimpleMapGenerator().GenerateMap(w, h, IMapGeneratorConstants.NO_SEED);

            map.MapName = "Test map";

            // add creatures to map
            Monster origMonster = new Monster("Test monster", map.Grid[0, 0], 4, 3654123, 87621235);

            map.AddCreature(origMonster);
            SimpleAIPlayer aiPlayer = new SimpleAIPlayer("Test player", map.Grid[3, 2]);

            map.AddCreature(aiPlayer);
            HumanPlayer hPlayer = new HumanPlayer("Příliš žluťoučký kůň úpěl ďábelské ódy", map.Grid[1, 3])
            {
                BaseHitPoints = 98432156, BaseAttack = 112348, BaseDeffense = 41226987
            };

            map.AddCreature(hPlayer);

            // add items to map
            AbstractWeapon weapon = ItemFactory.CreateAxe(map.Grid[1, 3]);

            map.AddItem(weapon);
            AbstractArmor armor = ItemFactory.CreateLeatherArmor(map.Grid[1, 1]);

            map.AddItem(armor);
            AbstractInventoryItem item = new BasicItem("Příliš žluťoučký kůň úpěl ďábelské ódy.!?_/()':123456789<>&@{}[]", map.Grid[2, 2], 514)
            {
                UniqueId = 6284
            };

            map.AddItem(item);


            // serialize - deserialize
            IMapSerializer <byte[], byte[]> byteSerializer = new BinaryMapSerializer();

            byte[] serializedMap   = byteSerializer.Serialize(map);
            Map    deserializedMap = byteSerializer.Deserialize(serializedMap);


            // check map
            Assert.AreEqual(map.MapName, deserializedMap.MapName, "Wrong map name!");
            Assert.AreEqual(w, deserializedMap.Width, "Wrong width after deserialization!");
            Assert.AreEqual(h, deserializedMap.Width, "Wrong height after deserialization!");
            Assert.AreEqual(map.WinningBlock.X, deserializedMap.WinningBlock.X, "Wrong x coordinate of winning block!");
            Assert.AreEqual(map.WinningBlock.Y, deserializedMap.WinningBlock.Y, "Wrong Y coordinate of winning block!");


            // check map blocks
            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    MapBlock origBlock   = map.Grid[i, j];
                    MapBlock testedBlock = deserializedMap.Grid[i, j];

                    foreach (Direction dir in  DirectionMethods.GetAllDirections())
                    {
                        Assert.AreEqual(origBlock.EntranceInDirection(dir).IsOpen(), testedBlock.EntranceInDirection(dir).IsOpen(), $"Wrong entrance in direction {dir} in block [{i},{j}].");
                    }
                }
            }


            // check creatures
            Monster m = (Monster)deserializedMap.Grid[0, 0].Creature;

            CheckCreature(origMonster, m);

            SimpleAIPlayer p = (SimpleAIPlayer)deserializedMap.Grid[3, 2].Creature;

            CheckCreature(aiPlayer, p);

            HumanPlayer hp = (HumanPlayer)deserializedMap.Grid[1, 3].Creature;

            CheckCreature(hPlayer, hp);


            // check items
            AbstractWeapon weap = (AbstractWeapon)map.Grid[1, 3].Item;

            CheckItem(weap, weapon);

            AbstractArmor arm = (AbstractArmor)map.Grid[1, 1].Item;

            CheckItem(arm, armor);

            AbstractInventoryItem itm = (AbstractInventoryItem)map.Grid[2, 2].Item;

            CheckItem(item, itm);
        }