#region << Using Directives >>
using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Volpe.Cafe.Data;
using Volpe.Cafe.Model;
using Volpe.Cafe.MonteCarlo.Model;
using Volpe.Cafe.MonteCarlo.Settings;
using Volpe.Cafe.UI.Panels;
#endregion
namespace Volpe.Cafe.UI
{
	public class ManageModelingSettings : System.Windows.Forms.Form
	{
        #region 
        class PanelItem
        {
            public PanelItem(string title, TreeNode node, CafeUserControl panel, bool enabled)
            {
                this.Title   = title;
                this.Node    = node;
                this.Panel   = panel;
                this.Enabled = enabled;
            }
            public string          Title;
            public TreeNode        Node;
            public CafeUserControl Panel;
            public bool Enabled;
        }
        class Panels
        {
            #region 
            public Panels(Point panelLocation, Size panelSize)
            {
                this._itemCount = PanelNames.Length;
                this._items     = new PanelItem[this._itemCount];
                for (int i = 0; i < this._itemCount; i++)
                {
                    TreeNode        node    = new TreeNode(PanelNames[i]);
                    CafeUserControl panel   = null;
                    bool            enabled = true;
                    switch (i)
                    {
                        case  0: panel = new CompliancePanel(); break;
                        case  1: panel = new InputPanel     (); break;
                        case  2: panel = new OutputPanel    (); break;
                        case  3: panel = new OpModesPanel   (); break;
                    }
                    panel.Location = panelLocation;
                    panel.Size     = panelSize;
                    this._items[i] = new PanelItem(PanelNames[i], node, panel, enabled);
                }
            }
            #endregion
            #region 
            public PanelItem this[int index] { get { return this._items[index]; } }
            public int ItemCount { get { return this._itemCount; } }
            public PanelItem GeneralComplianceSettingsPanelItem   { get { return this._items[ 0]; } }
            public PanelItem InputSettingsPanelItem               { get { return this._items[ 1]; } }
            public PanelItem OutputSettingsPanelItem              { get { return this._items[ 2]; } }
            public PanelItem OperatingModesPanelItem              { get { return this._items[ 3]; } }
            public CompliancePanel      GeneralCompliancePanel   { get { return (CompliancePanel     )this._items[ 0].Panel; } }
            public InputPanel           InputPanel               { get { return (InputPanel          )this._items[ 1].Panel; } }
            public OutputPanel          OutputPanel              { get { return (OutputPanel         )this._items[ 2].Panel; } }
            public OpModesPanel         OperatingModesPanel      { get { return (OpModesPanel        )this._items[ 3].Panel; } }
            #endregion
            #region 
            public static readonly string[] PanelNames =
                new string[] {
                                 "General Compliance Settings",
                                 "Input Settings",
                                 "Output Settings",
                                 "Runtime Settings"
                             };
            PanelItem[] _items;
            int         _itemCount;
            #endregion
        }
        #endregion
        #region 
        public ManageModelingSettings(Session session)
		{
            this.InitializeComponent();
            this.InitializeUI();
            this._session      = session;
            this._inputParsing = false;
            this._inputSaving  = false;
            this._saving       = false;
            Industry data = session.Data;
            if (data == null)
            {
                this._minYear = DateTime.Now.Year - 5;
                this._maxYear = this._minYear + 50;
            }
            else
            {
                this._minYear = data.MinYear.Year;
                this._maxYear = data.MaxYear.Year;
            }
		}
		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
		}
        #endregion
        #region 
		#region 
        void InitializeComponent()
		{
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ManageModelingSettings));
            this.ux_navigation = new System.Windows.Forms.TreeView();
            this.ux_settingsPanel = new System.Windows.Forms.Panel();
            this.ux_titleLabel = new System.Windows.Forms.Label();
            this.ux_toolbarPanel = new System.Windows.Forms.Panel();
            this.ux_close = new System.Windows.Forms.Button();
            this.ux_save = new System.Windows.Forms.Button();
            this.ux_status = new System.Windows.Forms.RichTextBox();
            this.ux_settingsPanel.SuspendLayout();
            this.ux_toolbarPanel.SuspendLayout();
            this.SuspendLayout();
            this.ux_navigation.Dock = System.Windows.Forms.DockStyle.Left;
            this.ux_navigation.FullRowSelect = true;
            this.ux_navigation.HideSelection = false;
            this.ux_navigation.HotTracking = true;
            this.ux_navigation.Location = new System.Drawing.Point(0, 0);
            this.ux_navigation.Name = "ux_navigation";
            this.ux_navigation.ShowRootLines = false;
            this.ux_navigation.Size = new System.Drawing.Size(160, 452);
            this.ux_navigation.TabIndex = 0;
            this.ux_navigation.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.Navigation_AfterSelect);
            this.ux_settingsPanel.AutoScroll = true;
            this.ux_settingsPanel.Controls.Add(this.ux_titleLabel);
            this.ux_settingsPanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.ux_settingsPanel.Location = new System.Drawing.Point(160, 0);
            this.ux_settingsPanel.Name = "ux_settingsPanel";
            this.ux_settingsPanel.Size = new System.Drawing.Size(474, 372);
            this.ux_settingsPanel.TabIndex = 1;
            this.ux_titleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_titleLabel.Location = new System.Drawing.Point(8, 8);
            this.ux_titleLabel.Name = "ux_titleLabel";
            this.ux_titleLabel.Size = new System.Drawing.Size(400, 24);
            this.ux_titleLabel.TabIndex = 0;
            this.ux_titleLabel.Text = "Modeling Settings";
            this.ux_toolbarPanel.Controls.Add(this.ux_close);
            this.ux_toolbarPanel.Controls.Add(this.ux_save);
            this.ux_toolbarPanel.Controls.Add(this.ux_status);
            this.ux_toolbarPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.ux_toolbarPanel.Location = new System.Drawing.Point(160, 372);
            this.ux_toolbarPanel.Name = "ux_toolbarPanel";
            this.ux_toolbarPanel.Size = new System.Drawing.Size(474, 80);
            this.ux_toolbarPanel.TabIndex = 2;
            this.ux_close.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_close.BackColor = System.Drawing.SystemColors.Control;
            this.ux_close.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.ux_close.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_close.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_close.ForeColor = System.Drawing.Color.Red;
            this.ux_close.Location = new System.Drawing.Point(416, 16);
            this.ux_close.Name = "ux_close";
            this.ux_close.Size = new System.Drawing.Size(48, 48);
            this.ux_close.TabIndex = 2;
            this.ux_close.Text = "Close";
            this.ux_close.UseVisualStyleBackColor = false;
            this.ux_close.Click += new System.EventHandler(this.Close_Click);
            this.ux_save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_save.BackColor = System.Drawing.SystemColors.Control;
            this.ux_save.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_save.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_save.ForeColor = System.Drawing.Color.Green;
            this.ux_save.Location = new System.Drawing.Point(360, 16);
            this.ux_save.Name = "ux_save";
            this.ux_save.Size = new System.Drawing.Size(48, 48);
            this.ux_save.TabIndex = 1;
            this.ux_save.Text = "Save";
            this.ux_save.UseVisualStyleBackColor = false;
            this.ux_save.Click += new System.EventHandler(this.Save_Click);
            this.ux_status.BackColor = System.Drawing.SystemColors.Control;
            this.ux_status.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.ux_status.Location = new System.Drawing.Point(8, 8);
            this.ux_status.Name = "ux_status";
            this.ux_status.ReadOnly = true;
            this.ux_status.Size = new System.Drawing.Size(344, 64);
            this.ux_status.TabIndex = 0;
            this.ux_status.Text = "";
            this.AcceptButton = this.ux_save;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.ux_close;
            this.ClientSize = new System.Drawing.Size(634, 452);
            this.Controls.Add(this.ux_settingsPanel);
            this.Controls.Add(this.ux_toolbarPanel);
            this.Controls.Add(this.ux_navigation);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "ManageModelingSettings";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Modeling Settings";
            this.ux_settingsPanel.ResumeLayout(false);
            this.ux_toolbarPanel.ResumeLayout(false);
            this.ResumeLayout(false);
        }
		#endregion
        #region 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.ux_save.Visible = !this._session.Running;
            this._session.Settings.AddCustomRuntimeSettings(typeof(MonteCarloSettings), false);
            this._panels.InputPanel.ParsingChanged += new EventHandler(this.InputPanel_ParsingChanged);
            this._panels.GeneralCompliancePanel.SetInitialState(Cafe2d.ComplianceTypes, this._session.Compliance);
            this._panels.InputPanel            .SetInitialState(this._session.Settings.InputSettings, (MonteCarloSettings)this._session.Settings.GetRuntimeSettings(typeof(MonteCarloSettings)));
            this._panels.OutputPanel           .SetInitialState(this._session.Settings.OutputSettings);
            this._panels.OperatingModesPanel   .SetInitialState(this._session.Settings.OperatingModes, this._minYear, this._maxYear);
            this.SelectPanel(0);
            Application.Idle += new EventHandler(this.ModelingSettings_Idle);
        }
        protected override void OnClosing(CancelEventArgs e)
        {
            if (this._saving || this._inputParsing || this._inputSaving) { e.Cancel = true; return; }
            this._panels.InputPanel.ParsingChanged -= new EventHandler(this.InputPanel_ParsingChanged);
            Application.Idle -= new EventHandler(this.ModelingSettings_Idle);
            bool isMC = (this._session.Compliance is MonteCarloModel);
            if (!isMC) { this._session.Settings.RemoveCustomRuntimeSettings(typeof(MonteCarloSettings)); }
            base.OnClosing(e);
        }
        #endregion
        void InitializeUI()
        {
            this._panels = new Panels(new Point(0, 24), new Size(this.ux_settingsPanel.Width, this.ux_settingsPanel.Height - 32));
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                this.ux_settingsPanel.Controls.Add(this._panels[i].Panel);
            }
            this.RefreshNavigationTree();
        }
        void RefreshNavigationTree()
        {
            this.ux_navigation.BeginUpdate();
            this.ux_navigation.Nodes.Clear();
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Enabled) { this.ux_navigation.Nodes.Add(this._panels[i].Node); }
            }
            this.ux_navigation.EndUpdate();
        }
        void RefreshStatusTextBox()
        {
            string newStatus;
            Color  statusColor;
            int numErr = 0, numChn = 0;
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Enabled)
                {
                    if      (this._panels[i].Panel.Messages.HasMessages) { numErr++; }
                    else if (this._panels[i].Panel.SettingsChanged     ) { numChn++; }
                }
            }
            if (numErr > 0)
            {
                StringBuilder errors = new StringBuilder();
                for (int i = 0; i < this._panels.ItemCount; i++)
                {
                    if (this._panels[i].Enabled && this._panels[i].Panel.Messages.HasMessages)
                    {
                        errors.Append(this._panels[i].Panel.Messages.ToString());
                        errors.Append("\n");
                    }
                }
                newStatus   = errors.ToString();
                statusColor = Color.Red;
            }
            else
            {
                newStatus   = string.Empty;
                statusColor = Color.Black;
            }
            if (this.ux_status.Text != newStatus)
            {
                this.ux_status.Text      = newStatus;
                this.ux_status.ForeColor = statusColor;
            }
        }
        void ModelingSettings_Idle(object sender, EventArgs e)
        {
            ICompliance selCompliance = this._panels.GeneralCompliancePanel.SelectedCompliance;
            bool isMC = (selCompliance is MonteCarloModel);
            if (this._panels.InputPanel.LoadMonteCarloTrials != isMC)
            {
                this._panels.InputPanel.LoadMonteCarloTrials = isMC;
            }
            bool hasErrors  = false;
            bool hasChanges = false;
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Enabled)
                {
                    if      (this._panels[i].Panel.Messages.HasMessages) { hasErrors  = true; break; }
                    else if (this._panels[i].Panel.SettingsChanged     ) { hasChanges = true; }
                }
            }
            this.ux_save.Enabled = !this._session.Running && !hasErrors && hasChanges;
            this.RefreshStatusTextBox();
        }
        void Navigation_AfterSelect(object sender, TreeViewEventArgs e)
        {
            this.SelectPanel(this.IndexOf(e.Node));
        }
        void InputPanel_ParsingChanged(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new EventHandler(this.InputPanel_ParsingChanged));
            }
            else
            {
                InputPanel pnl = (InputPanel)this._panels.InputSettingsPanelItem.Panel;
                this._inputParsing           = pnl.Parsing;
                bool enabled                 = !this._inputParsing;
                this.ux_toolbarPanel.Enabled = enabled;
                this.ControlBox              = enabled;
                this.ShowIcon                = enabled;
                for (int i = 0; i < this._panels.ItemCount; i++)
                {
                    this._panels[i].Panel.Enabled = enabled;
                }
                if (this._inputSaving && enabled)
                {   
                    if (pnl.MarketData   != null) { this._session.Data                  = pnl.MarketData; }
                    if (pnl.Technologies != null) { this._session.Settings.Technologies = pnl.Technologies; }
                    if (pnl.Parameters   != null) { this._session.Settings.Parameters   = pnl.Parameters; }
                    if (pnl.Scenarios    != null) { this._session.Settings.Scenarios    = pnl.Scenarios; }
                    this._inputSaving = false;
                }
            }
        }
        void Save_Click(object sender, EventArgs e)
        {
            this._saving = true;
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Panel.SettingsChanged)
                {
                    if (this._panels[i].Panel is InputPanel) { this._inputSaving = true; }
                    this._panels[i].Panel.SaveChanges();
                }
            }
            this._session.Compliance = ((CompliancePanel)this._panels.GeneralComplianceSettingsPanelItem.Panel).Compliance;
            this._session.SaveRequired = true;
            this._saving = false;
        }
        void Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        public void SelectPanel(int index)
        {
            if (index < 0 || index >= this._panels.ItemCount) { return; }
            this.SelectPanel(this._panels[index]);
        }
        void SelectPanel(PanelItem item)
        {
            if (!item.Enabled) { return; }
            item.Panel        .BringToFront();
            this.ux_titleLabel.BringToFront();
            this.ux_navigation.SelectedNode = item.Node;
            this.ux_titleLabel.Text         = item.Title;
        }
        int IndexOf(TreeNode node)
        {
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Node == node) { return i; }
            }
            return -1;
        }
        int IndexOf(CafeUserControl panel)
        {
            for (int i = 0; i < this._panels.ItemCount; i++)
            {
                if (this._panels[i].Panel == panel) { return i; }
            }
            return -1;
        }
        #endregion
        #region 
        #region 
        System.Windows.Forms.TreeView ux_navigation;
        System.Windows.Forms.Panel ux_settingsPanel;
        System.Windows.Forms.Label ux_titleLabel;
        System.Windows.Forms.Panel ux_toolbarPanel;
        System.Windows.Forms.RichTextBox ux_status;
        System.Windows.Forms.Button ux_save;
        System.Windows.Forms.Button ux_close;
        #endregion
        ManageModelingSettings.Panels _panels;
        bool _inputParsing;
        bool _inputSaving;
        bool _saving;
        Session _session;
        int _minYear;
        int _maxYear;
        #endregion
    }
}

