using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar.Metro;
namespace DevComponents.DotNetBar.Design
{
    class TabFormControlDesigner : BarBaseControlDesigner
    {
        #region Private Variables
        #endregion
        #region Internal Implementation
        public TabFormControlDesigner()
        {
            this.EnableItemDragDrop = true;
            this.AcceptExternalControls = false;
        }
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            if (!component.Site.DesignMode)
                return;
            TabFormControl c = component as TabFormControl;
            if (c != null)
            {
                c.SetDesignMode();
                //this.Expanded = c.Expanded;
            }
            this.EnableDragDrop(false);
        }
        public override bool CanParent(Control control)
        {
            if (control is TabFormPanel && !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(CreateTab)),
						new DesignerVerb("Create Button", new EventHandler(CreateButton)),
						new DesignerVerb("Create Combo Box", new EventHandler(CreateComboBox)),
                        new DesignerVerb("Create Label", new EventHandler(CreateLabel))};
                return new DesignerVerbCollection(verbs);
            }
        }
        private DesignerActionListCollection _ActionLists = null;
        public override DesignerActionListCollection ActionLists
        {
            get
            {
                if (this._ActionLists == null)
                {
                    this._ActionLists = new DesignerActionListCollection();
                    this._ActionLists.Add(new TabFormControlActionList(this));
                }
                return this._ActionLists;
            }
        }
        private BaseItem GetNewItemContainer()
        {
            TabFormControl r = this.Control as TabFormControl;
            //if (m_QuickAccessToolbarSelected)
            //    return r.TabStrip.CaptionContainerItem;
            //else
            return r.TabStrip.StripContainerItem;
        }
        public override ButtonItem CreateButton()
        {
            OnSubItemsChanging();
            ButtonItem button = CreateButton(GetNewItemContainer());
            OnSubItemsChanged();
            return button;
        }
        protected override void CreateButton(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateButton(GetNewItemContainer());
            }
        }
        protected override void CreateTextBox(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateTextBox(GetNewItemContainer());
            }
        }
        protected override void CreateComboBox(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateComboBox(GetNewItemContainer());
            }
        }
        protected override void CreateLabel(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateLabel(GetNewItemContainer());
            }
        }
        protected override void CreateColorPicker(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateColorPicker(GetNewItemContainer());
            }
        }
        protected override void CreateProgressBar(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateProgressBar(GetNewItemContainer());
            }
        }
        protected override void CreateRatingItem(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                CreateRatingItem(GetNewItemContainer());
            }
        }
        protected override void CreateSwitch(object sender, EventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            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();
            }
        }
        protected override ArrayList GetAllAssociatedComponents()
        {
            ArrayList c = new ArrayList(base.AssociatedComponents);
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                AddSubItems(r.TabStrip.StripContainerItem, c);
                AddSubItems(r.TabStrip.CaptionContainerItem, c);
            }
            return c;
        }
        public override System.Collections.ICollection AssociatedComponents
        {
            get
            {
                ArrayList c = new ArrayList(this.BaseAssociatedComponents);
                TabFormControl rc = this.Control as TabFormControl;
                if (rc != null)
                {
                    foreach (BaseItem item in rc.Items)
                    {
                        if (!item.SystemItem)
                            c.Add(item);
                    }
                    foreach (BaseItem item in rc.CaptionItems)
                    {
                        if (!item.SystemItem)
                            c.Add(item);
                    }
                }
                return c;
            }
        }
#if FRAMEWORK20
        public override void InitializeNewComponent(IDictionary defaultValues)
        {
            base.InitializeNewComponent(defaultValues);
            SetDesignTimeDefaults();
        }
#else
        public override void OnSetComponentDefaults()
        {
            SetDesignTimeDefaults();
            base.OnSetComponentDefaults();
        }
