using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using FizzyLauncher.Models;
using FizzyLauncher.Windows.Forms;
using RyzStudio.Windows.Forms;
using RyzStudio.Windows.ThemedForms.ButtonTextBox;
using RyzStudio.Windows.TileForms;

namespace FizzyLauncher
{
    public partial class MainForm : Form
    {
        //protected OptionsForm optionsForm = null;
        protected string sessionFilename = null;
        protected bool isBusy = false;
        protected bool requestExit = false;

        private readonly FileSessionManager _fileSessionManager;

        public MainForm()
        {
            InitializeComponent();

            _fileSessionManager = new FileSessionManager();
            _fileSessionManager.SessionFilename = sessionFilename;
            _fileSessionManager.OpenFileDialog = openFileDialog1;
            _fileSessionManager.SaveFileDialog = saveFileDialog1;
            _fileSessionManager.OnNewSession += fileSessionManager_OnNewSession;
            _fileSessionManager.OnLoadSession += fileSessionManager_OnLoadSession;
            _fileSessionManager.OnSaveSession += fileSessionManager_OnSaveSession;
            _fileSessionManager.OnClearSession += fileSessionManager_OnClearSession;

            //tileContainer1.OnColumnSizeChanged += tileContainer1_OnSizeChanged;
            notifyIcon1.Text = System.Windows.Forms.Application.ProductName;

            this.AutoScaleMode = AutoScaleMode.None;
            this.StartPosition = FormStartPosition.WindowsDefaultBounds;
            this.Visible = false;
        }


        #region File session manager

        private void fileSessionManager_OnNewSession(FileSessionManager sender)
        {
            var form = new NewForm();
            if (form.ShowDialog() == DialogResult.OK)
            {
                var result = form.Result;

                UIControl.Clear(flowLayoutPanel1);

                for (var i = 0; i < result.GroupCount; i++)
                {
                    AddNewTileGroup();
                }
            }

            sessionFilename = sender.SessionFilename;
            UIControl.SetText(this, System.Windows.Forms.Application.ProductName);
        }

        private async Task<bool> fileSessionManager_OnLoadSession(FileSessionManager sender, string filename)
        {
            return await Task.Run(async () =>
            {
                this.CurrentSession = RyzStudio.Text.Json.JsonSerialiser.DeserialiseFile<LauncherSession>(filename);
                if (this.CurrentSession == null)
                {
                    MessageBox.Show("Unable to read session", "Load session");

                    return false;
                }

                if (this.CurrentSession == null)
                {
                    this.CurrentSession = new LauncherSession();
                }

                UIControl.SetText(this, Path.GetFileNameWithoutExtension(sessionFilename) + " - " + System.Windows.Forms.Application.ProductName);

                // Reposition + resize
                if (!this.CurrentSession.StartPosition.IsEmpty)
                {
                    UIControl.SetLocation(this, this.CurrentSession.StartPosition);
                }

                if (this.CurrentSession.Height > 0)
                {
                    UIControl.SetClientHeight(this, this.CurrentSession.Height);
                }

                InvalidateOptions();

                // Load tiles
                await LoadTileGroups(this.CurrentSession.Groups);

                sessionFilename = sender.SessionFilename;

                UIControl.SetVisible(this, true);
                UIControl.SetFocus(this);

                return true;
            });
        }

