using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Administration
{
    public partial class MainForm : Form
    {
        private delegate void ProcessMessageDelegate();
        private PlayerForm playerForm;
        private ShipForm shipForm;
        private AddRealmForm addRealmForm;
        ClientCommunicator communicator = ClientCommunicator.Instance;

        public MainForm()
        {
            InitializeComponent();

            communicator.MessageAcceptedEvent += new ClientCommunicator.MessageAcceptedEventHandler(OnAcceptMessage);
        }

        private void MainForm_CloseOnStart(object sender, EventArgs e)
        {
            if (communicator != null)
            {
                communicator.Disconnect();
            }

            this.Close();
        }

        public void OnApplicationExit(object sender, EventArgs e)
        {
            if (communicator != null)
            {
                communicator.Disconnect();
            }
        }

        private void OnAcceptMessage()
        {
            if (Disposing || IsDisposed)
            {
                return;
            }

            if (InvokeRequired)
            {
                Invoke(new ProcessMessageDelegate(ProcessMessage));
            }
            else
            {
                ProcessMessage();
            }
        }

        private void ProcessMessage()
        {
            MessageWrapper message = communicator.ProcessNextMessage();

            switch (message.messageName)
            {
                case Requests.REQUEST_ADMIN_PLAYERS:
                    answerPlayers((PlayersAnswer)message.messageData);
                    break;

                case Requests.REQUEST_ADMIN_PLAYER_INFORMATION:
                    asnwerPlayerInformation((PlayerInformationAnswer)message.messageData);
                    break;
                case Requests.REQUEST_ADMIN_SHIP_INFORMATION:
                    answerShipInformation((ShipInformationAnswer)message.messageData);
                    break;

                case Requests.REQUEST_ADMIN_PLAYER_BAN_INFORMATION:
                    answerBanInformation((PlayerBanInformationAnswer)message.messageData);
                    break;

                case Requests.REQUEST_ADMIN_BAN_PLAYER:
                    answerBanPlayer((BanPlayerAnswer)message.messageData);
                    break;

                case Requests.REQUEST_ADMIN_ADD_REALM:
                    answerAddRealm((AddRealmAnswer)message.messageData);
                    break;

                case Requests.REQUEST_ADMIN_LOGIN:
                    mainTab.SelectedTab = playersTab;  
                    communicator.SendMessage(new PlayersRequest());
                    MessageBox.Show("Přihlášení do administrace proběhlo úspěšně", "Přihlášení do administrace");
                    break;
            }
        }

        private void answerPlayers(PlayersAnswer answer)
        {
            findPlayerControl.SetupFromPlayersList(answer.player);
        }

        private void asnwerPlayerInformation(PlayerInformationAnswer answer)
        {
            if (playerForm == null || playerForm.IsDisposed)
            {
                playerForm = new PlayerForm();
            }

            playerForm.SetState(answer);
            playerForm.Show();
        }

        private void answerShipInformation(ShipInformationAnswer answer)
        {
            if (shipForm == null || shipForm.IsDisposed)
            {
                shipForm = new ShipForm();
            }

            shipForm.SetState(answer);
            shipForm.Show();
        }

        private void answerBanInformation(PlayerBanInformationAnswer answer)
        {
            if (playerForm != null && playerForm.Visible)
            {
                playerForm.setBanState(answer);
            }
        }

        private void answerBanPlayer(BanPlayerAnswer answer)
        {
            if (playerForm != null)
            {
                playerForm.SetBanResult(answer);
            }
        }

        private void mainTab_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (mainTab.SelectedIndex == 0)
            {
                communicator.SendMessage(new PlayersRequest());
            }
        }

        private void addRealmButton_Click(object sender, EventArgs e)
        {
            if (addRealmForm == null || addRealmForm.IsDisposed)
            {
                addRealmForm = new AddRealmForm();
            }

            addRealmForm.Show();
        }

        private void answerAddRealm(AddRealmAnswer answer)
        {
            switch (answer.player_adding_result)
            {
                case Constants.PROTOCOL_PAR_OK:
                    ClientCommunicator.Instance.SendMessage(new PlayersRequest());
                    MessageBox.Show("Přidání hráče proběhlo úspěšně", "Přidání hráče");
                    break;
                case Constants.PROTOCOL_PAR_NAME_ALREADY_EXISTS:
                    MessageBox.Show("Přidání hráče se nezdařilo, hráč se zadaným skutečným jménem už existuje", "Přidání hráče");
                    break;
                case Constants.PROTOCOL_PAR_LOGIN_ALREADY_EXISTS:
                    MessageBox.Show("Přidání hráče se nezdařilo, hráč se zadaným loginem už existuje", "Přidání hráče");
                    break;
                case Constants.PROTOCOL_PAR_INTERNAL_ERROR:
                    MessageBox.Show("Přidání hráče se nezdařilo, interní chyba serveru", "Přidání hráče");
                    break;
            }
        }

        private void loginButton_Click(object sender, EventArgs e)
        {
            int port;

            try
            {
                port = int.Parse(portEdit.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Zadaný port není platný", "Neplatný port");
                return;
            }

            try
            {
                if (ClientCommunicator.Instance.IsActive)
                {
                    ClientCommunicator.Instance.Disconnect();
                }

                ClientCommunicator.Instance.Connect(serverEdit.Text, port);
                ClientCommunicator.Instance.SendMessage(new LoginRequest() { player_login = loginEdit.Text, player_password = passwordEdit.Text });

            }
            catch (Exception ex)
            {
                MessageBox.Show("Připojení k serveru se nezdařilo.\n\n" + ex.Message, "Problém s připojením");
            }
        }
    }
}
