using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
using nft.ui.docking;
using nft.framework;
using nft.ui.command;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using nft.framework.drawing;
using System.IO;
using WeifenLuo.WinFormsUI.Docking;
using System.Security.Permissions;
using nft.contributions.ui;
using System.Reactive.Linq;


namespace nft.ui.mainframe
{    
    /// <summary>
	/// MainFrame の概要の説明です。
	/// </summary>
    public class MainFrame : System.Windows.Forms.Form, IMainFrame {
        public static int WM_KEYDOWN = 0x0100;
        public static int WM_SYSKEYDOWN = 0x0104;
        private System.ComponentModel.IContainer components;

        internal readonly DockingManagerEx dockManager;
        private MenuBarController menuBarController;
        private ToolBarController toolBarController;
        private ToolStripPanel toolStripPanel;
        private StatusStrip statusBar;
        private DockPanel panelCenter;
        private ToolStripStatusLabel messageLabel;
        private MenuStrip mainMenu;

        public event EventHandler<EventArgs> ActiveViewChanged;
        public event EventHandler<EventArgs> ActiveSubformChanged;

        public MainFrame(ParamsReader reader) : this() { }

        public MainFrame()
		{			//
			// Windows フォーム デザイナ サポートに必要です。
			//
            InitializeComponent();
			//IsMdiContainer = true;
			dockManager = new DockingManagerEx(panelCenter);
            menuBarController = new MenuBarController(mainMenu);
            toolBarController = new ToolBarController(toolStripPanel);
            KeyPreview = true;
            PreviewKeyDown += new PreviewKeyDownEventHandler(MainFrame_PreviewKeyDown);

            FormClosed += delegate(object o, FormClosedEventArgs arg) {
                Main.Exit();
            };
		}

        void MainFrame_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
            Debug.WriteLine("PreviewKeyDown:" + e.KeyData);
        }

        #region Key event management
        /*
        [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
        protected override bool ProcessDialogKey(Keys keyData) {
            Debug.WriteLine("ProcessDialogKey:" + keyData);
            //処理されたとき(consume)は、trueを返す
            return base.ProcessDialogKey(keyData);
        }
        */

        //他のMDI子ウィンドウに渡る前にチェックできる。ここで処理するのが望ましい
        //PreviewKeyDownは思うように機能しない
        [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
            Debug.WriteLine("ProcessCmdKey:" + keyData);
            //処理されたとき(consume)は、trueを返す
            //一般のキーとして処理したい場合はfalseを返す
            //return false;
            return base.ProcessCmdKey(ref msg, keyData);
        }

        #endregion