        private async Task<bool> fileSessionManager_OnSaveSession(FileSessionManager sender, string filename, bool showNotices)
        {
            if (string.IsNullOrWhiteSpace(filename))
            {
                return false;
            }

            if (!flowLayoutPanel1.Controls.OfType<TileContainer>().Any())
            {
                return true;
            }

            return await Task.Run(() =>
            {
                if (isBusy)
                {
                    return false;
                }

                isBusy = true;

                // update session
                if (this.CurrentSession == null)
                {
                    this.CurrentSession = new LauncherSession();
                }

                this.CurrentSession.StartPosition = this.Location;
                this.CurrentSession.Height = this.Height;
                //this.CurrentSession.AlwaysOnTop = this.TopMost;

                this.CurrentSession.Groups = new List<TileGroupModel>();
                foreach (var container in flowLayoutPanel1.Controls.OfType<RyzStudio.Windows.TileForms.TileContainer>())
                {
                    this.CurrentSession.Groups.Add(container.Tag as TileGroupModel);
                }

                var result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession);
                if (result.IsSuccess)
                {
                    if (showNotices)
                    {
                        MessageBox.Show("Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                else
                {
                    MessageBox.Show(result.Message, "Save session");

                    isBusy = false;

                    return false;
                }

                sessionFilename = sender.SessionFilename;
                UIControl.SetText(this, Path.GetFileNameWithoutExtension(sessionFilename) + " - " + System.Windows.Forms.Application.ProductName);

                isBusy = false;

                return true;
            });
        }

        private async Task fileSessionManager_OnClearSession(FileSessionManager sender)
        {
            await Task.Run(() =>
            {
                UIControl.Clear(flowLayoutPanel1);

                sessionFilename = sender.SessionFilename;

                UIControl.SetText(this, System.Windows.Forms.Application.ProductName);
            });
        }

        #endregion


        //protected override void OnLoad(EventArgs e)
        //{
        //    base.OnLoad(e);

        //    //UIControl.SetSize(this, this.MinimumSize);
        //}

        protected async override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            var args = RyzStudio.Windows.Forms.Application.GetCommandLine();

            string jsonfigFilename = args.Where(x => (x.Key.Equals("o") || x.Key.Equals("open"))).Select(x => x.Value).FirstOrDefault();
            if (string.IsNullOrWhiteSpace(jsonfigFilename))
            {
                jsonfigFilename = Path.ChangeExtension(System.Windows.Forms.Application.ExecutablePath, "jsonfig");
            }

            if (!string.IsNullOrWhiteSpace(jsonfigFilename) && File.Exists(jsonfigFilename))
            {
                await _fileSessionManager.OpenSession(jsonfigFilename);

                sessionFilename = _fileSessionManager.SessionFilename;
            }
            else
            {
                this.CurrentSession = new LauncherSession();

                UIControl.SetVisible(this, true);
            }
        }

        protected async override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            if (this.CurrentSession == null)
            {
                this.CurrentSession = new LauncherSession();
            }

            if (this.CurrentSession.HideOnClose && !requestExit)
            {
                this.Visible = !this.Visible;
                e.Cancel = true;
                return;
            }

            requestExit = false;

            await _fileSessionManager.CloseSession();

            sessionFilename = _fileSessionManager.SessionFilename;

            //if (string.IsNullOrWhiteSpace(sessionFilename))
            //{
            //    // do nothing
            //}
            //else
            //{

                //if (this.CurrentSession.AutoSave == LauncherSession.AutoSaveOption.Prompt)
                //{
                    //DialogResult dr = MessageBox.Show("Save existing session?", "Exit", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    //if (dr == DialogResult.Yes)
                    //{
                    //    bool rv = saveFile(sessionFilename, false);
                    //    if (!rv)
                    //    {
                    //        e.Cancel = true;
                    //    }
                    //}
                    //else if (dr == DialogResult.No)
                    //{
                    //    // do nothing
                    //}
                    //else if (dr == DialogResult.Cancel)
                    //{
                    //    e.Cancel = true;
                    //}
                //}
                //else if (this.CurrentSession.AutoSave == LauncherSession.AutoSaveOption.Yes)
                //{
                //    saveFile(sessionFilename, false);
                //}
            //}

            if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None)
            {
#if !DEBUG
                RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1);
#endif
            }

        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case RyzStudio.Runtime.InteropServices.User32.WM_HOTKEY:
                    if (m.WParam.ToInt32() == 1)
                    {
                        this.Visible = !this.Visible;
                    }

                    break;
                case RyzStudio.Runtime.InteropServices.User32.WM_QUERYENDSESSION:
                    requestExit = true;
                    //this.Close();
                    System.Windows.Forms.Application.Exit();

                    break;
                default:
                    break;
            }

            base.WndProc(ref m);
        }


        public LauncherSession CurrentSession { get; set; } = null;


        public void Clear()
        {
            UIControl.Clear(flowLayoutPanel1);

            sessionFilename = null;
        }


        //protected async Task collapseWindow(int width, int increment = 6)
        //{
        //    await Task.Run(() =>
        //    {
        //        while (this.Width > width)
        //        {
        //            UIControl.SetWidth(this, (this.Width - increment));

        //            System.Windows.Forms.Application.DoEvents();
        //        }

        //        UIControl.SetWidth(this, width);
        //    });
        //}

        //protected async Task expandWindow(int width, int increment = 8)
        //{
        //    await Task.Run(() =>
        //    {
        //        while (this.Width < width)
        //        {
        //            UIControl.SetWidth(this, (this.Width + increment));

        //            System.Windows.Forms.Application.DoEvents();
        //        }

        //        UIControl.SetWidth(this, width);
        //    });
        //}

