//-------------------------------------------------------------------------------------
// SID Monitor - Utility for Sudden Ionospheric Disturbances Monitoring Stations
// Copyright (C) 2006 - 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.Threading;
using System.Globalization;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;
using System.Net.Mail;
using WeifenLuo.WinFormsUI;
using System.Deployment.Application;


namespace SID_monitor
{
    public partial class MainForm : Form
    {
        // UI configuration deserialization method
        private DeserializeDockContent m_deserializeDockContent;

        // all dockable panels
        public GOESDockablePanel goesDockablePanel = new GOESDockablePanel();
        public ChannelsDockablePanel channelsDockablePanel = new ChannelsDockablePanel();
        public DateDockablePanel dateDockablePanel = new DateDockablePanel();
        public ViewerDockablePanel viewerDockablePanel = new ViewerDockablePanel();
        public OutputTextBoxDockablePanel outputTextBoxDockablePanel = new OutputTextBoxDockablePanel();

        // global variables
        private DateTime TodayDate = DateTime.MinValue;
        private SunriseSunset TodaySunriseSunsetTimes = null;
        private int currentSunPosition = -1;

        public MainForm()
        {
            m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);

            InitializeComponent();


            // goesDockablePanel
            this.goesDockablePanel.GOES10ShowChanged += new GOESDockablePanel.GOESShowChangeEventHandler(this.timerGraphUpdate_Tick);
            this.goesDockablePanel.GOES11ShowChanged += new GOESDockablePanel.GOESShowChangeEventHandler(this.timerGraphUpdate_Tick);
            this.goesDockablePanel.GOES12ShowChanged += new GOESDockablePanel.GOESShowChangeEventHandler(this.timerGraphUpdate_Tick);
            this.goesDockablePanel.GOESDownloadRequested += new System.EventHandler(this.timerGOESUpdate_Tick);

            // channelsDockablePanel
            this.channelsDockablePanel.ShowSunChanged += new ChannelsDockablePanel.ShowChangeEventHandler(this.timerGraphUpdate_Tick);
            this.channelsDockablePanel.ShowForecastChanged += new ChannelsDockablePanel.ShowChangeEventHandler(this.timerGraphUpdate_Tick);
            this.channelsDockablePanel.ShowChannelsChanged += new ChannelsDockablePanel.ChannelsShowChangeEventHandler(this.timerGraphUpdate_Tick);

            // dateDockablePanel
            this.dateDockablePanel.GraphUpdateRequested += new System.EventHandler(this.timerGraphUpdate_Tick);

            // viewerDockablePanel
            this.viewerDockablePanel.GraphUpdateRequested += new System.EventHandler(this.viewerGraph_UpdateRequested);
            this.viewerDockablePanel.GraphFileChanged += new PictureViewer.Viewer.GraphFileChangeEventHandler(this.viewerGraph_GraphFileChanged);

            
            // helpProvider -------------------------------------------------------------------------------------------

            // goesDockablePanel
            this.helpProvider.SetHelpNavigator(this.goesDockablePanel, HelpNavigator.Topic);
            this.helpProvider.SetHelpKeyword(this.goesDockablePanel, "goestab.htm");

            // channelsDockablePanel
            this.helpProvider.SetHelpNavigator(this.channelsDockablePanel, HelpNavigator.Topic);
            this.helpProvider.SetHelpKeyword(this.channelsDockablePanel, "channelstab.htm");

            // dateDockablePanel
            this.helpProvider.SetHelpNavigator(this.dateDockablePanel, HelpNavigator.Topic);
            this.helpProvider.SetHelpKeyword(this.dateDockablePanel, "datetab.htm");
            
            // viewerDockablePanel
            this.helpProvider.SetHelpNavigator(this.viewerDockablePanel, HelpNavigator.Topic);
            this.helpProvider.SetHelpKeyword(this.viewerDockablePanel, "graphical_user_interface.htm");

            // outputTextBoxDockablePanel
            this.helpProvider.SetHelpNavigator(this.outputTextBoxDockablePanel, HelpNavigator.Topic);
            this.helpProvider.SetHelpKeyword(this.outputTextBoxDockablePanel, "message.htm");
        }

        #region Initialisation Methods

        /// <summary>
        /// creation of the dataset dsChannels rows
        /// </summary>
        public void createDsChannels()
        {
            dsChannels.Clear();

            // Acquisition Data
            dsChannels.AcquisitionDataRow rowAcquisitionData = dsChannels.AcquisitionData.NewAcquisitionDataRow();
            rowAcquisitionData.Values = new System.Collections.ArrayList();
            dsChannels.AcquisitionData.AddAcquisitionDataRow(rowAcquisitionData);
            dsChannels.AcquisitionData.AcceptChanges();


            #region creation of each channel in the Channels DataTable
            // channel 1
            dsChannels.ChannelsRow rowChannel1 = dsChannels.Channels.NewChannelsRow();

            rowChannel1.id = 1;

            rowChannel1.Active = SID_monitor.Properties.Settings.Default.Channel1Active;
            if (rowChannel1.Active)
            {
                rowChannel1.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel1Port);
                rowChannel1.StationCode = SID_monitor.Properties.Settings.Default.Channel1StationCode;
                rowChannel1.LineWidth = SID_monitor.Properties.Settings.Default.Channel1LineWidth;
                rowChannel1.LineColor = SID_monitor.Properties.Settings.Default.Channel1LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel1);


            // channel 2
            dsChannels.ChannelsRow rowChannel2 = dsChannels.Channels.NewChannelsRow();

            rowChannel2.id = 2;

