using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Volpe.Cafe.Data;
using Volpe.Cafe.IO;
using Volpe.Cafe.IO.InputParsers;
using Volpe.Cafe.MonteCarlo.Settings;
using Volpe.Cafe.Settings;
using Volpe.Cafe.Utils;
namespace Volpe.Cafe.UI.Panels
{
	public class InputPanel : CafeUserControl
	{
        #region 
        public event EventHandler ParsingChanged;
        #endregion
        #region 
		public InputPanel()
		{
			this.InitializeComponent();
            this.PostInitialize();
        }
		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
		}
        #endregion
        #region 
		#region 
		void InitializeComponent()
		{
            this.ux_inputFilesLabel = new System.Windows.Forms.Label();
            this.ux_inputFilesPanel = new System.Windows.Forms.Panel();
            this.ux_reloadAllFromDisk = new System.Windows.Forms.CheckBox();
            this.ux_scenariosFileBrowse = new System.Windows.Forms.Button();
            this.ux_scenariosFile = new System.Windows.Forms.TextBox();
            this.ux_parametersFileBrowse = new System.Windows.Forms.Button();
            this.ux_parametersFile = new System.Windows.Forms.TextBox();
            this.ux_technologiesFileBrowse = new System.Windows.Forms.Button();
            this.ux_technologiesFile = new System.Windows.Forms.TextBox();
            this.ux_marketDataFileBrowse = new System.Windows.Forms.Button();
            this.ux_marketDataFile = new System.Windows.Forms.TextBox();
            this.ux_marketDataFileOutdatedLabel = new System.Windows.Forms.Label();
            this.ux_scenariosFileOutdatedLabel = new System.Windows.Forms.Label();
            this.ux_parametersFileOutdatedLabel = new System.Windows.Forms.Label();
            this.ux_technologiesFileOutdatedLabel = new System.Windows.Forms.Label();
            this.ux_technologiesFileLabel = new System.Windows.Forms.Label();
            this.ux_parametersFileLabel = new System.Windows.Forms.Label();
            this.ux_scenariosFileLabel = new System.Windows.Forms.Label();
            this.ux_marketDataFileLabel = new System.Windows.Forms.Label();
            this.ux_mcTrialsFileBrowse = new System.Windows.Forms.Button();
            this.ux_mcTrialsFile = new System.Windows.Forms.TextBox();
            this.ux_mcTrialsFileLabel = new System.Windows.Forms.Label();
            this.ux_inputFilesPanel.SuspendLayout();
            this.SuspendLayout();
            this.ux_inputFilesLabel.AutoSize = true;
            this.ux_inputFilesLabel.Location = new System.Drawing.Point(8, 8);
            this.ux_inputFilesLabel.Name = "ux_inputFilesLabel";
            this.ux_inputFilesLabel.Size = new System.Drawing.Size(316, 13);
            this.ux_inputFilesLabel.TabIndex = 2;
            this.ux_inputFilesLabel.Text = "Please specify the input files you would like to use with the model:";
            this.ux_inputFilesPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_inputFilesPanel.Controls.Add(this.ux_reloadAllFromDisk);
            this.ux_inputFilesPanel.Controls.Add(this.ux_scenariosFileBrowse);
            this.ux_inputFilesPanel.Controls.Add(this.ux_scenariosFile);
            this.ux_inputFilesPanel.Controls.Add(this.ux_parametersFileBrowse);
            this.ux_inputFilesPanel.Controls.Add(this.ux_parametersFile);
            this.ux_inputFilesPanel.Controls.Add(this.ux_technologiesFileBrowse);
            this.ux_inputFilesPanel.Controls.Add(this.ux_technologiesFile);
            this.ux_inputFilesPanel.Controls.Add(this.ux_marketDataFileBrowse);
            this.ux_inputFilesPanel.Controls.Add(this.ux_marketDataFile);
            this.ux_inputFilesPanel.Controls.Add(this.ux_marketDataFileOutdatedLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_scenariosFileOutdatedLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_parametersFileOutdatedLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_technologiesFileOutdatedLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_technologiesFileLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_parametersFileLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_scenariosFileLabel);
            this.ux_inputFilesPanel.Controls.Add(this.ux_marketDataFileLabel);
            this.ux_inputFilesPanel.Location = new System.Drawing.Point(0, 16);
            this.ux_inputFilesPanel.Name = "ux_inputFilesPanel";
            this.ux_inputFilesPanel.Size = new System.Drawing.Size(440, 192);
            this.ux_inputFilesPanel.TabIndex = 3;
            this.ux_reloadAllFromDisk.AutoSize = true;
            this.ux_reloadAllFromDisk.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_reloadAllFromDisk.Location = new System.Drawing.Point(11, 168);
            this.ux_reloadAllFromDisk.Name = "ux_reloadAllFromDisk";
            this.ux_reloadAllFromDisk.Size = new System.Drawing.Size(183, 17);
            this.ux_reloadAllFromDisk.TabIndex = 99;
            this.ux_reloadAllFromDisk.Text = "Reload all selected files from disk.";
            this.ux_scenariosFileBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_scenariosFileBrowse.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_scenariosFileBrowse.Location = new System.Drawing.Point(352, 144);
            this.ux_scenariosFileBrowse.Name = "ux_scenariosFileBrowse";
            this.ux_scenariosFileBrowse.Size = new System.Drawing.Size(80, 21);
            this.ux_scenariosFileBrowse.TabIndex = 19;
            this.ux_scenariosFileBrowse.Text = "Browse";
            this.ux_scenariosFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_scenariosFile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ux_scenariosFile.Location = new System.Drawing.Point(11, 144);
            this.ux_scenariosFile.Name = "ux_scenariosFile";
            this.ux_scenariosFile.Size = new System.Drawing.Size(340, 20);
            this.ux_scenariosFile.TabIndex = 18;
            this.ux_parametersFileBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_parametersFileBrowse.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_parametersFileBrowse.Location = new System.Drawing.Point(352, 104);
            this.ux_parametersFileBrowse.Name = "ux_parametersFileBrowse";
            this.ux_parametersFileBrowse.Size = new System.Drawing.Size(80, 21);
            this.ux_parametersFileBrowse.TabIndex = 11;
            this.ux_parametersFileBrowse.Text = "Browse";
            this.ux_parametersFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_parametersFile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ux_parametersFile.Location = new System.Drawing.Point(11, 104);
            this.ux_parametersFile.Name = "ux_parametersFile";
            this.ux_parametersFile.Size = new System.Drawing.Size(340, 20);
            this.ux_parametersFile.TabIndex = 10;
            this.ux_technologiesFileBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_technologiesFileBrowse.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_technologiesFileBrowse.Location = new System.Drawing.Point(352, 64);
            this.ux_technologiesFileBrowse.Name = "ux_technologiesFileBrowse";
            this.ux_technologiesFileBrowse.Size = new System.Drawing.Size(80, 21);
            this.ux_technologiesFileBrowse.TabIndex = 7;
            this.ux_technologiesFileBrowse.Text = "Browse";
            this.ux_technologiesFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_technologiesFile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ux_technologiesFile.Location = new System.Drawing.Point(11, 64);
            this.ux_technologiesFile.Name = "ux_technologiesFile";
            this.ux_technologiesFile.Size = new System.Drawing.Size(340, 20);
            this.ux_technologiesFile.TabIndex = 6;
            this.ux_marketDataFileBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_marketDataFileBrowse.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_marketDataFileBrowse.Location = new System.Drawing.Point(352, 24);
            this.ux_marketDataFileBrowse.Name = "ux_marketDataFileBrowse";
            this.ux_marketDataFileBrowse.Size = new System.Drawing.Size(80, 21);
            this.ux_marketDataFileBrowse.TabIndex = 3;
            this.ux_marketDataFileBrowse.Text = "Browse";
            this.ux_marketDataFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_marketDataFile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ux_marketDataFile.Location = new System.Drawing.Point(11, 24);
            this.ux_marketDataFile.Name = "ux_marketDataFile";
            this.ux_marketDataFile.Size = new System.Drawing.Size(340, 20);
            this.ux_marketDataFile.TabIndex = 2;
            this.ux_marketDataFileOutdatedLabel.AutoEllipsis = true;
            this.ux_marketDataFileOutdatedLabel.AutoSize = true;
            this.ux_marketDataFileOutdatedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_marketDataFileOutdatedLabel.ForeColor = System.Drawing.Color.Gray;
            this.ux_marketDataFileOutdatedLabel.Location = new System.Drawing.Point(96, 8);
            this.ux_marketDataFileOutdatedLabel.Name = "ux_marketDataFileOutdatedLabel";
            this.ux_marketDataFileOutdatedLabel.Size = new System.Drawing.Size(228, 13);
            this.ux_marketDataFileOutdatedLabel.TabIndex = 1;
            this.ux_marketDataFileOutdatedLabel.Text = "(The file on disk is newer than data in memory.)";
            this.ux_marketDataFileOutdatedLabel.Visible = false;
            this.ux_scenariosFileOutdatedLabel.AutoEllipsis = true;
            this.ux_scenariosFileOutdatedLabel.AutoSize = true;
            this.ux_scenariosFileOutdatedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_scenariosFileOutdatedLabel.ForeColor = System.Drawing.Color.Gray;
            this.ux_scenariosFileOutdatedLabel.Location = new System.Drawing.Point(80, 128);
            this.ux_scenariosFileOutdatedLabel.Name = "ux_scenariosFileOutdatedLabel";
            this.ux_scenariosFileOutdatedLabel.Size = new System.Drawing.Size(228, 13);
            this.ux_scenariosFileOutdatedLabel.TabIndex = 17;
            this.ux_scenariosFileOutdatedLabel.Text = "(The file on disk is newer than data in memory.)";
            this.ux_scenariosFileOutdatedLabel.Visible = false;
            this.ux_parametersFileOutdatedLabel.AutoEllipsis = true;
            this.ux_parametersFileOutdatedLabel.AutoSize = true;
            this.ux_parametersFileOutdatedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_parametersFileOutdatedLabel.ForeColor = System.Drawing.Color.Gray;
            this.ux_parametersFileOutdatedLabel.Location = new System.Drawing.Point(88, 88);
            this.ux_parametersFileOutdatedLabel.Name = "ux_parametersFileOutdatedLabel";
            this.ux_parametersFileOutdatedLabel.Size = new System.Drawing.Size(228, 13);
            this.ux_parametersFileOutdatedLabel.TabIndex = 9;
            this.ux_parametersFileOutdatedLabel.Text = "(The file on disk is newer than data in memory.)";
            this.ux_parametersFileOutdatedLabel.Visible = false;
            this.ux_technologiesFileOutdatedLabel.AutoEllipsis = true;
            this.ux_technologiesFileOutdatedLabel.AutoSize = true;
            this.ux_technologiesFileOutdatedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ux_technologiesFileOutdatedLabel.ForeColor = System.Drawing.Color.Gray;
            this.ux_technologiesFileOutdatedLabel.Location = new System.Drawing.Point(96, 48);
            this.ux_technologiesFileOutdatedLabel.Name = "ux_technologiesFileOutdatedLabel";
            this.ux_technologiesFileOutdatedLabel.Size = new System.Drawing.Size(228, 13);
            this.ux_technologiesFileOutdatedLabel.TabIndex = 5;
            this.ux_technologiesFileOutdatedLabel.Text = "(The file on disk is newer than data in memory.)";
            this.ux_technologiesFileOutdatedLabel.Visible = false;
            this.ux_technologiesFileLabel.AutoSize = true;
            this.ux_technologiesFileLabel.Location = new System.Drawing.Point(8, 48);
            this.ux_technologiesFileLabel.Name = "ux_technologiesFileLabel";
            this.ux_technologiesFileLabel.Size = new System.Drawing.Size(90, 13);
            this.ux_technologiesFileLabel.TabIndex = 4;
            this.ux_technologiesFileLabel.Text = "Technologies file:";
            this.ux_parametersFileLabel.AutoSize = true;
            this.ux_parametersFileLabel.Location = new System.Drawing.Point(8, 88);
            this.ux_parametersFileLabel.Name = "ux_parametersFileLabel";
            this.ux_parametersFileLabel.Size = new System.Drawing.Size(79, 13);
            this.ux_parametersFileLabel.TabIndex = 8;
            this.ux_parametersFileLabel.Text = "Parameters file:";
            this.ux_scenariosFileLabel.AutoSize = true;
            this.ux_scenariosFileLabel.Location = new System.Drawing.Point(8, 128);
            this.ux_scenariosFileLabel.Name = "ux_scenariosFileLabel";
            this.ux_scenariosFileLabel.Size = new System.Drawing.Size(73, 13);
            this.ux_scenariosFileLabel.TabIndex = 16;
            this.ux_scenariosFileLabel.Text = "Scenarios file:";
            this.ux_marketDataFileLabel.AutoSize = true;
            this.ux_marketDataFileLabel.Location = new System.Drawing.Point(8, 8);
            this.ux_marketDataFileLabel.Name = "ux_marketDataFileLabel";
            this.ux_marketDataFileLabel.Size = new System.Drawing.Size(85, 13);
            this.ux_marketDataFileLabel.TabIndex = 0;
            this.ux_marketDataFileLabel.Text = "Market-Data file:";
            this.ux_mcTrialsFileBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_mcTrialsFileBrowse.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.ux_mcTrialsFileBrowse.Location = new System.Drawing.Point(352, 232);
            this.ux_mcTrialsFileBrowse.Name = "ux_mcTrialsFileBrowse";
            this.ux_mcTrialsFileBrowse.Size = new System.Drawing.Size(80, 21);
            this.ux_mcTrialsFileBrowse.TabIndex = 6;
            this.ux_mcTrialsFileBrowse.Text = "Browse";
            this.ux_mcTrialsFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_mcTrialsFile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ux_mcTrialsFile.Location = new System.Drawing.Point(11, 232);
            this.ux_mcTrialsFile.Name = "ux_mcTrialsFile";
            this.ux_mcTrialsFile.Size = new System.Drawing.Size(340, 20);
            this.ux_mcTrialsFile.TabIndex = 5;
            this.ux_mcTrialsFile.WordWrap = false;
            this.ux_mcTrialsFileLabel.AutoSize = true;
            this.ux_mcTrialsFileLabel.Location = new System.Drawing.Point(8, 216);
            this.ux_mcTrialsFileLabel.Name = "ux_mcTrialsFileLabel";
            this.ux_mcTrialsFileLabel.Size = new System.Drawing.Size(271, 13);
            this.ux_mcTrialsFileLabel.TabIndex = 4;
            this.ux_mcTrialsFileLabel.Text = "Please specify an input file containing Monte-Carlo trials:";
            this.Controls.Add(this.ux_mcTrialsFileBrowse);
            this.Controls.Add(this.ux_mcTrialsFile);
            this.Controls.Add(this.ux_mcTrialsFileLabel);
            this.Controls.Add(this.ux_inputFilesLabel);
            this.Controls.Add(this.ux_inputFilesPanel);
            this.MinimumSize = new System.Drawing.Size(440, 0);
            this.Name = "InputPanel";
            this.Size = new System.Drawing.Size(440, 264);
            this.ux_inputFilesPanel.ResumeLayout(false);
            this.ux_inputFilesPanel.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
        }
		#endregion
        #region 
        protected virtual void OnParsingChanged(EventArgs e)
        {
            if (this.ParsingChanged != null)
            {
                this.ParsingChanged(this, e);
            }
        }
        #endregion
        void PostInitialize()
        {
            this.InitializeInputPanelDragDrop();
            this.AutoInitializeCheckChangesDetector(this.Controls);
            this.DeInitializeCheckChangesDetector(this.ux_reloadAllFromDisk);
            this.ux_marketDataFile        .TextChanged    += new EventHandler(this.InputFile_TextChanged);
            this.ux_technologiesFile      .TextChanged    += new EventHandler(this.InputFile_TextChanged);
            this.ux_parametersFile        .TextChanged    += new EventHandler(this.InputFile_TextChanged);
            this.ux_scenariosFile         .TextChanged    += new EventHandler(this.InputFile_TextChanged);
            this.ux_marketDataFileBrowse  .Click          += new EventHandler(this.InputFileBrowse_Click);
            this.ux_technologiesFileBrowse.Click          += new EventHandler(this.InputFileBrowse_Click);
            this.ux_parametersFileBrowse  .Click          += new EventHandler(this.InputFileBrowse_Click);
            this.ux_scenariosFileBrowse   .Click          += new EventHandler(this.InputFileBrowse_Click);
            this.ux_mcTrialsFile          .TextChanged    += new EventHandler(this.MCTrialsFile_TextChanged);
            this.ux_mcTrialsFileBrowse    .Click          += new EventHandler(this.MCTrialsFileBrowse_Click);
            this.ux_mcTrialsFile          .EnabledChanged += new EventHandler(this.MCTrialsFile_EnabledChanged);
            this.InputFile_TextChanged   (this.ux_marketDataFile  , EventArgs.Empty);
            this.InputFile_TextChanged   (this.ux_technologiesFile, EventArgs.Empty);
            this.InputFile_TextChanged   (this.ux_parametersFile  , EventArgs.Empty);
            this.InputFile_TextChanged   (this.ux_scenariosFile   , EventArgs.Empty);
            this.MCTrialsFile_TextChanged(this.ux_mcTrialsFile    , EventArgs.Empty);
            this._data          = new object[FileCount];
            this._verifiedFiles = new bool  [FileCount];
            this._loadFailed    = new bool  [FileCount];
            this._parsing = 0;
            this._saveThread = null;
        }
        void InputFile_TextChanged(object sender, EventArgs e)
        {
            TextBox tb             = (TextBox)sender;
            bool    isMarketData   = (tb == this.ux_marketDataFile);
            bool    isTechnologies = (tb == this.ux_technologiesFile);
            bool    isParameters   = (tb == this.ux_parametersFile);
            bool    isScenarios    = (tb == this.ux_scenariosFile);
            int     fileID =
                (isMarketData  ) ? MarketDataID :
                (isTechnologies) ? TechnologiesID :
                (isParameters  ) ? ParametersID :
                (isScenarios   ) ? ScenariosID : -1;
            Label   outdatedLbl =
                (isMarketData  ) ? this.ux_marketDataFileOutdatedLabel :
                (isTechnologies) ? this.ux_technologiesFileOutdatedLabel :
                (isParameters  ) ? this.ux_parametersFileOutdatedLabel :
                (isScenarios   ) ? this.ux_scenariosFileOutdatedLabel : null;
            if (fileID == -1 || outdatedLbl == null) { return; }
            string filePath = tb.Text.Trim();
            if (filePath != string.Empty && File.Exists(filePath))
            {
                bool inputFilePathChanged =
                    (isMarketData   && !this.CompareFilePaths(this._inputSettings.MarketDataFile  , filePath)) ||
                    (isTechnologies && !this.CompareFilePaths(this._inputSettings.TechnologiesFile, filePath)) ||
                    (isParameters   && !this.CompareFilePaths(this._inputSettings.ParametersFile  , filePath)) ||
                    (isScenarios    && !this.CompareFilePaths(this._inputSettings.ScenariosFile   , filePath));
                tb.ForeColor = (this._visualTracking && inputFilePathChanged) ? this._visualTrackingColor : Control.DefaultForeColor;
                tb.BackColor = Color.Empty;
                this._messages.RemoveMessage(tb);
                if (inputFilePathChanged)
                {   
                    this.BeginParse();
                    if (this.VerifyFile(tb, fileID))
                    {
                        tb.ForeColor = (this._visualTracking) ? this._visualTrackingColor : Control.DefaultForeColor;
                        tb.BackColor = Color.Empty;
                    }
                    this.EndParse();
                    outdatedLbl.Visible = false;
                } 
            }
            else
            {
                if (filePath == string.Empty)
                {
                    this._messages.AddMessage(
                        "Please select a " + FriendlyTitles[fileID] + " file you would like to use with the model.", null, Color.Red, tb);
                }
                else
                {
                    this._messages.AddMessage(
                        "The specified " + FriendlyTitles[fileID] + " file does not exist on disk.", null, Color.Red, tb);
                }
                tb.BackColor = Color.Honeydew;
                tb.ForeColor = Color.Red;
            }
        }
        void InputFileBrowse_Click(object sender, EventArgs e)
        {
            TextBox tb = null;
            int id = -1;
            if      (sender == this.ux_marketDataFileBrowse  ) { id = MarketDataID  ; tb = this.ux_marketDataFile  ; }
            else if (sender == this.ux_technologiesFileBrowse) { id = TechnologiesID; tb = this.ux_technologiesFile; }
            else if (sender == this.ux_parametersFileBrowse  ) { id = ParametersID  ; tb = this.ux_parametersFile  ; }
            else if (sender == this.ux_scenariosFileBrowse   ) { id = ScenariosID   ; tb = this.ux_scenariosFile   ; }
            OpenFileDialog dlg = new OpenFileDialog();
            if (id != -1) { dlg.Title = "Please select the " + FriendlyTitles[id] + " file you would like to use with the model:"; }
            if (File.Exists(tb.Text)) { dlg.FileName = tb.Text; }
            dlg.Multiselect = false;
            dlg.Filter = "Microsoft Excel Workbook Files (*.xls*)|*.xls*";
            if (dlg.ShowDialog() == DialogResult.OK) { tb.Text = dlg.FileName; }
        }
        void MCTrialsFile_TextChanged(object sender, EventArgs e)
        {
            TextBox tb = (TextBox)sender;
            if (File.Exists(tb.Text))
            {
                bool trialsFileChanged = !this.CompareFilePaths(this._mcSettings.TrialsFile, tb.Text);
                tb.ForeColor = (this._visualTracking && trialsFileChanged) ? this._visualTrackingColor : Control.DefaultForeColor;
                tb.BackColor = Color.Empty;
                this._messages.RemoveMessage(tb);
            }
            else
            {
                if (tb.Text.Trim() == string.Empty)
                {
                    this._messages.AddMessage(
                        "Please select a Monte-Carlo trials file you would like to use with the model.", null, Color.Red, tb);
                }
                else
                {
                    this._messages.AddMessage(
                        "The specified Monte-Carlo trials file does not exist on disk.", null, Color.Red, tb);
                }
                tb.BackColor = Color.Honeydew;
                tb.ForeColor = Color.Red;
            }
        }
        void MCTrialsFileBrowse_Click(object sender, EventArgs e)
        {
            TextBox tb = this.ux_mcTrialsFile;
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files (*.*)|*.*|CSV Files (*.*)|*.*";
            dlg.FilterIndex = 1;
            dlg.Multiselect = false;
            dlg.FileName = File.Exists(tb.Text) ? tb.Text : "";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                tb.Text = dlg.FileName;
            }
        }
        void MCTrialsFile_EnabledChanged(object sender, EventArgs e)
        {
            TextBox tb = (TextBox)sender;
            if (tb.Enabled) { this.MCTrialsFile_TextChanged(sender, e); }
            else            { this._messages.RemoveMessage(sender); tb.BackColor = Color.Empty; }
        }
        bool CompareFilePaths(string path1, string path2)
        {
            if (File.Exists(path1)) { path1 = Path.GetFullPath(path1.TrimEnd('\\')); }
            if (File.Exists(path2)) { path2 = Path.GetFullPath(path2.TrimEnd('\\')); }
            return Interaction.StringCompare(path1, path2, false);
        }
        void InitializeInputPanelDragDrop()
        {
            this.ux_inputFilesPanel.AllowDrop  = true;
            this.ux_inputFilesPanel.DragEnter += new DragEventHandler(this.InputFilesPanel_DragEnter);
            this.ux_inputFilesPanel.DragDrop  += new DragEventHandler(this.InputFilesPanel_DragDrop);
            this.ux_mcTrialsFile.AllowDrop  = true;
            this.ux_mcTrialsFile.DragEnter += new DragEventHandler(this.MCTrialsFile_DragEnter);
            this.ux_mcTrialsFile.DragDrop  += new DragEventHandler(this.MCTrialsFile_DragDrop);
        }
        void InputFilesPanel_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
            {
                e.Effect = DragDropEffects.All;
            }
        }
        void InputFilesPanel_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            this.ParseFiles(files, false);
        }
        void MCTrialsFile_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
            {
                e.Effect = DragDropEffects.All;
            }
        }
        void MCTrialsFile_DragDrop(object sender, DragEventArgs e)
        {
            TextBox tb = (TextBox)sender;
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            for (int i = 0; i < files.Length; i++)
            {
                if (File.Exists(files[i]))
                {
                    tb.Text = files[i];
                    break;
                }
            }
        }
        void BeginParse()
        {
            this._parsing++;
            if (this._parsing == 1) { this.ChangeInputState(this, EventArgs.Empty); }
        }
        void EndParse()
        {
            if (this._parsing > 0)
            {
                this._parsing--;
                if (this._parsing == 0) { this.ChangeInputState(this, EventArgs.Empty); }
            }
        }
        void ChangeInputState(object sender, EventArgs e)
        {
            this.OnParsingChanged(e);
            if (this.Visible && this.IsHandleCreated)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new EventHandler(this.ChangeInputState));
                }
                else
                {
                    bool enabled = (this._parsing == 0);
                    this.AllowDrop                           =  enabled;
                    this.ux_inputFilesPanel       .AllowDrop =  enabled;
                    this.ux_marketDataFile        .ReadOnly  = !enabled;
                    this.ux_technologiesFile      .ReadOnly  = !enabled;
                    this.ux_parametersFile        .ReadOnly  = !enabled;
                    this.ux_scenariosFile         .ReadOnly  = !enabled;
                    this.ux_marketDataFileBrowse  .Enabled   =  enabled;
                    this.ux_technologiesFileBrowse.Enabled   =  enabled;
                    this.ux_parametersFileBrowse  .Enabled   =  enabled;
                    this.ux_scenariosFileBrowse   .Enabled   =  enabled;
                    if (enabled)
                    {
                        this.ux_reloadAllFromDisk.Checked = false;
                    }
                } 
            } 
        }
        void ParseFile(string path, bool keepExisting)
        {
            this.ParseFiles(new string[] {path}, keepExisting);
        }
        void ParseFiles(string[] paths, bool keepExisting)
        {
            if (paths == null || paths.Length == 0) { return; }
            this.BeginParse();
            StringCollection scFiles = new StringCollection();
            StringCollection scDirs  = new StringCollection();
            for (int i = 0; i < paths.Length; i++)
            {
                if      (Directory.Exists(paths[i])) { scDirs .Add(paths[i]); }
                else if (File     .Exists(paths[i])) { scFiles.Add(paths[i]); }
            }
            string[] files = new string[scFiles.Count]; scFiles.CopyTo(files, 0);
            string[] dirs  = new string[scDirs .Count]; scDirs .CopyTo(dirs , 0);
            bool[] found = new bool[FileCount];
            if (keepExisting)
            {
                if (File.Exists(this.ux_marketDataFile  .Text)) { found[MarketDataID  ] = true; }
                if (File.Exists(this.ux_technologiesFile.Text)) { found[TechnologiesID] = true; }
                if (File.Exists(this.ux_parametersFile  .Text)) { found[ParametersID  ] = true; }
                if (File.Exists(this.ux_scenariosFile   .Text)) { found[ScenariosID   ] = true; }
            }
            this.ParseFilesHelper(files, dirs, found, 3);
            this.EndParse();
        }
        void ParseFilesHelper(string[] files, string[] dirs, bool[] found, int recurseDepth)
        {
            int foundCount = 0;
            for (int i = 0; i < found.Length; i++)
            {
                if (found[i]) { foundCount++; }
            }
            for (int i = 0; i < files.Length; i++)
            {
                if (foundCount == FileCount) { return; }
                this._messages.AddMessage("Checking input file:  \"" + files[i] + "\"", null, Color.Blue, files[i]);
                Application.DoEvents();
                bool fileOpened = false;
                string wbTitle = null;
                try
                {   
                    Input input = new Input(files[i]);
                    input.Close();
                    wbTitle = input.Title;
                    fileOpened = true;
                }
                catch { fileOpened = false; }
                if (fileOpened)
                {
                    for (int j = 0; j < FileCount; j++)
                    {
                        if (!found[j] && Interaction.StringCompareAny(wbTitle, DesiredTitles[j], true))
                        {
                            found[j] = true;
                            foundCount++;
                            if      (j == MarketDataID  ) { this.ux_marketDataFile  .Text = files[i]; }
                            else if (j == TechnologiesID) { this.ux_technologiesFile.Text = files[i]; }
                            else if (j == ParametersID  ) { this.ux_parametersFile  .Text = files[i]; }
                            else if (j == ScenariosID   ) { this.ux_scenariosFile   .Text = files[i]; }
                            break;
                        }
                    }
                }
                this._messages.RemoveMessage(files[i]);
                Application.DoEvents();
            } 
            for (int i = 0; i < dirs.Length; i++)
            {
                string[] recurseFiles = Directory.GetFiles(dirs[i], "*.xls");
                string[] recurseDirs  = (recurseDepth > 0) ? Directory.GetDirectories(dirs[i]) : new string[0];
                this.ParseFilesHelper(recurseFiles, recurseDirs, found, recurseDepth - 1);
            }
        }
        void VerifyFiles()
        {
            this.BeginParse();
            this.VerifyFile(this.ux_marketDataFile  , MarketDataID  );
            this.VerifyFile(this.ux_technologiesFile, TechnologiesID);
            this.VerifyFile(this.ux_parametersFile  , ParametersID  );
            this.VerifyFile(this.ux_scenariosFile   , ScenariosID   );
            this.EndParse();
        }
        bool VerifyFile(TextBox tb, int fileID)
        {
            this._messages.AddMessage("Checking " + FriendlyTitles[fileID] + " input file ...", null, Color.Blue, tb);
            Application.DoEvents();
            bool verified = false;
            try
            {
                Input inputFile = new Input(tb.Text);
                inputFile.Close();
                verified = Interaction.StringCompareAny(inputFile.Title, DesiredTitles[fileID], true);
            }
            catch { verified = false; }
            this._messages.RemoveMessage(tb);
            Application.DoEvents();
            if (!verified)
            {
                this._messages.AddMessage("The selected " + FriendlyTitles[fileID] + " file could not be opened.", null, Color.Red, tb);
                tb.BackColor = Color.Honeydew;
                tb.ForeColor = Color.Red;
                Application.DoEvents();
            }
            return verified;
        }
        void LoadFiles()
        {
            this.BeginParse();
            this.LoadFile(MarketDataID  , this.ux_marketDataFile  , ref this._inputSettings.MarketDataFile  , ref this._inputSettings.MarketDataTimestamp  );
            this.LoadFile(TechnologiesID, this.ux_technologiesFile, ref this._inputSettings.TechnologiesFile, ref this._inputSettings.TechnologiesTimestamp);
            this.LoadFile(ParametersID  , this.ux_parametersFile  , ref this._inputSettings.ParametersFile  , ref this._inputSettings.ParametersTimestamp  );
            this.LoadFile(ScenariosID   , this.ux_scenariosFile   , ref this._inputSettings.ScenariosFile   , ref this._inputSettings.ScenariosTimestamp   );
            this.EndParse();
        }
        bool LoadFile(int fileID, TextBox tb, ref string file, ref DateTime timestamp)
        {
            if (!(this.ux_reloadAllFromDisk.Checked || !this.CompareFilePaths(file, tb.Text))) { return false; }
            this._messages.AddMessage("Loading " + FriendlyTitles[fileID] + " input file ...", null, Color.Blue, tb);
            Application.DoEvents();
            bool fileLoaded = false;
            string exMessage = string.Empty;
            try
            {
                if      (fileID == MarketDataID  ) { this._data[fileID] = XlParser.ParseMarketData  (tb.Text); }
                else if (fileID == TechnologiesID) { this._data[fileID] = XlParser.ParseTechnologies(tb.Text); }
                else if (fileID == ParametersID  ) { this._data[fileID] = XlParser.ParseParameters  (tb.Text); }
                else if (fileID == ScenariosID   ) { this._data[fileID] = XlParser.ParseScenarios   (tb.Text); }
                file       = tb.Text.Trim();
                timestamp  = File.GetLastWriteTime(file);
                fileLoaded = true;
            }
            catch (Exception ex) { exMessage = ex.Message; fileLoaded = false; }
            this._messages.RemoveMessage(tb);
            Application.DoEvents();
            if (!fileLoaded)
            {
                this._data[fileID] = null;
                this._messages.AddMessage("The selected " + FriendlyTitles[fileID] + " file could not be opened.", exMessage, Color.Red, tb);
                tb.BackColor = Color.Honeydew;
                tb.ForeColor = Color.Red;
            }
            this._loadFailed[fileID] = !fileLoaded;
            return fileLoaded;
        }
        public void SetInitialState(InputSettings inputSettings, MonteCarloSettings monteCarloSettings)
        {
            this._inputSettings = inputSettings;
            this._mcSettings    = monteCarloSettings;
            bool forceReload = false;
            this.SetInitialState_ProcessFile(inputSettings.MarketDataFile  , inputSettings.MarketDataTimestamp  , MarketDataID  , this.ux_marketDataFile  , this.ux_marketDataFileOutdatedLabel  , ref forceReload);
            this.SetInitialState_ProcessFile(inputSettings.TechnologiesFile, inputSettings.TechnologiesTimestamp, TechnologiesID, this.ux_technologiesFile, this.ux_technologiesFileOutdatedLabel, ref forceReload);
            this.SetInitialState_ProcessFile(inputSettings.ParametersFile  , inputSettings.ParametersTimestamp  , ParametersID  , this.ux_parametersFile  , this.ux_parametersFileOutdatedLabel  , ref forceReload);
            this.SetInitialState_ProcessFile(inputSettings.ScenariosFile   , inputSettings.ScenariosTimestamp   , ScenariosID   , this.ux_scenariosFile   , this.ux_scenariosFileOutdatedLabel   , ref forceReload);
            this.ux_mcTrialsFile.Text = this._mcSettings.TrialsFile;
            this.ux_reloadAllFromDisk.Checked = forceReload;
            base.SaveChanges();
        }
        void SetInitialState_ProcessFile(string file, DateTime timestamp, int fileID, TextBox tb, Label outdatedLbl, ref bool forceReload)
        {
            tb.Text = file;
            Application.DoEvents();
            if (File.Exists(file))
            {
                DateTime dt = File.GetLastWriteTime(file);
                if (timestamp < dt)
                {
                    outdatedLbl.Visible = true;
                    forceReload = true;
                }
            }
        }
        public override void SaveChanges()
        {
            if (this.SettingsChanged)
            {   
                this._mcSettings.TrialsFile = this.ux_mcTrialsFile.Text;
                this._saveThread = new Thread(new ThreadStart(this.SaveChangesThread));
                this._saveThread.Name = "InputPanelSaveThread";
                this._saveThread.Start();
            }
        }
        void SaveChangesThread()
        {
            this.LoadFiles();       
            base.SaveChanges();     
            this.PostSave();        
        }
        void PostSave()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new EmptyEventHandler(this.PostSave));
            }
            else if (this._visualTracking)
            {   
                if (!this._loadFailed[MarketDataID])
                {
                    this.ux_marketDataFile.ForeColor = Control.DefaultForeColor;
                    this.ux_marketDataFile.BackColor = Color  .Empty;
                }
                if (!this._loadFailed[TechnologiesID])
                {
                    this.ux_technologiesFile.ForeColor = Control.DefaultForeColor;
                    this.ux_technologiesFile.BackColor = Color  .Empty;
                }
                if (!this._loadFailed[ParametersID])
                {
                    this.ux_parametersFile.ForeColor = Control.DefaultForeColor;
                    this.ux_parametersFile.BackColor = Color  .Empty;
                }
                if (!this._loadFailed[ScenariosID])
                {
                    this.ux_scenariosFile.ForeColor = Control.DefaultForeColor;
                    this.ux_scenariosFile.BackColor = Color  .Empty;
                }
                this.ux_marketDataFileOutdatedLabel  .Visible = false;
                this.ux_technologiesFileOutdatedLabel.Visible = false;
                this.ux_parametersFileOutdatedLabel  .Visible = false;
                this.ux_scenariosFileOutdatedLabel   .Visible = false;
                this.ux_mcTrialsFile.ForeColor = Control.DefaultForeColor;
                this.ux_mcTrialsFile.BackColor = Color  .Empty;
            }
        }
        #endregion
        #region 
        [Browsable(false)]
        public Industry MarketData
        {
            get { return (this._data[MarketDataID] == null) ? null : (Industry)this._data[MarketDataID]; }
        }
        [Browsable(false)]
        public List<Technology> Technologies
        {
            get { return (this._data[TechnologiesID] == null) ? null : (List<Technology>)this._data[TechnologiesID]; }
        }
        [Browsable(false)]
        public Parameters Parameters
        {
            get { return (this._data[ParametersID] == null) ? null : (Parameters)this._data[ParametersID]; }
        }
        [Browsable(false)]
        public List<Scenario> Scenarios
        {
            get { return (this._data[ScenariosID] == null) ? null : (List<Scenario>)this._data[ScenariosID]; }
        }
        [Browsable(false)]
        public bool LoadMonteCarloTrials
        {
            get { return this.ux_mcTrialsFile.Enabled; }
            set
            {
                this.ux_mcTrialsFileLabel .Enabled = value;
                this.ux_mcTrialsFile      .Enabled = value;
                this.ux_mcTrialsFileBrowse.Enabled = value;
            }
        }
        [Browsable(false)]
        public bool Parsing { get { return this._parsing > 0; } }
        [Browsable(false)]
        public override bool SettingsChanged
        {
            get
            {
                if (this.Parsing) { return false; }     
                if ((!File.Exists(this.ux_marketDataFile  .Text)) ||
                    (!File.Exists(this.ux_technologiesFile.Text)) ||
                    (!File.Exists(this.ux_parametersFile  .Text)) ||
                    (!File.Exists(this.ux_scenariosFile   .Text)) ||
                    (             this.ux_mcTrialsFile    .Enabled &&
                     !File.Exists(this.ux_mcTrialsFile    .Text))) { return false; }
                return
                    base.SettingsChanged ||
                    this.ux_reloadAllFromDisk.Checked ||
                    (!this.CompareFilePaths(this._inputSettings.MarketDataFile  , this.ux_marketDataFile  .Text)) ||
                    (!this.CompareFilePaths(this._inputSettings.TechnologiesFile, this.ux_technologiesFile.Text)) ||
                    (!this.CompareFilePaths(this._inputSettings.ParametersFile  , this.ux_parametersFile  .Text)) ||
                    (!this.CompareFilePaths(this._inputSettings.ScenariosFile   , this.ux_scenariosFile   .Text)) ||
                    (                                                             this.ux_mcTrialsFile    .Enabled &&
                     !this.CompareFilePaths(this._mcSettings   .TrialsFile      , this.ux_mcTrialsFile    .Text));
            }
        }
        #endregion
        #region 
        #region 
        Label   ux_inputFilesLabel;
        Panel   ux_inputFilesPanel;
        Label   ux_marketDataFileLabel;
        Label   ux_marketDataFileOutdatedLabel;
        TextBox ux_marketDataFile;
        Button  ux_marketDataFileBrowse;
        Label   ux_technologiesFileLabel;
        Label   ux_technologiesFileOutdatedLabel;
        TextBox ux_technologiesFile;
        Button  ux_technologiesFileBrowse;
        Label   ux_parametersFileLabel;
        Label   ux_parametersFileOutdatedLabel;
        TextBox ux_parametersFile;
        Button  ux_parametersFileBrowse;
        Label   ux_scenariosFileLabel;
        Label   ux_scenariosFileOutdatedLabel;
        TextBox ux_scenariosFile;
        Button  ux_scenariosFileBrowse;
        CheckBox ux_reloadAllFromDisk;
        Label   ux_mcTrialsFileLabel;
        TextBox ux_mcTrialsFile;
        Button  ux_mcTrialsFileBrowse;
        #endregion
        static readonly string[][] DesiredTitles =
            new string[][] {
                               new string[] {"CAFE Market Data"},
                               new string[] {"CAFE Technologies"},
                               new string[] {"CAFE Parameters"},
                               new string[] {"CAFE Scenarios"}
                           };
        static readonly string[] FriendlyTitles =
            new string[] {
                             "Market-Data",
                             "Technologies",
                             "Parameters",
                             "Scenarios"
                         };
        const int FileCount      = 4;   
        const int MarketDataID   = 0;
        const int TechnologiesID = 1;
        const int ParametersID   = 2;
        const int ScenariosID    = 3;
        int    _parsing;                        
        Thread _saveThread;                     
        bool  [] _verifiedFiles;                
        bool  [] _loadFailed;                   
        object[] _data;                         
        InputSettings _inputSettings;
        MonteCarloSettings _mcSettings;
        #endregion
    }
}

