using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using SdlDotNet;
using SdlDotNet.Graphics;
using SdlDotNet.Graphics.Sprites;
using SdlDotNet.Core;
using SdlDotNet.Input;


namespace ProjectKraehwinkel
{
    //Klasse, die das Spielfeld verwaltet und auch zeichnet evtl ohne die Gebäude direkt zu kennen
    class Spielfeld
    {
        private Surface m_VideoSurface;
        private bool[] m_CursorKeys = new bool[4];

        Size WorldSize, ViewSize, TileSize;
        Point ViewPos;

        public Tile[,] karte;
        private Surface test;

        public Point Selected;
        Menue menue;
        MenueSpieler menueSp;

       public  Stadt stadt;

        int counter;
        bool machen;

        enum CursorKeys
        {
            Up, Down, Left, Right
        }

        public Spielfeld()
        {
            counter = 0;
            machen = true;
            
            //Spielfeldwerte
            ViewSize.Width = 500;
            ViewSize.Height = 300;
            WorldSize.Height = 800;
            WorldSize.Width = 2000;
            TileSize.Height = 50;
            TileSize.Width = 50;
            ViewPos.X = 0;
            ViewPos.Y = 0;
            Selected.X = 0;
            Selected.Y = 0;
          
            SdlDotNet.Core.Events.Fps = 60;

            //Stadt erstellen
            stadt = new Stadt(200);
            menue = new Menue(new Size(200, 180), stadt, this);
            menueSp = new MenueSpieler(new Size(200, 120), stadt, this);


            //karte
            karte = new Tile[WorldSize.Width / TileSize.Width, WorldSize.Height / TileSize.Height];

            m_VideoSurface = Video.SetVideoMode(ViewSize.Width + menue.MenueSize.Width, ViewSize.Height, false, false, false, true);
            SdlDotNet.Core.Events.Tick += new EventHandler<TickEventArgs>(Events_Tick);
            SdlDotNet.Core.Events.Quit += new EventHandler<QuitEventArgs>(Events_Quit);
            SdlDotNet.Core.Events.KeyboardDown += new EventHandler<KeyboardEventArgs>(Events_KeyDown);
            SdlDotNet.Core.Events.KeyboardUp += new EventHandler<KeyboardEventArgs>(Events_KeyDown);
            SdlDotNet.Core.Events.MouseButtonDown += new EventHandler<MouseButtonEventArgs>(Events_MouseDown);
            test = new Surface(50, 50);
            test.Fill(Color.Green);
            SdlDotNet.Graphics.Primitives.Box box;
            box = new SdlDotNet.Graphics.Primitives.Box(0, 0, 49, 49);
            test.Draw(box, Color.Black);

            for (int i = 0; i < karte.GetLength(0); i++)
                for (int j = 0; j < karte.GetLength(1); j++)
                    karte[i, j] = new Tile(test,null);

            //Bauen Stadt zusammen
            stadt.Oberschicht.Add(new Buerger("Adam", 1000));
            stadt.Oberschicht.Add(new Buerger("Berta", 1000));
            stadt.Oberschicht.Add(new Buerger("Carola", 1000));
            stadt.Oberschicht[0].Besitz.Add(new Fabrik(new Point(3, 3), Gebaeudearten.Saegewerk, this, stadt.Oberschicht[0]));
            stadt.Oberschicht[1].Besitz.Add(new Fabrik(new Point(3, 6), Gebaeudearten.Bauernhof, this, stadt.Oberschicht[0]));
            stadt.Oberschicht[2].Besitz.Add(new Fabrik(new Point(8, 7), Gebaeudearten.Eisenschelze, this, stadt.Oberschicht[1]));

            stadt.Haeuser.Add(new Wohnung(new Point(2,2),20,this));
            stadt.Haeuser.Add(new Wohnung(new Point(4,4), 20,this));
            stadt.Haeuser.Add(new Wohnung(new Point(5,9), 20,this));
            stadt.Haeuser.Add(new Wohnung(new Point(1,5), 20,this));
            stadt.Haeuser.Add(new Wohnung(new Point(6,7), 20,this));

            karte[3, 5] = new Tile(new Surface(grafic.Kirche as Bitmap), new Kirche());
            karte[5, 5] = new Tile(new Surface(grafic.Markt as Bitmap), new Marktbuilding());

            SdlDotNet.Core.Events.Run();
        }

