//-------------------------------------------------------------------------------------
// SID Monitor - Utility for Sudden Ionospheric Disturbances Monitoring Stations
// Copyright (C) 2006-2011 - Lionel Loudet
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//-------------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;


namespace SID_monitor
{

    partial class Options : Form
    {
        // those booleans indicate whether or not database has been altered
        // after the OK button has been pressed.
        private static bool needToTuneChannelsDatabase = false;
        private static bool needToRenameChannelsDS = false;
        private static bool needToGenerateChannelsDatabase = false;
        private static bool needToGenerateGOESDatabase = false;

        // Option panels
        private PanelStartup startupDlg = new PanelStartup();
        private PanelDataAcquisition dataAcquisitionDlg = new PanelDataAcquisition();
        private PanelChannels channelsDlg = new PanelChannels();
        private PanelDatabase databaseDlg = new PanelDatabase();
        private PanelForecast forecastDlg = new PanelForecast();
        private PanelGraph graphDlg = new PanelGraph();
        private PanelReports reportsDlg = new PanelReports();
        private PanelLocation locationDlg = new PanelLocation();

        public Options()
        {
            InitializeComponent();

            startupDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            dataAcquisitionDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            channelsDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            databaseDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            forecastDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            graphDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            reportsDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);
            locationDlg.ValidData += new ValidDataEventHandler(this.ValidDataHandler);

        }


        private void treeViewParameters_AfterSelect(object sender, TreeViewEventArgs e)
        {
            this.panelOptions.Controls.Clear();

            switch ((e.Node.Name))
            {
                case "NodeStartup":
                    this.panelOptions.Controls.Add(startupDlg);
                    startupDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeDataAcquisition":
                    this.panelOptions.Controls.Add(dataAcquisitionDlg);
                    dataAcquisitionDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeChannels":
                    this.panelOptions.Controls.Add(channelsDlg);
                    channelsDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeDatabase":
                    this.panelOptions.Controls.Add(databaseDlg);
                    databaseDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeForecast":
                    this.panelOptions.Controls.Add(forecastDlg);
                    forecastDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeGraph":
                    this.panelOptions.Controls.Add(graphDlg);
                    graphDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeReports":
                    this.panelOptions.Controls.Add(reportsDlg);
                    reportsDlg.Dock = DockStyle.Fill;
                    break;
                case "NodeLocation":
                    this.panelOptions.Controls.Add(locationDlg);
                    locationDlg.Dock = DockStyle.Fill;
                    break;
            }
            this.panelOptions.ResumeLayout(false);
            this.panelOptions.PerformLayout();
        }

        #region Options Methods
        private void Options_Load(object sender, EventArgs e)
        {
            // Stop all background operations while modifying parameters
            Program.MainForm.StopAllTimers();

            // send an empty event to check the validity of elements and highlight erroneous nodes
            this.ValidDataHandler(sender, new validDataEventArgs());

            this.treeViewOptions.ExpandAll();
            this.treeViewOptions.Select();
            this.treeViewOptions.SelectedNode = this.treeViewOptions.Nodes["Startup"];
            this.panelOptions.Controls.Add(startupDlg);
            this.panelOptions.ResumeLayout(false);
            this.panelOptions.PerformLayout();
        }

        private void Options_FormClosing(object sender, FormClosingEventArgs e)
        {
            // check for necessary files and folders existence. Stop Timers if there is a problem.
            if (!File.Exists(SID_monitor.Properties.Settings.Default.RRDToolPath) ||
                !File.Exists(SID_monitor.Properties.Settings.Default.RRDToolDatabase) ||
                !File.Exists(SID_monitor.Properties.Settings.Default.RRDToolGOES) ||
                !Directory.Exists(SID_monitor.Properties.Settings.Default.HistoryDatabaseFolder))
            {
                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextErrorMessage("Invalid Configuration. Please correct the settings in the Tools/Options menu, \"Database\" pane.\n");
            }
            else
            {
                // restart all background operations
                Program.MainForm.StartAllTimers();
            }

        }
        #endregion

