
using FlatRedBall;
using FlatRedBall.Input;
using FlatRedBall.Math.Geometry;
using Lidgren.Network;
using TomShane.Neoforce.Controls;

public enum MessageTypes2
{
    NONE,                   // None
    CHANGE_SETTINGS,          // Send game settings change 
    BEGIN_GAME               //Server has received settings, Ok to begin game
}


namespace Wizard_Duel.Screens
{
    static public class GameSettings
    {
        static public float attractorPower { get; set; }
        static public float attractorDuration { get; set; }
        static public float fireballSpeed { get; set; }
        static public float fireballDamage { get; set; }
        static public float startingHealth { get; set; }
        static public float startingMana { get; set; }
        static public float wizardSpeed { get; set; }
        static public float lightningDamage { get; set; }
        static public float lightningSpeed { get; set; }
        static public float manaRegen { get; set; }
    }

    public class NetworkScreen : Screen
    {

        // Neoforce GUI manager

        #region Methods

        int count, top = 5;
        Manager manager;
        Sprite background, cursor;
        TextBox manaRegenTxt, ipTxt, attractorTxt, attractorDurationTxt, fireballSpeedTxt, fireballDamageTxt, wizardSpeedTxt, lightningDamageTxt, lightningSpeedTxt, startingHealthTxt, startingManaTxt;
        Label label;
        Window window;
        Button button, button2;
        AxisAlignedRectangle rectangle, rectangle2, cursorrec;

        public static bool isHost
        {
            get;
            set; // could make this private if we don't want anyone but the Screen to set this
        }
        public static bool isClient
        {
            get;
            set; // could make this private if we don't want anyone but the Screen to set this
        }

        public static NetPeerConfiguration config
        {
            get;
            set; // could make this private if we don't want anyone but the Screen to set this
        }

        public static NetServer server
        {
            get;
            set; // could make this private if we don't want anyone but the Screen to set this
        }

        public static NetClient client
        {
            get;
            set; // could make this private if we don't want anyone but the Screen to set this
        }

        #region Constructor and Initialize

        public NetworkScreen()
            : base("NetworkScreen")
        {
            // Don't put initialization code here, do it in
            // the Initialize method below
            //   |   |   |   |   |   |   |   |   |   |   |
            //   |   |   |   |   |   |   |   |   |   |   |
            //   V   V   V   V   V   V   V   V   V   V   V

        }



        public override void Initialize(bool addToManagers)
        {



            // Set the screen up here instead of in the Constructor to avoid
            // exceptions occurring during the constructor.

            // The Screen even provides a content manager for us.  How nice!

            //    FlatRedBallServices.Game.IsMouseVisible = true;

            background = SpriteManager.AddSprite("Menu.jpg");
            background.PixelSize = .0173f;

            rectangle = ShapeManager.AddAxisAlignedRectangle();
            rectangle.ScaleX = 5;
            rectangle.ScaleY = 2;
            rectangle.Y = 5;
            rectangle.Visible = false;

            rectangle2 = ShapeManager.AddAxisAlignedRectangle();
            rectangle2.ScaleX = 5;
            rectangle2.ScaleY = 2;
            rectangle2.Y = -3;
            rectangle2.Visible = false;

            cursor = SpriteManager.AddSprite("cursor.png");
            cursor.PixelSize = .015f;
            cursorrec = ShapeManager.AddAxisAlignedRectangle();
            cursorrec.SetScale(cursor);
            cursorrec.AttachTo(cursor, false);
            cursor.X = InputManager.Mouse.WorldXAt(0);
            cursor.Y = InputManager.Mouse.WorldYAt(0);
            cursorrec.Visible = false;

            // Manager setup -- we use default skin and do not 
            // register manager as a component
            // AddToManagers should be called LAST in this method:


            if (addToManagers)
            {
                AddToManagers();
            }
        }

        public override void AddToManagers()
        {


        }

        #endregion

        #region Public Methods

