using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenTK;

namespace Fuseren
{
#if !__MonoCS__
    class DoublebufferedForm : Form
    {
        public DoublebufferedForm()
        {
            SetStyle(ControlStyles.DoubleBuffer | 
                ControlStyles.UserPaint | 
                ControlStyles.AllPaintingInWmPaint,
                true);
            UpdateStyles();
        }
    }
#endif

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            var interop = new Interop.InteropService("Fuseren", -1, "127.0.0.1", 31337);
			AIEngine aiEngine = null;
			try
			{
            	aiEngine = new AIEngine(interop);
			}
			catch(Exception e) {
				Console.WriteLine (e.Message);
				Environment.Exit(0);
			}

            Task.Run(
                () =>
                {
                    while (true)
                    {
                        try
                        {
                            aiEngine.Run();
                            Thread.Sleep(13);
                        }
                        catch (Exception e)
                        {
                            var aggregateException = e as AggregateException;
                            if (aggregateException != null)
                            {
                                foreach (var innerException in aggregateException.InnerExceptions)
                                    Console.WriteLine(innerException.Message);
                            }
                            else
                            {
                                Console.WriteLine(e.Message);
                            }
                        }
                    }
                });
#if __MonoCS__
			while (true) {
			}
#endif
#if !__MonoCS__
            var form = new DoublebufferedForm();

            form.Paint += (s, e) =>
            {                    
                var bitmap = aiEngine.CurrentBitmap;
                if (bitmap == null)
                    return;

                var gpu = e.Graphics;
				gpu.ScaleTransform(0.6f, 0.6f);
                gpu.DrawImage(
					bitmap,
                    0,
                    0);

                var state = aiEngine.OldState;
                var endPos = state.Position + state.Direction;
                gpu.DrawLine(new Pen(Color.Blue, 5), (float)state.Position.X, (float)state.Position.Y, (float)endPos.X, (float)endPos.Y);

                if (state.Path != null)
                {
                    var rectangles = new List<Rectangle>();
	                var copyPath = state.Path.ToArray();
					foreach (var tile in copyPath)
                    {
                        rectangles.Add(new Rectangle(tile.X * 128, tile.Y * 128, tile.X + 128, tile.Y + 128));
                    }

                    if(rectangles.Count > 0)
                        gpu.DrawRectangles(new Pen(Color.Cyan), rectangles.ToArray());
                }					
            };

            Application.Idle += (sender, eventArgs) =>
            {
                form.Invalidate();
                Thread.Sleep(16);
            }; 

            Application.EnableVisualStyles();
            Application.Run(form);
#endif
        }
    }
}