        /// <summary>
        /// Updates all datat when 'OK' is pressed
        /// </summary>
        private void button_OK_Click(object sender, EventArgs e)
        {

            string[] oldChannelStationCodes = new string[16] {
                SID_monitor.Properties.Settings.Default.Channel1StationCode ,
                SID_monitor.Properties.Settings.Default.Channel2StationCode ,
                SID_monitor.Properties.Settings.Default.Channel3StationCode ,
                SID_monitor.Properties.Settings.Default.Channel4StationCode ,
                SID_monitor.Properties.Settings.Default.Channel5StationCode ,
                SID_monitor.Properties.Settings.Default.Channel6StationCode ,
                SID_monitor.Properties.Settings.Default.Channel7StationCode ,
                SID_monitor.Properties.Settings.Default.Channel8StationCode ,
                SID_monitor.Properties.Settings.Default.Channel9StationCode ,
                SID_monitor.Properties.Settings.Default.Channel10StationCode,
                SID_monitor.Properties.Settings.Default.Channel11StationCode,
                SID_monitor.Properties.Settings.Default.Channel12StationCode,
                SID_monitor.Properties.Settings.Default.Channel13StationCode,
                SID_monitor.Properties.Settings.Default.Channel14StationCode,
                SID_monitor.Properties.Settings.Default.Channel15StationCode,
                SID_monitor.Properties.Settings.Default.Channel16StationCode
            };


            if (!File.Exists(this.databaseDlg.RRDToolGOESDatabase))
            {
                Options.needToGenerateGOESDatabase = true;
            }


            if (!File.Exists(this.databaseDlg.RRDToolChannelsDatabase) ||
                SID_monitor.Properties.Settings.Default.AcquisitionUpdate != this.dataAcquisitionDlg.AcquisitionUpdateValue ||
                SID_monitor.Properties.Settings.Default.RRDToolPath != this.databaseDlg.RRDToolPath ||
                SID_monitor.Properties.Settings.Default.RRDToolDatabase != this.databaseDlg.RRDToolChannelsDatabase ||
                SID_monitor.Properties.Settings.Default.Channel1Active != this.channelsDlg.Channel1Active ||
                SID_monitor.Properties.Settings.Default.Channel2Active != this.channelsDlg.Channel2Active ||
                SID_monitor.Properties.Settings.Default.Channel3Active != this.channelsDlg.Channel3Active ||
                SID_monitor.Properties.Settings.Default.Channel4Active != this.channelsDlg.Channel4Active ||
                SID_monitor.Properties.Settings.Default.Channel5Active != this.channelsDlg.Channel5Active ||
                SID_monitor.Properties.Settings.Default.Channel6Active != this.channelsDlg.Channel6Active ||
                SID_monitor.Properties.Settings.Default.Channel7Active != this.channelsDlg.Channel7Active ||
                SID_monitor.Properties.Settings.Default.Channel8Active != this.channelsDlg.Channel8Active ||
                SID_monitor.Properties.Settings.Default.Channel9Active != this.channelsDlg.Channel9Active ||
                SID_monitor.Properties.Settings.Default.Channel10Active != this.channelsDlg.Channel10Active ||
                SID_monitor.Properties.Settings.Default.Channel11Active != this.channelsDlg.Channel11Active ||
                SID_monitor.Properties.Settings.Default.Channel12Active != this.channelsDlg.Channel12Active ||
                SID_monitor.Properties.Settings.Default.Channel13Active != this.channelsDlg.Channel13Active ||
                SID_monitor.Properties.Settings.Default.Channel14Active != this.channelsDlg.Channel14Active ||
                SID_monitor.Properties.Settings.Default.Channel15Active != this.channelsDlg.Channel15Active ||
                SID_monitor.Properties.Settings.Default.Channel16Active != this.channelsDlg.Channel16Active)
            {
                Options.needToGenerateChannelsDatabase = true;
            }
            else
            {
                if (
                SID_monitor.Properties.Settings.Default.Channel1StationCode != this.channelsDlg.Channel1StationCode ||
                SID_monitor.Properties.Settings.Default.Channel2StationCode != this.channelsDlg.Channel2StationCode ||
                SID_monitor.Properties.Settings.Default.Channel3StationCode != this.channelsDlg.Channel3StationCode ||
                SID_monitor.Properties.Settings.Default.Channel4StationCode != this.channelsDlg.Channel4StationCode ||
                SID_monitor.Properties.Settings.Default.Channel5StationCode != this.channelsDlg.Channel5StationCode ||
                SID_monitor.Properties.Settings.Default.Channel6StationCode != this.channelsDlg.Channel6StationCode ||
                SID_monitor.Properties.Settings.Default.Channel7StationCode != this.channelsDlg.Channel7StationCode ||
                SID_monitor.Properties.Settings.Default.Channel8StationCode != this.channelsDlg.Channel8StationCode ||
                SID_monitor.Properties.Settings.Default.Channel9StationCode != this.channelsDlg.Channel9StationCode ||
                SID_monitor.Properties.Settings.Default.Channel10StationCode != this.channelsDlg.Channel10StationCode ||
                SID_monitor.Properties.Settings.Default.Channel11StationCode != this.channelsDlg.Channel11StationCode ||
                SID_monitor.Properties.Settings.Default.Channel12StationCode != this.channelsDlg.Channel12StationCode ||
                SID_monitor.Properties.Settings.Default.Channel13StationCode != this.channelsDlg.Channel13StationCode ||
                SID_monitor.Properties.Settings.Default.Channel14StationCode != this.channelsDlg.Channel14StationCode ||
                SID_monitor.Properties.Settings.Default.Channel15StationCode != this.channelsDlg.Channel15StationCode ||
                SID_monitor.Properties.Settings.Default.Channel16StationCode != this.channelsDlg.Channel16StationCode)
                {
                    Options.needToRenameChannelsDS = true;
                }

                if (
                SID_monitor.Properties.Settings.Default.ForecastAlpha != this.forecastDlg.ForecastAlpha ||
                SID_monitor.Properties.Settings.Default.ForecastBeta != this.forecastDlg.ForecastBeta ||
                SID_monitor.Properties.Settings.Default.ForecastGammaSeasonal != this.forecastDlg.ForecastGammaSeasonal ||
                SID_monitor.Properties.Settings.Default.ForecastGammaDevSeasonal != this.forecastDlg.ForecastGammaDevSeasonal ||
                SID_monitor.Properties.Settings.Default.DeltaPos != this.forecastDlg.DeltaPos ||
                SID_monitor.Properties.Settings.Default.DeltaNeg != this.forecastDlg.DeltaNeg ||
                SID_monitor.Properties.Settings.Default.ForecastThreshold != this.forecastDlg.ForecastThreshold ||
                SID_monitor.Properties.Settings.Default.ForecastWindowLength != this.forecastDlg.ForecastWindowLength)
                {
                    Options.needToTuneChannelsDatabase = true;
                }
            }


            // indicates if necessary that database needs to be updated and asks user confirmation
            if (needToGenerateGOESDatabase == true)
            {
                if (MessageBox.Show("You are about to change the current GOES database parameters. A new database consistent with the new parameters has to be generated.\n\nWarning: Previous data will be lost!!!\n\nPlease hit <OK> to proceed and <Cancel> to cancel changes.", "GOES Database Update Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                {
                    return;
                }
            }
            if (needToGenerateChannelsDatabase == true)
            {
                if (MessageBox.Show("You are about to change the current channels database parameters. A new database consistent with the new parameters has to be generated.\n\nWarning: Previous data will be lost!!!\n\nPlease hit <OK> to proceed and <Cancel> to cancel changes.", "Channels Database Update Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                {
                    return;
                }
            }
            else if ((needToTuneChannelsDatabase == true) || (needToRenameChannelsDS == true)) 
            {
                if (MessageBox.Show("You are about to change the current channels database parameters.\n\nNO DATA LOSS will result from this operation.\n\nPlease hit <OK> to proceed and <Cancel> to cancel changes.", "Database Tuning Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                {
                    return;
                }
            }


            // ----------------------------------------------
            // we start modifying parameters from here

            // Node Startup
            SID_monitor.Properties.Settings.Default.StartMinimized = this.startupDlg.StartMinimized;
            SID_monitor.Properties.Settings.Default.MinimizeToTray = this.startupDlg.MinimizeToTray;
            SID_monitor.Properties.Settings.Default.Verbose = this.startupDlg.Verbose;

            if (this.startupDlg.AutoStartup)
            {
                Registry.SetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "SID_monitor", "\"" + Path.GetFullPath(Application.ExecutablePath) + "\"");
            }
            else
            {
                Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true).DeleteValue("SID_monitor", false);
            }


            // Node Data Acquisition
            SID_monitor.Properties.Settings.Default.AcquisitionUpdate = this.dataAcquisitionDlg.AcquisitionUpdateValue;
            SID_monitor.Properties.Settings.Default.GOESUpdate = this.dataAcquisitionDlg.GOESUpdateValue;


            #region Node Channels
            // - checkbox 
            SID_monitor.Properties.Settings.Default.Channel1Active = this.channelsDlg.Channel1Active;
            SID_monitor.Properties.Settings.Default.Channel2Active = this.channelsDlg.Channel2Active;
            SID_monitor.Properties.Settings.Default.Channel3Active = this.channelsDlg.Channel3Active;
            SID_monitor.Properties.Settings.Default.Channel4Active = this.channelsDlg.Channel4Active;
            SID_monitor.Properties.Settings.Default.Channel5Active = this.channelsDlg.Channel5Active;
            SID_monitor.Properties.Settings.Default.Channel6Active = this.channelsDlg.Channel6Active;
            SID_monitor.Properties.Settings.Default.Channel7Active = this.channelsDlg.Channel7Active;
            SID_monitor.Properties.Settings.Default.Channel8Active = this.channelsDlg.Channel8Active;
            SID_monitor.Properties.Settings.Default.Channel9Active = this.channelsDlg.Channel9Active;
            SID_monitor.Properties.Settings.Default.Channel10Active = this.channelsDlg.Channel10Active;
            SID_monitor.Properties.Settings.Default.Channel11Active = this.channelsDlg.Channel11Active;
            SID_monitor.Properties.Settings.Default.Channel12Active = this.channelsDlg.Channel12Active;
            SID_monitor.Properties.Settings.Default.Channel13Active = this.channelsDlg.Channel13Active;
            SID_monitor.Properties.Settings.Default.Channel14Active = this.channelsDlg.Channel14Active;
            SID_monitor.Properties.Settings.Default.Channel15Active = this.channelsDlg.Channel15Active;
            SID_monitor.Properties.Settings.Default.Channel16Active = this.channelsDlg.Channel16Active;

            // Port selection
            SID_monitor.Properties.Settings.Default.Channel1Port = this.channelsDlg.Channel1Port;
            SID_monitor.Properties.Settings.Default.Channel2Port = this.channelsDlg.Channel2Port;
            SID_monitor.Properties.Settings.Default.Channel3Port = this.channelsDlg.Channel3Port;
            SID_monitor.Properties.Settings.Default.Channel4Port = this.channelsDlg.Channel4Port;
            SID_monitor.Properties.Settings.Default.Channel5Port = this.channelsDlg.Channel5Port;
            SID_monitor.Properties.Settings.Default.Channel6Port = this.channelsDlg.Channel6Port;
            SID_monitor.Properties.Settings.Default.Channel7Port = this.channelsDlg.Channel7Port;
            SID_monitor.Properties.Settings.Default.Channel8Port = this.channelsDlg.Channel8Port;
            SID_monitor.Properties.Settings.Default.Channel9Port = this.channelsDlg.Channel9Port;
            SID_monitor.Properties.Settings.Default.Channel10Port = this.channelsDlg.Channel10Port;
            SID_monitor.Properties.Settings.Default.Channel11Port = this.channelsDlg.Channel11Port;
            SID_monitor.Properties.Settings.Default.Channel12Port = this.channelsDlg.Channel12Port;
            SID_monitor.Properties.Settings.Default.Channel13Port = this.channelsDlg.Channel13Port;
            SID_monitor.Properties.Settings.Default.Channel14Port = this.channelsDlg.Channel14Port;
            SID_monitor.Properties.Settings.Default.Channel15Port = this.channelsDlg.Channel15Port;
            SID_monitor.Properties.Settings.Default.Channel16Port = this.channelsDlg.Channel16Port;


            // Line width
            SID_monitor.Properties.Settings.Default.Channel1LineWidth = this.channelsDlg.Channel1LineWidth;
            SID_monitor.Properties.Settings.Default.Channel2LineWidth = this.channelsDlg.Channel2LineWidth;
            SID_monitor.Properties.Settings.Default.Channel3LineWidth = this.channelsDlg.Channel3LineWidth;
            SID_monitor.Properties.Settings.Default.Channel4LineWidth = this.channelsDlg.Channel4LineWidth;
            SID_monitor.Properties.Settings.Default.Channel5LineWidth = this.channelsDlg.Channel5LineWidth;
            SID_monitor.Properties.Settings.Default.Channel6LineWidth = this.channelsDlg.Channel6LineWidth;
            SID_monitor.Properties.Settings.Default.Channel7LineWidth = this.channelsDlg.Channel7LineWidth;
            SID_monitor.Properties.Settings.Default.Channel8LineWidth = this.channelsDlg.Channel8LineWidth;
            SID_monitor.Properties.Settings.Default.Channel9LineWidth = this.channelsDlg.Channel9LineWidth;
            SID_monitor.Properties.Settings.Default.Channel10LineWidth = this.channelsDlg.Channel10LineWidth;
            SID_monitor.Properties.Settings.Default.Channel11LineWidth = this.channelsDlg.Channel11LineWidth;
            SID_monitor.Properties.Settings.Default.Channel12LineWidth = this.channelsDlg.Channel12LineWidth;
            SID_monitor.Properties.Settings.Default.Channel13LineWidth = this.channelsDlg.Channel13LineWidth;
            SID_monitor.Properties.Settings.Default.Channel14LineWidth = this.channelsDlg.Channel14LineWidth;
            SID_monitor.Properties.Settings.Default.Channel15LineWidth = this.channelsDlg.Channel15LineWidth;
            SID_monitor.Properties.Settings.Default.Channel16LineWidth = this.channelsDlg.Channel16LineWidth;
            SID_monitor.Properties.Settings.Default.PrimaryGOESLineWidth = this.channelsDlg.PrimaryGOESLineWidth;
            SID_monitor.Properties.Settings.Default.SecondaryGOESLineWidth = this.channelsDlg.SecondaryGOESLineWidth;

            // stationCode
            SID_monitor.Properties.Settings.Default.Channel1StationCode = this.channelsDlg.Channel1StationCode;
            SID_monitor.Properties.Settings.Default.Channel2StationCode = this.channelsDlg.Channel2StationCode;
            SID_monitor.Properties.Settings.Default.Channel3StationCode = this.channelsDlg.Channel3StationCode;
            SID_monitor.Properties.Settings.Default.Channel4StationCode = this.channelsDlg.Channel4StationCode;
            SID_monitor.Properties.Settings.Default.Channel5StationCode = this.channelsDlg.Channel5StationCode;
            SID_monitor.Properties.Settings.Default.Channel6StationCode = this.channelsDlg.Channel6StationCode;
            SID_monitor.Properties.Settings.Default.Channel7StationCode = this.channelsDlg.Channel7StationCode;
            SID_monitor.Properties.Settings.Default.Channel8StationCode = this.channelsDlg.Channel8StationCode;
            SID_monitor.Properties.Settings.Default.Channel9StationCode = this.channelsDlg.Channel9StationCode;
            SID_monitor.Properties.Settings.Default.Channel10StationCode = this.channelsDlg.Channel10StationCode;
            SID_monitor.Properties.Settings.Default.Channel11StationCode = this.channelsDlg.Channel11StationCode;
            SID_monitor.Properties.Settings.Default.Channel12StationCode = this.channelsDlg.Channel12StationCode;
            SID_monitor.Properties.Settings.Default.Channel13StationCode = this.channelsDlg.Channel13StationCode;
            SID_monitor.Properties.Settings.Default.Channel14StationCode = this.channelsDlg.Channel14StationCode;
            SID_monitor.Properties.Settings.Default.Channel15StationCode = this.channelsDlg.Channel15StationCode;
            SID_monitor.Properties.Settings.Default.Channel16StationCode = this.channelsDlg.Channel16StationCode;

            // title
            SID_monitor.Properties.Settings.Default.Channel1Title = this.channelsDlg.Channel1Title;
            SID_monitor.Properties.Settings.Default.Channel2Title = this.channelsDlg.Channel2Title;
            SID_monitor.Properties.Settings.Default.Channel3Title = this.channelsDlg.Channel3Title;
            SID_monitor.Properties.Settings.Default.Channel4Title = this.channelsDlg.Channel4Title;
            SID_monitor.Properties.Settings.Default.Channel5Title = this.channelsDlg.Channel5Title;
            SID_monitor.Properties.Settings.Default.Channel6Title = this.channelsDlg.Channel6Title;
            SID_monitor.Properties.Settings.Default.Channel7Title = this.channelsDlg.Channel7Title;
            SID_monitor.Properties.Settings.Default.Channel8Title = this.channelsDlg.Channel8Title;
            SID_monitor.Properties.Settings.Default.Channel9Title = this.channelsDlg.Channel9Title;
            SID_monitor.Properties.Settings.Default.Channel10Title = this.channelsDlg.Channel10Title;
            SID_monitor.Properties.Settings.Default.Channel11Title = this.channelsDlg.Channel11Title;
            SID_monitor.Properties.Settings.Default.Channel12Title = this.channelsDlg.Channel12Title;
            SID_monitor.Properties.Settings.Default.Channel13Title = this.channelsDlg.Channel13Title;
            SID_monitor.Properties.Settings.Default.Channel14Title = this.channelsDlg.Channel14Title;
            SID_monitor.Properties.Settings.Default.Channel15Title = this.channelsDlg.Channel15Title;
            SID_monitor.Properties.Settings.Default.Channel16Title = this.channelsDlg.Channel16Title;
            SID_monitor.Properties.Settings.Default.PrimaryGOESTitle = this.channelsDlg.PrimaryGOESTitle;
            SID_monitor.Properties.Settings.Default.SecondaryGOESTitle = this.channelsDlg.SecondaryGOESTitle;


            // color selection
            SID_monitor.Properties.Settings.Default.Channel1LineColor = this.channelsDlg.Channel1LineColor;
            SID_monitor.Properties.Settings.Default.Channel2LineColor = this.channelsDlg.Channel2LineColor;
            SID_monitor.Properties.Settings.Default.Channel3LineColor = this.channelsDlg.Channel3LineColor;
            SID_monitor.Properties.Settings.Default.Channel4LineColor = this.channelsDlg.Channel4LineColor;
            SID_monitor.Properties.Settings.Default.Channel5LineColor = this.channelsDlg.Channel5LineColor;
            SID_monitor.Properties.Settings.Default.Channel6LineColor = this.channelsDlg.Channel6LineColor;
            SID_monitor.Properties.Settings.Default.Channel7LineColor = this.channelsDlg.Channel7LineColor;
            SID_monitor.Properties.Settings.Default.Channel8LineColor = this.channelsDlg.Channel8LineColor;
            SID_monitor.Properties.Settings.Default.Channel9LineColor = this.channelsDlg.Channel9LineColor;
            SID_monitor.Properties.Settings.Default.Channel10LineColor = this.channelsDlg.Channel10LineColor;
            SID_monitor.Properties.Settings.Default.Channel11LineColor = this.channelsDlg.Channel11LineColor;
            SID_monitor.Properties.Settings.Default.Channel12LineColor = this.channelsDlg.Channel12LineColor;
            SID_monitor.Properties.Settings.Default.Channel13LineColor = this.channelsDlg.Channel13LineColor;
            SID_monitor.Properties.Settings.Default.Channel14LineColor = this.channelsDlg.Channel14LineColor;
            SID_monitor.Properties.Settings.Default.Channel15LineColor = this.channelsDlg.Channel15LineColor;
            SID_monitor.Properties.Settings.Default.Channel16LineColor = this.channelsDlg.Channel16LineColor;
            SID_monitor.Properties.Settings.Default.PrimaryGOESLineColor = this.channelsDlg.PrimaryGOESLineColor;
            SID_monitor.Properties.Settings.Default.SecondaryGOESLineColor = this.channelsDlg.SecondaryGOESLineColor;

            #endregion

            
            // Node Database
            SID_monitor.Properties.Settings.Default.RRDToolPath = this.databaseDlg.RRDToolPath;
            SID_monitor.Properties.Settings.Default.RRDToolDatabase = this.databaseDlg.RRDToolChannelsDatabase;
            SID_monitor.Properties.Settings.Default.RRDToolGOES = this.databaseDlg.RRDToolGOESDatabase;
            SID_monitor.Properties.Settings.Default.HistoryDatabaseFolder = this.databaseDlg.HistoryDatabaseFolder;


            // Node Forecast
            SID_monitor.Properties.Settings.Default.ForecastAlpha = this.forecastDlg.ForecastAlpha;
            SID_monitor.Properties.Settings.Default.ForecastBeta = this.forecastDlg.ForecastBeta;
            SID_monitor.Properties.Settings.Default.ForecastGammaSeasonal = this.forecastDlg.ForecastGammaSeasonal;
            SID_monitor.Properties.Settings.Default.ForecastGammaDevSeasonal = this.forecastDlg.ForecastGammaDevSeasonal;
            SID_monitor.Properties.Settings.Default.DeltaPos = this.forecastDlg.DeltaPos;
            SID_monitor.Properties.Settings.Default.DeltaNeg = this.forecastDlg.DeltaNeg;
            SID_monitor.Properties.Settings.Default.ForecastThreshold = this.forecastDlg.ForecastThreshold;
            SID_monitor.Properties.Settings.Default.ForecastWindowLength = this.forecastDlg.ForecastWindowLength;


            // Node Graph
            SID_monitor.Properties.Settings.Default.GraphUpdate = this.graphDlg.GraphUpdateValue;

            SID_monitor.Properties.Settings.Default.CivilTwilightColor = this.graphDlg.CivilTwilightColor;
            SID_monitor.Properties.Settings.Default.NauticalTwilightColor = this.graphDlg.NautiTwilightColor;
            SID_monitor.Properties.Settings.Default.AstronomicalTwilightColor = this.graphDlg.AstroTwilightColor;
            SID_monitor.Properties.Settings.Default.NightColor = this.graphDlg.NightTwilightColor;

            SID_monitor.Properties.Settings.Default.FailuresColor = this.graphDlg.FailuresColor;

            SID_monitor.Properties.Settings.Default.ShadeValue1 = this.graphDlg.ShadeValue1;
            SID_monitor.Properties.Settings.Default.ShadeValue2 = this.graphDlg.ShadeValue2;
            SID_monitor.Properties.Settings.Default.ShadeValue3 = this.graphDlg.ShadeValue3;


            // Node Reports
            SID_monitor.Properties.Settings.Default.SendMailUponEventDetection = this.reportsDlg.SendMailUponEventDetection;
            SID_monitor.Properties.Settings.Default.SendMailHourly = this.reportsDlg.SendMailHourly;
            SID_monitor.Properties.Settings.Default.SendMailWithGraph = this.reportsDlg.SendMailWithGraph;
            SID_monitor.Properties.Settings.Default.SendMailTo = this.reportsDlg.SendMailTo;
            SID_monitor.Properties.Settings.Default.ObserverCode = this.reportsDlg.ObserverCode;
            SID_monitor.Properties.Settings.Default.SendMailFrom = this.reportsDlg.SendMailFrom;
            SID_monitor.Properties.Settings.Default.SMTPServerAddress = this.reportsDlg.SMTPServerAddress;
            SID_monitor.Properties.Settings.Default.SMTPServerPort = this.reportsDlg.SMTPServerPort;


            // Node Location
            SID_monitor.Properties.Settings.Default.LatDeg = this.locationDlg.LatDegs;
            SID_monitor.Properties.Settings.Default.LatMins = this.locationDlg.LatMins;
            SID_monitor.Properties.Settings.Default.LatSecs = this.locationDlg.LatSecs;
            SID_monitor.Properties.Settings.Default.LatHemi = this.locationDlg.LatHemi;

            SID_monitor.Properties.Settings.Default.LongDeg = this.locationDlg.LongDegs;
            SID_monitor.Properties.Settings.Default.LongMins = this.locationDlg.LongMins;
            SID_monitor.Properties.Settings.Default.LongSecs = this.locationDlg.LongSecs;
            SID_monitor.Properties.Settings.Default.LongHemi = this.locationDlg.LongHemi;

            // save settings
            SID_monitor.Properties.Settings.Default.Save();

            // create Dataset dsChannels from settings
            Program.MainForm.createDsChannels();

            // setting channel selection on graph and value labels
            Program.MainForm.channelsDockablePanel.setGraphChannelsItems();

            // we update the GOES database if necessary
            if (needToGenerateGOESDatabase == true)
            {
                string RRDCommand = GOES.CreateRRDToolGOESCreateCommand(SID_monitor.Properties.Settings.Default.RRDToolGOES);
                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextMessage("Creating New GOES Database...\n");
                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextRRDToolMessage("rrdtool " + RRDCommand + "\n");
                RRDToolConnection.ExecuteRRDTool(RRDCommand, RRDToolProcess.ShowOptions.ErrorsAndStdOut, Program.MainForm.outputTextBoxDockablePanel.Handle);
                Program.MainForm.goesDockablePanel.updateLabelGOESUpdate();
                needToGenerateGOESDatabase = false;
            }

            // we update the channels database if necessary
            if (needToGenerateChannelsDatabase == true)
            {
                string RRDCommand = SID_monitor.Program.MainForm.CreateRRDToolCreateCommand();

                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextMessage("Creating New Channels Database...\n");
                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextRRDToolMessage("rrdtool " + RRDCommand + "\n");
                RRDToolConnection.ExecuteRRDTool(RRDCommand, RRDToolProcess.ShowOptions.ErrorsAndStdOut, Program.MainForm.outputTextBoxDockablePanel.Handle);
                needToGenerateChannelsDatabase = false;
            }
            else
            {
                if (needToRenameChannelsDS == true)
                {
                    string RRDCommand = SID_monitor.Program.MainForm.CreateRRDToolRenameDSCommand(oldChannelStationCodes);

                    Program.MainForm.outputTextBoxDockablePanel.AddOutputTextMessage("Renaming Datasets...\n");
                    Program.MainForm.outputTextBoxDockablePanel.AddOutputTextRRDToolMessage("rrdtool " + RRDCommand + "\n");
                    RRDToolConnection.ExecuteRRDTool(RRDCommand, RRDToolProcess.ShowOptions.ErrorsAndStdOut, Program.MainForm.outputTextBoxDockablePanel.Handle);
                    needToRenameChannelsDS = false;
                }

                if (needToTuneChannelsDatabase == true)
                {
                    string RRDCommand = SID_monitor.Program.MainForm.CreateRRDToolTuneCommand();

                    Program.MainForm.outputTextBoxDockablePanel.AddOutputTextMessage("Tuning Database...\n");
                    Program.MainForm.outputTextBoxDockablePanel.AddOutputTextRRDToolMessage("rrdtool " + RRDCommand + "\n");
                    RRDToolConnection.ExecuteRRDTool(RRDCommand, RRDToolProcess.ShowOptions.ErrorsAndStdOut, Program.MainForm.outputTextBoxDockablePanel.Handle);
                    needToTuneChannelsDatabase = false;
                }
            }

            this.Close();
        }


        /// <summary>
        /// Closes the form when Cancel is pressed
        /// </summary>
        private void button_cancel_Click(object sender, EventArgs e)
        {
    
            // clears the static list of errors in the panels. This list will be recreated when the "options" window is reopened
            validDataEventArgs ev = new validDataEventArgs();
            ev.Clear();

            this.Close();
        }


        #region Validation Events Handling
        /// <summary>
        /// Enables or disables the OK button according to the ValidData Event
        /// Sets the tree node colors according to the panel validity
        /// </summary>
        public void ValidDataHandler(object sender, validDataEventArgs e)
        {
            if (e.ValidData)
            {
                this.button_OK.Enabled = true;
            }
            else
            {
                this.button_OK.Enabled = false;
            }

            // NodeStartup
            if (e.NodeStartupValidData)
            {
                this.treeViewOptions.Nodes["NodeStartup"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeStartup"].Expand();
                this.treeViewOptions.Nodes["NodeStartup"].ForeColor = Color.Red;
            }

            // NodeDataAcquisition
            if (e.NodeDataAcquisitionValidData)
            {
                this.treeViewOptions.Nodes["NodeDataAcquisition"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeDataAcquisition"].Expand();
                this.treeViewOptions.Nodes["NodeDataAcquisition"].ForeColor = Color.Red;
            }

            // NodeChannels
            if (e.NodeChannelsValidData)
            {
                this.treeViewOptions.Nodes["NodeChannels"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeChannels"].Expand();
                this.treeViewOptions.Nodes["NodeChannels"].ForeColor = Color.Red;
            }

            // NodeDatabase
            if (e.NodeDatabaseValidData)
            {
                this.treeViewOptions.Nodes["NodeDatabase"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeDatabase"].Expand();
                this.treeViewOptions.Nodes["NodeDatabase"].ForeColor = Color.Red;
            }

            // NodeForecast
            if (e.NodeForecastValidData)
            {
                this.treeViewOptions.Nodes["NodeForecast"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeForecast"].Expand();
                this.treeViewOptions.Nodes["NodeForecast"].ForeColor = Color.Red;
            }

            // NodeGraph
            if (e.NodeGraphValidData)
            {
                this.treeViewOptions.Nodes["NodeGraph"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeGraph"].Expand();
                this.treeViewOptions.Nodes["NodeGraph"].ForeColor = Color.Red;
            }

            // NodeReports
            if (e.NodeReportsValidData)
            {
                this.treeViewOptions.Nodes["NodeReports"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeReports"].Expand();
                this.treeViewOptions.Nodes["NodeReports"].ForeColor = Color.Red;
            }

            // NodeLocation
            if (e.NodeLocationValidData)
            {
                this.treeViewOptions.Nodes["NodeLocation"].ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.treeViewOptions.Nodes["NodeLocation"].Expand();
                this.treeViewOptions.Nodes["NodeLocation"].ForeColor = Color.Red;
            }
        }
        #endregion


    }



    /// <summary>
    /// Class that defines the event for validity of the data in each dialog of the panel
    /// </summary>
    public class validDataEventArgs : EventArgs
    {
        private static ArrayList NodeStartupErroneousElements = new ArrayList();
        private static ArrayList NodeDataAcquisitionErroneousElements = new ArrayList();
        private static ArrayList NodeChannelsErroneousElements = new ArrayList();
        private static ArrayList NodeDatabaseErroneousElements = new ArrayList();
        private static ArrayList NodeForecastErroneousElements = new ArrayList();
        private static ArrayList NodeGraphErroneousElements = new ArrayList();
        private static ArrayList NodeReportsErroneousElements = new ArrayList();
        private static ArrayList NodeLocationErroneousElements = new ArrayList();


        #region Constructors
        /// <summary>
        /// Empty Event
        /// </summary>
        public validDataEventArgs()
        {
        }

        /// <summary>
        /// Updates the content of the static array list when receiving a new event
        /// </summary>
        /// <param name="NodeName">The Node that raised the event</param>
        /// <param name="ControlId">The handle of the control that gets valid/invalid</param>
        /// <param name="validData">Validity or invalidity of the control content</param>
        public validDataEventArgs(string NodeName, Object ControlId, bool validData)
        {

            switch (NodeName)
            {
                case "NodeStartup":
                    if ((validData) && (NodeStartupErroneousElements.Contains(ControlId)))
                    {
                        NodeStartupErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeStartupErroneousElements.Contains(ControlId)))
                    {
                        NodeStartupErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeDataAcquisition":
                    if ((validData) && (NodeDataAcquisitionErroneousElements.Contains(ControlId)))
                    {
                        NodeDataAcquisitionErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeDataAcquisitionErroneousElements.Contains(ControlId)))
                    {
                        NodeDataAcquisitionErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeChannels":
                    if ((validData) && (NodeChannelsErroneousElements.Contains(ControlId)))
                    {
                        NodeChannelsErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeChannelsErroneousElements.Contains(ControlId)))
                    {
                        NodeChannelsErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeDatabase":
                    if ((validData) && (NodeDatabaseErroneousElements.Contains(ControlId)))
                    {
                        NodeDatabaseErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeDatabaseErroneousElements.Contains(ControlId)))
                    {
                        NodeDatabaseErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeForecast":
                    if ((validData) && (NodeForecastErroneousElements.Contains(ControlId)))
                    {
                        NodeForecastErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeForecastErroneousElements.Contains(ControlId)))
                    {
                        NodeForecastErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeGraph":
                    if ((validData) && (NodeGraphErroneousElements.Contains(ControlId)))
                    {
                        NodeGraphErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeGraphErroneousElements.Contains(ControlId)))
                    {
                        NodeGraphErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeReports":
                    if ((validData) && (NodeReportsErroneousElements.Contains(ControlId)))
                    {
                        NodeReportsErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeReportsErroneousElements.Contains(ControlId)))
                    {
                        NodeReportsErroneousElements.Add(ControlId);
                    }
                    break;
                case "NodeLocation":
                    if ((validData) && (NodeLocationErroneousElements.Contains(ControlId)))
                    {
                        NodeLocationErroneousElements.Remove(ControlId);
                    }
                    else if ((!validData) && (!NodeLocationErroneousElements.Contains(ControlId)))
                    {
                        NodeLocationErroneousElements.Add(ControlId);
                    }
                    break;
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Clears the static values of the event
        /// </summary>
        public void Clear()
        {
            NodeStartupErroneousElements.Clear();
            NodeDataAcquisitionErroneousElements.Clear();
            NodeChannelsErroneousElements.Clear();
            NodeDatabaseErroneousElements.Clear();
            NodeForecastErroneousElements.Clear();
            NodeGraphErroneousElements.Clear();
            NodeReportsErroneousElements.Clear();
            NodeLocationErroneousElements.Clear();
        }
        #endregion

        #region Properties
        // Indicates if data is valid or not (for all and each panel)
        public bool ValidData
        {
            get
            {
                return ((NodeStartupErroneousElements.Count == 0) &&
                         (NodeDataAcquisitionErroneousElements.Count == 0) &&
                         (NodeChannelsErroneousElements.Count == 0) &&
                         (NodeDatabaseErroneousElements.Count == 0) &&
                         (NodeForecastErroneousElements.Count == 0) &&
                         (NodeGraphErroneousElements.Count == 0) &&
                         (NodeReportsErroneousElements.Count == 0) &&
                         (NodeLocationErroneousElements.Count == 0));
            }
        }

        public bool NodeStartupValidData
        {
            get
            {
                return (NodeStartupErroneousElements.Count == 0);
            }
        }

        public bool NodeDataAcquisitionValidData
        {
            get
            {
                return (NodeDataAcquisitionErroneousElements.Count == 0);
            }
        }

        public bool NodeChannelsValidData
        {
            get
            {
                return (NodeChannelsErroneousElements.Count == 0);
            }
        }

        public bool NodeDatabaseValidData
        {
            get
            {
                return (NodeDatabaseErroneousElements.Count == 0);
            }
        }

        public bool NodeForecastValidData
        {
            get
            {
                return (NodeForecastErroneousElements.Count == 0);
            }
        }

        public bool NodeGraphValidData
        {
            get
            {
                return (NodeGraphErroneousElements.Count == 0);
            }
        }

        public bool NodeReportsValidData
        {
            get
            {
                return (NodeReportsErroneousElements.Count == 0);
            }
        }

        public bool NodeLocationValidData
        {
            get
            {
                return (NodeLocationErroneousElements.Count == 0);
            }
        }
        #endregion

    }

    // Delegate declaration of the ValidDataEventHandler
    public delegate void ValidDataEventHandler(object sender, validDataEventArgs e);


}