        public override void Activity(bool firstTimeCalled)
        {

            cursor.X = InputManager.Mouse.WorldXAt(0) + 2.1F;
            cursor.Y = InputManager.Mouse.WorldYAt(0) + 1.2F;
            manager = Wizard_Duel.Game1.Manager;

            if (count != 1)
            {
                if (InputManager.Mouse.ButtonPushed(FlatRedBall.Input.Mouse.MouseButtons.LeftButton))
                {
                    if (rectangle.CollideAgainst(cursorrec))
                    {
                        FlatRedBallServices.Game.IsMouseVisible = true;
                        count++;
                        window = new Window(manager);
                        window.Init();
                        window.Text = "Network Menu";
                        window.Top = 150; // this is in pixels, top-left is the origin
                        window.Left = 250;
                        window.Width = 350;
                        window.Height = 350;

                        manager.Add(window);

                        // Create Button control and set the previous window as its parent.
                        button = new Button(manager);
                        button.Init();
                        button.Text = "Host";
                        button.Width = 72;
                        button.Height = 24;
                        button.Left = (window.ClientWidth / 2) - (button.Width / 2) - 40;
                        button.Top = window.ClientHeight - button.Height - 8;
                        button.Anchor = Anchors.Bottom;
                        button.Parent = window;
                        button.Click += new TomShane.Neoforce.Controls.EventHandler(host_Click);


                    }
                }
            }

            if (count != 1)
            {
                if (InputManager.Mouse.ButtonPushed(FlatRedBall.Input.Mouse.MouseButtons.LeftButton))
                {
                    if (rectangle2.CollideAgainst(cursorrec))
                    {
                        FlatRedBallServices.Game.IsMouseVisible = true;
                        count++;
                        window = new Window(manager);
                        window.Init();
                        window.Text = "Network Menu";
                        window.Top = 150; // this is in pixels, top-left is the origin
                        window.Left = 250;
                        window.Width = 350;
                        window.Height = 350;

                        manager.Add(window);

                        button2 = new Button(manager);
                        button2.Init();
                        button2.Text = "Join";
                        button2.Width = 72;
                        button2.Height = 24;
                        button2.Left = (window.ClientWidth / 2) - (button2.Width / 2) + 40;
                        button2.Top = window.ClientHeight - button2.Height - 8;
                        button2.Anchor = Anchors.Bottom;
                        button2.Parent = window;
                        button2.Click += new TomShane.Neoforce.Controls.EventHandler(join_Click);
                        

                        ipTxt = new TextBox(manager);
                        ipTxt.Init();
                        ipTxt.Parent = window;
                        ipTxt.Left = 5;
                        ipTxt.Top = 250;
                        ipTxt.Width = window.ClientWidth;
                        ipTxt.Height = 20;
                        ipTxt.Anchor = Anchors.Left | Anchors.Top | Anchors.Right | Anchors.Bottom;
                        ipTxt.Text = "localhost";
                        
                        wizardSpeedTxt = new TextBox(manager);
                        textFieldCreate(wizardSpeedTxt, "8");
                        label = new Label(manager);
                        LabelCreate("Wizard Speed");

                        attractorTxt = new TextBox(manager);
                        textFieldCreate(attractorTxt, "95");
                        label = new Label(manager);
                        LabelCreate("Attractor Power");

                        attractorDurationTxt = new TextBox(manager);
                        textFieldCreate(attractorDurationTxt, "20");
                        label = new Label(manager);
                        LabelCreate("Attractor Duration");

                        fireballSpeedTxt = new TextBox(manager);
                        textFieldCreate(fireballSpeedTxt, "15");
                        label = new Label(manager);
                        LabelCreate("Fireball Speed");

                        fireballDamageTxt = new TextBox(manager);
                        textFieldCreate(fireballDamageTxt, "1");
                        label = new Label(manager);
                        LabelCreate("Fireball Damage");

                        lightningDamageTxt = new TextBox(manager);
                        textFieldCreate(lightningDamageTxt, "3");
                        label = new Label(manager);
                        LabelCreate("Lightning Damage");

                        lightningSpeedTxt = new TextBox(manager);
                        textFieldCreate(lightningSpeedTxt, "20");
                        label = new Label(manager);
                        LabelCreate("Lightning Speed");

                        startingHealthTxt = new TextBox(manager);
                        textFieldCreate(startingHealthTxt, "10");
                        label = new Label(manager);
                        LabelCreate("Starting Health");

                        startingManaTxt = new TextBox(manager);
                        textFieldCreate(startingManaTxt, "10");
                        label = new Label(manager);
                        LabelCreate("Starting Mana");

                        manaRegenTxt = new TextBox(manager);
                        textFieldCreate(manaRegenTxt, "1");
                        label = new Label(manager);
                        LabelCreate("Mana Per Second");
                    }
                }
            }


            base.Activity(firstTimeCalled);
            if (isHost == true)
            {
                server_routine();
            }
            else if (isClient == true)
            {
                client_routine();
            }

        }

        public void textFieldCreate(TextBox textname, string text)
        {
            textname.Init();
            textname.Parent = window;
            textname.Left = 5;
            textname.Top = top;
            textname.Width = 50;
            textname.Height = 20;
            textname.Anchor = Anchors.Left | Anchors.Top | Anchors.Right | Anchors.Bottom;
            textname.Text = text;
        }

        public void LabelCreate(string text)
        {
            label.Init();
            label.Parent = window;
            label.Left = 70;
            label.Top = top;
            label.Height = 16;
            label.Width = 100;
            label.Text = text;
            top = top + 20;
        }

        public override void Destroy()
        {
            base.Destroy();

        }

        public void host_Click(object source, TomShane.Neoforce.Controls.EventArgs e)
        {

            window.Remove(button);

            config = new NetPeerConfiguration("WizardNetConfig");
            config.Port = 14242;
            config.MaximumConnections = 100;

            server = new NetServer(config);
            server.Start();

            isHost = true;
            window.Text = "Waiting for connection...";

        }
        public void join_Click(object source, TomShane.Neoforce.Controls.EventArgs e)
        {
            window.Remove(button2);
            window.Remove(ipTxt);

            window.Text = "Attempting to connect...";


            float myFloat = float.Parse(attractorTxt.Text);

            NetPeerConfiguration config = new NetPeerConfiguration("WizardNetConfig");
            client = new NetClient(config);


            client.Start();
            NetOutgoingMessage hail = client.CreateMessage();

            string connectIP = ipTxt.Text;

            client.Connect(connectIP, 14242);

            isHost = false;
            isClient = true;



        }


