/// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            TimeSpan currentFrame = gameTime.TotalGameTime;
            bool updateFrame = false;
            if ((currentFrame - lastFrame) > timeBetweenFrames)
            {
                lastFrame = currentFrame;
                updateFrame = true;
            }

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            MouseState currentMouse = Mouse.GetState();
            KeyboardState currentKeyboard = Keyboard.GetState();

            //generic mouse input

            int mx = currentMouse.X;
            int my = currentMouse.Y;

            int ax = (int)(mx / zoom + zoomScreen.X);
            int ay = (int)(my / zoom + zoomScreen.Y);

            //LEFTCLICKING

            if (minimapArea.Contains(mx, my) && currentMouse.LeftButton == ButtonState.Pressed)
            {
                int gx = (mx - minimapArea.X) / minimapScale;
                int gy = (my - minimapArea.Y) / minimapScale;

                int lx = screen.X;
                int ly = screen.Y;

                screen.X = (gx * GRID_PIXEL) - screen.Width / 2;
                screen.Y = (gy * GRID_PIXEL) - screen.Height / 2;

                ZoomScreen();

                if (!maxSize.Contains(zoomScreen))
                {
                    screen.X = lx;
                    screen.Y = ly;
                    ZoomScreen();
                }
            }
            else if (IsPressed(stopButton, currentMouse))
            {
                foreach (Unit u in units)
                {
                    u.Destination = u.Center;
                }
                currentMouseActionState = MouseActionState.Stop;
            }
            else if (IsPressed(moveButton, currentMouse))
            {
                currentMouseActionState = MouseActionState.Move;
            }
            else if (IsPressed(actionButton, currentMouse))
            {
                currentMouseActionState = MouseActionState.Action;
            }
            else if (screen.Contains(mx + screen.X, my + screen.Y))
            {
                if (currentMouse.LeftButton == ButtonState.Pressed)
                {
                    if (currentMouseActionState == MouseActionState.Action)
                    {
                        foreach (Unit u in units)
                        {
                            u.Action(ax, ay, units);
                        }
                    }
                    else if (currentMouseActionState == MouseActionState.Move)
                    {
                        Vector2 d = new Vector2(ax, ay);
                        foreach (Unit u in selected)
                        {
                            u.Destination = d;
                        }
                    }
                    else if (currentMouseActionState == MouseActionState.Stop)
                    {
                    }
                    else if (currentMouseActionState == MouseActionState.Normal)
                    {
                        if (lastMouse.LeftButton == ButtonState.Pressed)
                        {

                            int width = mx - ((int)lastLeftClick.X);
                            int height = my - ((int)lastLeftClick.Y);

                            selection = new Rectangle((int)lastLeftClick.X, (int)lastLeftClick.Y, width, height);
                        }
                        else
                        {
                            lastLeftClick = new Vector2(mx, my);
                            selection = new Rectangle((int)lastLeftClick.X, (int)lastLeftClick.Y, 0, 0);
                        }
                    }
                    currentMouseActionState = MouseActionState.Normal;
                }
                else
                {
                    if (lastMouse.LeftButton == ButtonState.Pressed)
                    {
                        Rectangle scaleSel = new Rectangle((int)(selection.X * zoom + zoomScreen.X), (int)(selection.Y * zoom + zoomScreen.Y), (int)(selection.Width * zoom), (int)(selection.Height * zoom));
                        if (!currentKeyboard.IsKeyDown(Keys.LeftShift) && !currentKeyboard.IsKeyDown(Keys.RightShift))
                        {
                            selected.Clear();
                        }

                        foreach (Unit u in player.Units)
                        {
                            if (scaleSel.Intersects(u.HardCollisionBox) && !selected.Contains(u) && selected.Count < portraits.Count)
                            {
                                selected.Add(u);
                            }
                        }
                        selection = new Rectangle(-1, -1, 0, 0);
                        lastLeftClick = new Vector2(-1, -1);
                    }
                }
            }

            //RIGHTCLICKING

            if (currentMouse.RightButton == ButtonState.Pressed)
            {
                if (lastMouse.RightButton == ButtonState.Released)
                {
                    Vector2 d = new Vector2(ax, ay);
                    foreach (Unit u in selected)
                    {
                        u.Destination = d;
                    }
                }
            }
            //screen scrolling logic
            if (scrolledLast || (currentMouse.X != lastMouse.X && currentMouse.Y != lastMouse.Y))
            {
                int dx = 0;
                int dy = 0;
                if (scrollDown.Contains(currentMouse.X, currentMouse.Y))
                {
                    dy = scrollSpeed;
                }
                if (scrollUp.Contains(currentMouse.X, currentMouse.Y))
                {
                    dy = -scrollSpeed;
                }
                if (scrollLeft.Contains(currentMouse.X, currentMouse.Y))
                {
                    dx = -scrollSpeed;
                }
                if (scrollRight.Contains(currentMouse.X, currentMouse.Y))
                {
                    dx = scrollSpeed;
                }
                if (dx != 0)
                {
                    scrolledLast = true;
                    screen.Offset(dx, 0);
                    ZoomScreen();
                    if (!maxSize.Contains(zoomScreen))
                    {
                        screen.Offset(-dx, 0);
                        ZoomScreen();
                    }
                }
                if (dy != 0)
                {
                    scrolledLast = true;
                    screen.Offset(0,dy);
                    ZoomScreen();
                    if (!maxSize.Contains(zoomScreen))
                    {
                        screen.Offset(0,-dy);
                        ZoomScreen();
                    }
                }
            }

            //generic keyboard input
            if (currentKeyboard.IsKeyDown(Keys.N) && lastKeyboard.IsKeyUp(Keys.N))
            {
                Unit toAdd;
                do
                {
                    int rx = random.Next(screen.X, screen.X + screen.Width);
                    int ry = random.Next(screen.Y, screen.Y + screen.Height);
                    toAdd = new Unit(rx, ry, 50, 50, unitTexture, unitTexture, attack);
                } while (!maxSize.Contains(toAdd.DrawArea));
                units.Add(toAdd);
                if (currentKeyboard.IsKeyDown(Keys.RightShift) || currentKeyboard.IsKeyDown(Keys.LeftShift))
                {
                    enemy.AddUnit(toAdd);
                }
                else
                {
                    player.AddUnit(toAdd);
                }
            }
            if (currentKeyboard.IsKeyDown(Keys.F) && lastKeyboard.IsKeyUp(Keys.F))
            {
                graphics.ToggleFullScreen();
                CalculateScreen();
            }
            if (currentKeyboard.IsKeyDown(Keys.S) && lastKeyboard.IsKeyUp(Keys.S))
            {
                Team temp = player;
                player = enemy;
                enemy = temp;
            }
            if (currentKeyboard.IsKeyDown(Keys.Escape) && lastKeyboard.IsKeyUp(Keys.Escape))
            {
                if (graphics.IsFullScreen)
                {
                    graphics.ToggleFullScreen();
                    CalculateScreen();
                }
            }

            lastKeyboard = currentKeyboard;
            lastMouse = currentMouse;

            if (updateFrame)
            {
                for (int x = 0; x < GRID_WIDTH; x++)
                {
                    for (int y = 0; y < GRID_HEIGHT; y++)
                    {
                        minimap[x, y] = Color.White;
                    }
                }

                foreach (Unit u in units)
                {
                    u.Update();
                    if (u.IsMoving())
                    {
                        foreach (Unit v in units)
                        {
                            if (u.ID != v.ID && u.CollidesWith(v))
                            {
                                //lets go on the assumption that something will only ever collide with something else if it is moving
                                u.UndoUpdate();
                            }
                        }
                    }
                    int gx = (int)(u.Center.X / GRID_PIXEL);
                    int gy = (int)(u.Center.Y / GRID_PIXEL);

                    minimap[gx, gy] = u.Team.TeamColor;
                }
            }

            base.Update(gameTime);
        }
        /// <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>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            grid = new Rectangle[GRID_WIDTH, GRID_HEIGHT];
            colors = new Color[GRID_WIDTH, GRID_HEIGHT];
            minimap = new Color[GRID_WIDTH, GRID_HEIGHT];

            maxSize = new Rectangle(0, 0, GRID_PIXEL * GRID_WIDTH, GRID_PIXEL * GRID_HEIGHT);

            units = new List<Unit>();
            selected = new List<Unit>();
            portraits = new List<Rectangle>();

            random = new Random();

            player = new Team("Player", Color.Blue);
            enemy = new Team("Enemy", Color.Red);
            neutral = new Team("Neutral", Color.LightGray);

            for (int x = 0; x < GRID_WIDTH; x++)
            {
                for (int y = 0; y < GRID_HEIGHT; y++)
                {
                    grid[x, y] = new Rectangle(x * GRID_PIXEL, y * GRID_PIXEL, GRID_PIXEL, GRID_PIXEL);
                    colors[x, y] = y % 2 == x % 2 ? Color.Gray : Color.GhostWhite;
                    minimap[x, y] = Color.White;
                }
            }

            //CONSTANTS
            minimapScale = 4;
            zoom = 1.0f;
            zoomFactor = 0.01f;
            scrollSpeed = 5;
            timeBetweenFrames = new TimeSpan(TimeSpan.TicksPerSecond / 60);

            CalculateScreen();

            base.Initialize();
        }