//        protected void invalidateHotKey()
//        {
//#if !DEBUG
//            UIControl.Invoke(this, (x) =>
//            {
//                RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1);
//            });

//            if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None)
//            {
//                UIControl.Invoke(this, (x) =>
//                {
//                    RyzStudio.Runtime.InteropServices.User32.RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.HotKey.ModifierCode, this.CurrentSession.HotKey.Key);
//                });
//            }
//#endif
//        }

        //protected void newSession()
        //{
        //    var form = new NewForm();
        //    if (form.ShowDialog() == DialogResult.OK)
        //    {
        //        var result = form.Result;

        //        flowLayoutPanel1.Controls.Clear();

        //        for (var i = 0; i < result.GroupCount; i++)
        //        {
        //            AddNewTileGroup();
        //        }
        //    }
        //}

        //protected async Task loadFile(string filename)
        //{
        //    //await Task.Run(async () =>
        //    //{
        //    if (isBusy)
        //    {
        //        return;
        //    }

        //    this.CurrentSession = RyzStudio.Text.Json.JsonSerialiser.DeserialiseFile<LauncherSession>(filename);
        //    if (this.CurrentSession == null)
        //    {
        //        MessageBox.Show("Unable to read session", "Load session");
        //        return;
        //    }

        //    if (this.CurrentSession == null)
        //    {
        //        this.CurrentSession = new LauncherSession();
        //    }

        //    InvalidateOptions();

        //    // load tiles
        //    //tileContainer1.Load(this.CurrentSession.Groups);
        //    await LoadTileGroups(this.CurrentSession.Groups);

        //    // reposition
        //    //if (!this.CurrentSession.StartPosition.IsEmpty)
        //    //{
        //        //UIControl.SetLocation(this, this.CurrentSession.StartPosition);
        //    //}

        //    //
        //    //UIControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop);
        //    UIControl.SetVisible(this, true);
        //    //UIControl.SetChecked(showBigIconsToolStripMenuItem, this.CurrentSession.EnableBigIconInFolder);
        //    //UIControl.SetClientHeight(this, this.CurrentSession.DefaultHeight);

        //    UIControl.SetFocus(this);

        //    // hotkey
        //    //invalidateHotKey();

        //    //});
        //}

        //protected bool saveFile(string filename, bool showNotices = true)
        //{
        //    if (isBusy)
        //    {
        //        return false;
        //    }

        //    if (string.IsNullOrWhiteSpace(filename))
        //    {
        //        return false;
        //    }

        //    //if (tileContainer1.GroupCount <= 0)
        //    //{
        //    //    return true;
        //    //}

        //    isBusy = true;

        //    // update session
        //    if (this.CurrentSession == null)
        //    {
        //        this.CurrentSession = new LauncherSession();
        //    }

        //    this.CurrentSession.Height = this.Height;
        //    //this.CurrentSession.AlwaysOnTop = this.TopMost;
        //    this.CurrentSession.StartPosition = this.Location;
        //    //this.CurrentSession.Groups = flowLayoutPanel1.Controls.OfType<RyzStudio.Windows.TileForms.TileContainer>()?.ToList() ?? new List<TileGroupModel>();

        //    var result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession);
        //    if (result.IsSuccess)
        //    {
        //        if (showNotices)
        //        {
        //            MessageBox.Show("Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information);
        //        }
        //    }
        //    else
        //    {
        //        MessageBox.Show(result.Message, "Save session");

        //        return false;
        //    }

        //    isBusy = false;

        //    return true;
        //}

        //protected bool saveAsFile()
        //{
        //    if (isBusy)
        //    {
        //        return false;
        //    }

        //    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
        //    {
        //        bool rv = saveFile(saveFileDialog1.FileName);
        //        if (rv)
        //        {
        //            sessionFilename = saveFileDialog1.FileName;
        //        }

        //        return rv;
        //    }

        //    return false;
        //}

        private void InvalidateOptions()
        {
            /// todo: big icons

#if !DEBUG
            UIControl.Invoke(this, (x) =>
            {
                RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1);
            });

            if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None)
            {
                UIControl.Invoke(this, (x) =>
                {
                    RyzStudio.Runtime.InteropServices.User32.RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.HotKey.ModifierCode, this.CurrentSession.HotKey.Key);
                });
            }