            rowChannel2.Active = SID_monitor.Properties.Settings.Default.Channel2Active;
            if (rowChannel2.Active)
            {
                rowChannel2.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel2Port);
                rowChannel2.StationCode = SID_monitor.Properties.Settings.Default.Channel2StationCode;
                rowChannel2.LineWidth = SID_monitor.Properties.Settings.Default.Channel2LineWidth;
                rowChannel2.LineColor = SID_monitor.Properties.Settings.Default.Channel2LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel2);


            // channel 3
            dsChannels.ChannelsRow rowChannel3 = dsChannels.Channels.NewChannelsRow();

            rowChannel3.id = 3;

            rowChannel3.Active = SID_monitor.Properties.Settings.Default.Channel3Active;
            if (rowChannel3.Active)
            {
                rowChannel3.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel3Port);
                rowChannel3.StationCode = SID_monitor.Properties.Settings.Default.Channel3StationCode;
                rowChannel3.LineWidth = SID_monitor.Properties.Settings.Default.Channel3LineWidth;
                rowChannel3.LineColor = SID_monitor.Properties.Settings.Default.Channel3LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel3);

            // channel 4
            dsChannels.ChannelsRow rowChannel4 = dsChannels.Channels.NewChannelsRow();

            rowChannel4.id = 4;

            rowChannel4.Active = SID_monitor.Properties.Settings.Default.Channel4Active;
            if (rowChannel4.Active)
            {
                rowChannel4.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel4Port);
                rowChannel4.StationCode = SID_monitor.Properties.Settings.Default.Channel4StationCode;
                rowChannel4.LineWidth = SID_monitor.Properties.Settings.Default.Channel4LineWidth;
                rowChannel4.LineColor = SID_monitor.Properties.Settings.Default.Channel4LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel4);


            // channel 5
            dsChannels.ChannelsRow rowChannel5 = dsChannels.Channels.NewChannelsRow();

            rowChannel5.id = 5;

            rowChannel5.Active = SID_monitor.Properties.Settings.Default.Channel5Active;
            if (rowChannel5.Active)
            {
                rowChannel5.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel5Port);
                rowChannel5.StationCode = SID_monitor.Properties.Settings.Default.Channel5StationCode;
                rowChannel5.LineWidth = SID_monitor.Properties.Settings.Default.Channel5LineWidth;
                rowChannel5.LineColor = SID_monitor.Properties.Settings.Default.Channel5LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel5);


            // channel 6
            dsChannels.ChannelsRow rowChannel6 = dsChannels.Channels.NewChannelsRow();

            rowChannel6.id = 6;

            rowChannel6.Active = SID_monitor.Properties.Settings.Default.Channel6Active;
            if (rowChannel6.Active)
            {
                rowChannel6.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel6Port);
                rowChannel6.StationCode = SID_monitor.Properties.Settings.Default.Channel6StationCode;
                rowChannel6.LineWidth = SID_monitor.Properties.Settings.Default.Channel6LineWidth;
                rowChannel6.LineColor = SID_monitor.Properties.Settings.Default.Channel6LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel6);


            // channel 7
            dsChannels.ChannelsRow rowChannel7 = dsChannels.Channels.NewChannelsRow();

            rowChannel7.id = 7;

            rowChannel7.Active = SID_monitor.Properties.Settings.Default.Channel7Active;
            if (rowChannel7.Active)
            {
                rowChannel7.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel7Port);
                rowChannel7.StationCode = SID_monitor.Properties.Settings.Default.Channel7StationCode;
                rowChannel7.LineWidth = SID_monitor.Properties.Settings.Default.Channel7LineWidth;
                rowChannel7.LineColor = SID_monitor.Properties.Settings.Default.Channel7LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel7);


            // channel 8
            dsChannels.ChannelsRow rowChannel8 = dsChannels.Channels.NewChannelsRow();

            rowChannel8.id = 8;

            rowChannel8.Active = SID_monitor.Properties.Settings.Default.Channel8Active;
            if (rowChannel8.Active)
            {
                rowChannel8.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel8Port);
                rowChannel8.StationCode = SID_monitor.Properties.Settings.Default.Channel8StationCode;
                rowChannel8.LineWidth = SID_monitor.Properties.Settings.Default.Channel8LineWidth;
                rowChannel8.LineColor = SID_monitor.Properties.Settings.Default.Channel8LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel8);


            // channel 9
            dsChannels.ChannelsRow rowChannel9 = dsChannels.Channels.NewChannelsRow();

            rowChannel9.id = 9;

            rowChannel9.Active = SID_monitor.Properties.Settings.Default.Channel9Active;
            if (rowChannel9.Active)
            {
                rowChannel9.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel9Port);
                rowChannel9.StationCode = SID_monitor.Properties.Settings.Default.Channel9StationCode;
                rowChannel9.LineWidth = SID_monitor.Properties.Settings.Default.Channel9LineWidth;
                rowChannel9.LineColor = SID_monitor.Properties.Settings.Default.Channel9LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel9);


            // channel 10
            dsChannels.ChannelsRow rowChannel10 = dsChannels.Channels.NewChannelsRow();

            rowChannel10.id = 10;

            rowChannel10.Active = SID_monitor.Properties.Settings.Default.Channel10Active;
            if (rowChannel10.Active)
            {
                rowChannel10.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel10Port);
                rowChannel10.StationCode = SID_monitor.Properties.Settings.Default.Channel10StationCode;
                rowChannel10.LineWidth = SID_monitor.Properties.Settings.Default.Channel10LineWidth;
                rowChannel10.LineColor = SID_monitor.Properties.Settings.Default.Channel10LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel10);


            // channel 11
            dsChannels.ChannelsRow rowChannel11 = dsChannels.Channels.NewChannelsRow();

            rowChannel11.id = 11;

            rowChannel11.Active = SID_monitor.Properties.Settings.Default.Channel11Active;
            if (rowChannel11.Active)
            {
                rowChannel11.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel11Port);
                rowChannel11.StationCode = SID_monitor.Properties.Settings.Default.Channel11StationCode;
                rowChannel11.LineWidth = SID_monitor.Properties.Settings.Default.Channel11LineWidth;
                rowChannel11.LineColor = SID_monitor.Properties.Settings.Default.Channel11LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel11);


            // channel 12
            dsChannels.ChannelsRow rowChannel12 = dsChannels.Channels.NewChannelsRow();

            rowChannel12.id = 12;

            rowChannel12.Active = SID_monitor.Properties.Settings.Default.Channel12Active;
            if (rowChannel12.Active)
            {
                rowChannel12.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel12Port);
                rowChannel12.StationCode = SID_monitor.Properties.Settings.Default.Channel12StationCode;
                rowChannel12.LineWidth = SID_monitor.Properties.Settings.Default.Channel12LineWidth;
                rowChannel12.LineColor = SID_monitor.Properties.Settings.Default.Channel12LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel12);


            // channel 13
            dsChannels.ChannelsRow rowChannel13 = dsChannels.Channels.NewChannelsRow();

            rowChannel13.id = 13;

            rowChannel13.Active = SID_monitor.Properties.Settings.Default.Channel13Active;
            if (rowChannel13.Active)
            {
                rowChannel13.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel13Port);
                rowChannel13.StationCode = SID_monitor.Properties.Settings.Default.Channel13StationCode;
                rowChannel13.LineWidth = SID_monitor.Properties.Settings.Default.Channel13LineWidth;
                rowChannel13.LineColor = SID_monitor.Properties.Settings.Default.Channel13LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel13);


            // channel 14
            dsChannels.ChannelsRow rowChannel14 = dsChannels.Channels.NewChannelsRow();

            rowChannel14.id = 14;

            rowChannel14.Active = SID_monitor.Properties.Settings.Default.Channel14Active;
            if (rowChannel14.Active)
            {
                rowChannel14.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel14Port);
                rowChannel14.StationCode = SID_monitor.Properties.Settings.Default.Channel14StationCode;
                rowChannel14.LineWidth = SID_monitor.Properties.Settings.Default.Channel14LineWidth;
                rowChannel14.LineColor = SID_monitor.Properties.Settings.Default.Channel14LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel14);


            // channel 15
            dsChannels.ChannelsRow rowChannel15 = dsChannels.Channels.NewChannelsRow();

            rowChannel15.id = 15;

            rowChannel15.Active = SID_monitor.Properties.Settings.Default.Channel15Active;
            if (rowChannel15.Active)
            {
                rowChannel15.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel15Port);
                rowChannel15.StationCode = SID_monitor.Properties.Settings.Default.Channel15StationCode;
                rowChannel15.LineWidth = SID_monitor.Properties.Settings.Default.Channel15LineWidth;
                rowChannel15.LineColor = SID_monitor.Properties.Settings.Default.Channel15LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel15);


            // channel 16
            dsChannels.ChannelsRow rowChannel16 = dsChannels.Channels.NewChannelsRow();

            rowChannel16.id = 16;

            rowChannel16.Active = SID_monitor.Properties.Settings.Default.Channel16Active;
            if (rowChannel16.Active)
            {
                rowChannel16.Port = new SerialADC(SID_monitor.Properties.Settings.Default.Channel16Port);
                rowChannel16.StationCode = SID_monitor.Properties.Settings.Default.Channel16StationCode;
                rowChannel16.LineWidth = SID_monitor.Properties.Settings.Default.Channel16LineWidth;
                rowChannel16.LineColor = SID_monitor.Properties.Settings.Default.Channel16LineColor;
            }
            dsChannels.Channels.AddChannelsRow(rowChannel16);
            #endregion


            dsChannels.AcceptChanges();

        }

        public void StopAllTimers(bool showMessage)
        {
            this.timerADCUpdate.Enabled = false;
            this.timerDatabaseUpdate.Enabled = false;
            this.timerGOESUpdate.Enabled = false;
            this.timerGraphUpdate.Enabled = false;
            this.timerSunUpdate.Enabled = false;

            this.dataToolStripMenuItem.Enabled = false;
            this.graphToolStripMenuItem.Enabled = false;
            this.reportsToolStripMenuItem.Enabled = false;
            this.statusStrip.Enabled = false;
            this.acquisitionToolStripMenuItemContext.Enabled = false;
            this.graphUpdateToolStripMenuItemContext.Enabled = false;

            this.dateDockablePanel.Enabled = false;
            this.channelsDockablePanel.Enabled = false;
            this.goesDockablePanel.Enabled = false;
            this.viewerDockablePanel.Enabled = false;
            this.outputTextBoxDockablePanel.Enabled = false;

            if (showMessage)
            {
                this.outputTextBoxDockablePanel.AddOutputTextMessage("All background tasks stopped.\n");
            }
        }

        public void StopAllTimers()
        {
            StopAllTimers(true);
        }

        public void StartAllTimers()
        {
            this.timerADCUpdate.Enabled = SID_monitor.Properties.Settings.Default.AcquisitionActive;
            this.timerDatabaseUpdate.Enabled = true;
            this.timerGOESUpdate.Enabled = true;
            this.timerGraphUpdate.Enabled = SID_monitor.Properties.Settings.Default.GraphActive;
            this.timerSunUpdate.Enabled = true;

            this.dataToolStripMenuItem.Enabled = true;
            this.graphToolStripMenuItem.Enabled = true;
            this.reportsToolStripMenuItem.Enabled = true;
            this.statusStrip.Enabled = true;
            this.acquisitionToolStripMenuItemContext.Enabled = true;
            this.graphUpdateToolStripMenuItemContext.Enabled = true;

            this.dateDockablePanel.Enabled = true;
            this.channelsDockablePanel.Enabled = true;
            this.goesDockablePanel.Enabled = true;
            this.viewerDockablePanel.Enabled = true;
            this.outputTextBoxDockablePanel.Enabled = true;

            this.outputTextBoxDockablePanel.AddOutputTextMessage("All background tasks started.\n");
        }
        #endregion

        #region MainForm Methods

        /// <summary>
        /// Gets UI configuration
        /// </summary>
        private IDockContent GetContentFromPersistString(string persistString)
        {
            if (persistString == typeof(GOESDockablePanel).ToString())
                return goesDockablePanel;
            else if (persistString == typeof(ChannelsDockablePanel).ToString())
                return channelsDockablePanel;
            else if (persistString == typeof(DateDockablePanel).ToString())
                return dateDockablePanel;
            else if (persistString == typeof(ViewerDockablePanel).ToString())
                return viewerDockablePanel;
            else if (persistString == typeof(OutputTextBoxDockablePanel).ToString())
                return outputTextBoxDockablePanel;
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Default configuration of the panels
        /// </summary>
        private void SetDefaultUI()
        {
            try
            {
                // default configuration: all panels visible
                // viewerDockablePanel
                this.viewerDockablePanel.Show(this.dockPanel);

                // outputTextBoxDockablePanel
                this.outputTextBoxDockablePanel.Show(this.dockPanel);

                // goesDockablePanel
                this.goesDockablePanel.Show(this.dockPanel);

                // channelsDockablePanel
                this.channelsDockablePanel.Show(this.dockPanel);

                // dateDockablePanel
                this.dateDockablePanel.Show(this.dockPanel);
            }
            catch
            {
                MessageBox.Show("User Interface internal error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // loads UI configuration
            string configFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), SID_monitor.Properties.Settings.Default.MainFormLayoutFile);
            if (File.Exists(configFile))
            {
                try
                {
                    dockPanel.LoadFromXml(configFile, m_deserializeDockContent);
                }
                catch
                {
                    SetDefaultUI();
                }
            }
            else
            {
                SetDefaultUI();
            }

            // Enable or not "Check For Update" menu item
            if (!ApplicationDeployment.IsNetworkDeployed)
            {
                this.checkForUpdatesToolStripMenuItem.Enabled = false;
            }
            else {
                this.checkForUpdatesToolStripMenuItem.Enabled = true;
            }

            // 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))
            {
                this.outputTextBoxDockablePanel.AddOutputTextErrorMessage("Invalid Configuration. Please correct the settings in the Tools/Options menu, \"Database\" pane.\n");
                StopAllTimers(false);
            }
            else
            {
                StartAllTimers();
            }

            // create dsChannels
            createDsChannels();

            // ADC and Graph checkboxes on the menu and on the status Strip
            updateLabelsADC();
            updateLabelsGraph();

            // Minimize to tray checkbox on the menu
            this.minimizeToTrayToolStripMenuItem.Checked = SID_monitor.Properties.Settings.Default.MinimizeToTray;

            Program.MainForm.toolStripStatusLabelDatabaseLocation.Text = "Database: " + SID_monitor.Properties.Settings.Default.RRDToolDatabase.ToString();


            // Start the application minimized or visible
            if (SID_monitor.Properties.Settings.Default.StartMinimized)
            {
                this.WindowState = FormWindowState.Minimized;
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
            }


        }


        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // save UI config
            string configFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), SID_monitor.Properties.Settings.Default.MainFormLayoutFile);
            dockPanel.SaveAsXml(configFile);

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

            //// pressing the 'X' does not close the application.
            //if ( !exitApplicationAsked)
            //{
            //    this.Visible = false;
            //    e.Cancel = true;
            //}
        }

        /// <summary>
        /// hide from the taskbar when minimized if "minimize to tray" option is set.
        /// </summary>
        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                if (SID_monitor.Properties.Settings.Default.MinimizeToTray)
                {
                    this.ShowInTaskbar = false;
                }
            }
            else
            {
                this.ShowInTaskbar = true;
            }
        }
        #endregion

        public void updateLabelsADC()
        {
            if (SID_monitor.Properties.Settings.Default.AcquisitionActive == false)
            {
                // acquisitionToolStripMenuItem
                this.acquisitionToolStripMenuItem.Checked = false;
                this.acquisitionToolStripMenuItem.Text = "Acquisition (Now stopped)";
                this.acquisitionToolStripMenuItem.ToolTipText = "Click to restart data acquisition";

                // acquisitionToolStripMenuItemContext
                this.acquisitionToolStripMenuItemContext.Checked = false;
                this.acquisitionToolStripMenuItemContext.Text = "Acquisition (Now stopped)";
                this.acquisitionToolStripMenuItemContext.ToolTipText = "Click to restart data acquisition";

                //toolStripStatusLabelADC
                this.toolStripStatusLabelADC.Image = SID_monitor.Properties.Resources.led_yellow;
                this.toolStripStatusLabelADC.ToolTipText = "ADC Update: Stopped";

                //notify Icon
                this.notifyIcon.Text = "SID Monitor (Stopped)";
                this.notifyIcon.Icon = SID_monitor.Properties.Resources.SID_monitor_gray;
            }
            else
            {
                // acquisitionToolStripMenuItem
                this.acquisitionToolStripMenuItem.Checked = true;
                this.acquisitionToolStripMenuItem.Text = "Acquisition (Now running: " + ((UInt32)(SID_monitor.Properties.Settings.Default.AcquisitionUpdate / 1000)).ToString() + "s)";
                this.acquisitionToolStripMenuItem.ToolTipText = "Click to stop data acquisition";

                // acquisitionToolStripMenuItemContext
                this.acquisitionToolStripMenuItemContext.Checked = true;
                this.acquisitionToolStripMenuItemContext.Text = "Acquisition (Now running: " + ((UInt32)(SID_monitor.Properties.Settings.Default.AcquisitionUpdate / 1000)).ToString() + "s)";
                this.acquisitionToolStripMenuItemContext.ToolTipText = "Click to stop data acquisition";

                //toolStripStatusLabelADC
                this.toolStripStatusLabelADC.Image = SID_monitor.Properties.Resources.led_green;
                this.toolStripStatusLabelADC.ToolTipText = "ADC Update: Running (" + ((UInt32)(SID_monitor.Properties.Settings.Default.AcquisitionUpdate / 1000)).ToString() + "s)";

                //notify Icon
                this.notifyIcon.Text = "SID Monitor (Running)";
                this.notifyIcon.Icon = SID_monitor.Properties.Resources.SID_monitor;
            }
        }

        public void updateLabelsGraph()
        {
            if (SID_monitor.Properties.Settings.Default.GraphActive == false)
            {
                // graphUpdateToolStripMenuItem
                this.graphUpdateToolStripMenuItem.Checked = false;
                this.graphUpdateToolStripMenuItem.Text = "Graph Update (Now stopped)";
                this.graphUpdateToolStripMenuItem.ToolTipText = "Click to retart automatic graph update";

                // graphUpdateToolStripMenuItemContext
                this.graphUpdateToolStripMenuItemContext.Checked = false;
                this.graphUpdateToolStripMenuItemContext.Text = "Graph Update (Now stopped)";
                this.graphUpdateToolStripMenuItemContext.ToolTipText = "Click to retart automatic graph update";

                //toolStripStatusLabelGraph
                this.toolStripStatusLabelGraph.Image = SID_monitor.Properties.Resources.led_yellow;
                this.toolStripStatusLabelGraph.ToolTipText = "Graph Update: Stopped";
            }
            else
            {
                // graphUpdateToolStripMenuItem
                this.graphUpdateToolStripMenuItem.Checked = true;
                this.graphUpdateToolStripMenuItem.Text = "Graph Update (Now running: " + ((UInt32)(SID_monitor.Properties.Settings.Default.GraphUpdate / 1000)).ToString() + "s)";
                this.graphUpdateToolStripMenuItem.ToolTipText = "Click to stop automatic graph update";

                // graphUpdateToolStripMenuItemContext
                this.graphUpdateToolStripMenuItemContext.Checked = true;
                this.graphUpdateToolStripMenuItemContext.Text = "Graph Update (Now running: " + ((UInt32)(SID_monitor.Properties.Settings.Default.GraphUpdate / 1000)).ToString() + "s)";
                this.graphUpdateToolStripMenuItemContext.ToolTipText = "Click to stop automatic graph update";

                //toolStripStatusLabelGraph
                this.toolStripStatusLabelGraph.Image = SID_monitor.Properties.Resources.led_green;
                this.toolStripStatusLabelGraph.ToolTipText = "Graph Update: Running (" + ((UInt32)(SID_monitor.Properties.Settings.Default.GraphUpdate / 1000)).ToString() + "s)";
            }
        }


        #region Periodic Tasks

        /// The Application starts the following background tasks:
        /// - Sun Update (always activated)
        /// - Database Update (always activated)
        /// - GOES Update (always activated). Period is user-defined.
        /// - ADC Update. Period and Activation are user-defined.
        /// - Graph Update. Period and Activation are user-defined.

        /// <summary>
        /// Acquires channels data periodically
        /// </summary>
        private void timerADCUpdate_Tick(object sender, EventArgs e)
        {
            dsChannels.AcquisitionDataRow currentRow = null;

            if (dsChannels.AcquisitionData.Rows.Count > 0) // robustness only: dsChannels not defined...
            {
                currentRow = (dsChannels.AcquisitionDataRow)dsChannels.AcquisitionData.Rows[0];
            }
            else
            {
                this.outputTextBoxDockablePanel.AddOutputTextErrorMessage("Internal Error: dsChannels not defined.\n");
                return;
            }

            DataElement currentDataElement;

            // values acquisition
            foreach (dsChannels.ChannelsRow currentChannel in dsChannels.Channels.Rows)
            {
                if (currentChannel.Active)
                {
                    try
                    {
                        UInt64 currentUnixTime = SIDMonitorDateTime.UtcNow.UnixTime;

                        // we search if a previous element in the list has the same time
                        int i = currentRow.Values.Count - 1;
                        bool found = false;
                        while (i >= 0)
                        {
                            DataElement searchedDataElement = (DataElement)currentRow.Values[i];
                            if (searchedDataElement.Time == currentUnixTime) // a previous element is defined with the same time
                            {
                                found = true;
                                break;
                            }
                            i--;
                        }

                        if (found == true)
                        {
                            currentDataElement = (DataElement)currentRow.Values[i];
                        }
                        else
                        {
                            currentDataElement = new DataElement();
                            currentDataElement.Time = currentUnixTime;
                        }

                        // set Channel ADC value and Sun Position
                        currentDataElement.Value[currentChannel.id - 1] = currentChannel.Port.GetADC();
                        currentDataElement.SunPosition = currentSunPosition;

                        //AddOutputTextMessage("  Channel " + currentChannel.id.ToString() +
                        //    " [" + currentChannel.StationCode + "]: " +
                        //    currentDataElement.Time.ToString() + ": " + currentDataElement.Value[currentChannel.id - 1].ToString() + "\n");
                        this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Text = currentDataElement.Value[currentChannel.id - 1].ToString();

                        if (currentDataElement.Value[currentChannel.id - 1] == 0)
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level0;
                        }
                        else if (currentDataElement.Value[currentChannel.id - 1] < 1023)
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level1;
                        }
                        else if (currentDataElement.Value[currentChannel.id - 1] < 2047)
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level2;
                        }
                        else if (currentDataElement.Value[currentChannel.id - 1] < 3071)
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level3;
                        }
                        else if (currentDataElement.Value[currentChannel.id - 1] < 4095)
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level4;
                        }
                        else // = 4095
                        {
                            this.channelsDockablePanel.LabelChannelValues[currentChannel.id - 1].Image = SID_monitor.Properties.Resources.level5;
                        }

                        if (found == false) // we add the new element to the array list
                        {

                            currentRow.Values.Add(currentDataElement);
                        }

                    }
                    catch (Exception ex)
                    {
                        this.outputTextBoxDockablePanel.AddOutputTextErrorMessage("  Channel " + currentChannel.id.ToString() +
                            " [" + currentChannel.StationCode + "]: " +
                            "\n*** Cannot acquire data on serial port \"" + currentChannel.Port.PortName +
                            "\"\n*** " + ex.ToString().Split('\n')[0] + "\n");
                    }
                }
            }

        }


        /// <summary>
        /// Periodically updates the Channels database (basically every minute)
        /// Creates monthly database backups
        /// </summary>
        private void timerDatabaseUpdate_Tick(object sender, EventArgs e)
        {

            SIDMonitorDateTime lastDatabaseUpdateTime;
            try
            {
                lastDatabaseUpdateTime = RRDTool.getLastDatabaseUpdateTime(SID_monitor.Properties.Settings.Default.RRDToolDatabase, this.outputTextBoxDockablePanel.Handle);
            }
            catch (Exception ex)
            {
                Program.MainForm.outputTextBoxDockablePanel.AddOutputTextErrorMessage(" Cannot read last channels database update time \"" + SID_monitor.Properties.Settings.Default.RRDToolDatabase +
                    "\"\n*** " + ex.ToString().Split('\n')[0] + "\n");
                return;
            }

            if (!SIDMonitorDateTime.IsNullOrEmpty(lastDatabaseUpdateTime))
            {
                // check if a new month has happened since last update. If so: create a copy of the database.
                if (lastDatabaseUpdateTime.WinTime.Month != DateTime.UtcNow.Month) // we changed month
                {
                    String NewDirectory = Path.GetFullPath(SID_monitor.Properties.Settings.Default.HistoryDatabaseFolder) + "\\" + lastDatabaseUpdateTime.WinTime.ToString("MMyy");
                    try
                    {
                        // create a new directory if it does not exists
                        Directory.CreateDirectory(NewDirectory);

                        // copy the channels file in that directory
                        // previous: Path.GetFileNameWithoutExtension(SID_monitor.Properties.Settings.Default.RRDToolDatabase) et Path.GetExtension(SID_monitor.Properties.Settings.Default.RRDToolDatabase)
                        File.Copy(SID_monitor.Properties.Settings.Default.RRDToolDatabase,
                                  Path.Combine(NewDirectory, SID_monitor.Properties.Settings.Default.RRDToolChannelsSaveFilename + "." + lastDatabaseUpdateTime.WinTime.ToString("MMyy") + ".rrd"));

                        this.outputTextBoxDockablePanel.AddOutputTextMessage(" Creating monthly copy of the Channels database file for " + lastDatabaseUpdateTime.WinTime.ToString("MMMM yyyy") + " in folder \"" + NewDirectory + "\"\n");

                        // copy the GOES file in that directory
                        File.Copy(SID_monitor.Properties.Settings.Default.RRDToolGOES,
                                  Path.Combine(NewDirectory, SID_monitor.Properties.Settings.Default.RRDToolGOESSaveFilename + "." + lastDatabaseUpdateTime.WinTime.ToString("MMyy") + ".rrd"));

                        this.outputTextBoxDockablePanel.AddOutputTextMessage(" Creating monthly copy of the GOES database file for " + lastDatabaseUpdateTime.WinTime.ToString("MMMM yyyy") + " in folder \"" + NewDirectory + "\"\n");
                    }
                    catch (Exception ex)
                    {
                        this.outputTextBoxDockablePanel.AddOutputTextErrorMessage(" Cannot create history file in folder \"" + NewDirectory +
                            "\"\n*** " + ex.ToString().Split('\n')[0] + "\n");
                    }
                }

                // check if a failure has been detected and send a report if necessary
                if ((SID_monitor.Properties.Settings.Default.SendMailUponEventDetection) &&
                   ((SID_monitor.Properties.Settings.Default.SendMailHourly && (lastDatabaseUpdateTime.WinTime.Hour != DateTime.UtcNow.Hour)) ||
                   (lastDatabaseUpdateTime.WinTime.Day != DateTime.UtcNow.Day)))
                {
                    string DatabaseName = SID_monitor.Properties.Settings.Default.RRDToolDatabase.Replace(":", "\\:");
                    string xport_string = "xport ";

                    if (SID_monitor.Properties.Settings.Default.SendMailHourly)
                    {
                        xport_string += "--maxrows " + Convert.ToString(3600000 / SID_monitor.Properties.Settings.Default.AcquisitionUpdate + 1) + " ";
                        xport_string += "--start " + SIDMonitorDateTime.UtcNow.AddHours(-1).UnixTime + " ";
                    }
                    else
                    {
                        xport_string += "--maxrows " + Convert.ToString(86400000 / SID_monitor.Properties.Settings.Default.AcquisitionUpdate + 1) + " ";
                        xport_string += "--start " + SIDMonitorDateTime.UtcNow.AddDays(-1).UnixTime + " ";
                    }

                    xport_string += "--end " + SIDMonitorDateTime.UtcNow.UnixTime + " ";

                    xport_string += "DEF:_sun=\"" + DatabaseName + "\":sun:AVERAGE ";
                    xport_string += "CDEF:daytime=_sun,UN,-1,_sun,FLOOR,IF,0,EQ,1,0,IF ";

                    foreach (dsChannels.ChannelsRow currentChannel in dsChannels.Channels.Rows)
                    {
                        if (currentChannel.Active)
                        {
                            // Failures (shown only during daytime)
                            xport_string += "DEF:_failures-" + currentChannel.StationCode + "=\"" + DatabaseName + "\":" + currentChannel.StationCode + ":FAILURES ";
                            xport_string += "CDEF:failures-" + currentChannel.StationCode + "=daytime,_failures-" + currentChannel.StationCode + ",UN,0,_failures-" + currentChannel.StationCode + ",IF,0,IF ";
                            xport_string += "XPORT:failures-" + currentChannel.StationCode + ":\"" + currentChannel.StationCode + "\" ";
                        }
                    }

                    String FailureValues = RRDToolConnection.ExecuteRRDTool(xport_string, RRDToolProcess.ShowOptions.ErrorsOnly);

                    // search for value 1
                    Regex FailureRegEx = new Regex("^.*<v>1.*</v>.*$",
                                  RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);

                    Match FailuresMatch = FailureRegEx.Match(FailureValues);

                    if (FailuresMatch.Success)
                    {
                        try
                        {
                            MailAddress to = new MailAddress(SID_monitor.Properties.Settings.Default.SendMailTo);
                            MailAddress from = new MailAddress(SID_monitor.Properties.Settings.Default.SendMailFrom, "SID Monitor");
                            MailMessage message = new MailMessage(from, to);
                            message.Subject = "Possible detection of a new SID Event.";
                            message.Body = "\nAn SID Event has potentially been detected during the last ";
                            if (SID_monitor.Properties.Settings.Default.SendMailHourly)
                            {
                                message.Body += "hour.\n\n";
                            }
                            else
                            {
                                message.Body += "day.\n\n";
                            }

                            String ImageFile = String.Empty; // image filename

                            if (SID_monitor.Properties.Settings.Default.SendMailWithGraph)
                            {
                                // Generates the graph image
                                bool[] ChannelsToShow = new bool[16];
                                for (int i = 0; i < dsChannels.Channels.Rows.Count; i++)
                                {
                                    ChannelsToShow[i] = ((dsChannels.ChannelsRow)dsChannels.Channels.Rows[i]).Active;
                                }

                                bool[] GOESToShow = new bool[3] { this.goesDockablePanel.GOES10Checked, this.goesDockablePanel.GOES11Checked, this.goesDockablePanel.GOES12Checked };
                                ImageFile = this.viewerDockablePanel.GenerateGraphFile(SID_monitor.Properties.Settings.Default.RRDToolDatabase,
                                                                  SID_monitor.Properties.Settings.Default.RRDToolGOES,
                                                                  SIDMonitorDateTime.UtcNow.AddDays(-1).UnixTime.ToString(),
                                                                  SIDMonitorDateTime.UtcNow.UnixTime.ToString(),
                                                                  DateTime.UtcNow.AddDays(-1).ToString("dd MMM yyyy HH:mm") + " UTC - " + DateTime.UtcNow.ToString("dd MMM yyyy HH:mm") + " UTC",
                                                                  true,
                                                                  true,
                                                                  SID_monitor.Properties.Settings.ChannelStationCodes,
                                                                  SID_monitor.Properties.Settings.ChannelTitles,
                                                                  SID_monitor.Properties.Settings.ChannelLineWidths,
                                                                  SID_monitor.Properties.Settings.ChannelColors,
                                                                  SID_monitor.Properties.Settings.ChannelDev1Colors,
                                                                  SID_monitor.Properties.Settings.ChannelDev2Colors,
                                                                  SID_monitor.Properties.Settings.ChannelDev3Colors,
                                                                  ChannelsToShow,
                                                                  SID_monitor.Properties.Settings.GOESTitles,
                                                                  SID_monitor.Properties.Settings.GOESLineWidths,
                                                                  SID_monitor.Properties.Settings.GOESColors,
                                                                  GOESToShow);

                                message.Attachments.Add(new Attachment(ImageFile));
                                message.Attachments[0].ContentDisposition.FileName = "Graph.png";

                                message.Body += "See attached image file.\n\n";
                            }

                            message.Body += "--\nThis is an automatically generated email. Please do not respond.";

                            SmtpClient client = new SmtpClient(SID_monitor.Properties.Settings.Default.SMTPServerAddress, SID_monitor.Properties.Settings.Default.SMTPServerPort);
                            client.Send(message);
                            if (SID_monitor.Properties.Settings.Default.SendMailHourly)
                            {
                                this.outputTextBoxDockablePanel.AddOutputTextMessage("Events detected during the last hour. Mail sent to " + SID_monitor.Properties.Settings.Default.SendMailTo + "\n");
                            }
                            else
                            {
                                this.outputTextBoxDockablePanel.AddOutputTextMessage("Events detected during the last day. Mail sent to " + SID_monitor.Properties.Settings.Default.SendMailTo + "\n");
                            }

                            if (!String.IsNullOrEmpty(ImageFile) && File.Exists(ImageFile))
                            {
                                try
                                {
                                    File.Delete(ImageFile);
                                }
                                catch (Exception ex)
                                {
                                    this.outputTextBoxDockablePanel.AddOutputTextWarningMessage("Cannot delete temp image file " + ImageFile + "\n*** " + ex.ToString().Split('\n')[0] + "\n");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.outputTextBoxDockablePanel.AddOutputTextErrorMessage("Events detected but cannot send mail to " + SID_monitor.Properties.Settings.Default.SendMailTo + "\n*** " + ex.ToString().Split('\n')[0] + "\n");
                        }
                    }
                }
            }

            string update_string = "update \"" + SID_monitor.Properties.Settings.Default.RRDToolDatabase + "\" ";
            string template_string = "-t sun";
            string data_string = String.Empty;
            uint[] nb_updates = new uint[dsChannels.Channels.Rows.Count];

            dsChannels.AcquisitionDataRow currentRow = null;
            if (dsChannels.AcquisitionData.Rows.Count > 0) // robustness only. dsChannels not defined...
            {
                currentRow = (dsChannels.AcquisitionDataRow)dsChannels.AcquisitionData.Rows[0];
            }
            else
            {
                this.outputTextBoxDockablePanel.AddOutputTextErrorMessage("Internal Error: dsChannels not defined.\n");
                return;
            }

            if ((currentRow != null) && (currentRow.Values.Count > 0)) // new data has actually been refreshed
            {
                // data copy
                System.Collections.ArrayList currentValuesCopy = (System.Collections.ArrayList)(currentRow.Values.Clone());
                currentRow.Values.RemoveRange(0, currentValuesCopy.Count); // remove all values already copied. Not using Clear() just in case another element has been added in between

                // template string creation
                foreach (dsChannels.ChannelsRow currentChannel in dsChannels.Channels.Rows)
                {
                    if (currentChannel.Active)
                    {
                        template_string += ":" + currentChannel.StationCode;
                    }
                }
                template_string += " ";

                // data string creation
                foreach (DataElement currentElement in currentValuesCopy)
                {
                    if (currentElement.Time != UInt64.MinValue) // the time has to be set
                    {
                        if (currentElement.SunPosition != int.MinValue) // has sun been updated?
                        {
                            data_string += currentElement.Time.ToString() + ":" + currentElement.SunPosition.ToString();
                        }
                        else
                        {
                            data_string += currentElement.Time.ToString() + ":U";
                        }
                        foreach (dsChannels.ChannelsRow currentChannel in dsChannels.Channels.Rows)
                        {
                            if (currentChannel.Active)
                            {
                                if (currentElement.Value[currentChannel.id - 1] != uint.MinValue) // has this channel value been updated?
                                {
                                    data_string += ":" + currentElement.Value[currentChannel.id - 1].ToString();
                                    nb_updates[currentChannel.id]++;
                                }
                                else
                                {
                                    data_string += ":U";
                                }
                            }
                        }
                        data_string += " ";
                    }
                }

                string Msg = "Updating Database... ";
                foreach (dsChannels.ChannelsRow currentChannel in dsChannels.Channels.Rows)
                {
                    if (currentChannel.Active)
                    {
                        Msg += currentChannel.StationCode + " (" + nb_updates[currentChannel.id] + " values) ";
                    }
                }
                this.outputTextBoxDockablePanel.AddOutputTextMessage(Msg + "\n");
                RRDToolConnection.ExecuteRRDTool(update_string + template_string + data_string, RRDToolProcess.ShowOptions.ErrorsAndStdOut);

            }

        }


        /// <summary>
        /// Periodically refreshes the graph
        /// </summary>
        public void timerGraphUpdate_Tick(object sender, EventArgs e)
        {
            this.dateDockablePanel.LabelRefreshGraphVisible = false;
            this.outputTextBoxDockablePanel.AddOutputTextMessage("Updating graph...\n");

            string GraphTitle;
            string GraphStartTime;
            string GraphEndTime;

            if (this.dateDockablePanel.GraphTodayChecked == true)
            {
                GraphStartTime = SIDMonitorDateTime.UtcNow.Date.UnixTime.ToString();
                GraphEndTime = SIDMonitorDateTime.UtcNow.AddDays(1).Date.UnixTime.ToString();
                GraphTitle = DateTime.UtcNow.Date.ToLongDateString();
            }
            else if (this.dateDockablePanel.GraphLast24HoursChecked == true)
            {
                GraphStartTime = SIDMonitorDateTime.UtcNow.AddDays(-1).UnixTime.ToString();
                GraphEndTime = SIDMonitorDateTime.UtcNow.UnixTime.ToString();
                GraphTitle = DateTime.UtcNow.AddDays(-1).ToString("dd MMM yyyy HH:mm") + " UTC - " + DateTime.UtcNow.ToString("dd MMM yyyy HH:mm") + " UTC";
            }
            else if (this.dateDockablePanel.GraphSelectDateChecked == true)
            {
                GraphStartTime = (new SIDMonitorDateTime(this.dateDockablePanel.MonthCalendarSelectionStart)).UnixTime.ToString();
                GraphEndTime = (new SIDMonitorDateTime(this.dateDockablePanel.MonthCalendarSelectionEnd)).AddDays(1).UnixTime.ToString();
                GraphTitle = this.dateDockablePanel.MonthCalendarSelectionStart.Date.ToLongDateString();
                if (this.dateDockablePanel.MonthCalendarSelectionEnd.CompareTo(this.dateDockablePanel.MonthCalendarSelectionStart) != 0)
                {
                    GraphTitle += " - " + this.dateDockablePanel.MonthCalendarSelectionEnd.Date.ToLongDateString();
                }
            }
            else // GraphSelectRangeChecked
            {
                GraphStartTime = (new SIDMonitorDateTime(this.dateDockablePanel.DateTimePickerStart)).UnixTime.ToString();
                GraphEndTime = (new SIDMonitorDateTime(this.dateDockablePanel.DateTimePickerEnd)).UnixTime.ToString();
                GraphTitle = this.dateDockablePanel.DateTimePickerStart.ToString("dd MMM yyyy HH:mm") + " UTC - " + this.dateDockablePanel.DateTimePickerEnd.ToString("dd MMM yyyy HH:mm") + " UTC";
            }

            bool[] ChannelsToShow = new bool[16];
            for (int i = 0; i < dsChannels.Channels.Rows.Count; i++)
            {
                ChannelsToShow[i] = (((dsChannels.ChannelsRow)dsChannels.Channels.Rows[i]).Active && this.channelsDockablePanel.CheckBoxChannels[i].Checked);
            }
            bool[] GOESToShow = new bool[3] { this.goesDockablePanel.GOES10Checked, this.goesDockablePanel.GOES11Checked, this.goesDockablePanel.GOES12Checked };

            this.viewerDockablePanel.GenerateGraph(SID_monitor.Properties.Settings.Default.RRDToolDatabase,
                                           SID_monitor.Properties.Settings.Default.RRDToolGOES,
                                           GraphStartTime, GraphEndTime, GraphTitle,
                                           this.channelsDockablePanel.ShowSunChecked,
                                           this.channelsDockablePanel.ShowForecastChecked,
                                           SID_monitor.Properties.Settings.ChannelStationCodes,
                                           SID_monitor.Properties.Settings.ChannelTitles,
                                           SID_monitor.Properties.Settings.ChannelLineWidths,
                                           SID_monitor.Properties.Settings.ChannelColors,
                                           SID_monitor.Properties.Settings.ChannelDev1Colors,
                                           SID_monitor.Properties.Settings.ChannelDev2Colors,
                                           SID_monitor.Properties.Settings.ChannelDev3Colors,
                                           ChannelsToShow,
                                           SID_monitor.Properties.Settings.GOESTitles,
                                           SID_monitor.Properties.Settings.GOESLineWidths,
                                           SID_monitor.Properties.Settings.GOESColors,
                                           GOESToShow);

            //AddOutputTextRRDToolMessage("rrdtool " + graph_string + "\n");
            this.dateDockablePanel.GraphLastUpdateText = "          " + DateTime.UtcNow.ToString("dd MMM yyyy HH:mm:ss") + " UTC";

        }

        /// <summary>
        /// defines periodically the sun / day status
        /// </summary>
        private void timerSunUpdate_Tick(object sender, EventArgs e)
        {
            // sun position update
            if (TodayDate.CompareTo(DateTime.Today) != 0)
            { // we changed day since last update
                TodayDate = DateTime.Today;
                TodaySunriseSunsetTimes = new SunriseSunset(TodayDate);
            }

            currentSunPosition = TodaySunriseSunsetTimes.DayNightStatus(DateTime.UtcNow.TimeOfDay.TotalHours);

        }

        /// <summary>
        /// Periodically updates the GOES database
        /// </summary>
        public void timerGOESUpdate_Tick(object sender, EventArgs e)
        {
            // first check that the database exists. Otherwise, do nothing.
            if (!File.Exists(SID_monitor.Properties.Settings.Default.RRDToolGOES))
            {
                return;
            }

            // we update the GOES data
            SIDMonitorDateTime GOESDatabaseUpdateTime = GOES.updateGOESdata();

            // we update the last update time label on the GOES pane
            if (SIDMonitorDateTime.IsNullOrEmpty(GOESDatabaseUpdateTime))
            {
                this.goesDockablePanel.GOESLastUpdateText = "          N/A";
            }
            else
            {
                this.goesDockablePanel.GOESLastUpdateText = "          " + GOESDatabaseUpdateTime.WinTime.ToString("dd MMM yyyy HH:mm:ss") + " UTC";
            }

            // we refresh the graph if the GOES data is to be plotted
            if ((this.goesDockablePanel.GOES10Checked) || (this.goesDockablePanel.GOES11Checked) || (this.goesDockablePanel.GOES12Checked))
            {
                timerGraphUpdate_Tick(sender, e);
            }
        }

        #endregion

        #region Viewer Graph Methods
        /// <summary>
        /// A graph update has been requested
        /// </summary>
        private void viewerGraph_UpdateRequested(object sender, EventArgs e)
        {
            this.timerGraphUpdate_Tick(sender, e);
        }

        /// <summary>
        /// The validity of the displayed file has changed
        /// </summary>
        private void viewerGraph_GraphFileChanged(object sender, PictureViewer.Viewer.GraphFileChangeEventArgs e)
        {
            this.saveGraphAsPNGToolStripMenuItem.Enabled = e.FileValid;
        }

        #endregion

        #region Status Labels Methods
        private void toolStripStatusLabelADC_DoubleClick(object sender, EventArgs e)
        {
            SID_monitor.Properties.Settings.Default.AcquisitionActive = !SID_monitor.Properties.Settings.Default.AcquisitionActive;
        }


        private void toolStripStatusLabelGraph_DoubleClick(object sender, EventArgs e)
        {
            SID_monitor.Properties.Settings.Default.GraphActive = !SID_monitor.Properties.Settings.Default.GraphActive;
        }
        #endregion

        #region File Menu Methods
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //       exitApplicationAsked = true;
            Application.Exit();
        }
        #endregion

        #region View Menu Methods
        private void dateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.dateDockablePanel.IsDisposed)
            {
                this.dateDockablePanel.Show(this.dockPanel);
                this.dateDockablePanel.PanelPane.Activate();
            }
        }

        private void channelsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.channelsDockablePanel.IsDisposed)
            {
                this.channelsDockablePanel.Show(this.dockPanel);
                this.channelsDockablePanel.PanelPane.Activate();
            }
        }

        private void gOESToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.goesDockablePanel.IsDisposed)
            {
                this.goesDockablePanel.Show(this.dockPanel);
                this.goesDockablePanel.PanelPane.Activate();
            }
        }

        private void graphViewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.viewerDockablePanel.IsDisposed)
            {
                this.viewerDockablePanel.Show(this.dockPanel);
                this.viewerDockablePanel.PanelPane.Activate();
            }
        }

        private void showOutputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.outputTextBoxDockablePanel.IsDisposed)
            {
                this.outputTextBoxDockablePanel.Show(this.dockPanel);
                this.outputTextBoxDockablePanel.PanelPane.Activate();
            }
        }
        #endregion

        #region Data Menu Methods

        private void acquisitionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SID_monitor.Properties.Settings.Default.AcquisitionActive = !SID_monitor.Properties.Settings.Default.AcquisitionActive;
        }

        private void resetDetectionAlgorithmToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("You are about to reset aberrant behaviour detection algorithm parameters.\n\nPlease hit <OK> to proceed and <Cancel> to cancel changes.", "Forecast Algorithm Reset Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
            {
                return;
            }

            string RRDCommand = SID_monitor.Program.MainForm.CreateRRDToolResetForecastCommand();

            this.outputTextBoxDockablePanel.AddOutputTextMessage("Resetting Aberrant Behaviour Detection Algorithm...\n");
            this.outputTextBoxDockablePanel.AddOutputTextRRDToolMessage("rrdtool " + RRDCommand + "\n");
            RRDToolConnection.ExecuteRRDTool(RRDCommand, RRDToolProcess.ShowOptions.ErrorsAndStdOut);

        }


        private void reapplyAlgorithmParametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HWReapply dlgHWReapply = new HWReapply();
            dlgHWReapply.Show();
        }

        #endregion

        #region Graph Menu Methods
        private void graphUpdateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SID_monitor.Properties.Settings.Default.GraphActive = !SID_monitor.Properties.Settings.Default.GraphActive;
        }

        private void saveGraphAsPNGToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.viewerDockablePanel.SaveGraphFile();
        }

        #endregion

        #region Reports Menu Methods
        private void viewReportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NGDCReportView reportDlg = new NGDCReportView();
            reportDlg.ShowDialog();
        }

        private void generateReportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NGCDReportGenerate reportDlg = new NGCDReportGenerate();
            reportDlg.ShowDialog();
        }
        #endregion

        #region Tools Menu Methods
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Options optionsDlg = new Options();
            optionsDlg.ShowDialog();
        }

        private void sunriseandSunsetTimesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SunriseSunsetTimes sunriseSunsetTimesDlg = new SunriseSunsetTimes();
            sunriseSunsetTimesDlg.ShowDialog();
        }

        private void minimizeToTrayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SID_monitor.Properties.Settings.Default.MinimizeToTray = !SID_monitor.Properties.Settings.Default.MinimizeToTray;
        }
        #endregion

        #region Help Menu Methods
        private void contentsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, this.helpProvider.HelpNamespace);
        }

        private void indexToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Help.ShowHelpIndex(this, this.helpProvider.HelpNamespace);
        }

        private void searchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, this.helpProvider.HelpNamespace, HelpNavigator.Find, "");
        }

        private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!ApplicationDeployment.IsNetworkDeployed)
            {
                MessageBox.Show("This application deployment does not support network updates.", "SID Monitor On-Demand Update", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            ApplicationDeployment deployment = ApplicationDeployment.CurrentDeployment;
            Cursor currCursor = this.Cursor;
            this.Cursor = Cursors.WaitCursor;
            if (deployment.CheckForUpdate())
            {
                deployment.Update();

                this.Cursor = currCursor;

                DialogResult result = MessageBox.Show("Update Complete. Restart?", "SID Monitor On-Demand Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

                if (result == DialogResult.Yes)
                {
                    Application.Restart();
                }
            }
            else
            {
                MessageBox.Show("No updates available", "SID Monitor On-Demand Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            this.Cursor = currCursor;
        }

        /// <summary>
        /// Shows the About... box
        /// </summary>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About aboutDlg = new About();
            aboutDlg.ShowDialog();
        }
        #endregion

        #region Notify Icon Methods
        /// <summary>
        /// Minimize or restores the main program window when double clicking on the notify icon
        /// </summary>
        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            if (Program.MainForm != null)
            {
                if ((Program.MainForm.WindowState == FormWindowState.Maximized) || (Program.MainForm.WindowState == FormWindowState.Normal))
                {
                    Program.MainForm.WindowState = FormWindowState.Minimized;
                }
                else
                {
                    Program.MainForm.WindowState = FormWindowState.Normal;
                }
            }
        }

        /// <summary>
        /// Restores the main program window
        /// </summary>
        private void restoreSIDMonitorWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Program.MainForm != null)
            {
                if (Program.MainForm.WindowState == FormWindowState.Minimized)
                {
                    Program.MainForm.WindowState = FormWindowState.Normal;
                }
            }
        }

        #endregion

        #region DataElement Class containing data value and time
        private class DataElement
        {
            private UInt64 time;
            private int sunPosition;
            private uint[] value = new uint[16];

            public DataElement()
            {
                this.time = UInt64.MinValue;
                this.sunPosition = int.MinValue;
                for (int i = 0; i < 16; i++)
                {
                    this.value[i] = uint.MinValue;
                }

            }

            public UInt64 Time
            {
                get { return this.time; }
                set { this.time = value; }
            }

            public int SunPosition
            {
                get { return this.sunPosition; }
                set { this.sunPosition = value; }
            }

            public uint[] Value
            {
                get { return this.value; }
                set { this.value = value; }
            }
        }
        #endregion

        #region RRDTool Commands Creation

        /// <summary>
        ///  The RRDTool command when creating a new database.
        /// </summary>
        public string CreateRRDToolCreateCommand()
        {
            return CreateRRDToolCreateCommand(SID_monitor.Properties.Settings.Default.RRDToolDatabase,
                                              SIDMonitorDateTime.UtcNow.UnixTime - 10,
                                              SID_monitor.Properties.Settings.Default.ForecastAlpha,
                                              SID_monitor.Properties.Settings.Default.ForecastBeta,
                                              SID_monitor.Properties.Settings.Default.ForecastGammaSeasonal,
                                              SID_monitor.Properties.Settings.Default.ForecastGammaDevSeasonal,
                                              SID_monitor.Properties.Settings.Default.ForecastThreshold,
                                              SID_monitor.Properties.Settings.Default.ForecastWindowLength);
        }

        /// <summary>
        ///  The RRDTool command when creating a new database with a specific filename, starting at the given time and with specific forecast parameters.
        /// </summary>
        public string CreateRRDToolCreateCommand(string filename, ulong startTime, int forecastAlpha, int forecastBeta, int forecastGammaSeasonal, int forecastGammaDevSeasonal, int forecastThreshold, int forecastWindowLength)
        {
            UInt64 step = (UInt64)(SID_monitor.Properties.Settings.Default.AcquisitionUpdate / 1000);  // database nominal update
            UInt64 data_heartbeat = 2 * step;                                                          // we accept to miss one value
            UInt64 sun_heartbeat = (UInt64)(2 * (Program.MainForm.timerSunUpdate.Interval / 1000));    // we accept to miss one value

            UInt64 datapoints_per_day = 86400 / step;                                                  // number of datapoints in a given day
            UInt64 archive_size = (UInt64)(datapoints_per_day * SID_monitor.Properties.Settings.Default.DatabaseSize);      // number on points to store in the archive

            String RRDCommand = String.Empty;

            RRDCommand = "create \"" + filename + "\" ";
            RRDCommand += "--start " + startTime.ToString() + " ";
            RRDCommand += "--step " + step.ToString() + " ";
            RRDCommand += "DS:sun:GAUGE:" + sun_heartbeat.ToString() + ":0:8 ";

            #region channels DSs
            // channel 1
            if (SID_monitor.Properties.Settings.Default.Channel1Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel1StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel1StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel1StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 1 (" + SID_monitor.Properties.Settings.Default.Channel1StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel1StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 2
            if (SID_monitor.Properties.Settings.Default.Channel2Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel2StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel2StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel2StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 2 (" + SID_monitor.Properties.Settings.Default.Channel2StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel2StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 3
            if (SID_monitor.Properties.Settings.Default.Channel3Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel3StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel3StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel3StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 3 (" + SID_monitor.Properties.Settings.Default.Channel3StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel3StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 4
            if (SID_monitor.Properties.Settings.Default.Channel4Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel4StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel4StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel4StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 4 (" + SID_monitor.Properties.Settings.Default.Channel4StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel4StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 5
            if (SID_monitor.Properties.Settings.Default.Channel5Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel5StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel5StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel5StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 5 (" + SID_monitor.Properties.Settings.Default.Channel5StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel5StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 6
            if (SID_monitor.Properties.Settings.Default.Channel6Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel6StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel6StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel6StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 6 (" + SID_monitor.Properties.Settings.Default.Channel6StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel6StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 7
            if (SID_monitor.Properties.Settings.Default.Channel7Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel7StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel7StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel7StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 7 (" + SID_monitor.Properties.Settings.Default.Channel7StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel7StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 8
            if (SID_monitor.Properties.Settings.Default.Channel8Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel8StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel8StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel8StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 8 (" + SID_monitor.Properties.Settings.Default.Channel8StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel8StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 9
            if (SID_monitor.Properties.Settings.Default.Channel9Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel9StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel9StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel9StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 9 (" + SID_monitor.Properties.Settings.Default.Channel9StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel9StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 10
            if (SID_monitor.Properties.Settings.Default.Channel10Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel10StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel10StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel10StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 10 (" + SID_monitor.Properties.Settings.Default.Channel10StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel10StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 11
            if (SID_monitor.Properties.Settings.Default.Channel11Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel11StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel11StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel11StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 11 (" + SID_monitor.Properties.Settings.Default.Channel11StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel11StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 12
            if (SID_monitor.Properties.Settings.Default.Channel12Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel12StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel12StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel12StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 12 (" + SID_monitor.Properties.Settings.Default.Channel12StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel12StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 13
            if (SID_monitor.Properties.Settings.Default.Channel13Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel13StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel13StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel13StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 13 (" + SID_monitor.Properties.Settings.Default.Channel13StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel13StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 14
            if (SID_monitor.Properties.Settings.Default.Channel14Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel14StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel14StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel14StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 14 (" + SID_monitor.Properties.Settings.Default.Channel14StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel14StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 15
            if (SID_monitor.Properties.Settings.Default.Channel15Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel15StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel15StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel15StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 15 (" + SID_monitor.Properties.Settings.Default.Channel15StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel15StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }

            // channel 16
            if (SID_monitor.Properties.Settings.Default.Channel16Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel16StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel16StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel16StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 16 (" + SID_monitor.Properties.Settings.Default.Channel16StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "DS:" + SID_monitor.Properties.Settings.Default.Channel16StationCode + ":GAUGE:" + data_heartbeat.ToString() + ":0:4095 ";
                }
            }
            #endregion

            // RRA
            RRDCommand += "RRA:AVERAGE:0.99:1:" + archive_size.ToString() + " "; // RRA #1

            // forecasting seasonal period is one day
            RRDCommand += "RRA:HWPREDICT:" + archive_size.ToString() + ":" + ((decimal)(forecastAlpha / 100.0)).ToString("0.00") + ":" + ((decimal)(forecastBeta / 100.0)).ToString("0.00") + ":" + datapoints_per_day.ToString() + ":3 "; // RRA #2
            RRDCommand += "RRA:SEASONAL:" + datapoints_per_day.ToString() + ":" + ((decimal)(forecastGammaSeasonal / 100.0)).ToString("0.00") + ":2 "; // RRA #3
            RRDCommand += "RRA:DEVSEASONAL:" + datapoints_per_day.ToString() + ":" + ((decimal)(forecastGammaDevSeasonal / 100.0)).ToString("0.00") + ":2 "; // RRA #4
            RRDCommand += "RRA:DEVPREDICT:" + archive_size.ToString() + ":4 "; // RRA #5
            RRDCommand += "RRA:FAILURES:" + archive_size.ToString() + ":" + forecastThreshold.ToString() + ":" + forecastWindowLength.ToString() + ":4 "; // RRA #6

            return RRDCommand;

        }

        /// <summary>
        /// The RRDTool command when renaming datasets from the database
        /// </summary>
        public string CreateRRDToolRenameDSCommand(string[] old_names)
        {
            string RRDCommand = string.Empty;

            RRDCommand = "tune \"" + SID_monitor.Properties.Settings.Default.RRDToolDatabase + "\" ";

            #region channels DSs
            // channel 1
            if (SID_monitor.Properties.Settings.Default.Channel1Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel1StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel1StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel1StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 1 (" + SID_monitor.Properties.Settings.Default.Channel1StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[0] + ":" + SID_monitor.Properties.Settings.Default.Channel1StationCode + " ";
                }
            }

            // channel 2
            if (SID_monitor.Properties.Settings.Default.Channel2Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel2StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel2StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel2StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 2 (" + SID_monitor.Properties.Settings.Default.Channel2StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[1] + ":" + SID_monitor.Properties.Settings.Default.Channel2StationCode + " ";
                }
            }

            // channel 3
            if (SID_monitor.Properties.Settings.Default.Channel3Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel3StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel3StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel3StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 3 (" + SID_monitor.Properties.Settings.Default.Channel3StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[2] + ":" + SID_monitor.Properties.Settings.Default.Channel3StationCode + " ";
                }
            }

            // channel 4
            if (SID_monitor.Properties.Settings.Default.Channel4Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel4StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel4StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel4StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 4 (" + SID_monitor.Properties.Settings.Default.Channel4StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[3] + ":" + SID_monitor.Properties.Settings.Default.Channel4StationCode + " ";
                }
            }

            // channel 5
            if (SID_monitor.Properties.Settings.Default.Channel5Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel5StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel5StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel5StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 5 (" + SID_monitor.Properties.Settings.Default.Channel5StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[4] + ":" + SID_monitor.Properties.Settings.Default.Channel5StationCode + " ";
                }
            }

            // channel 6
            if (SID_monitor.Properties.Settings.Default.Channel6Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel6StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel6StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel6StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 6 (" + SID_monitor.Properties.Settings.Default.Channel6StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[5] + ":" + SID_monitor.Properties.Settings.Default.Channel6StationCode + " ";
                }
            }

            // channel 7
            if (SID_monitor.Properties.Settings.Default.Channel7Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel7StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel7StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel7StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 7 (" + SID_monitor.Properties.Settings.Default.Channel7StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[6] + ":" + SID_monitor.Properties.Settings.Default.Channel7StationCode + " ";
                }
            }

            // channel 8
            if (SID_monitor.Properties.Settings.Default.Channel8Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel8StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel8StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel8StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 8 (" + SID_monitor.Properties.Settings.Default.Channel8StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[7] + ":" + SID_monitor.Properties.Settings.Default.Channel8StationCode + " ";
                }
            }

            // channel 9
            if (SID_monitor.Properties.Settings.Default.Channel9Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel9StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel9StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel9StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 9 (" + SID_monitor.Properties.Settings.Default.Channel9StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[8] + ":" + SID_monitor.Properties.Settings.Default.Channel9StationCode + " ";
                }
            }

            // channel 10
            if (SID_monitor.Properties.Settings.Default.Channel10Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel10StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel10StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel10StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 10 (" + SID_monitor.Properties.Settings.Default.Channel10StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[9] + ":" + SID_monitor.Properties.Settings.Default.Channel10StationCode + " ";
                }
            }

            // channel 11
            if (SID_monitor.Properties.Settings.Default.Channel11Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel11StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel11StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel11StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 11 (" + SID_monitor.Properties.Settings.Default.Channel11StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[10] + ":" + SID_monitor.Properties.Settings.Default.Channel11StationCode + " ";
                }
            }

            // channel 12
            if (SID_monitor.Properties.Settings.Default.Channel12Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel12StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel12StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel12StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 12 (" + SID_monitor.Properties.Settings.Default.Channel12StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[11] + ":" + SID_monitor.Properties.Settings.Default.Channel12StationCode + " ";
                }
            }

            // channel 13
            if (SID_monitor.Properties.Settings.Default.Channel13Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel13StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel13StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel13StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 13 (" + SID_monitor.Properties.Settings.Default.Channel13StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[12] + ":" + SID_monitor.Properties.Settings.Default.Channel13StationCode + " ";
                }
            }

            // channel 14
            if (SID_monitor.Properties.Settings.Default.Channel14Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel14StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel14StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel14StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 14 (" + SID_monitor.Properties.Settings.Default.Channel14StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[13] + ":" + SID_monitor.Properties.Settings.Default.Channel14StationCode + " ";
                }
            }

            // channel 15
            if (SID_monitor.Properties.Settings.Default.Channel15Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel15StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel15StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel15StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 15 (" + SID_monitor.Properties.Settings.Default.Channel15StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[14] + ":" + SID_monitor.Properties.Settings.Default.Channel15StationCode + " ";
                }
            }

            // channel 16
            if (SID_monitor.Properties.Settings.Default.Channel16Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel16StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel16StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel16StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 16 (" + SID_monitor.Properties.Settings.Default.Channel16StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--data-source-rename " + old_names[15] + ":" + SID_monitor.Properties.Settings.Default.Channel16StationCode + " ";
                }
            }
            #endregion

            return RRDCommand;
        }

        /// <summary>
        /// The RRDTool command when tuning the default database
        /// </summary>
        public string CreateRRDToolTuneCommand()
        {
            return CreateRRDToolTuneCommand(SID_monitor.Properties.Settings.Default.RRDToolDatabase,
                                            SID_monitor.Properties.Settings.Default.ForecastAlpha,
                                            SID_monitor.Properties.Settings.Default.ForecastBeta,
                                            SID_monitor.Properties.Settings.Default.ForecastGammaSeasonal,
                                            SID_monitor.Properties.Settings.Default.ForecastGammaDevSeasonal,
                                            SID_monitor.Properties.Settings.Default.ForecastThreshold,
                                            SID_monitor.Properties.Settings.Default.ForecastWindowLength,
                                            SID_monitor.Properties.Settings.Default.DeltaPos,
                                            SID_monitor.Properties.Settings.Default.DeltaNeg);
        }

        /// <summary>
        /// The RRDTool command when tuning a specific database
        /// </summary>
        public string CreateRRDToolTuneCommand(string filename, int forecastAlpha, int forecastBeta, int forecastGammaSeasonal, int forecastGammaDevSeasonal, int forecastThreshold, int forecastWindowLength, int forecastDeltaPos, int forecastDeltaNeg)
        {
            string RRDCommand = string.Empty;

            RRDCommand = "tune \"" + filename + "\" ";

            // Alpha
            RRDCommand += "--alpha " + ((decimal)(forecastAlpha / 100.0)).ToString("0.00") + " ";

            // Beta
            RRDCommand += "--beta " + ((decimal)(forecastBeta / 100.0)).ToString("0.00") + " ";

            // Gamma Seasonal
            RRDCommand += "--gamma " + ((decimal)(forecastGammaSeasonal / 100.0)).ToString("0.00") + " ";

            // Gamma Deviation Seasonal
            RRDCommand += "--gamma-deviation " + ((decimal)(forecastGammaDevSeasonal / 100.0)).ToString("0.00") + " ";

            // DeltaPos
            RRDCommand += "--deltapos  " + forecastDeltaPos.ToString() + " ";

            // DeltaNeg
            RRDCommand += "--deltaneg  " + forecastDeltaNeg.ToString() + " ";

            // Threshold
            RRDCommand += "--failure-threshold " + forecastThreshold.ToString() + " ";

            // Window Length
            RRDCommand += "--window-length " + forecastWindowLength.ToString() + " ";

            return RRDCommand;
        }

        ///// <summary>
        ///// The RRDTool command for determining start time of the database
        ///// </summary>
        //public string CreateRRDToolFirstCommand()
        //{
        //    string RRDCommand = string.Empty;

        //    RRDCommand = "first \"" + SID_monitor.Properties.Settings.Default.RRDToolDatabase + "\" ";

        //    return RRDCommand;
        //}


        ///// <summary>
        ///// The RRDTool command for determining last database update time
        ///// </summary>
        //public string CreateRRDToolLastCommand()
        //{
        //    return CreateRRDToolLastCommand(SID_monitor.Properties.Settings.Default.RRDToolDatabase);
        //}

        ///// <summary>
        ///// The RRDTool command for determining last database update time for the given database filename
        ///// </summary>
        //public string CreateRRDToolLastCommand(string filename)
        //{
        //    string RRDCommand = string.Empty;

        //    RRDCommand = "last \"" + filename + "\" ";

        //    return RRDCommand;
        //}

        /// <summary>
        /// The RRDTool command for restoring database from XML file
        /// </summary>
        public string CreateRRDToolRestoreCommand(string databaseName, string xmlFile)
        {
            string RRDCommand = string.Empty;

            RRDCommand = "restore \"" + xmlFile + "\" \"" + databaseName + "\" ";

            return RRDCommand;
        }

        /// <summary>
        /// The RRDTool command for dumping database
        /// </summary>
        public string CreateRRDToolFetchCommand(string filename, ulong startTime)
        {
            string RRDCommand = string.Empty;

            RRDCommand = "fetch \"" + filename + "\" AVERAGE ";
            RRDCommand += "--start " + startTime.ToString() + " ";

            return RRDCommand;
        }

        /// <summary>
        /// The RRDTool command when resetting the aberrant behaviour detection algorithm
        /// </summary>
        public string CreateRRDToolResetForecastCommand()
        {
            string RRDCommand = string.Empty;

            RRDCommand = "tune \"" + SID_monitor.Properties.Settings.Default.RRDToolDatabase + "\" ";

            #region channels DSs
            // channel 1
            if (SID_monitor.Properties.Settings.Default.Channel1Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel1StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel1StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel1StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 1 (" + SID_monitor.Properties.Settings.Default.Channel1StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel1StationCode + " ";
                }
            }

            // channel 2
            if (SID_monitor.Properties.Settings.Default.Channel2Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel2StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel2StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel2StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 2 (" + SID_monitor.Properties.Settings.Default.Channel2StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel2StationCode + " ";
                }
            }

            // channel 3
            if (SID_monitor.Properties.Settings.Default.Channel3Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel3StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel3StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel3StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 3 (" + SID_monitor.Properties.Settings.Default.Channel3StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel3StationCode + " ";
                }
            }

            // channel 4
            if (SID_monitor.Properties.Settings.Default.Channel4Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel4StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel4StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel4StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 4 (" + SID_monitor.Properties.Settings.Default.Channel4StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel4StationCode + " ";
                }
            }

            // channel 5
            if (SID_monitor.Properties.Settings.Default.Channel5Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel5StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel5StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel5StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 5 (" + SID_monitor.Properties.Settings.Default.Channel5StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel5StationCode + " ";
                }
            }

            // channel 6
            if (SID_monitor.Properties.Settings.Default.Channel6Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel6StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel6StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel6StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 6 (" + SID_monitor.Properties.Settings.Default.Channel6StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel6StationCode + " ";
                }
            }

            // channel 7
            if (SID_monitor.Properties.Settings.Default.Channel7Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel7StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel7StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel7StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 7 (" + SID_monitor.Properties.Settings.Default.Channel7StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel7StationCode + " ";
                }
            }

            // channel 8
            if (SID_monitor.Properties.Settings.Default.Channel8Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel8StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel8StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel8StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 8 (" + SID_monitor.Properties.Settings.Default.Channel8StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel8StationCode + " ";
                }
            }

            // channel 9
            if (SID_monitor.Properties.Settings.Default.Channel9Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel9StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel9StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel9StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 9 (" + SID_monitor.Properties.Settings.Default.Channel9StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel9StationCode + " ";
                }
            }

            // channel 10
            if (SID_monitor.Properties.Settings.Default.Channel10Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel10StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel10StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel10StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 10 (" + SID_monitor.Properties.Settings.Default.Channel10StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel10StationCode + " ";
                }
            }

            // channel 11
            if (SID_monitor.Properties.Settings.Default.Channel11Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel11StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel11StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel11StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 11 (" + SID_monitor.Properties.Settings.Default.Channel11StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel11StationCode + " ";
                }
            }

            // channel 12
            if (SID_monitor.Properties.Settings.Default.Channel12Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel12StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel12StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel12StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 12 (" + SID_monitor.Properties.Settings.Default.Channel12StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel12StationCode + " ";
                }
            }

            // channel 13
            if (SID_monitor.Properties.Settings.Default.Channel13Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel13StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel13StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel13StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 13 (" + SID_monitor.Properties.Settings.Default.Channel13StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel13StationCode + " ";
                }
            }

            // channel 14
            if (SID_monitor.Properties.Settings.Default.Channel14Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel14StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel14StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel14StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 14 (" + SID_monitor.Properties.Settings.Default.Channel14StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel14StationCode + " ";
                }
            }

            // channel 15
            if (SID_monitor.Properties.Settings.Default.Channel15Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel15StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel15StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel15StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 15 (" + SID_monitor.Properties.Settings.Default.Channel15StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel15StationCode + " ";
                }
            }

            // channel 16
            if (SID_monitor.Properties.Settings.Default.Channel16Active == true)
            {
                if ((SID_monitor.Properties.Settings.Default.Channel16StationCode.Length == 0) || (SID_monitor.Properties.Settings.Default.Channel16StationCode.Length > 19) || Regex.IsMatch(SID_monitor.Properties.Settings.Default.Channel16StationCode, "[^A-Za-z1-9_]"))
                {
                    MessageBox.Show("Invalid Name for Channel 16 (" + SID_monitor.Properties.Settings.Default.Channel16StationCode + "). Name must be 1 to 19 characters long in the range [a-zA-Z0-9_]", "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    RRDCommand += "--aberrant-reset " + SID_monitor.Properties.Settings.Default.Channel16StationCode + " ";
                }
            }
            #endregion

            return RRDCommand;

        }

        #endregion

 
    }
}