using DevComponents.DotNetBar.Metro;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar.Controls;
using System.Drawing;
using System.Collections;
namespace DevComponents.DotNetBar.Design
{
    /// 
    /// Represents Windows Forms designer for SideNav control.
    /// 
    public class SideNavDesigner: BarBaseControlDesigner
    {
        #region Private Variables
        #endregion
        #region Internal Implementation
        public SideNavDesigner()
        {
            this.EnableItemDragDrop = true;
            this.AcceptExternalControls = false;
        }
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            if (!component.Site.DesignMode)
                return;
            SideNav c = component as SideNav;
            if (c != null)
            {
                c.SetDesignMode();
            }
            this.EnableDragDrop(false);
        }
        public override bool CanParent(Control control)
        {
            if (control is SideNavPanel && !this.Control.Controls.Contains(control))
                return true;
            return false;
        }
        public override DesignerVerbCollection Verbs
        {
            get
            {
                DesignerVerb[] verbs = null;
                verbs = new DesignerVerb[]
					{
						new DesignerVerb("Create Tab", new EventHandler(CreateSideNavTab)),
						new DesignerVerb("Create Button", new EventHandler(CreateButton)),
						new DesignerVerb("Create Separator", new EventHandler(CreateSeparator))};
                return new DesignerVerbCollection(verbs);
            }
        }
        private void CreateSeparator(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateSeparator(GetNewItemContainer());
            }
        }
        private void CreateSeparator(BaseItem parent)
        {
            if (parent == null)
                return;
            Separator item = null;
            IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (dh != null)
            {
                DesignerTransaction trans = dh.CreateTransaction("Adding new item");
                try
                {
                    m_CreatingItem = true;
                    item = dh.CreateComponent(typeof(Separator)) as Separator;
                    if (item == null)
                        return;
                    TypeDescriptor.GetProperties(item)["FixedSize"].SetValue(item, new Size(3,1));
                    TypeDescriptor.GetProperties(item)["SeparatorOrientation"].SetValue(item, eDesignMarkerOrientation.Vertical);
                    item.Padding.Left = 6;
                    item.Padding.Right = 6;
                    IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                    if (parent != this.GetDefaultNewItemContainer() && cc != null)
                        cc.OnComponentChanging(parent, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]);
                    parent.SubItems.Add(item);
                    this.RecalcLayout();
                    if (parent != this.GetDefaultNewItemContainer() && cc != null)
                        cc.OnComponentChanged(parent, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"], null, null);
                    OnitemCreated(item);
                }
                catch
                {
                    trans.Cancel();
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }   
        }
        private BaseItem GetNewItemContainer()
        {
            SideNav r = this.Control as SideNav;
            return r.SideNavStrip.GetBaseItemContainer();
        }
        protected override void CreateButton(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateSideNavButton(GetNewItemContainer());
            }
        }
        protected virtual SideNavItem CreateSideNavButton(BaseItem parent)
        {
            if (parent == null)
                return null;
            SideNavItem item = null;
            IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (dh != null)
            {
                DesignerTransaction trans = dh.CreateTransaction("Adding new item");
                try
                {
                    m_CreatingItem = true;
                    item = dh.CreateComponent(typeof(SideNavItem)) as SideNavItem;
                    if (item == null)
                        return null;
                    TypeDescriptor.GetProperties(item)["Text"].SetValue(item, item.Name);
                    TypeDescriptor.GetProperties(item)["Symbol"].SetValue(item, "\uf10c");
                    IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                    if (parent != this.GetDefaultNewItemContainer() && cc != null)
                        cc.OnComponentChanging(parent, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]);
                    parent.SubItems.Add(item);
                    this.RecalcLayout();
                    if (parent != this.GetDefaultNewItemContainer() && cc != null)
                        cc.OnComponentChanged(parent, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"], null, null);
                    OnitemCreated(item);
                }
                catch
                {
                    trans.Cancel();
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }
            return item;
        }
        protected override void CreateTextBox(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateTextBox(GetNewItemContainer());
            }
        }
        protected override void CreateComboBox(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateComboBox(GetNewItemContainer());
            }
        }
        protected override void CreateLabel(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateLabel(GetNewItemContainer());
            }
        }
        protected override void CreateColorPicker(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateColorPicker(GetNewItemContainer());
            }
        }
        protected override void CreateProgressBar(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateProgressBar(GetNewItemContainer());
            }
        }
        protected override void CreateRatingItem(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateRatingItem(GetNewItemContainer());
            }
        }
        protected override void CreateSwitch(object sender, EventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                CreateSwitch(GetNewItemContainer());
            }
        }
        protected override void ComponentChangeComponentAdded(object sender, ComponentEventArgs e)
        {
            if (m_AddingItem)
            {
                m_AddingItem = false;
                IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                if (cc != null)
                    cc.OnComponentChanging(this.Control, null);
                this.GetNewItemContainer().SubItems.Add(e.Component as BaseItem);
                if (cc != null)
                    cc.OnComponentChanged(this.Control, null, null, null);
                m_InsertItemTransaction.Commit();
                m_InsertItemTransaction = null;
                this.RecalcLayout();
            }
        }
#if FRAMEWORK20
        public override void InitializeNewComponent(IDictionary defaultValues)
        {
            base.InitializeNewComponent(defaultValues);
            SetDesignTimeDefaults();
        }
