public Inventory()
        {
            int    tilesetFirstGid = 1;                                          // default value
            string tilesetFilename = "dogs.tsx";
            string tilesetXmlPath  = Path.Combine(TILESET_DIR, tilesetFilename); // TODO: support several tilesets

            InventoryTileset = TilesetParser.ParseTilesetXml(tilesetXmlPath, tilesetFirstGid);
        }
        public static Scene ParseSceneXml(string sceneXmlPath)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(sceneXmlPath);
            XmlNode                      baseNode            = doc.DocumentElement;
            XmlNodeList                  nodes               = baseNode.ChildNodes;
            int                          sceneWidth          = int.Parse(baseNode.Attributes["width"].Value);
            List <Tileset>               tilesets            = new List <Tileset>();
            List <IDrawable>             drawables           = new List <IDrawable>();
            List <IUpdateable>           updateables         = new List <IUpdateable>();
            List <IDog>                  dogs                = new List <IDog>();
            List <ILoadContent>          loadables           = new List <ILoadContent>();
            IDictionary <string, Portal> portals             = new Dictionary <string, Portal>();
            WalkingArea                  walkingArea         = null;
            Player                       player              = null;
            float                        characterScalingMin = 1.0F;

            XmlNode propertiesNode = GetChildNode(baseNode, "properties");
            string  songName       = GetPropertyValue(propertiesNode, "song");

            // Get tileset first to be used when loading dogs
            foreach (XmlNode node in nodes)
            {
                if (node.Name == "tileset")
                {
                    string tilesetXmlPathRelative = node.Attributes["source"].Value;
                    string tilesetXmlPath         = Path.Combine(Path.GetDirectoryName(sceneXmlPath),
                                                                 Path.GetDirectoryName(tilesetXmlPathRelative),
                                                                 Path.GetFileName(tilesetXmlPathRelative));
                    int     tilesetFirstGid = int.Parse(node.Attributes["firstgid"].Value);
                    Tileset tileset         = TilesetParser.ParseTilesetXml(tilesetXmlPath, tilesetFirstGid);
                    tilesets.Add(tileset);
                    loadables.Add(tileset);
                }
            }

            foreach (XmlNode node in nodes)
            {
                if (node.Name == "imagelayer")
                {
                    if (node.Attributes["name"]?.InnerText == "background")
                    {
                        Debug.Assert(node.ChildNodes.Count == 1, "More than one background layer in scene");
                        ImageLayer background = ParseImageNode(node.ChildNodes[0], sceneXmlPath, 0);
                        drawables.Add(background);
                        loadables.Add(background);
                    }
                    else if (node.Attributes["name"]?.InnerText == "foreground")
                    {
                        Debug.Assert(node.ChildNodes.Count == 1, "More than one foreground layer in scene");
                        ImageLayer foreground = ParseImageNode(node.ChildNodes[0], sceneXmlPath, 1000);
                        drawables.Add(foreground);
                        loadables.Add(foreground);
                    }
                }
                else if (node.Name == "objectgroup" && node.Attributes["name"]?.InnerText == "dogs")
                {
                    foreach (XmlNode dogNode in node.ChildNodes)
                    {
                        IDog dog = ParseDogNode(dogNode, tilesets, sceneWidth);
                        drawables.Add(dog);
                        dogs.Add(dog);
                    }
                }
                else if (node.Name == "objectgroup" && node.Attributes["name"]?.InnerText == "player")
                {
                    Debug.Assert(node.ChildNodes.Count == 1);
                    XmlNode playerNode = node.ChildNodes[0];
                    int     x          = (int)Math.Round(float.Parse(playerNode.Attributes["x"].Value));
                    int     y          = (int)Math.Round(float.Parse(playerNode.Attributes["y"].Value));
                    y -= (int)Math.Round(float.Parse(playerNode.Attributes["height"].Value)); // Compensate for Tiled's coordinate system
                    string name = playerNode.Attributes["name"]?.InnerText;
                    player = new Player(x, y, name ?? "Felixia");
                }
                else if (node.Name == "objectgroup" && node.Attributes["name"]?.InnerText == "walking")
                {
                    walkingArea = new WalkingArea(ParsePolygonXml(node.ChildNodes[0]), sceneWidth);
                    drawables.Add(walkingArea);
                }
                else if (node.Name == "objectgroup" && node.Attributes["name"]?.InnerText == "portals")
                {
                    foreach (XmlNode portalNode in node.ChildNodes)
                    {
                        Portal portal = ParsePortalNode(portalNode, sceneWidth);
                        portals[portal.Name] = portal;
                        drawables.Add(portal);
                    }
                }
                else if (node.Name == "properties")
                {
                    characterScalingMin = float.Parse(GetPropertyValueOrDefault(node, "scaling_min", "1.0"));
                }
                if (player == null)
                {
                    player = new Player("Felixia");
                }
            }
            return(new Scene(drawables,
                             updateables,
                             loadables,
                             dogs,
                             portals,
                             player,
                             walkingArea,
                             sceneWidth,
                             characterScalingMin,
                             songName));
        }