using System;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Text;
using nft.ui.mainframe;
using System.IO;
using nft.framework;
using System.Collections.Generic;

namespace nft.ui.docking
{
	public class DockingManagerEx : IDisposable
	{
        public delegate DockContent ContentsResolver(string persist);
        
        /// <summary>
		/// Repository of icons associated with the contents of this docking manager.
		/// </summary>
		public readonly ImageList imageList = new ImageList();
        protected DockPanel dockPanel;
        protected DeserializeDockContent deserializeDockContent;
        protected IList<ContentsResolver> resolvers;

        public DockingManagerEx(DockPanel dp) {
            dockPanel = dp;
            resolvers = new List<ContentsResolver>();
            DockPanelCustomizer.SetupFactories(dockPanel);
            deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
            // Regsiter default resolver which find from contributions.
            RegisterResolver(new ContentsResolver(DockContentContributionResolver.ResolveDockContent));
		}

        protected static String LayoutFilePath {
            get { return Path.Combine(Directories.SettingDir, "layout.config"); }
        }

        public void RegisterResolver(ContentsResolver cr) {
            resolvers.Insert(0,cr); // latest order
        }

        public void SaveLayout(){
            dockPanel.SuspendLayout(true);
            int n = dockPanel.Contents.Count;
            while(--n>=0){
                IDockContent dc = dockPanel.Contents[n];
                if (dc is MdiChildFrame) {
                    ((DockContent)dc).Close();
                } else {
                    DefaultDockForm ddf = dc as DefaultDockForm;
                    if (ddf != null) {
                        ddf.OnBeforeSaveLayout();
                    }
                }
            }
            dockPanel.SaveAsXml(LayoutFilePath, Encoding.UTF8);
            dockPanel.ResumeLayout();
        }

        public void LoadLayout() {
            dockPanel.LoadFromXml(LayoutFilePath, deserializeDockContent);            
        }

        internal protected DockPanel DockPanel { get { return dockPanel; } }

        protected IDockContent GetContentFromPersistString(string persistString) {
            if (persistString.Length == 0 || persistString == typeof(MdiChildFrame).ToString())
                return null;
            else {
                IEnumerator<ContentsResolver> en = resolvers.GetEnumerator();
                DockContent dc;
                while (en.MoveNext()) {
                    dc = en.Current.Invoke(persistString);
                    if (dc != null) {
                        return dc;
                    }
                }
                return null;
            }
        }

        #region IDisposable implementation

        private bool disposed = false;

        public void Dispose() {
            GC.SuppressFinalize(this);
            this.Dispose(true);
        }

        ~DockingManagerEx() {
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing) {
            if (this.disposed) {
                return;
            }
            this.disposed = true;
            if (disposing) {
                imageList.Dispose();
            }
        }
        #endregion
	}
}
