public TileSelector(EditorScreen parentScreen, SpriteBatch spriteBatch, RectangleF bounds, TileMapLayer tileMapLayer, InputMonitor inputMonitor)
            : base(parentScreen, spriteBatch, bounds)
        {
            this.tileMapLayer = tileMapLayer;
            this.tilePropertyComponents = new List<ITilePropertyComponent>();
            this.inputMonitor = inputMonitor;

            this.selectButton = -1;
            this.selectedTileCoordinates = new List<int[]>();
            this.selectingTileCoordinates = new List<int[]>();
        }
        // TODO: add proper support for parallax layers. This will require a new class that derives from
        //        TileMapLayer and overrides Draw()
        private void LoadWorldXmlFile(string fileName)
        {
            XDocument fileContents = ScreenManager.Instance.Content.Load<XDocument>(fileName);

            #region LOAD INTERACTIVE MAP LAYERS

            // Load the interactive TileMap:
            map = new TileMap(this, fileContents.Root.Attribute("InteractiveMapFileName").Value);

            for (int i = 0; i < map.Width; ++i)
            {
                for (int j = 0; j < map.Height; ++j)
                {
                    if (map[i, j] != null && map[i, j] is ISpriteCollideable)
                    {
                        spriteCollisionManager.addObjectToRegisteredObjectList((ISpriteCollideable)map[i, j]);
                    }
                }
            }

            IEnumerable<XElement> allMapLayers = fileContents.Descendants("MapLayer");

            foreach (XElement mapLayer in allMapLayers)
            {
                string LayerName;
                int LayerIndex, ZIndex;

                LayerName = mapLayer.Attribute("LayerName").Value;
                LayerIndex = Int32.Parse(mapLayer.Attribute("LayerIndex").Value);
                ZIndex = Int32.Parse(mapLayer.Attribute("ZIndex").Value);

                interactiveLayers[ZIndex] = new TileMapLayer(ParentScreen, batchService.GetSpriteBatch(TileMapLayer.SpriteBatchName), map, LayerIndex);
                interactiveLayers[ZIndex].DrawOrder = ZIndex;

                ParentScreen.Components.Add(interactiveLayers[ZIndex]);
            }

            #endregion

            #region LOAD CHARACTERS

            // Add the player:
            Vector2 playerPosition = new Vector2(float.Parse(fileContents.Root.Attribute("PlayerPositionX").Value),
                                                 float.Parse(fileContents.Root.Attribute("PlayerPositionY").Value));

            player = new Player(this, spriteBatch, playerPosition);
            player.UpdateOrder = 3;
            player.DrawOrder = PLAYER_DRAW_ORDER;
            ParentScreen.Components.Add(player);
            spriteCollisionManager.addObjectToRegisteredObjectList(player);

            foreach (XElement woElement in fileContents.Descendants("o"))
            {
                string name = woElement.Attribute("n").Value;
                Vector2 position = new Vector2();
                position.X = float.Parse(woElement.Attribute("x").Value);
                position.Y = float.Parse(woElement.Attribute("y").Value);

                ConstructorInfo ci = (from CI in WorldObjectCtorInfos
                                      where CI.DeclaringType.Name == name
                                      select CI).First<ConstructorInfo>();
                AddWorldObject((WorldObject)ci.Invoke(new object[]{this, SpriteBatch, position}));
            }

            #endregion

            #region LOAD PARALLAX LAYERS

            IEnumerable<XElement> allParallaxMaps = fileContents.Descendants("Parallax");

            // A parallaxMap is made up of a tileMap just like the interactive map,
            //  so it can have multiple layers in and of itself. This might not be common
            //  but the functionality is there.
            foreach (XElement parallaxMap in allParallaxMaps)
            {
                IEnumerable<XElement> allParallaxLayers = parallaxMap.Descendants("Layer");
                float ScrollSpeed;
                TileMap tileMap;

                tileMap = new TileMap(this, parallaxMap.Attribute("MapFileName").Value);
                otherMaps.Add(tileMap);

                ScrollSpeed = Single.Parse(parallaxMap.Attribute("ScrollSpeed").Value);

                foreach (XElement parallaxLayer in allParallaxLayers)
                {
                    string LayerName;
                    int LayerIndex, ZIndex;

                    LayerName = parallaxLayer.Attribute("LayerName").Value;
                    LayerIndex = Int32.Parse(parallaxLayer.Attribute("LayerIndex").Value);
                    ZIndex = Int32.Parse(parallaxLayer.Attribute("ZIndex").Value);

                    parallaxLayers[ZIndex] = new TileMapLayer(ParentScreen, batchService.GetSpriteBatch(TileMapLayer.SpriteBatchName), tileMap, LayerIndex, ScrollSpeed);
                    parallaxLayers[ZIndex].DrawOrder = ZIndex;

                    ParentScreen.Components.Add(parallaxLayers[ZIndex]);
                }
            }

            #endregion
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        public override void Initialize()
        {
            if (!this.IsInitialized)
            {
                tileEngine = new TileEngine();

                fullScreenSettings = new ResolutionSettings(640, 480, 640,
                                                                      480,
                                                                      true);

                ScreenManager.Instance.ResolutionService.CurrentResolutionSettings = windowedSettings;

                batchService = (ISpriteBatchService)this.Game.Services.GetService(typeof(ISpriteBatchService));

                // Create a new, empty world:
                world = new World(this, WORLD_FILENAME);

                // We need to disable the SpriteSpriteCollisionManager because it makes some assumptions about
                //  the gameScreen...
                world.SpriteCollisionManager.Enabled = false;

                // Create an empty, maximally-sized tilemap to center
                //  the loaded map onto:
                TileMap bigMap = new TileMap(MAX_TILEMAP_WIDTH, MAX_TILEMAP_HEIGHT,
                                          DEFAULT_TILE_WIDTH, DEFAULT_TILE_HEIGHT,
                                          LAYER_COUNT, SUB_LAYER_COUNT);
                bigMap.FileName = world.Map.FileName;

                // Backup the original map:
                TileMap map = world.Map;

                // Compute the point where we want to blit it onto the empty map:
                this.offsetX = (bigMap.Width / 2) - (map.Width / 2);
                this.offsetY = (bigMap.Height / 2) - (map.Height / 2);

                bigMap.BlitTileMap(map, offsetX, offsetY);

                world.Map = bigMap;
                foreach (TileMapLayer tml in world.interactiveLayers.Values)
                {
                    Components.Remove(tml);
                }
                world.interactiveLayers.Clear();
                world.ShiftWorldObjects(new Vector2(world.Map.TileWidth * offsetX, world.Map.TileWidth * offsetY));

                for (int i = 0; i < world.Map.LayerCount; ++i)
                {
                    TileMapLayer tml = new TileMapLayer(this, batchService.GetSpriteBatch(TileMapLayer.SpriteBatchName), world.Map, i);
                    if (i == 0)
                    {
                        tml.DrawOrder = World.PLAYER_DRAW_ORDER - DEFAULT_LAYER_SPACING;
                    }
                    else
                    {
                        if (i == world.Map.LayerCount - 1)
                        {
                            tml.DrawBlanksEnabled = true;
                            tml.DrawEdgesEnabled = true;
                            tml.DrawDestructablesEnabled = true;
                        }
                        tml.DrawOrder = World.PLAYER_DRAW_ORDER + i * DEFAULT_LAYER_SPACING;
                    }
                    world.interactiveLayers[tml.DrawOrder] = tml;
                    Components.Add(world.interactiveLayers[tml.DrawOrder]);
                }

                world.Initialize();
                world.Camera.Position = world.Player.Position;// -new Vector2(world.Camera.VisibleArea.Width / 2, world.Camera.VisibleArea.Height / 2);
                world.Paused = true;

                Components.Add(world);

                // Set up editor controls:
                inputMonitor = InputMonitor.Instance;
                inputMonitor.AssignPressable("EditorLeft", new PressableKey(Keys.A));
                inputMonitor.AssignPressable("EditorRight", new PressableKey(Keys.D));
                inputMonitor.AssignPressable("EditorUp", new PressableKey(Keys.W));
                inputMonitor.AssignPressable("EditorDown", new PressableKey(Keys.S));
                inputMonitor.AssignPressable("EditorAppend", new PressableKey(Keys.LeftShift));
                inputMonitor.AssignPressable("ToggleFullScreen", new PressableKey(Keys.F));
                inputMonitor.AssignPressable("EditorCycleMode", new PressableKey(Keys.Tab));
                Components.Add(inputMonitor);

                CreateUIComponents();

                Mode = EditMode.SpriteEdit;
                CycleMode();

                // Initialize all components
                base.Initialize();
            }
        }