#endif
        private void SetDesignTimeDefaults()
        {
            CreateTab("Document 1");
            CreateTab("Document 2");
            TabFormControl c = this.Control as TabFormControl;
            c.Dock = DockStyle.Fill;
        }
        protected override BaseItem GetItemContainer()
        {
            TabFormControl tab = this.Control as TabFormControl;
            if (tab != null)
                return tab.TabStrip.GetBaseItemContainer();
            return null;
        }
        protected override System.Windows.Forms.Control GetItemContainerControl()
        {
            TabFormControl tab = this.Control as TabFormControl;
            if (tab != null)
                return tab.TabStrip;
            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);
            TabFormControl r = this.Control as TabFormControl;
            if (r == null) return;
            BaseItem container = r.TabStrip.StripContainerItem;
            if (container == null) return;
            if (ss.PrimarySelection is TabFormItem)
            {
                TabFormItem item = ss.PrimarySelection as TabFormItem;
                if (container.SubItems.Contains(item))
                {
                    TypeDescriptor.GetProperties(item)["Checked"].SetValue(item, true);
                }
            }
        }
        private bool ContainsControl(Control container, Control childControl)
        {
            Control parent = childControl;
            while (parent != null)
            {
                if (parent == container) return true;
                parent = parent.Parent;
            }
            return false;
        }
        /// 
        /// Triggered when some other component on the form is removed.
        /// 
        protected override void OtherComponentRemoving(object sender, ComponentEventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (r != null)
            {
                BaseItem container = r.TabStrip.StripContainerItem;
                if (e.Component is TabFormItem && container != null && container.SubItems != null &&
                    container.SubItems.Contains(((TabFormItem)e.Component)))
                {
                    IDesignerHost dh = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
                    if (dh != null)
                        dh.DestroyComponent(((TabFormItem)e.Component).Panel);
                }
            }
            base.OtherComponentRemoving(sender, e);
        }
        protected override void ComponentRemoved(object sender, ComponentEventArgs e)
        {
            TabFormControl r = this.Control as TabFormControl;
            if (e.Component is BaseItem && r != null)
            {
                BaseItem item = e.Component as BaseItem;
                if (r.Items.Contains(item))
                    r.Items.Remove(item);
                else if (r.CaptionItems.Contains(item))
                    r.CaptionItems.Remove(item);
                DestroySubItems(item);
            }
        }
        protected override bool OnMouseDown(ref Message m, MouseButtons button)
        {
            System.Windows.Forms.Control ctrl = this.GetItemContainerControl();
            TabFormStripControl strip = ctrl as TabFormStripControl;
            if (strip == null)
                return base.OnMouseDown(ref m, button);
            Point pos = strip.PointToClient(System.Windows.Forms.Control.MousePosition);
            if (!strip.ClientRectangle.Contains(pos))
                return base.OnMouseDown(ref m, button);
            bool callBase = true;
            if (callBase)
                return base.OnMouseDown(ref m, button);
            else
                return true;
        }
        #endregion
        #region Design-Time Item Creation
        protected virtual void CreateTab(object sender, EventArgs e)
        {
            CreateTab(string.Empty);
        }
        internal void CreateTab(string text)
        {
            IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (dh != null)
            {
                DesignerTransaction trans = dh.CreateTransaction("Creating Tab");
                IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService));
                TabFormControl tab = this.Control as TabFormControl;
                try
                {
                    m_CreatingItem = true;
                    OnSubItemsChanging();
                    TabFormItem item = dh.CreateComponent(typeof(TabFormItem)) as TabFormItem;
                    if (string.IsNullOrEmpty(text))
                        TypeDescriptor.GetProperties(item)["Text"].SetValue(item, item.Name);
                    else
                        TypeDescriptor.GetProperties(item)["Text"].SetValue(item, text);
                    TabFormPanel panel = (TabFormPanel)dh.CreateComponent(typeof(TabFormPanel));
                    TypeDescriptor.GetProperties(panel)["Dock"].SetValue(panel, DockStyle.Fill);
                    //TypeDescriptor.GetProperties(panel)["ColorSchemeStyle"].SetValue(panel, tab.Style);
                    tab.SetTabPanelStyle(panel);
                    //panel.Style.BorderBottom = eStyleBorderType.Solid;
                    //TypeDescriptor.GetProperties(panel.Style)["BorderBottom"].SetValue(panel.Style, eStyleBorderType.Solid);
                    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 = tab.TabStrip.StripContainerItem;
                    cc.OnComponentChanging(cont, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]);
                    cont.SubItems.Add(item);
                    cc.OnComponentChanged(cont, TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"], null, null);
                    if (cont.SubItems.Count == 1)
                        TypeDescriptor.GetProperties(item)["Checked"].SetValue(item, true);
                    this.RecalcLayout();
                    OnSubItemsChanged();
                }
                catch
                {
                    trans.Cancel();
                    throw;
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }
        }
        #endregion
        #region Shadowing
        ///// 
        ///// Gets or sets whether custom caption and quick access toolbar provided by the control is visible. Default value is false.
        ///// This property should be set to true when control is used on MetroForm.
        ///// 
        //[Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether custom caption and quick access toolbar provided by the control is visible.")]
        //public bool CaptionVisible
        //{
        //    get
        //    {
        //        TabFormControl r = this.Control as TabFormControl;
        //        return r.CaptionVisible;
        //    }
        //    set
        //    {
        //        TabFormControl r = this.Control as TabFormControl;
        //        if (r.CaptionVisible == value) return;
        //        r.CaptionVisible = value;
        //        if (r.CaptionVisible && (
        //            r.QuickToolbarItems.Count == 6 && r.QuickToolbarItems[0] is SystemCaptionItem && r.QuickToolbarItems[5] is SystemCaptionItem))
        //        {
        //            // Add custom items to the toolbar
        //            IDesignerHost dh = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
        //            IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
        //            if (dh != null && !dh.Loading && cc != null && dh.TransactionDescription != "Paste components")
        //            {
        //                DesignerTransaction trans = dh.CreateTransaction();
        //                try
        //                {
        //                    m_CreatingItem = true;
        //                    MetroAppButton sb = dh.CreateComponent(typeof(MetroAppButton)) as MetroAppButton;
        //                    sb.Text = "&File";
        //                    sb.ShowSubItems = false;
        //                    sb.CanCustomize = false;
        //                    sb.AutoExpandOnClick = true;
        //                    cc.OnComponentChanging(r, TypeDescriptor.GetProperties(r)["QuickToolbarItems"]);
        //                    sb.ImageFixedSize = new Size(16, 16);
        //                    r.Items.Insert(0, sb);
        //                    cc.OnComponentChanged(r, TypeDescriptor.GetProperties(r)["QuickToolbarItems"], null, null);
        //                    ButtonItem buttonStart = sb;
        //                    ButtonItem b = dh.CreateComponent(typeof(ButtonItem)) as ButtonItem;
        //                    b.Text = b.Name;
        //                    cc.OnComponentChanging(r, TypeDescriptor.GetProperties(r)["QuickToolbarItems"]);
        //                    r.QuickToolbarItems.Add(b, 2);
        //                    cc.OnComponentChanged(r, TypeDescriptor.GetProperties(r)["QuickToolbarItems"], null, null);
        //                }
        //                catch
        //                {
        //                    trans.Cancel();
        //                }
        //                finally
        //                {
        //                    if (!trans.Canceled) trans.Commit();
        //                    m_CreatingItem = false;
        //                }
        //            }
        //        }
        //    }
        //}
        internal static Bitmap LoadImage(string imageName)
        {
            string imagesFolder = GetImagesFolder();
            if (imagesFolder != "")
            {
                if (File.Exists(imagesFolder + imageName))
                    return new Bitmap(imagesFolder + imageName);
            }
            return null;
        }
        private static string GetImagesFolder()
        {
            try
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine;
                string path = "";
                try
                {
                    if (key != null)
                        key = key.OpenSubKey("Software\\DevComponents\\DotNetBar");
                    if (key != null)
                        path = key.GetValue("InstallationFolder", "").ToString();
                }
                finally { if (key != null) key.Close(); }
                if (path != "")
                {
                    if (path.Substring(path.Length - 1, 1) != "\\")
                        path += "\\";
                    path += "Images\\";
                    return path;
                }
            }
            catch (Exception)
            {
            }
            return "";
        }
        //protected override void PreFilterProperties(IDictionary properties)
        //{
        //    base.PreFilterProperties(properties);
        //    properties["CaptionVisible"] = TypeDescriptor.CreateProperty(typeof(TabFormControlDesigner), (PropertyDescriptor)properties["CaptionVisible"], new Attribute[]
        //        {
        //            new DefaultValueAttribute(false),
        //            new BrowsableAttribute(true),
        //            new CategoryAttribute("Appearance"),
        //            new DescriptionAttribute("Indicates whether custom caption and quick access toolbar provided by the control is visible.")});
        //}
        #endregion
        protected override void OnItemDragAndDropped(BaseItem dragItem)
        {
            TabFormControl tc = (TabFormControl)this.Component;
            IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService));
            if (cc != null && tc != null && tc.CaptionItems.Contains(dragItem))
            {
                cc.OnComponentChanged(tc, TypeDescriptor.GetProperties(typeof(BaseItem))["CaptionItems"], null, null);
            }
            else
                base.OnItemDragAndDropped(dragItem);
        }
        public void CreateCaptionButton()
        {
            ButtonItem 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(ButtonItem)) as ButtonItem;
                    if (item == null)
                        return;
                    TabFormControl tc = (TabFormControl)this.Component;
                    TypeDescriptor.GetProperties(item)["Text"].SetValue(item, item.Name);
                    item.ItemAlignment = eItemAlignment.Far;
                    IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                    cc.OnComponentChanging(this.Component, TypeDescriptor.GetProperties(typeof(TabFormControl))["CaptionItems"]);
                    tc.CaptionItems.Add(item);
                    this.RecalcLayout();
                    cc.OnComponentChanged(this.Component, TypeDescriptor.GetProperties(typeof(TabFormControl))["CaptionItems"], null, null);
                    OnitemCreated(item);
                }
                catch
                {
                    trans.Cancel();
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }
        }
        public void CreateCaptionLabel()
        {
            LabelItem 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(LabelItem)) as LabelItem;
                    if (item == null)
                        return;
                    TabFormControl tc = (TabFormControl)this.Component;
                    TypeDescriptor.GetProperties(item)["Text"].SetValue(item, item.Name);
                    item.ItemAlignment = eItemAlignment.Far;
                    IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                    cc.OnComponentChanging(this.Component, TypeDescriptor.GetProperties(typeof(TabFormControl))["CaptionItems"]);
                    tc.CaptionItems.Add(item);
                    this.RecalcLayout();
                    cc.OnComponentChanged(this.Component, TypeDescriptor.GetProperties(typeof(TabFormControl))["CaptionItems"], null, null);
                    OnitemCreated(item);
                }
                catch
                {
                    trans.Cancel();
                }
                finally
                {
                    if (!trans.Canceled)
                        trans.Commit();
                    m_CreatingItem = false;
                }
            }
        }
        internal void CreateLabel()
        {
            CreateLabel(this, EventArgs.Empty);
        }
        internal void CreateComboBox()
        {
            CreateComboBox(this, EventArgs.Empty);
        }
        internal void CreateTextBox()
        {
            CreateTextBox(this, EventArgs.Empty);
        }
    }
    internal class TabFormControlActionList : DesignerActionList
    {
        private TabFormControlDesigner _Designer = null;
        /// 
        /// Initializes a new instance of the AdvTreeActionList class.
        /// 
        /// 
        public TabFormControlActionList(TabFormControlDesigner designer)
            : base(designer.Component)
        {
            _Designer = designer;
        }
        public override DesignerActionItemCollection GetSortedActionItems()
        {
            DesignerActionItemCollection items = new DesignerActionItemCollection();
            string tabStripCategory = "Tab Strip";
            items.Add(new DesignerActionHeaderItem(tabStripCategory));
            string captionCategory = "Caption";
            items.Add(new DesignerActionHeaderItem(captionCategory));
            items.Add(new DesignerActionMethodItem(this, "CreateTab", "Create Tab", tabStripCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateButton", "Create Button", tabStripCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateLabel", "Create Label", tabStripCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateComboBox", "Create ComboBox", tabStripCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateTextBox", "Create TextBox", tabStripCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateCaptionButton", "Create Button", captionCategory, true));
            items.Add(new DesignerActionMethodItem(this, "CreateCaptionLabel", "Create Label", captionCategory, true));
            items.Add(new DesignerActionPropertyItem("CaptionVisible", "Caption visible?", captionCategory, "Indicates whether caption is visible"));
            return items;
        }
        public void CreateCaptionButton()
        {
            _Designer.CreateCaptionButton();
        }
        public void CreateCaptionLabel()
        {
            _Designer.CreateCaptionLabel();
        }
        public void CreateTab()
        {
            _Designer.CreateTab(string.Empty);
        }
        public void CreateButton()
        {
            _Designer.CreateButton();
        }
        public void CreateLabel()
        {
            _Designer.CreateLabel();
        }
        public void CreateComboBox()
        {
            _Designer.CreateComboBox();
        }
        public void CreateTextBox()
        {
            _Designer.CreateTextBox();
        }
        public bool CaptionVisible
        {
            get
            {
                return ((TabFormControl)base.Component).CaptionVisible;
            }
            set
            {
                TypeDescriptor.GetProperties(base.Component)["CaptionVisible"].SetValue(base.Component, value);
            }
        }
    }
}