        //Events
        private void Events_Tick(object sender, TickEventArgs e)
        {
            m_VideoSurface.Fill(Color.White);

            if (machen == true && counter == 200)
            {
                stadt.RundeBeenden();
                counter = 0;
            }

            counter++;


            if (m_CursorKeys[(int)CursorKeys.Up] == true)
            {
               if(ViewPos.Y>0)
                  ViewPos.Y -= 2;
            }

            if (m_CursorKeys[(int)CursorKeys.Down] == true)
            {
               if(ViewPos.Y + ViewSize.Height < WorldSize.Height-3)
                  ViewPos.Y += 2;
            }

            if (m_CursorKeys[(int)CursorKeys.Left] == true)
            {
                if(ViewPos.X > 0)
                   ViewPos.X -= 2;
            }

            if (m_CursorKeys[(int)CursorKeys.Right] == true)
            {
                if (ViewPos.X + ViewSize.Width < WorldSize.Width-3)
                    ViewPos.X += 2;
            }

            Surface Anzeige = new Surface(ViewSize.Width + menue.MenueSize.Width, ViewSize.Height);
            
            Anzeige.Blit(GetViewSpace(new Point(ViewPos.X, ViewPos.Y), ViewSize),new Point(0,0),new Rectangle(0,0,ViewSize.Width,ViewSize.Height));
            Anzeige.Blit(menue.draw(),new Point(ViewSize.Width, 0),new Rectangle(new Point(0,0),menue.MenueSize));
            Anzeige.Blit(menueSp.draw(),new Point(ViewSize.Width,180),new Rectangle(new Point(0,0),new Size(200,120)));

            m_VideoSurface.Blit(Anzeige);

            // Update the screen
            Video.Screen.Update();
        }

        private void Events_Quit(object sender, QuitEventArgs e)
        {
            SdlDotNet.Core.Events.QuitApplication();
        }

        private void Events_KeyDown(object sender, KeyboardEventArgs e)
        {
            switch (e.Key)
            {
                case Key.UpArrow:
                    m_CursorKeys[(int)CursorKeys.Up] = e.Down;
                    break;

                case Key.DownArrow:
                    m_CursorKeys[(int)CursorKeys.Down] = e.Down;
                    break;

                case Key.LeftArrow:
                    m_CursorKeys[(int)CursorKeys.Left] = e.Down;
                    break;

                case Key.RightArrow:
                    m_CursorKeys[(int)CursorKeys.Right] = e.Down;
                    break;
            }
        }

        private void Events_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Position.X < ViewSize.Width && e.Position.Y < ViewSize.Height)
            {
                Selected.X = (e.Position.X + ViewPos.X) / 50;
                Selected.Y = (e.Position.Y + ViewPos.Y) / 50;
            }

            if (karte[Selected.X, Selected.Y].inhalt != null)
            {
                menue.Aktuell = karte[Selected.X, Selected.Y].inhalt.Menuetyp;
            }
            else
            {
                menue.Aktuell = MenueAnzeige.Bauflaeche;
            }

            //Menues
            if (e.Position.X > ViewSize.Width)
            {
                //Menue
                if (e.Position.Y < 180)
                {
                   menue.Clicked(e.Position.X - ViewSize.Width,e.Position.Y);
                }

                //MenueSpieler
                if (e.Position.Y > 180)
                {
                    menueSp.Clicked(e.Position.X - ViewSize.Width, e.Position.Y - 180);
                }
            }
        }

        public void end()
        {
             SdlDotNet.Core.Events.QuitApplication();
        }

        //Diese Methode ist stark an das Tutorial angelehnt
        public Surface GetViewSpace(Point offset, Size viewSize)
        {
            Surface viewspace = new Surface(viewSize.Width, viewSize.Height);

            Point startTile = new Point(offset.X / 50, offset.Y / 50);
            Point endTile = new Point((offset.X + viewSize.Width) / 50, (offset.Y + viewSize.Height) / 50);
            int offsetX = offset.X % 50;
            int offsetY = offset.Y % 50;


            for (int y = startTile.Y, yCnt = 0; y <= endTile.Y; y++, yCnt++)
            {
                for (int x = startTile.X, xCnt = 0; x <= endTile.X; x++, xCnt++)
                {
                    if (Selected.X == x && Selected.Y == y)
                    {
                        Surface temp = new Surface(karte[x, y].Surface);                  
                        SdlDotNet.Graphics.Primitives.Box box;
                        box = new SdlDotNet.Graphics.Primitives.Box(0, 0, 49, 49);
                        temp.Draw(box, Color.Blue);
                        box = new SdlDotNet.Graphics.Primitives.Box(1, 1, 48, 48);
                        temp.Draw(box, Color.Blue);
                        viewspace.Blit(
                          temp,
                          new Point(offsetX >= 0 ? (50 - offsetX) + ((xCnt - 1) * 50) : (50 - offsetX) * (xCnt * 50),
                                    offsetY >= 0 ? (50 - offsetY) + ((yCnt - 1) * 50) : (50 - offsetY) * (yCnt * 50)),
                          new Rectangle(0, 0, 50, 50));
                    }
                    else
                    {
                        viewspace.Blit(
                            karte[x, y].Surface,
                            new Point(offsetX >= 0 ? (50 - offsetX) + ((xCnt - 1) * 50) : (50 - offsetX) * (xCnt * 50),
                                      offsetY >= 0 ? (50 - offsetY) + ((yCnt - 1) * 50) : (50 - offsetY) * (yCnt * 50)),
                            new Rectangle(0, 0, 50, 50));
                    }
                }
            }
            return viewspace;
        }
  
    }
}
