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

using EQNetwork;
using EQNetwork.Objects;
using EQNetwork.Services;
using EQNetwork.Utility;
using EQNetwork.Controllers;

namespace jdi_sdk_csharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBoxUsername.Text = "BrianARice";
            textBoxPassword.Text = "f00tball";
            UpdateUserStatus(LoginState.NotLoggedIn);

            ATest();

            Login();
        }

        EQProcess _eq = new EQProcess("accesskey", "secret");

        public enum LoginState
        {
            NotLoggedIn,
            LoggingIn,
            LoggedIn,
        };
        LoginState _loginState = LoginState.NotLoggedIn;

        string message = null;
        
        void ATest()
        {
            EQProcess eq = new EQProcess("accesskey", "secret");

            eq.SessionService.Create("BrianARice", "f00tball",
                (Session session, EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        eq.MiscService.ContentMenu_List(null,
                            (List<ContentMenu> contentMenus, DateTime? maxModified, EQException ex2) => // onComplete
                            {
                                if (ex == null)
                                    message = "success";
                                else
                                    message = ex2.Message;
                            }
                        );
                    }
                    else 
                        message = ex.Message;
                }
            );


            while (message == null)
                System.Threading.Thread.Sleep(100);

        }

        void Login()
        {
            UpdateUserStatus(LoginState.LoggingIn);
            _eq.SessionService.Create(textBoxUsername.Text, textBoxPassword.Text,
                (Session session, EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        UpdateUserStatus(LoginState.LoggedIn);
                        ListCollections();
                    }
                    else
                    {
                        UpdateUserStatus(LoginState.NotLoggedIn);
                        HandleException("SessionService.Create", ex);
                    }
                }
            );
        }

        void Logout()
        {
            _eq.Session = null;
            UpdateUserStatus(LoginState.NotLoggedIn);
        }

        void UpdateUserStatus(LoginState loginState)
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => UpdateUserStatus(loginState))); return; }

            _loginState = loginState;
            switch (loginState)
            {
                case LoginState.NotLoggedIn:
                    labelCurrentUser.Text = "Not Logged In";
                    buttonLogin.Text = "Login";
                    pictureBoxUserActivity.Visible = false;
                    break;
                case LoginState.LoggingIn:
                    labelCurrentUser.Text = "Logging In...";
                    buttonLogin.Text = "";
                    pictureBoxUserActivity.Visible = true;
                    break;
                case LoginState.LoggedIn:
                    labelCurrentUser.Text = "Logged in as " + _eq.Session.User.Username;
                    buttonLogin.Text = "Logout";
                    pictureBoxUserActivity.Visible = false;
                    break;
            }
            UpdateCollections();
        }

        User_ListCollections_Controller _user_ListCollections_Controller = null;

        public void UpdateCollections()
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => UpdateCollections())); return; }

            buttonMoreCollections.Enabled = (_loginState == LoginState.LoggedIn && _user_ListCollections_Controller != null && _user_ListCollections_Controller.HasMore == true);
            if (_loginState != LoginState.LoggedIn)
                ClearCollections();

            UpdateContentFiles();
        }

        public void ListCollections()
        {
            ClearCollections();

            _user_ListCollections_Controller = new User_ListCollections_Controller(_eq);
            _user_ListCollections_Controller.PagingParameters =
                new PagingParameters
                {
                    PageSize = 5,
                    OrderBy = ListCollectionsContext.SortOrder.Alpha.ToString(),
                };

            _user_ListCollections_Controller.Start(
                (EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        ShowCollections(_user_ListCollections_Controller);
                        UpdateCollections();
                    }
                    else
                    {
                        HandleException("_user_ListCollections_Controller.Start", ex);
                    }
                }
            );

            UpdateCollections();
        }

        public void MoreCollections()
        {
            _user_ListCollections_Controller.More(
                (EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        ShowCollections(_user_ListCollections_Controller);
                        UpdateCollections();
                    }
                    else
                    {
                        HandleException("_user_ListCollections_Controller.More", ex);
                    }
                }
            );

            UpdateCollections();
        }

        public void ClearCollections()
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => ClearCollections())); return; }

            listBoxCollections.Items.Clear();

            _collection_ListContentFiles_Controller = null;
            UpdateContentFiles();
        }

        public void ShowCollections(User_ListCollections_Controller controller)
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => ShowCollections(controller))); return; }

            // only add new ones
            for (int i = listBoxCollections.Items.Count; i < controller.Collections.Count; i++)
            {
                listBoxCollections.Items.Add(controller.Collections[i]);
            }
        }

        Collection_ListContentFiles_Controller _collection_ListContentFiles_Controller;

        public void UpdateContentFiles()
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => UpdateContentFiles())); return; }

            buttonMoreContentFiles.Enabled = (_loginState == LoginState.LoggedIn && _collection_ListContentFiles_Controller != null && _collection_ListContentFiles_Controller.HasMore == true);
            if (_loginState != LoginState.LoggedIn)
                ClearContentFiles();
        }

        public void ListContentFiles(Collection collection)
        {
            ClearContentFiles();

            if (collection == null)
                return;

            _collection_ListContentFiles_Controller = new Collection_ListContentFiles_Controller(_eq, (int)collection.CollectionId);
            _collection_ListContentFiles_Controller.PagingParameters =
                new PagingParameters
                {
                    PageSize = 5,
                    OrderBy = ListCollectionsContext.SortOrder.Alpha.ToString(),
                };

            _collection_ListContentFiles_Controller.Start(
                (EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        ShowContentFiles(_collection_ListContentFiles_Controller);
                        UpdateContentFiles();
                    }
                    else
                    {
                        HandleException("_collection_ListContentFiles_Controller.Start", ex);
                    }
                }
            );

            UpdateContentFiles();
        }

        public void MoreContentFiles()
        {
            _collection_ListContentFiles_Controller.More(
                (EQException ex) => // onComplete
                {
                    if (ex == null)
                    {
                        ShowContentFiles(_collection_ListContentFiles_Controller);
                        UpdateCollections();
                    }
                    else
                    {
                        HandleException("_collection_ListContentFiles_Controller.More", ex);
                    }
                }
            );

            UpdateContentFiles();
        }

        public void ClearContentFiles()
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => ClearContentFiles())); return; }

            listBoxContentFiles.Items.Clear();
        }

        public void ShowContentFiles(Collection_ListContentFiles_Controller controller)
        {
            // must be on UI thread
            if (InvokeRequired) { BeginInvoke(new MethodInvoker(() => ShowContentFiles(controller))); return; }

            // only add new ones
            for (int i = listBoxContentFiles.Items.Count; i < controller.ContentFiles.Count; i++)
            {
                listBoxContentFiles.Items.Add(controller.ContentFiles[i]);
            }
        }

        private void HandleException(string title, Exception ex)
        {
            if (ex.GetType() == typeof(EQException))
            {
                int code = ((EQException)ex).Code;

                MessageBox.Show("Code = " + code + "; " + ex.Message, title);
            }
            else
            {
                MessageBox.Show(ex.Message, title);
            }
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            if (_loginState == LoginState.NotLoggedIn)
                Login();
            else if (_loginState == LoginState.LoggedIn)
                Logout();
        }

        private void buttonMoreCollections_Click(object sender, EventArgs e)
        {
            MoreCollections();
        }

        private void listBoxCollections_SelectedIndexChanged(object sender, EventArgs e)
        {
            Collection collection = (Collection)listBoxCollections.SelectedItem;
            ListContentFiles(collection);
        }

        private void buttonMoreContentFiles_Click(object sender, EventArgs e)
        {
            MoreContentFiles();
        }


    }
}