        public void server_routine()
        {
            NetIncomingMessage im;
            while ((im = server.ReadMessage()) != null)
            {
                // handle incoming message
                switch (im.MessageType)
                {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                        string text = im.ReadString();

                        break;
                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)im.ReadByte();
                        if (status == NetConnectionStatus.Connected)
                        {

                        }
                        break;
                    case NetIncomingMessageType.Data:
                        MessageTypes2 msgType = (MessageTypes2)im.ReadByte();
                        if (msgType == MessageTypes2.CHANGE_SETTINGS)
                        {
                            window.Visible = false;
                            SpriteManager.RemoveSprite(cursor);
                            ShapeManager.Remove(cursorrec);
                            ShapeManager.Remove(rectangle);
                            ShapeManager.Remove(rectangle2);
                            SpriteManager.RemoveSprite(background);



                            GameSettings.wizardSpeed = im.ReadFloat();
                            GameSettings.attractorPower = im.ReadFloat();
                            GameSettings.attractorDuration = im.ReadFloat();

                            GameSettings.fireballDamage = im.ReadFloat();
                            GameSettings.fireballSpeed = im.ReadFloat();

                            GameSettings.lightningDamage = im.ReadFloat();
                            GameSettings.lightningSpeed = im.ReadFloat();

                            GameSettings.startingHealth = im.ReadFloat();
                            GameSettings.startingMana = im.ReadFloat();
                            GameSettings.manaRegen = im.ReadFloat();
                            NetConnection player = server.Connections[0];
                            NetOutgoingMessage om = server.CreateMessage();
                            om.Write((byte)MessageTypes2.BEGIN_GAME);
                            server.SendMessage(om, player, NetDeliveryMethod.ReliableUnordered);
                            MoveToScreen(typeof(WizardSelectionScreen).FullName);
                        }
                        break;
                }
            }
        }

        public void client_routine()
        {

            NetIncomingMessage om;
            while ((om = client.ReadMessage()) != null)
            {
                //  handle incoming message
                switch (om.MessageType)
                {

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)om.ReadByte();

                        if (status == NetConnectionStatus.Connected)
                        {
                            NetOutgoingMessage om2 = client.CreateMessage();
                            om2.Write((byte)MessageTypes2.CHANGE_SETTINGS);

                            om2.Write(float.Parse(wizardSpeedTxt.Text));
                            om2.Write(float.Parse(attractorTxt.Text));
                            om2.Write(float.Parse(attractorDurationTxt.Text));
                            om2.Write(float.Parse(fireballDamageTxt.Text));
                            om2.Write(float.Parse(fireballSpeedTxt.Text));
                            om2.Write(float.Parse(lightningDamageTxt.Text));
                            om2.Write(float.Parse(lightningSpeedTxt.Text));
                            om2.Write(float.Parse(startingHealthTxt.Text));
                            om2.Write(float.Parse(startingManaTxt.Text));
                            om2.Write(float.Parse(manaRegenTxt.Text));
                            GameSettings.attractorPower = float.Parse(attractorTxt.Text);
                            GameSettings.attractorDuration = float.Parse(attractorDurationTxt.Text);
                            GameSettings.fireballDamage = float.Parse(fireballDamageTxt.Text);
                            GameSettings.fireballSpeed = float.Parse(fireballSpeedTxt.Text);
                            GameSettings.wizardSpeed = float.Parse(wizardSpeedTxt.Text);
                            GameSettings.lightningDamage = (float.Parse(lightningDamageTxt.Text));
                            GameSettings.lightningSpeed = (float.Parse(lightningSpeedTxt.Text));
                            GameSettings.startingHealth = (float.Parse(startingHealthTxt.Text));
                            GameSettings.startingMana = (float.Parse(startingManaTxt.Text));
                            GameSettings.manaRegen = (float.Parse(manaRegenTxt.Text));
                            client.SendMessage(om2, NetDeliveryMethod.ReliableUnordered);

                        }
                        break;
                    case NetIncomingMessageType.Data:
                        MessageTypes2 msgType = (MessageTypes2)om.ReadByte();
                        if (msgType == MessageTypes2.BEGIN_GAME)
                        {
                            window.Visible = false;
                            SpriteManager.RemoveSprite(cursor);
                            ShapeManager.Remove(cursorrec);
                            ShapeManager.Remove(rectangle);
                            ShapeManager.Remove(rectangle2);
                            SpriteManager.RemoveSprite(background);

                            MoveToScreen(typeof(WizardSelectionScreen).FullName);
                        }
                        break;
                }
            }
        }
        #endregion
        #endregion
    }
}
