/// <summary>
 ///		Add the given event to the event stack so it can be processed later.
 /// </summary>
 /// <param name="fireEvent">Event to fire.</param>
 public static void FireEvent(Event fireEvent)
 {
     //DebugLogger.WriteLog("Event fired: " + fireEvent.ToString());
     _eventStack.Push(fireEvent);
 }
 /// <summary>
 ///		Called by the event manager when an event is fired that this class should process.
 /// </summary>
 /// <param name="firedEvent">Event to process.</param>
 public void ProcessEvent(Event firedEvent)
 {
     if (_process == null) return;
     switch (firedEvent.ID)
     {
         case "game_begin":
             if (_process != null) _process[0].InvokeFunction("OnGameBegin", true, false);
             break;
         case "game_finish":
             if (_process.SymbolExists("OnGameFinish", SymbolType.Function) == false)
                 _process.Stop();
             else
                 _process[0].InvokeFunction("OnGameFinish", true, false);
             break;
         case "map_begin":
             if (_process != null) _process[0].InvokeFunction("OnMapBegin", true, false);
             break;
         case "map_finish":
             if (_process != null) _process[0].InvokeFunction("OnMapFinish", true, false);
             break;
         case "key_pressed":
         case "key_released":
         case "mouse_move":
         //	if (_process != null) _process[0].InvokeFunction("OnInputRecieved");
             break;
     }
 }
 /// <summary>
 ///		Notifys this listeners delegate about the given event.
 /// </summary>
 /// <param name="processEvent">Event to process.</param>
 public void ProcessEvent(Event processEvent)
 {
     _delegate(processEvent);
 }
        /// <summary>
        ///		Called when the eraser tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdateEraser(Event firedEvent)
        {
            bool placeTiles = false;
            if (firedEvent.ID == "mouse_move" && InputManager.KeyDown(KeyCodes.LeftMouse))
            {
                if (_toolActive == false) return;
                placeTiles = true;
            }
            else if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolActive = true;
                placeTiles = true;
            }
            else if (firedEvent.ID == "key_released" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
                _toolActive = false;

            // Place the tiles onto the map at the cursor position if we have been asked to.
            if (placeTiles == true)
            {
                // Go through entitys and see if we are on a tilemap.
                TilemapSegmentNode tilemapToEdit = null;
                foreach (EntityNode entity in _selectedEntityList)
                {
                    if ((entity is TilemapSegmentNode) == false) continue;
                    if (entity.RectangleBoundingBoxIntersect(new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1), Editor.GlobalInstance.CameraNode) == true)
                        tilemapToEdit = entity as TilemapSegmentNode;
                }
                if (tilemapToEdit == null) return;

                // Work out what tile the mouse if over.
                Transformation tilemapTransformation = tilemapToEdit.CalculateTransformation(Editor.GlobalInstance.CameraNode);
                int tileX = (int)((InputManager.MouseX - tilemapTransformation.X) / (tilemapToEdit.TileWidth * Editor.GlobalInstance.CameraNode.Zoom));
                int tileY = (int)((InputManager.MouseY - tilemapTransformation.Y) / (tilemapToEdit.TileHeight * Editor.GlobalInstance.CameraNode.Zoom));
                if (tileX < 0 || tileY < 0 || tileX >= tilemapToEdit.Width / tilemapToEdit.TileWidth || tileY >= tilemapToEdit.Height / tilemapToEdit.TileHeight) return;

                // Erase the given tile.
                tilemapToEdit[tileX, tileY].Tileset = null;
                tilemapToEdit[tileX, tileY].Frame = 0;

                _mapChangedSinceSave = true;
            }
        }
        /// <summary>
        ///		Called when the paint bucket tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdatePaintBucket(Event firedEvent)
        {
            if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                // Go through entitys and see if we are on a tilemap.
                TilemapSegmentNode tilemapToEdit = null;
                foreach (EntityNode entity in _selectedEntityList)
                {
                    if ((entity is TilemapSegmentNode) == false) continue;
                    if (entity.RectangleBoundingBoxIntersect(new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1), Editor.GlobalInstance.CameraNode) == true)
                        tilemapToEdit = entity as TilemapSegmentNode;
                }
                if (tilemapToEdit == null) return;

                // Work out what tile the mouse if over.
                Transformation tilemapTransformation = tilemapToEdit.CalculateTransformation(Editor.GlobalInstance.CameraNode);
                int tileX = (int)((InputManager.MouseX - tilemapTransformation.X) / (tilemapToEdit.TileWidth * Editor.GlobalInstance.CameraNode.Zoom));
                int tileY = (int)((InputManager.MouseY - tilemapTransformation.Y) / (tilemapToEdit.TileHeight * Editor.GlobalInstance.CameraNode.Zoom));

                // Preform a flood fill at the given position.
                bool[,] tracker = (new bool[tilemapToEdit.Width / tilemapToEdit.TileWidth, tilemapToEdit.Height / tilemapToEdit.TileHeight]);
                FloodFill(tilemapToEdit, tileX, tileY, tilemapToEdit[tileX, tileY].Tileset, tilemapToEdit[tileX, tileY].Frame, ref tracker, _assetManagerWindow.TilesetSelection.X, _assetManagerWindow.TilesetSelection.Y);

                _mapChangedSinceSave = true;
            }
        }
        /// <summary>
        ///		Called when an event is being processed by the EventManager.
        /// </summary>
        /// <param name="firedEvent">Event that needs to be processed.</param>
        public void EventCaptured(Event firedEvent)
        {
            // Switch over to the map canvas so all input is relative to it.
            GraphicsManager.RenderTarget = (IRenderTarget)_mapCanvas;

            // If we are supressing selection see if we can unsupress selection.
            if (_supressSelection == true && _supressSelectionTimer.DurationMillisecond > 500)
                _supressSelection = false;

            // Check what event we have retrieved.
            switch (firedEvent.ID)
            {
                case "key_pressed":
                    {
                        InputEventData data = (InputEventData)firedEvent.Data;
                        int mouseX = InputManager.MouseX;
                        int mouseY = InputManager.MouseY;
                        if (ActiveForm != this || mouseX < 0 || mouseY < 0 || mouseX > mapPanel.ClientRectangle.Width || mouseY > mapPanel.ClientRectangle.Height)
                            return;
                        if (mapCanvasContextMenuStrip.Visible == true)
                            return;

                        if (data.KeyCode == KeyCodes.RightMouse)
                        {
                            mousePositionBeforeRightClick[0] = mouseX;
                            mousePositionBeforeRightClick[1] = mouseY;
                            mapCanvasContextMenuStrip.Show(new Point(InputManager.MouseScreenX + 5, InputManager.MouseScreenY - 16));
                        }
                    }
                    break;
            }

            // Update the current tool's logic.
            switch (_currentTool)
            {
                case Tools.Camera: UpdateCamera(firedEvent); break;
                case Tools.Ellipse: break;
                case Tools.Eraser: UpdateEraser(firedEvent); break;
                case Tools.PaintBucket: UpdatePaintBucket(firedEvent); break;
                case Tools.Pencil: UpdatePencil(firedEvent); break;
                case Tools.Rectangle: break;
                case Tools.RoundedRectangle: break;
                case Tools.Line: break;
                case Tools.Selector: UpdateSelector(firedEvent); break;
                case Tools.TilePicker: UpdateTilePicker(firedEvent); break;
            }
        }
        /// <summary>
        ///		Called when the camera tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdateCamera(Event firedEvent)
        {
            if (firedEvent.ID == "mouse_move")
            {
                // Zoom in and out.
                InputEventData data = (InputEventData)firedEvent.Data;
                int mouseX = InputManager.MouseX;
                int mouseY = InputManager.MouseY;
                if (data.MouseScroll != 0)
                {
                    if (ActiveForm != this || mouseX < 0 || mouseY < 0 || mouseX > ClientRectangle.Width || mouseY > ClientRectangle.Height)
                        return;
                    Editor.GlobalInstance.CameraNode.Zoom += (data.MouseScroll < 0 ? (Editor.GlobalInstance.CameraNode.Zoom > 0.25 ? -0.25f : 0.0f) : (Editor.GlobalInstance.CameraNode.Zoom < 10.0f ? 0.25f : 0.0f));
                    zoomStatusLabel.Text = "Zoom: " + ((int)(Editor.GlobalInstance.CameraNode.Zoom * 100.0f)) + "%";
                    zoomToolStripComboBox.Text = (Editor.GlobalInstance.CameraNode.Zoom * 100.0f) + "%";
                }

                if (_toolMoving == false || InputManager.KeyDown(KeyCodes.LeftMouse) == false) return;
                Editor.GlobalInstance.CameraNode.Move(_xAxisLocked == true ? 0.0f : -((InputManager.MouseX - _toolMovementDimensions.X) / Editor.GlobalInstance.CameraNode.Zoom), _yAxisLocked == true ? 0.0f : -((InputManager.MouseY - _toolMovementDimensions.Y) / Editor.GlobalInstance.CameraNode.Zoom), 0);
                _toolMovementDimensions.X = InputManager.MouseX;
                _toolMovementDimensions.Y = InputManager.MouseY;
            }
            else if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolMoving = true;
                _toolMovementDimensions.X = InputManager.MouseX;
                _toolMovementDimensions.Y = InputManager.MouseY;
            }
            else if (firedEvent.ID == "key_released" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolMoving = false;
            }
        }
        /// <summary>
        ///		Called when the paint bucket tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdateTilePicker(Event firedEvent)
        {
            bool selectTile = false;
            if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolActive = true;
                selectTile = true;
            }
            else if (firedEvent.ID == "key_released" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolActive = false;
            }
            else if (firedEvent.ID == "mouse_move")
            {
                if (_toolActive == true) selectTile = true;
            }

            if (selectTile == true)
            {
                // Go through entitys and see if we are on a tilemap.
                TilemapSegmentNode tilemapToEdit = null;
                foreach (EntityNode entity in _selectedEntityList)
                {
                    if ((entity is TilemapSegmentNode) == false) continue;
                    if (entity.RectangleBoundingBoxIntersect(new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1), Editor.GlobalInstance.CameraNode) == true)
                        tilemapToEdit = entity as TilemapSegmentNode;
                }
                if (tilemapToEdit == null) return;

                // Work out what tile the mouse if over.
                Transformation tilemapTransformation = tilemapToEdit.CalculateTransformation(Editor.GlobalInstance.CameraNode);
                int tileX = (int)((InputManager.MouseX - tilemapTransformation.X) / (tilemapToEdit.TileWidth * Editor.GlobalInstance.CameraNode.Zoom));
                int tileY = (int)((InputManager.MouseY - tilemapTransformation.Y) / (tilemapToEdit.TileHeight * Editor.GlobalInstance.CameraNode.Zoom));
                if (tileX < 0 || tileY < 0 || tileX >= tilemapToEdit.Width / tilemapToEdit.TileWidth || tileY >= tilemapToEdit.Height / tilemapToEdit.TileHeight) return;

                // TO DO Pick the tile.
                //_assetManagerWindow.SelectedTileset = tilemapToEdit[tileX, tileY].Tileset;
                //if (tilemapToEdit[tileX, tileY].Tileset == null || tilemapToEdit[tileX, tileY].Frame == -1) return;

                //int frame = tilemapToEdit[tileX, tileY].Frame;
                //int cellsH = tilemapToEdit[tileX, tileY].Tileset.Image.FullWidth / (tilemapToEdit[tileX, tileY].Tileset.Image.Width + tilemapToEdit[tileX, tileY].Tileset.Image.HorizontalSpacing);
                //int cellsV = tilemapToEdit[tileX, tileY].Tileset.Image.FullHeight / (tilemapToEdit[tileX, tileY].Tileset.Image.Height + tilemapToEdit[tileX, tileY].Tileset.Image.VerticalSpacing);
                //_assetManagerWindow.TilesetSelection = new Rectangle(frame % cellsH, frame / cellsH, 1, 1);
                //_assetManagerWindow.TilesetColor = tilemapToEdit[tileX, tileY].Color;
            }
        }
        /// <summary>
        ///		Called when the selector tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdateSelector(Event firedEvent)
        {
            if (firedEvent.ID == "mouse_move" && InputManager.KeyDown(KeyCodes.LeftMouse))
            {
                if (_toolMoving == true)
                {
                    _toolMovementDimensions.Width = InputManager.MouseX - _toolMovementDimensions.X;
                    _toolMovementDimensions.Height = InputManager.MouseY - _toolMovementDimensions.Y;
                }
                else if (_movingObject == true)
                {
                    ArrayList groupsMoved = new ArrayList();
                    foreach (EntityNode iterationEntity in _selectedEntityList)
                    {
                        if (iterationEntity.Parent != null && iterationEntity.Parent as GroupNode != null && groupsMoved.Contains(iterationEntity.Parent) == true) continue;
                        EntityNode entity = (iterationEntity.Parent != null && iterationEntity.Parent as GroupNode != null) ? (GroupNode)iterationEntity.Parent : iterationEntity;

                        entity.Move(_xAxisLocked == true ? 0.0f : ((InputManager.MouseX - _moveObjectDimensions.X) / Editor.GlobalInstance.CameraNode.Zoom), _yAxisLocked == true ? 0.0f : ((InputManager.MouseY - _moveObjectDimensions.Y) / Editor.GlobalInstance.CameraNode.Zoom), 0.0f);

                        if (iterationEntity.Parent != null && iterationEntity.Parent as GroupNode != null)
                            groupsMoved.Add(iterationEntity.Parent);
                    }
                    _moveObjectDimensions.X = InputManager.MouseX;
                    _moveObjectDimensions.Y = InputManager.MouseY;
                    _mapChangedSinceSave = true;
                }
                else if (_sizingObject == true)
                {
                    int movementX = _xAxisLocked == true ? 0 : (int)((InputManager.MouseX - _moveObjectDimensions.X) / Editor.GlobalInstance.CameraNode.Zoom), movementY = _yAxisLocked == true ? 0 : (int)((InputManager.MouseY - _moveObjectDimensions.Y) / Editor.GlobalInstance.CameraNode.Zoom);
                    _objectToSize.BoundingRectangle = _objectSizeOriginalBoundingBox;
                    _objectToSize.Transformation = _objectSizeOriginalTransformation;

                    if ((_sizingDirection & SizingDirection.Top) != 0)
                    {
                        _objectToSize.Resize(_objectToSize.BoundingRectangle.Width, Math.Max(_objectToSize.BoundingRectangle.Height + -movementY,_gridHeight));
                        _objectToSize.Position(_objectToSize.Transformation.X, _objectToSize.Transformation.Y + -(_objectToSize.BoundingRectangle.Height - _objectSizeOriginalBoundingBox.Height), _objectToSize.Transformation.Z);
                    }
                    if ((_sizingDirection & SizingDirection.Left) != 0)
                    {
                        _objectToSize.Resize(Math.Max(_objectToSize.BoundingRectangle.Width + -movementX, _gridWidth), _objectToSize.BoundingRectangle.Height);
                        _objectToSize.Position(_objectToSize.Transformation.X + -(_objectToSize.BoundingRectangle.Width - _objectSizeOriginalBoundingBox.Width), _objectToSize.Transformation.Y, _objectToSize.Transformation.Z);
                    }

                    if ((_sizingDirection & SizingDirection.Bottom) != 0)
                        _objectToSize.Resize(_objectToSize.BoundingRectangle.Width, Math.Max(_objectToSize.BoundingRectangle.Height + movementY, _gridHeight));
                    if ((_sizingDirection & SizingDirection.Right) != 0)
                        _objectToSize.Resize(Math.Max(_objectToSize.BoundingRectangle.Width + movementX, _gridWidth), _objectToSize.BoundingRectangle.Height);
                    _mapChangedSinceSave = true;
                }
            }
            else if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                bool touchingSizingPoint = false;
                Rectangle mouseRectangle = new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1);
                foreach (EntityNode node in _selectedEntityList)
                    if (node.RectangleSizingPointsIntersect(mouseRectangle, Editor.GlobalInstance.CameraNode))
                        touchingSizingPoint = true;

                // Was last click in same spot? If so we want to select the new object.
                if (touchingSizingPoint == false && ((_toolMovementDimensions.X == InputManager.MouseX && _toolMovementDimensions.Y == InputManager.MouseY) || (_toolMovementDimensions.Width == 0 || _toolMovementDimensions.Height == 0)))
                {
                    if (InputManager.KeyDown(KeyCodes.LeftControl))
                    {
                        Rectangle intersectRectangle = new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1);
                        foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
                        {
                            EntityNode entity = node as EntityNode;
                            if (entity == null) continue;

                            if (entity.RectangleBoundingBoxIntersect(intersectRectangle, Editor.GlobalInstance.CameraNode) == true)
                            {
                                if (_selectedEntityList.Contains(entity))
                                    RemoveEntityFromSelection(entity);
                                else
                                    AddEntityToSelection(entity);
                                break;
                            }
                        }

                        SyncronizeWindow();
                    }
                    else
                    {
                        Rectangle intersectRectangle = new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1);
                        bool canSelect = (_selectedEntityList.Count == 0);
                        EntityNode selectEntity = null, firstEntity = null;

                        foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
                        {
                            EntityNode entity = node as EntityNode;
                            if (entity == null) continue;

                            if (entity.RectangleBoundingBoxIntersect(intersectRectangle, Editor.GlobalInstance.CameraNode) == true)
                            {
                                if (canSelect == true)
                                {
                                    selectEntity = entity;
                                    break;
                                }
                                else if (firstEntity != null)
                                    firstEntity = entity;

                                if (_selectedEntityList.Contains(entity))
                                    canSelect = true;
                            }
                        }
                        if (selectEntity == null)
                            selectEntity = firstEntity;

                        ClearSelection();

                        if (selectEntity != null)
                        {
                            AddEntityToSelection(selectEntity);
                            SyncronizeWindow();
                        }

                        _movingObject = true;
                        _moveObjectDimensions.X = InputManager.MouseX;
                        _moveObjectDimensions.Y = InputManager.MouseY;
                    }
                }
                else
                {
                    ArrayList removeList = new ArrayList();
                    Rectangle intersectRectangle = new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1);
                    foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
                    {
                        EntityNode entity = node as EntityNode;
                        if (entity == null) continue;
                        if (entity.RectangleBoundingBoxIntersect(intersectRectangle, Editor.GlobalInstance.CameraNode) == false &&
                            entity.RectangleSizingPointsIntersect(intersectRectangle, Editor.GlobalInstance.CameraNode) == false)
                            removeList.Add(entity);
                    }
                    if (!InputManager.KeyDown(KeyCodes.LeftControl))
                    {
                        foreach (EntityNode entity in removeList)
                            RemoveEntityFromSelection(entity);
                    }

                    _movingObject = true;
                    _moveObjectDimensions.X = InputManager.MouseX;
                    _moveObjectDimensions.Y = InputManager.MouseY;
                }

                // Lets select an object or size one.
                foreach (EntityNode entity in _selectedEntityList)
                {
                    Transformation transformation = entity.CalculateTransformation(Editor.GlobalInstance.CameraNode);
                    int x = (int)(transformation.X - (entity.SizingPointsSize / 2)), y = (int)(transformation.Y - (entity.SizingPointsSize / 2));
                    int w = (int)(entity.BoundingRectangle.Width * Editor.GlobalInstance.CameraNode.Zoom), h = (int)(entity.BoundingRectangle.Height * Editor.GlobalInstance.CameraNode.Zoom);

                    bool previousMoving = _movingObject;
                    _movingObject = false;
                    _sizingObject = true;
                    _objectToSize = entity;
                    _objectSizeOriginalBoundingBox = _objectToSize.BoundingRectangle;
                    _objectSizeOriginalTransformation = _objectToSize.Transformation;
                    if (mouseRectangle.IntersectsWith(new Rectangle(x, y, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Top | SizingDirection.Left;
                        Cursor = Cursors.SizeNWSE;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x + w, y, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Top | SizingDirection.Right;
                        Cursor = Cursors.SizeNESW;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x, y + h, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Bottom | SizingDirection.Left;
                        Cursor = Cursors.SizeNESW;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x + w, y + h, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Bottom | SizingDirection.Right;
                        Cursor = Cursors.SizeNWSE;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x + (w / 2), y, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Top;
                        Cursor = Cursors.SizeNS;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x + (w / 2), y + h, entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Bottom;
                        Cursor = Cursors.SizeNS;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x, y + (h / 2), entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Left;
                        Cursor = Cursors.SizeWE;
                    }
                    else if (mouseRectangle.IntersectsWith(new Rectangle(x + w, y + (h / 2), entity.SizingPointsSize, entity.SizingPointsSize)))
                    {
                        _sizingDirection = SizingDirection.Right;
                        Cursor = Cursors.SizeWE;
                    }
                    else
                    {
                        _sizingObject = false;
                        _objectToSize = null;
                        _movingObject = previousMoving;
                    }
                }

                // If we are holding shift then we want to select multiple objects.
                if (InputManager.KeyDown(KeyCodes.LeftShift))
                {
                    _movingObject = false;
                    _sizingObject = false;
                    _toolMoving = true;
                }

                // Log the original transformations of the selected nodes.
                _originalEntityTransformations.Clear();
                _originalEntityBoundingBoxs.Clear();
                foreach (EntityNode entity in _selectedEntityList)
                {
                    _originalEntityTransformations.Add(entity, entity.Transformation);
                    _originalEntityBoundingBoxs.Add(entity, entity.BoundingRectangle);
                }

                _toolMovementDimensions.X = InputManager.MouseX;
                _toolMovementDimensions.Y = InputManager.MouseY;
                _toolMovementDimensions.Width = _selectedEntityList.Count > 0 ? 1 : 0;
                _toolMovementDimensions.Height = _selectedEntityList.Count > 0 ? 1 : 0;
            }
            else if (firedEvent.ID == "key_released" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                if (_toolMoving == true)
                {
                    _toolMoving = false;

                    // Create a rectangle from which we can check intersection against.
                    Rectangle intersectRectangle = new Rectangle();

                    // If we have a negative width then make it positive.
                    if (_toolMovementDimensions.Width < 0)
                    {
                        intersectRectangle.X = _toolMovementDimensions.X + _toolMovementDimensions.Width;
                        intersectRectangle.Width = Math.Abs(_toolMovementDimensions.Width);
                    }
                    else
                    {
                        intersectRectangle.X = _toolMovementDimensions.X;
                        intersectRectangle.Width = _toolMovementDimensions.Width;
                    }

                    // If we have a negative height then make it positive.
                    if (_toolMovementDimensions.Height < 0)
                    {
                        intersectRectangle.Y = _toolMovementDimensions.Y + _toolMovementDimensions.Height;
                        intersectRectangle.Height = Math.Abs(_toolMovementDimensions.Height);
                    }
                    else
                    {
                        intersectRectangle.Y = _toolMovementDimensions.Y;
                        intersectRectangle.Height = _toolMovementDimensions.Height;
                    }

                    // Unselect all the pervious entitys.
                    ArrayList oldSelectionList = new ArrayList();
                    oldSelectionList.AddRange(_selectedEntityList);

                    // Clear out old selection.
                    if (InputManager.KeyDown(KeyCodes.LeftControl) == false)
                        ClearSelection();

                    // Grab all the entitys within our selection rectangle and select them.
                    bool canSelect = (oldSelectionList.Count == 0 || !(intersectRectangle.Width < 2 && intersectRectangle.Height < 2));
                    EntityNode selectEntity = null;
                    foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
                    {
                        EntityNode entity = node as EntityNode;
                        if (entity == null) continue;

                        if (entity.RectangleBoundingBoxIntersect(intersectRectangle, Editor.GlobalInstance.CameraNode) == true)
                        {
                            if (canSelect == true)
                            {
                                AddEntityToSelection(entity);
                                if (intersectRectangle.Width < 2 && intersectRectangle.Height < 2)
                                    break;
                            }
                            else if (selectEntity == null)
                                selectEntity = entity;

                            if (oldSelectionList.Contains(entity))
                                canSelect = true;
                        }
                    }
                    if (canSelect == false && selectEntity != null)
                        AddEntityToSelection(selectEntity);
                }
                else if (_movingObject == true)
                {
                    // Snap the objects to the grid.
                    if (_snapToGrid == true)
                    {
                        foreach (EntityNode entity in _selectedEntityList)
                        {
                            entity.Position(((int)entity.Transformation.X / _gridWidth) * _gridWidth, ((int)entity.Transformation.Y / _gridHeight) * _gridHeight, entity.Transformation.Z);

                            // Create a new transformation undo operation if transformation has changed.
                            Transformation originalTransformation = (Transformation)_originalEntityTransformations[entity];
                            if (originalTransformation != entity.Transformation)
                                PushUndoOperation(new TransformNodeUndoOperation(entity, originalTransformation, entity.Transformation));
                        }
                        _originalEntityTransformations.Clear();
                        if (_entityPropertiesWindow != null && _entityPropertiesWindow.Entity != null)
                            _entityPropertiesWindow.UpdateProperty("location", new Point((int)_entityPropertiesWindow.Entity.Transformation.X, (int)_entityPropertiesWindow.Entity.Transformation.Y));
                    }
                    _movingObject = false;
                    _mapChangedSinceSave = true;
                }
                else if (_sizingObject == true)
                {
                    if (_snapToGrid == true)
                    {
                        _objectToSize.Position(((int)_objectToSize.Transformation.X / _gridWidth) * _gridWidth, ((int)_objectToSize.Transformation.Y / _gridHeight) * _gridHeight, _objectToSize.Transformation.Z);
                        _objectToSize.BoundingRectangle = new Rectangle(_objectToSize.BoundingRectangle.X, _objectToSize.BoundingRectangle.Y, ((int)_objectToSize.BoundingRectangle.Width / _gridWidth) * _gridWidth, ((int)_objectToSize.BoundingRectangle.Height / _gridHeight) * _gridHeight);

                        Rectangle newBoundingRectangle = _objectToSize.BoundingRectangle;
                        if (newBoundingRectangle.Width < _gridWidth) newBoundingRectangle.Width = _gridWidth;
                        if (newBoundingRectangle.Height < _gridHeight) newBoundingRectangle.Height = _gridHeight;
                        _objectToSize.BoundingRectangle = newBoundingRectangle;

                        // Create a new sizing undo operation if size has changed.
                        Rectangle originalBoundingBox = (Rectangle)_originalEntityBoundingBoxs[_objectToSize];
                        if (!_objectToSize.BoundingRectangle.Equals(originalBoundingBox))
                            PushUndoOperation(new ResizeNodeUndoOperation(_objectToSize, originalBoundingBox, (Transformation)_originalEntityTransformations[_objectToSize], _objectToSize.BoundingRectangle, _objectToSize.Transformation));
                    }
                    if (_entityPropertiesWindow != null && _entityPropertiesWindow.Entity != null)
                    {
                        _entityPropertiesWindow.UpdateProperty("bounding rectangle", new Rectangle(_entityPropertiesWindow.Entity.BoundingRectangle.X, _entityPropertiesWindow.Entity.BoundingRectangle.Y, _entityPropertiesWindow.Entity.BoundingRectangle.Width, _entityPropertiesWindow.Entity.BoundingRectangle.Height));
                        _entityPropertiesWindow.UpdateProperty("collision rectangle", new Rectangle(_entityPropertiesWindow.Entity.CollisionRectangle.X, _entityPropertiesWindow.Entity.CollisionRectangle.Y, _entityPropertiesWindow.Entity.CollisionRectangle.Width, _entityPropertiesWindow.Entity.CollisionRectangle.Height));
                    }
                    Cursor = Cursors.Arrow;
                    _sizingObject = false;
                    _mapChangedSinceSave = true;
                }

                SyncronizeWindow();
            }
        }
        /// <summary>
        ///		Called when the pencil tool is selected and an event has been recieved.
        /// </summary>
        /// <param name="firedEvent">Event that caused this update to be called.</param>
        public void UpdatePencil(Event firedEvent)
        {
            bool placeTiles = false;
            if (firedEvent.ID == "mouse_move" && InputManager.KeyDown(KeyCodes.LeftMouse))
            {
                if (_toolActive == false) return;
                placeTiles = true;
            }
            else if (firedEvent.ID == "key_pressed" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
            {
                _toolActive = true;
                placeTiles = true;
            }
            else if (firedEvent.ID == "key_released" && ((InputEventData)firedEvent.Data).KeyCode == KeyCodes.LeftMouse)
                _toolActive = false;

            // Place the tiles onto the map at the cursor position if we have been asked to.
            if (placeTiles == true)
            {
                // Go through entitys and see if we are on a tilemap.
                TilemapSegmentNode tilemapToEdit = null;
                foreach (EntityNode entity in _selectedEntityList)
                {
                    if ((entity is TilemapSegmentNode) == false) continue;
                    if (entity.RectangleBoundingBoxIntersect(new Rectangle(InputManager.MouseX, InputManager.MouseY, 1, 1), Editor.GlobalInstance.CameraNode) == true)
                    {
                        tilemapToEdit = entity as TilemapSegmentNode;
                        break;
                    }
                }
                if (tilemapToEdit == null) return;

                // Work out what tile the mouse if over.
                Transformation tilemapTransformation = tilemapToEdit.CalculateTransformation(Editor.GlobalInstance.CameraNode);
                int tileX = (int)((InputManager.MouseX - tilemapTransformation.X) / (tilemapToEdit.TileWidth * Editor.GlobalInstance.CameraNode.Zoom));
                int tileY = (int)((InputManager.MouseY - tilemapTransformation.Y) / (tilemapToEdit.TileHeight * Editor.GlobalInstance.CameraNode.Zoom));

                // Place the tiles onto the tilemap.
                Rectangle tilesetSelection = _assetManagerWindow.TilesetSelection;
                Tileset selectedTileset = GetSelectedTileset();

                for (int x = tileX; x < tileX + tilesetSelection.Width; x++)
                {
                    for (int y = tileY; y < tileY + tilesetSelection.Height; y++)
                    {
                        if (x < 0 || y < 0 || x >= tilemapToEdit.Width / tilemapToEdit.TileWidth || y >= tilemapToEdit.Height / tilemapToEdit.TileHeight) continue;
                        tilemapToEdit[x, y].Tileset = selectedTileset;
                        tilemapToEdit[x, y].Frame = selectedTileset.Image.FrameIndexAtPosition((tilesetSelection.X + (x - tileX)) * selectedTileset.Image.Width, (tilesetSelection.Y + (y - tileY)) * selectedTileset.Image.Height);
                        tilemapToEdit[x, y].Color = _assetManagerWindow.TilesetColor;
                        tilemapToEdit[x, y].Scale(_flipTilesX == true ? -1 : 1, _flipTilesY == true ? -1 : 1, 1);
                    }
                }

                _mapChangedSinceSave = true;
            }
        }
        /// <summary>
        ///		Called when an event is being processed by the EventManager.
        /// </summary>
        /// <param name="firedEvent">Event that needs to be processed.</param>
        public void EventCaptured(Event firedEvent)
        {
            GraphicsManager.RenderTarget = (IRenderTarget)_canvas;
            int mouseX = Input.InputManager.MouseX, mouseY = Input.InputManager.MouseY;
            bool mouseInPanel = !(mouseX < 0 || mouseY < 0 || mouseX > canvasPanel.ClientSize.Width || mouseY > canvasPanel.ClientSize.Height);
            int hOffset = -(tilesetHScrollBar.Value * (_tileset.Image.Width + _tileset.Image.HorizontalSpacing));
            int vOffset = -(tilesetVScrollBar.Value * (_tileset.Image.Height + _tileset.Image.VerticalSpacing));
            int tileX = (mouseX / (_tileset.Image.Width + _tileset.Image.HorizontalSpacing)) + tilesetHScrollBar.Value;
            int tileY = (mouseY / (_tileset.Image.Height + _tileset.Image.VerticalSpacing)) + tilesetVScrollBar.Value;
            int hTileCount = _tileset.Image.FullWidth / (_tileset.Image.Width + _tileset.Image.HorizontalSpacing);
            int vTileCount = _tileset.Image.FullHeight / (_tileset.Image.Height + _tileset.Image.VerticalSpacing);

            // Check what event we have retrieved.
            switch (firedEvent.ID)
            {
                case "key_pressed":
                    if (((Input.InputEventData)firedEvent.Data).KeyCode != BinaryPhoenix.Fusion.Input.KeyCodes.LeftMouse) break;
                    if (mouseInPanel == false) break;
                    if (tileX < 0 || tileY < 0 || tileX >= hTileCount || tileY >= vTileCount) break;
                    _selectingTiles = true;
                    _selectedTiles = false;
                    _selection.X = tileX;
                    _selection.Y = tileY;
                    _selection.Width = _selection.Height = 1;
                    break;

                case "key_released":
                    if (_selectingTiles == false || ((Input.InputEventData)firedEvent.Data).KeyCode != BinaryPhoenix.Fusion.Input.KeyCodes.LeftMouse) break;
                    _selectedTiles = true;
                    _selectingTiles = false;
                    _selection.Width = tileX - _selection.X + (_selection.Width >= 0 ? 1 : 0);
                    _selection.Height = tileY - _selection.Y + (_selection.Height >= 0 ? 1 : 0);
                    if (_selection.Width == 0) _selection.Width = 1;
                    if (_selection.Height == 0) _selection.Height = 1;
                    if (_selection.X + _selection.Width < 0 || _selection.X + _selection.Width > hTileCount) _selection.Width = hTileCount - _selection.X;
                    if (_selection.Y + _selection.Height < 0 || _selection.Y + _selection.Height > vTileCount) _selection.Height = vTileCount - _selection.Y;

                    // If the selection is negative then correct it.
                    if (_selection.Width < 0)
                    {
                        _selection.X += _selection.Width;
                        _selection.Width = -_selection.Width;
                    }
                    if (_selection.Height < 0)
                    {
                        _selection.Y += _selection.Height;
                        _selection.Height = -_selection.Height;
                    }

                    if (SelectionChanged != null) SelectionChanged(this, new EventArgs());
                    break;

                case "mouse_move":
                    if (mouseInPanel == false || _selectingTiles == false) break;
                    _selection.Width = tileX - _selection.X + (_selection.Width >= 0 ? 1 : 0);
                    _selection.Height = tileY - _selection.Y + (_selection.Height >= 0 ? 1 : 0);
                    if (_selection.Width == 0) _selection.Width = 1;
                    if (_selection.Height == 0) _selection.Height = 1;
                    if (_selection.X + _selection.Width < 0 || _selection.X + _selection.Width > hTileCount) _selection.Width = hTileCount - _selection.X;
                    if (_selection.Y + _selection.Height < 0 || _selection.Y + _selection.Height > vTileCount) _selection.Height = vTileCount - _selection.Y;
                    break;
            }

            GraphicsManager.RenderTarget = null;
        }
 /// <summary>
 ///		Called when an event is being processed by the EventManager.
 /// </summary>
 /// <param name="firedEvent">Event that needs to be processed.</param>
 public void EventCaptured(Event firedEvent)
 {
 }