        /// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			dockManager.Dispose();
			base.Dispose( disposing );
		}
		protected override void OnClosing( CancelEventArgs e ) 
		{
            base.OnClosing(e);
			//Main.options.save();
            dockManager.SaveLayout();
            Debug.WriteIf(e.Cancel, "Close action canceled.");
		}

		#region Windows フォーム デザイナで生成されたコード 
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
            WeifenLuo.WinFormsUI.Docking.DockPanelSkin dockPanelSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPanelSkin();
            WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin autoHideStripSkin1 = new WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin();
            WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient1 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin dockPaneStripSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin();
            WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient dockPaneStripGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient2 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient2 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient3 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient dockPaneStripToolWindowGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient4 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient5 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient3 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient6 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient7 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainFrame));
            this.mainMenu = new System.Windows.Forms.MenuStrip();
            this.toolStripPanel = new System.Windows.Forms.ToolStripPanel();
            this.statusBar = new System.Windows.Forms.StatusStrip();
            this.messageLabel = new System.Windows.Forms.ToolStripStatusLabel();
            this.panelCenter = new WeifenLuo.WinFormsUI.Docking.DockPanel();
            this.statusBar.SuspendLayout();
            this.SuspendLayout();
            // 
            // mainMenu
            // 
            this.mainMenu.Location = new System.Drawing.Point(0, 0);
            this.mainMenu.Name = "mainMenu";
            this.mainMenu.Size = new System.Drawing.Size(992, 24);
            this.mainMenu.TabIndex = 0;
            this.mainMenu.Text = "menuStrip1";
            // 
            // toolStripPanel
            // 
            this.toolStripPanel.Dock = System.Windows.Forms.DockStyle.Top;
            this.toolStripPanel.Location = new System.Drawing.Point(0, 0);
            this.toolStripPanel.Name = "toolStripPanel";
            this.toolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
            this.toolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
            this.toolStripPanel.Size = new System.Drawing.Size(992, 0);
            // 
            // statusBar
            // 
            this.statusBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.messageLabel});
            this.statusBar.Location = new System.Drawing.Point(0, 701);
            this.statusBar.Name = "statusBar";
            this.statusBar.Size = new System.Drawing.Size(992, 22);
            this.statusBar.TabIndex = 15;
            this.statusBar.Text = "statusStrip1";
            // 
            // messageLabel
            // 
            this.messageLabel.Name = "messageLabel";
            this.messageLabel.Size = new System.Drawing.Size(0, 17);
            // 
            // panelCenter
            // 
            this.panelCenter.BackColor = System.Drawing.SystemColors.AppWorkspace;
            this.panelCenter.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panelCenter.DockBackColor = System.Drawing.SystemColors.AppWorkspace;
            this.panelCenter.Location = new System.Drawing.Point(0, 24);
            this.panelCenter.Name = "panelCenter";
            this.panelCenter.Size = new System.Drawing.Size(992, 677);
            dockPanelGradient1.EndColor = System.Drawing.SystemColors.ControlLight;
            dockPanelGradient1.StartColor = System.Drawing.SystemColors.ControlLight;
            autoHideStripSkin1.DockStripGradient = dockPanelGradient1;
            tabGradient1.EndColor = System.Drawing.SystemColors.Control;
            tabGradient1.StartColor = System.Drawing.SystemColors.Control;
            tabGradient1.TextColor = System.Drawing.SystemColors.ControlDarkDark;
            autoHideStripSkin1.TabGradient = tabGradient1;
            autoHideStripSkin1.TextFont = new System.Drawing.Font("MS UI Gothic", 9F);
            dockPanelSkin1.AutoHideStripSkin = autoHideStripSkin1;
            tabGradient2.EndColor = System.Drawing.SystemColors.ControlLightLight;
            tabGradient2.StartColor = System.Drawing.SystemColors.ControlLightLight;
            tabGradient2.TextColor = System.Drawing.SystemColors.ControlText;
            dockPaneStripGradient1.ActiveTabGradient = tabGradient2;
            dockPanelGradient2.EndColor = System.Drawing.SystemColors.Control;
            dockPanelGradient2.StartColor = System.Drawing.SystemColors.Control;
            dockPaneStripGradient1.DockStripGradient = dockPanelGradient2;
            tabGradient3.EndColor = System.Drawing.SystemColors.ControlLight;
            tabGradient3.StartColor = System.Drawing.SystemColors.ControlLight;
            tabGradient3.TextColor = System.Drawing.SystemColors.ControlText;
            dockPaneStripGradient1.InactiveTabGradient = tabGradient3;
            dockPaneStripSkin1.DocumentGradient = dockPaneStripGradient1;
            dockPaneStripSkin1.TextFont = new System.Drawing.Font("MS UI Gothic", 9F);
            tabGradient4.EndColor = System.Drawing.SystemColors.ActiveCaption;
            tabGradient4.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
            tabGradient4.StartColor = System.Drawing.SystemColors.GradientActiveCaption;
            tabGradient4.TextColor = System.Drawing.SystemColors.ActiveCaptionText;
            dockPaneStripToolWindowGradient1.ActiveCaptionGradient = tabGradient4;
            tabGradient5.EndColor = System.Drawing.SystemColors.Control;
            tabGradient5.StartColor = System.Drawing.SystemColors.Control;
            tabGradient5.TextColor = System.Drawing.SystemColors.ControlText;
            dockPaneStripToolWindowGradient1.ActiveTabGradient = tabGradient5;
            dockPanelGradient3.EndColor = System.Drawing.SystemColors.ControlLight;
            dockPanelGradient3.StartColor = System.Drawing.SystemColors.ControlLight;
            dockPaneStripToolWindowGradient1.DockStripGradient = dockPanelGradient3;
            tabGradient6.EndColor = System.Drawing.SystemColors.GradientInactiveCaption;
            tabGradient6.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
            tabGradient6.StartColor = System.Drawing.SystemColors.GradientInactiveCaption;
            tabGradient6.TextColor = System.Drawing.SystemColors.ControlText;
            dockPaneStripToolWindowGradient1.InactiveCaptionGradient = tabGradient6;
            tabGradient7.EndColor = System.Drawing.Color.Transparent;
            tabGradient7.StartColor = System.Drawing.Color.Transparent;
            tabGradient7.TextColor = System.Drawing.SystemColors.ControlDarkDark;
            dockPaneStripToolWindowGradient1.InactiveTabGradient = tabGradient7;
            dockPaneStripSkin1.ToolWindowGradient = dockPaneStripToolWindowGradient1;
            dockPanelSkin1.DockPaneStripSkin = dockPaneStripSkin1;
            this.panelCenter.Skin = dockPanelSkin1;
            this.panelCenter.TabIndex = 16;
            // 
            // MainFrame
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(992, 723);
            this.Controls.Add(this.panelCenter);
            this.Controls.Add(this.statusBar);
            this.Controls.Add(this.mainMenu);
            this.Controls.Add(this.toolStripPanel);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.IsMdiContainer = true;
            this.MainMenuStrip = this.mainMenu;
            this.MinimumSize = new System.Drawing.Size(600, 400);
            this.Name = "MainFrame";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "MainFrame";
            this.statusBar.ResumeLayout(false);
            this.statusBar.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		protected override void OnLoad(EventArgs e)
		{
            base.OnLoad(e);
            panelCenter.ActiveDocumentChanged += new EventHandler(panelCenter_ActiveDocumentChanged);
            panelCenter.ActiveContentChanged += new EventHandler(panelCenter_ActiveContentChanged);

            // Debug code -->
            /*MdiChildFrame child = new MdiChildFrame();
            AddChildWindow(child);
            child.ViewDrawer = new nft.debug.TestViewDrawer();
            child.Show();*/
            // Debug code <--
            // load the screen layout
			try 
			{
                dockManager.LoadLayout();
			} 
			catch( Exception ex ) 
			{
				// exception will be thrown if the file doesn't exist.
				Debug.WriteLine(ex.Message);
				Debug.WriteLine(ex.StackTrace);
			}			
		}

        void panelCenter_ActiveContentChanged(object sender, EventArgs e) {
            if (panelCenter.ActiveContent == panelCenter.ActiveDocument) return;
            Debug.WriteLine("ActiveContent:"+panelCenter.ActiveContent);
            if (ActiveSubformChanged != null) {
                ActiveSubformChanged(this, e);
            }
        }

        void panelCenter_ActiveDocumentChanged(object sender, EventArgs e) {
            Debug.WriteLine("ActiveDocument:" + panelCenter.ActiveDocument);
            if (ActiveViewChanged != null) {
                ActiveViewChanged(this, e);
            }
        }

		public void SetSubTitle(string subtitle) 
		{
			string long_title = I18n.T("long_title");
			string short_title = I18n.T("short_title");
			if( subtitle==null || subtitle.Trim().Length==0 )
				this.Text = long_title;
			else
				this.Text = short_title+" - "+subtitle;
		}

        #region child view management
        public MdiChildFrame OpenViewWindow() {
            throw new NotImplementedException();
        }

        public void AddView(String caption, IView content)
		{                                    
            MdiChildFrame dc = new MdiChildFrame(caption, (Control) content);
            dc.DockAreas = DockAreas.Document;
            dc.Show(panelCenter);
             /*
            Form f = new Form();
            f.Controls.Add(content);
            content.Dock = DockStyle.Fill;
            f.Show();
             */
		}

        public IView ActiveView {
            get { 
                MdiChildFrame dc = panelCenter.ActiveDocument as MdiChildFrame;
                if (dc != null) {
                    return dc.Content as IView;
                } else {
                    return null;
                }
            }
            set {
                if(value == null ){
                    throw new ArgumentNullException();
                }
                Control control = value as Control;
                MdiChildFrame dc = (control != null) ? control.Parent as MdiChildFrame : null;
                if(dc==null || dc.Parent==null){
                    throw new InvalidOperationException("The control is not a View. Please call AddView first.");
                }
                foreach(IDockContent f in panelCenter.Documents){
                    dc = f as MdiChildFrame;
                    if (dc != null && dc.Content==value) {
                        SetSubTitle(dc.Text);
                        dc.Activate();
                        return;
                    }
                }
                throw new InvalidOperationException("The control is not a View. Please call AddView first.");
            }
        }

        public DockingManagerEx DockingManager {
            get { return dockManager; }
        }
		#endregion

        #region IMainFrame implementation

        public IMenuBarController MenuBarController {
            get { return menuBarController; }
        }

        public IToolBarController ToolBarController {
            get { return toolBarController; }
        }

        /// <summary>
        /// Create UI dependent ICommandProcedure if possible, return null otherwise.
        /// </summary>
        /// <param name="commandType"></param>
        /// <param name="targetType"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        public ICommandProcedure Createprocedure(string commandType, Type targetType, ParamsReader reader) {
            if (commandType.Equals("ModalForm"))
                return new ModalFormCommand(targetType);
            if (commandType.Equals("ModelessForm"))
                return new ModelessFormCommand(targetType);
            if (commandType.Equals("SubForm"))
                return new SubformCommand(reader);
            return null;
        }

        #endregion
    }
}
