using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OPCTrendControl;

namespace OPCMonitoring
{
    /// <summary>
    /// Main Form for the application
    /// </summary>
    public partial class MainForm : Form
    {
        /// <summary>
        /// Alarms that we watch in the application
        /// </summary>
        public List<Alarm> Alarms = new List<Alarm>();
        private LogViewer logViewer = new LogViewer();
        private int mailCounter = 0;

        private delegate void ChangeLogDelegate(string message);

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            MailEditor mailEditor = new MailEditor();
            mailEditor.ShowDialog();
        }

        private void btnAlarms_Click(object sender, EventArgs e)
        {
            List<ClassPen> pensProcessorXP = new List<ClassPen>();
            List<ClassPen> pensProcessorServer = new List<ClassPen>();

            foreach (ClassPen pen in processorXP1.Pens)
                pensProcessorXP.Add(pen);

            foreach (ClassPen pen in processorXP2.Pens)
                pensProcessorXP.Add(pen);

            foreach (ClassPen pen in processorServer1.Pens)
                pensProcessorServer.Add(pen);

            foreach (ClassPen pen in processorServer2.Pens)
                pensProcessorServer.Add(pen);


            List<ClassPen> pensXpMemory = new List<ClassPen>();
            List<ClassPen> pensServerMemory = new List<ClassPen>();

            foreach (ClassPen pen in memoryXP.Pens)
                pensXpMemory.Add(pen);

            foreach (ClassPen pen in memoryServer.Pens)
                pensServerMemory.Add(pen);

            List<ClassPen> pensXpHardDisc = new List<ClassPen>();
            List<ClassPen> pensServerHardDisc = new List<ClassPen>();

            foreach (ClassPen pen in hardDiscXP.Pens)
                pensXpHardDisc.Add(pen);

            foreach (ClassPen pen in hardDiscServer.Pens)
                pensServerHardDisc.Add(pen);

            List<ClassPen> pensXpNetwork = new List<ClassPen>();
            List<ClassPen> pensServerNetwork = new List<ClassPen>();

            foreach (ClassPen pen in networkXP.Pens)
                pensXpNetwork.Add(pen);

            foreach (ClassPen pen in networkServer.Pens)
                pensServerNetwork.Add(pen);

            AlarmEditor alarmEditor = new AlarmEditor(pensProcessorXP, pensProcessorServer, pensXpMemory, pensServerMemory, pensXpHardDisc, pensServerHardDisc, pensXpNetwork, pensServerNetwork, this);
            if (alarmEditor.ShowDialog() == DialogResult.OK)
            {
                foreach (Alarm alarm in Alarms)
                {
                    opcControlsData1.AddTag(alarm.Pen);
                }

                lblStatus.Text = Alarms.Count.ToString() + " Counters watching";
            }
        }

        private void AddToLog(string message)
        {
            if (logViewer.TextField.InvokeRequired)
            {
                logViewer.TextField.Invoke(new ChangeLogDelegate(ChangeLog) , message);
            }
            else
                ChangeLog(message);
        }

        private void ChangeLog(string message)
        {
            logViewer.TextField.Text += message + Environment.NewLine;
        }

        private void btnViewLog_Click(object sender, EventArgs e)
        {
            logViewer.Show();
        }

        private void opcControlsData1_ValuesChangedAll(string[] Tags, object[] Values, bool[] Qualities, DateTime[] TimeStamps)
        {
            List<ExcelRow> rows = new List<ExcelRow>();

            for (int i = 0; i < Tags.Length; i++)
            {
                Alarm alarm = Alarms.Find(p => p.Pen == Tags[i]);

                string machine = alarm.Pen.ToLower().Contains("server") ? "Server2003" : "XP";
                switch (alarm.Option)
                {
                    case "<": if (Convert.ToDouble(Values[i]) < alarm.Value)
                            AddToLog("Alarm for counter \"" + alarm.Description + "\", on " + machine + " machine, Current Value: " + Values[i].ToString() + " (<" + alarm.Value.ToString() + "), on " + DateTime.Now.ToString());
                        break;
                    case ">": if (Convert.ToDouble(Values[i]) > alarm.Value)
                            AddToLog("Alarm for counter \"" + alarm.Description + "\", on " + machine + " machine, Current Value: " + Values[i].ToString() + " (>" + alarm.Value.ToString() + "), on " + DateTime.Now.ToString());
                        break;
                    case "=": if (Convert.ToDouble(Values[i]) == alarm.Value)
                            AddToLog("Alarm for counter \"" + alarm.Description + "\", on " + machine + " machine, Current Value: " + Values[i].ToString() + " (=" + alarm.Value.ToString() + "), on " + DateTime.Now.ToString());
                        break;

                    default: MessageBox.Show("Unknown case");
                        break;
                }

                rows.Add(new ExcelRow { Counter = alarm.Description, Machine = machine, Value = Values[i].ToString() });

            }

            mailCounter += MailController.SendMail(rows);
            lblStatus2.Text = mailCounter.ToString() + " Emails sent (Click on View Log to see the details)";
        }
    }

    /// <summary>
    /// Object that represents one pen in the grid that we are monitoring
    /// </summary>
    public class Alarm
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Alarm"/> class.
        /// </summary>
        public Alarm()
        {

        }
        /// <summary>
        /// Gets or sets the pen.
        /// </summary>
        /// <value>The pen.</value>
        public string Pen { get; set; }
        /// <summary>
        /// Gets or sets the option.
        /// </summary>
        /// <value>The option.</value>
        public string Option { get; set; }
        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        public double Value { get; set; }
        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        public string Description { get; set; }
    }
}