#endif

            UIControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop);

        }


        #region main menu

        /// <summary>
        /// New
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            await _fileSessionManager.NewSession();

            //if (string.IsNullOrWhiteSpace(sessionFilename))
            //{
            //    newSession();
            //}
            //else
            //{
            //    var result = MessageBox.Show("Save existing session?", "New session", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            //    if (result == DialogResult.Yes)
            //    {
            //        bool rv = saveFile(sessionFilename, false);
            //        if (rv)
            //        {
            //            newSession();
            //        }
            //    }
            //    else if (result == DialogResult.No)
            //    {
            //        newSession();
            //    }
            //    else if (result == DialogResult.Cancel)
            //    {
            //        return;
            //    }
            //}
        }

        /// <summary>
        /// Open
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            await _fileSessionManager.OpenSession();


            //if (string.IsNullOrWhiteSpace(sessionFilename))
            //{
            //    if (openFileDialog1.ShowDialog() == DialogResult.OK)
            //    {
            //        await loadFile(openFileDialog1.FileName);
            //    }
            //}
            //else
            //{
            //    var result = MessageBox.Show("Save existing session?", "Open session", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            //    if (result == DialogResult.Yes)
            //    {
            //        bool rv = saveFile(sessionFilename, false);
            //        if (rv)
            //        {
            //            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            //            {
            //                await loadFile(openFileDialog1.FileName);
            //            }
            //        }
            //    }
            //    else if (result == DialogResult.No)
            //    {
            //        if (openFileDialog1.ShowDialog() == DialogResult.OK)
            //        {
            //            await loadFile(openFileDialog1.FileName);
            //        }
            //    }
            //    else if (result == DialogResult.Cancel)
            //    {
            //        return;
            //    }
            //}
        }

        /// <summary>
        /// Close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            await _fileSessionManager.CloseSession();

            //if (string.IsNullOrWhiteSpace(sessionFilename))
            //{
            //    //flowLayoutPanel1.Controls.Clear();

            //    this.Clear();
            //}
            //else
            //{
            //    var result = MessageBox.Show("Save existing session?", "Close session", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            //    if (result == DialogResult.Yes)
            //    {
            //        bool rv = saveFile(sessionFilename, false);
            //        if (rv)
            //        {
            //            this.Clear();
            //            //flowLayoutPanel1.Controls.Clear();

            //            //sessionFilename = null;
            //        }
            //    }
            //    else if (result == DialogResult.No)
            //    {
            //        this.Clear();
            //        //flowLayoutPanel1.Controls.Clear();

            //        //sessionFilename = null;
            //    }
            //    else if (result == DialogResult.Cancel)
            //    {
            //        return;
            //    }
            //}
        }

        /// <summary>
        /// Save
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            await _fileSessionManager.SaveSession();

            //if (string.IsNullOrWhiteSpace(sessionFilename))
            //{
            //    saveAsFile();
            //}
            //else
            //{
            //    saveFile(sessionFilename, true);
            //}
        }

        /// <summary>
        /// Save As
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            await _fileSessionManager.SaveAsSession();

            //saveAsFile();
        }

        /// <summary>
        /// Exit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            requestExit = true;

            this.Close();
        }


        /// <summary>
        /// Add group
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addGroupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddNewTileGroup();
        }


        /// <summary>
        /// Show big icons
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void showBigIconsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.CurrentSession == null)
            {
                return;
            }

            this.CurrentSession.ShowBigIcons = !this.CurrentSession.ShowBigIcons;
        }

        /// <summary>
        /// Always on top
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void alwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.CurrentSession == null)
            {
                return;
            }

            this.CurrentSession.AlwaysOnTop = !this.CurrentSession.AlwaysOnTop;

            this.TopMost = this.CurrentSession.AlwaysOnTop;
        }


        /// <summary>
        /// Options
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new OptionsForm(this.CurrentSession);
            if (form.ShowDialog() == DialogResult.OK)
            {
                this.CurrentSession = form.Result;

                InvalidateOptions();
            }
        }


        /// <summary>
        /// View help
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL);
        }

        /// <summary>
        /// About
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(System.Windows.Forms.Application.ProductName + " v" + System.Windows.Forms.Application.ProductVersion, "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }


        private void menuStrip1_MenuActivate(object sender, EventArgs e)
        {
            saveAsToolStripMenuItem.Enabled = !string.IsNullOrWhiteSpace(sessionFilename);

            showBigIconsToolStripMenuItem.Checked = this.CurrentSession.ShowBigIcons;
            alwaysOnTopToolStripMenuItem.Checked = this.CurrentSession.AlwaysOnTop;
        }

        #endregion

        #region notification icon

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Visible = !this.Visible;
            }
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            requestExit = true;

            this.Close();
        }

        #endregion

        //private void tileContainer1_OnSizeChanged(object sender, EventArgs e)
        //{
        //    //int newWidth = this.Padding.Horizontal + SystemInformation.VerticalScrollBarWidth + tileContainer1.CalcWidth;

        //    //UIControl.SetClientWidth(this, newWidth);
        //}



        private void AddNewTileGroup()
        {
            var group = new TileGroupModel();
            group.Title = "New Group";
            group.IsExpanded = true;
            group.GridSize = new System.Drawing.Size(8, 1);

            var container = new RyzStudio.Windows.TileForms.TileContainer();
            container.Title = group.Title;
            container.IsOpen = group.IsExpanded;
            container.TitleContextMenuStrip = tileContainerMenu1;
            container.AutoSizeHeight = true;
            container.Tag = group;

            container.AutoResize(group.GridSize.Width, group.GridSize.Height);

            UIControl.Add(flowLayoutPanel1, container);
        }

        private async Task LoadTileGroups(List<TileGroupModel> groupList)
        {
            await Task.Run(() =>
            {
                UIControl.Clear(flowLayoutPanel1);

                // Load groups
                foreach (var item in groupList ?? new List<TileGroupModel>())
                {
                    var panel = new RyzStudio.Windows.TileForms.TileContainer();
                    panel.Title = item.Title;
                    panel.IsOpen = item.IsExpanded;
                    panel.TitleContextMenuStrip = tileContainerMenu1;
                    panel.AutoSizeHeight = true;
                    panel.Tag = item;

                    panel.AutoResize(item.GridSize.Width, item.GridSize.Height);

                    UIControl.Add(flowLayoutPanel1, panel);

                    // Load tiles
                    foreach (var item2 in item.Items ?? new List<TileModel>())
                    {
                        var tile = new FizzyLauncher.Windows.Forms.TilePanel();
                        tile.LoadInfo(item2);

                        panel.Add(tile, item2.Position.X, item2.Position.Y);
                    }
                }

                //InvalidateColumnSize();
            });
        }

        #region Tile container

        /// <summary>
        /// Add Tile
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addGroupToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
            if (container == null)
            {
                return;
            }

            var form = new EditTileForm();
            if (form.ShowDialog() == DialogResult.OK)
            {
                var result = form.Result;
                var newCoord = container.GetNextCoord();

                var newTile = new FizzyLauncher.Windows.Forms.TilePanel();
                newTile.LoadInfo(result);

                container.Add(newTile, newCoord.X, newCoord.Y);
            };
        }

        /// <summary>
        /// Add Tile Group
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
            if (container == null)
            {
                return;
            }

            var form = new EditTileFolderForm();
            if (form.ShowDialog() == DialogResult.OK)
            {
                var result = form.Result;
                var newCoord = container.GetNextCoord();

                var newTile = new FizzyLauncher.Windows.Forms.TilePanel();
                newTile.LoadInfo(result);

                container.Add(newTile, newCoord.X, newCoord.Y);
            };
        }

        /// <summary>
        /// Edit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
            if (container == null)
            {
                return;
            }

            var model = UIControl.GetTag<TileGroupModel>(container);

            var form = new EditGroupForm(model);
            if (form.ShowDialog() == DialogResult.OK)
            {
                var result = form.Result;

                container.Title = result.Title;
                container.Tag = result;

                container.Invalidate();
            };
        }

        /// <summary>
        /// Row - Add Row
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addRowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            container.AddRow();
        }

        /// <summary>
        /// Row - Remove Row
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void removeRowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            container.RemoveRow();
        }

        /// <summary>
        /// Move Top
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void topToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            UIControl.MoveTop(flowLayoutPanel1, container);
        }

        /// <summary>
        /// Move Up
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void upToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            UIControl.MoveUp(flowLayoutPanel1, container);
        }

        /// <summary>
        /// Move Down
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void downToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            UIControl.MoveDown(flowLayoutPanel1, container);
        }

        /// <summary>
        /// Move Bottom
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bottomToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
            if (container == null)
            {
                return;
            }

            UIControl.MoveBottom(flowLayoutPanel1, container);
        }

        /// <summary>
        /// Remove
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
            if (container == null)
            {
                return;
            }

            flowLayoutPanel1.Controls.Remove(container);
        }

        #endregion

    }
}