#else
        public override void OnSetComponentDefaults()
        {
            SetDesignTimeDefaults();
            base.OnSetComponentDefaults();
        }
#endif
        private void SetDesignTimeDefaults()
        {
            CreateSideNavTab("Menu", true);
            CreateSeparator(GetNewItemContainer());
            CreateSideNavTab("Home");
            SideNav c = this.Control as SideNav;
            
            c.Size = new Size(400, 200);
            c.Dock = DockStyle.Left;
        }
        protected override BaseItem GetItemContainer()
        {
            SideNav tab = this.Control as SideNav;
            if (tab != null)
                return tab.SideNavStrip.GetBaseItemContainer();
            return null;
        }
        protected override System.Windows.Forms.Control GetItemContainerControl()
        {
            SideNav tab = this.Control as SideNav;
            if (tab != null)
                return tab.SideNavStrip;
            return null;
        }
        /// 
        /// Support for popup menu closing.
        /// 
        protected override void DesignTimeSelectionChanged(ISelectionService ss)
        {
            if (ss == null)
                return;
            if (this.Control == null || this.Control.IsDisposed)
                return;
            base.DesignTimeSelectionChanged(ss);
            SideNav r = this.Control as SideNav;
            if (r == null) return;
            BaseItem container = r.SideNavStrip.GetBaseItemContainer();
            if (container == null) return;
            if (ss.PrimarySelection is SideNavItem)
            {
                SideNavItem item = ss.PrimarySelection as SideNavItem;
                if (container.SubItems.Contains(item) && !item.IsSystemMenu && item.Panel != null)
                {
                    TypeDescriptor.GetProperties(item)["Checked"].SetValue(item, true);
                }
            }
        }
        /// 
        /// Triggered when some other component on the form is removed.
        /// 
        protected override void OtherComponentRemoving(object sender, ComponentEventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (r != null)
            {
                BaseItem container = r.SideNavStrip.GetBaseItemContainer();
                if (e.Component is SideNavItem && container != null && container.SubItems != null &&
                    container.SubItems.Contains(((SideNavItem)e.Component)))
                {
                    IDesignerHost dh = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
                    if (dh != null && ((SideNavItem)e.Component).Panel != null)
                        dh.DestroyComponent(((SideNavItem)e.Component).Panel);
                }
            }
            base.OtherComponentRemoving(sender, e);
        }
        protected override void ComponentRemoved(object sender, ComponentEventArgs e)
        {
            SideNav r = this.Control as SideNav;
            if (e.Component is BaseItem && r != null)
            {
                BaseItem item = e.Component as BaseItem;
                if (r.Items.Contains(item))
                    r.Items.Remove(item);
                DestroySubItems(item);
            }
        }
        #endregion
        #region Design-Time Item Creation
        protected virtual void CreateSideNavTab(object sender, EventArgs e)
        {
            CreateSideNavTab(string.Empty);
        }
        private void CreateSideNavTab(string text)
        {
            CreateSideNavTab(text, false);
        }
        private void CreateSideNavTab(string text, bool isSysMenu)
        {
            IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (dh != null)
            {
                DesignerTransaction trans = dh.CreateTransaction("Creating SideNav Tab");
                IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService));
                SideNav tab = this.Control as SideNav;
                try
                {
                    m_CreatingItem = true;
                    OnSubItemsChanging();
                    SideNavItem item = dh.CreateComponent(typeof(SideNavItem)) as SideNavItem;
                    if (string.IsNullOrEmpty(text))
                        TypeDescriptor.GetProperties(item)["Text"].SetValue(item, item.Name);
                    else
                        TypeDescriptor.GetProperties(item)["Text"].SetValue(item, text);
                    if (isSysMenu)
                    {
                        TypeDescriptor.GetProperties(item)["Symbol"].SetValue(item, "\uf0c9");
                        TypeDescriptor.GetProperties(item)["IsSystemMenu"].SetValue(item, true);
                    }
                    else
                    {
                        TypeDescriptor.GetProperties(item)["Symbol"].SetValue(item, "\uf015");
                        SideNavPanel panel = dh.CreateComponent(typeof (SideNavPanel)) as SideNavPanel;
                        TypeDescriptor.GetProperties(panel)["Dock"].SetValue(panel, DockStyle.Fill);
                        cc.OnComponentChanging(this.Control, TypeDescriptor.GetProperties(typeof (Control))["Controls"]);
                        this.Control.Controls.Add(panel);
                        panel.SendToBack();
                        cc.OnComponentChanged(this.Control, TypeDescriptor.GetProperties(typeof (Control))["Controls"],
                            null, null);
                        TypeDescriptor.GetProperties(item)["Panel"].SetValue(item, panel);
                    }
                    SimpleItemContainer cont = (SimpleItemContainer)tab.SideNavStrip.GetBaseItemContainer();
                    cc.OnComponentChanging(cont, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]);
                    cont.SubItems.Add(item);
                    cc.OnComponentChanged(cont, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"], null, null);
                    if (tab.SelectedItem == null && !isSysMenu)
                        TypeDescriptor.GetProperties(item)["Checked"].SetValue(item, true);
                    this.RecalcLayout();
                    OnSubItemsChanged();
                }
                catch
                {
                    trans.Cancel();
                    throw;
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }
        }
        #endregion
    }
}