using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;

namespace Game1
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont Bold;
        private Texture2D[] tile = new Texture2D[5];
        private Texture2D[] Crops = new Texture2D[5];
        private Texture2D tractor;
        private Texture2D house;
        private Texture2D markers;
        private Texture2D mouseCursor;

        private Texture2D ProgressionBar;
        private Texture2D ProgressionBarStatus;

        private Tractor tractorUnit = new Tractor();
        private Input input = new Input();
        private House houseUnit = new House();
        private Rectangle mousePosition;

        private Inventory inventory = new Inventory();

        DayNightCycle Time = new DayNightCycle();

        private string[] cropTypesNames = new string[12];

        private int x, y;

        MouseState state;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            base.Initialize();

            cropTypesNames[0] = "Barley";
            cropTypesNames[1] = "Cotton";
            cropTypesNames[2] = "Ground Nuts";
            cropTypesNames[3] = "Maize";
            cropTypesNames[4] = "Millets";
            cropTypesNames[5] = "Oil Seeds";
            cropTypesNames[6] = "Paddy";
            cropTypesNames[7] = "Pulses";
            cropTypesNames[8] = "Sugarcane";
            cropTypesNames[9] = "Tobacco";
            cropTypesNames[10] = "Wheat";







            //Generates the map with some random values
            inventory.initInventorySystem();
            input.init(graphics, new Vector2(16,16), 56, 1);                        //Generates the starting size
            houseUnit.init(input.getTileSize(), input.getSpacing());                //Generates the house position
            tractorUnit.init(houseUnit.GetRectangle(), input);                      //Generates the Tractor
            tractorUnit.updateSizing(input, 0, houseUnit.getVector(), Time);              //Updates the first Size of the Tractor
            tractorUnit.setPos(houseUnit.getVector());                              //Changes the position of the tractor to the houses position at the start
            tractorUnit.setNewHousePos(houseUnit.getVector() / input.getSpacingTile(), true);



            graphics.PreferredBackBufferWidth = (input.getTileSize() + input.getSpacing()) * (int)input.getSize().X;
            graphics.PreferredBackBufferHeight = (input.getTileSize() + input.getSpacing()) * (int)input.getSize().Y + 300;
            graphics.ApplyChanges();
        }

        protected override void LoadContent()
        {   
            spriteBatch = new SpriteBatch(GraphicsDevice);




            //Loads the PNG content and Fonts
            tile[0] = Content.Load<Texture2D>("Mountain");
            tile[1] = Content.Load<Texture2D>("tileunplantable");
            tile[2] = Content.Load<Texture2D>("Plantable");
            tile[3] = Content.Load<Texture2D>("Planted");
            tile[4] = Content.Load<Texture2D>("Crop");

            Crops[0] = Content.Load<Texture2D>("CarrotIcon");
            Crops[1] = Content.Load<Texture2D>("WheatIcon");
            Crops[2] = Content.Load<Texture2D>("BerriesIcon"); //Replace 2 and 3 with the new crop Textures
            Crops[3] = Content.Load<Texture2D>("TreePlantationIcon");

            ProgressionBar = Content.Load<Texture2D>("ProgressionBar");
            ProgressionBarStatus = Content.Load<Texture2D>("ProgressionBarStatus");

            tractor = Content.Load<Texture2D>("Tractor");
            mouseCursor = Content.Load<Texture2D>("MouseCursor");
            Bold = Content.Load<SpriteFont>("Font");
            house = Content.Load<Texture2D>("house");
            markers = Content.Load<Texture2D>("Markers");
        }



        protected override void UnloadContent()
        {

        }


        protected override void Update(GameTime gameTime) //updates every 60 seconds
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();


            state = Mouse.GetState();
            mousePosition = new Rectangle(state.X, state.Y, 1, 1);

            tractorUnit.updateSizing(input, 0, houseUnit.getVector(), Time);                                                                  //Updates the size
            tractorUnit.setSpeed(input.changeSpeed(tractorUnit.getSpeed()));                                                            //Updates the Simulation Speed
            tractorUnit.setTractorSpeed(input.changeTractorSpeed(tractorUnit.getTractorSpeed(), tractorUnit.getPos()));                 //Updates the Tractor Speed
            input.controlWindowSize();                                                                                                  //Controls the size of the screen depending on the number of tiles
            houseUnit.updateRectangle(input.getSize(), input.getTileSize(), input.getSpacing());                                        //Updates the position of the house if the house appears out of bound
            Time.updateTime(tractorUnit.getSpeed());
            


            base.Update(gameTime);
        }


        protected override void Draw(GameTime gameTime) //Draw Function
        {
            GraphicsDevice.Clear(Color.FromNonPremultiplied(255,255,255,140));

            spriteBatch.Begin();

            DrawTiles();

            spriteBatch.Draw(markers, new Rectangle((int)tractorUnit.getTargetPosition().X / input.getSpacingTile() * (input.getTileSize() + input.getSpacing()) + input.getTileSize() / 4, (int)tractorUnit.getTargetPosition().Y / input.getSpacingTile() * (input.getTileSize() + input.getSpacing()) + input.getTileSize() / 4, input.getTileSize()/2, input.getTileSize()/2), Color.Green);
            for (int i = 0; i < tractorUnit.getPath().getCount() + 1; i++)
            {
                spriteBatch.Draw(markers, new Rectangle((int)tractorUnit.getPath().getByIndex(i).getCords().X * (input.getSpacingTile()) + input.getTileSize() / 4, (int)tractorUnit.getPath().getByIndex(i).getCords().Y * (input.getSpacingTile()) + input.getTileSize() / 4, input.getTileSize()/2, input.getTileSize()/2), Color.Green);
            }




            spriteBatch.Draw(house, houseUnit.GetRectangle(), Time.GetTimeOfDay());
            spriteBatch.Draw(markers, new Rectangle((int)tractorUnit.getPath().getFinalDest().getCords().X * (input.getSpacingTile()) + Convert.ToInt32(input.getTileSize() / 6), (int)tractorUnit.getPath().getFinalDest().getCords().Y * (input.getSpacingTile()) + Convert.ToInt32(input.getTileSize() / 6), Convert.ToInt32(input.getTileSize() / 1.5), Convert.ToInt32(input.getTileSize() / 1.5)), Color.Red);                         //Draws the current target of the tractor
            spriteBatch.Draw(tractor, new Vector2((int)tractorUnit.getPos().X + input.getTileSize() / 2, (int)tractorUnit.getPos().Y + input.getTileSize() / 2), new Rectangle(0, 0, input.getTileSize(), input.getTileSize()), Time.GetTimeOfDay(), tractorUnit.getRotation(), new Vector2(input.getTileSize() / 2, input.getTileSize() / 2), 1.0f, SpriteEffects.None, 1);



            for (int i = 0; i < 5; i++)
            {
                spriteBatch.Draw(ProgressionBar, new Rectangle(i * 227, (int)(input.getSize().Y * (input.getTileSize() + input.getSpacing())), 5, 300), Color.White);
            }
            for (int i = 0; i < 15; i++)
            {
                spriteBatch.Draw(ProgressionBar, new Rectangle(0, (int)(input.getSize().Y * (input.getTileSize() + input.getSpacing())) + i * 20, (int)(input.getSize().X * (input.getTileSize() + input.getSpacing())), 1), Color.White);
            }

            spriteBatch.DrawString(Bold, "Time: ", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 2), Color.DarkRed);
            spriteBatch.DrawString(Bold, "Days " + Time.getDays(), new Vector2(60, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 2), Color.DarkBlue);
            spriteBatch.DrawString(Bold, "Day Progression: ", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 22), Color.DarkRed);
            spriteBatch.DrawString(Bold, Time.GetTimeOfDayInt().ToString() + "%", new Vector2(140, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 22), Color.DarkBlue);

            spriteBatch.DrawString(Bold, "Tractor Properties:", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 62), Color.DarkRed);

            spriteBatch.DrawString(Bold, "Speed:" + tractorUnit.getSpeed().ToString(), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 82) , Color.DarkBlue);
            spriteBatch.DrawString(Bold, "Tractor Position:" + new Vector2((float)Math.Round(tractorUnit.getPos().X / input.getSpacingTile(), 1), (float)Math.Round(tractorUnit.getPos().Y / input.getSpacingTile(), 1)), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 102), Color.DarkBlue);
            spriteBatch.DrawString(Bold, "Tractor Rotation:" + Math.Round(tractorUnit.getRotation(), 2).ToString() + " Degrees", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 122), Color.DarkBlue);
            spriteBatch.DrawString(Bold, "Tractor Speed:" + tractorUnit.getTractorSpeed().ToString(), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 142), Color.DarkBlue);
            spriteBatch.DrawString(Bold, "Tractor Target:" + tractorUnit.getPath().getFinalDest().getCords().ToString(), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 162), Color.DarkBlue);



            spriteBatch.DrawString(Bold, "Map Properties:", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 202), Color.DarkRed);
            spriteBatch.DrawString(Bold, "Tile Size:" + input.getTileSize().ToString() + "pix", new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 222), Color.DarkBlue);                                        //Draws the tile size
            spriteBatch.DrawString(Bold, "Matrix Size: " + input.getSize().X.ToString() + " X " + input.getSize().Y.ToString(), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 242), Color.DarkBlue);
            spriteBatch.DrawString(Bold, "House Position: " + houseUnit.getVector() / input.getSpacingTile(), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 262), Color.DarkBlue);

            spriteBatch.DrawString(Bold, "Total Weight: ", new Vector2(700, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 182), Color.DarkRed);
            spriteBatch.DrawString(Bold, "(" + tractorUnit.getInventory().getWeight() + "/" + tractorUnit.getInventory().getMaxWeight() + ")", new Vector2(800, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 182), Color.DarkBlue);

            tractorUnit.drawInventory(input, spriteBatch, Bold, inventory.getPredefinedItems());

            InspectTile();

            spriteBatch.Draw(mouseCursor, new Rectangle((int)mousePosition.X, (int)mousePosition.Y, 14, 21), Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }


        public void DrawTiles()
        {
            for (int i = 0; i < input.getSize().X; i++) //Draw the tiles
            {
                for (int j = 0; j < input.getSize().Y; j++)
                {
                    Rectangle tilePos = new Rectangle(i * (input.getSpacingTile()), j * (input.getSpacingTile()), input.getTileSize(), input.getTileSize());
                    spriteBatch.Draw(tile[tractorUnit.getFarm().getCrop(i, j).getStatus()], tilePos, Time.GetTimeOfDay());
                    if (tilePos.Intersects(mousePosition))
                    {
                        spriteBatch.Draw(tile[tractorUnit.getFarm().getCrop(i, j).getStatus()], tilePos, Color.FromNonPremultiplied(0, 0, 20, 40));
                        if (state.LeftButton == ButtonState.Pressed && !tractorUnit.getFarm().getCrop(i, j).getHousePos())
                        {
                            tractorUnit.setNewHousePos(new Vector2(i, j), true);
                            tractorUnit.setNewHousePos(houseUnit.getVector() / input.getSpacingTile(), false);
                            houseUnit.setRectangle(i, j, input.getTileSize(), input.getSpacing());
                        }
                        if (state.RightButton == ButtonState.Pressed)
                        {
                            x = i;
                            y = j;
                        }
                    }
                    if ((tractorUnit.getFarm().getCrop(i, j).getStatus() == 4))
                    {
                        spriteBatch.Draw(ProgressionBar, new Rectangle(i * (input.getSpacingTile()) + input.getTileSize() - input.getTileSize() / 3, j * (input.getSpacingTile()), input.getTileSize() / 3, input.getTileSize()), Color.White);
                        spriteBatch.Draw(ProgressionBarStatus, new Rectangle(i * (input.getSpacingTile()) + input.getTileSize() - input.getTileSize() / 4, j * (input.getSpacingTile()) + input.getTileSize() / 3, input.getTileSize() / 4, tractorUnit.getFarm().getCrop(i, j).getCropTimerBar((input.getTileSize())) + 1), Color.White);
                    }
                    if (tractorUnit.getFarm().getCrop(i, j).getStatus() != 0 && tractorUnit.getFarm().getCrop(i, j).getStatus() != 1)
                    {
                        spriteBatch.Draw(Crops[tractorUnit.getFarm().getCrop(i, j).getCropType()], new Rectangle(i * (input.getSpacingTile()) + input.getTileSize() - input.getTileSize() / 3, j * (input.getSpacingTile()), input.getTileSize() / 3, input.getTileSize() / 3), Color.White);
                    }

                }
            }
        }

        public void InspectTile()
        {
            spriteBatch.DrawString(Bold, "Crop:", new Vector2(240, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 2), Color.DarkRed);
            spriteBatch.DrawString(Bold, "Selected tile: (" + x.ToString() + ", " + y.ToString() + ")", new Vector2(240, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 22), Color.DarkBlue);
            tractorUnit.getFarm().getCrop(x, y).Inspect(input.getTileSize(), input.getSpacing(), Bold, new SpriteBatch(GraphicsDevice), cropTypesNames);
        }
    }
}