using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;

using Ivi.Driver.Interop;

namespace MIMOTestPlan
{
    public partial class MIMODemoProgram
    {
        // Data Logging
        public bool loggingData = false;
        public bool generateHeader = false;
        public bool updateResultWindow = true;
        public StringBuilder loggingString = new StringBuilder();
        public StringBuilder headerString = new StringBuilder();
        public StringBuilder testHeaderString = new StringBuilder();
        public StringBuilder freqHeaderString = new StringBuilder();
        public string resultsString;
        public int testIndex = 0;
        private int dutCount = 0;
        public string tstName;
        public string freqString;

        // Data Logging Methods here
        private TextWriter logFile;
        public void openDataLog(string filePath, string fileName)
        {
            string logFileFullName = Path.Combine(filePath, fileName);
            try
            {
                logFile = new StreamWriter(logFileFullName, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + "Is Log File open in Excel?");
                logFile = new StreamWriter(logFileFullName, false);
            }
        }
        public void createHeader(int numReps)
        {
            if (loggingData)
            {
                // Setup header for data log
                loggingString.Remove(0, loggingString.Length);
                loggingString.Append(",");
                generateHeader = true;
                headerString.Remove(0, headerString.Length);
                testHeaderString.Remove(0, testHeaderString.Length);
                freqHeaderString.Remove(0, freqHeaderString.Length);
                testHeaderString.Append("Test" + ",");
                freqHeaderString.Append("Freq (MHz)" + ",");
                headerString.Append("Step" + ",");
            }
            dutCount = numReps;
        }

        public void logDataItems(string[] dataNames, string[] unitNames, string[] numFormats, double[] dataValues)
        {
            for (int i = 0; i < dataNames.Length; i++)
            {
                logDataItem(dataNames[i], unitNames[i], numFormats[i], dataValues[i]);
            }
        }

        private void logDataItem(string dataName, string unitName, string numFormat, double dataValue)
        {
            // Output Result to the Results window in the GUI
            if (updateResultWindow)
                resultsString = resultsString + dataName + "     "
                + (dataValue).ToString(numFormat) + " " + unitName + Environment.NewLine;

            // Create the hearder information for the CSV File (only done on first DUT)
            if (generateHeader)
            {
                headerString.Append(dataName + ",");
                freqHeaderString.Append(freqString + ",");
                testHeaderString.Append(tstName + ",");
            }

            // Add Result to the .CSV Data file
            if (loggingData)
                loggingString.Append(dataValue.ToString(numFormat) + ",");
        }

        public void logLine(string dataLine)
        {
            logFile.Write(dataLine);
        }

        public void closeDataLog()
        {
            logFile.Close();
        }

        public void addResultsHeader(string testName)
        {
            resultsString = resultsString + Environment.NewLine + testName + ":" + Environment.NewLine;
        }

        public void addResultsFooter(string testName, long testTime_ms)
        {
            resultsString = resultsString + Environment.NewLine + testName + " Elapsed Time:  " +
                testTime_ms.ToString() + Environment.NewLine + Environment.NewLine;
            if (loggingData) loggingString.Append(testTime_ms.ToString() + ",,");
            if (generateHeader)
            {
                headerString.Append("Time" + ",,");
                testHeaderString.Append(tstName + ",,");
                freqHeaderString.Append(",,");
            }
        }

        public void nextTest()
        {
            testIndex++;
            if (updateResultWindow) resultsString = resultsString + Environment.NewLine;
        }

        public void endDutLog()
        {
            if (loggingData)
            {
                if (generateHeader)
                {
                    // Write the test names to the log file
                    testHeaderString.Append(Environment.NewLine);
                    logLine(testHeaderString.ToString());
                    // Write the test Frequencies to the log file
                    freqHeaderString.Append(Environment.NewLine);
                    logLine(freqHeaderString.ToString());
                    // Write the step names to the log file
                    headerString.Append(Environment.NewLine);
                    logLine(headerString.ToString());
                    generateHeader = false;
                    // find how many columns
                    string[] testNames = headerString.ToString().Split(',');
                    int count = testNames.Length - 1;
                    headerString.Remove(0, headerString.Length);
                    // Create the statistics formulas
                    // Step 1:  Create the column names to use in the formulas
                    string[] columnLetter = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", 
                        "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
                    string[] columnNames = new string[count];
                    int idx0 = -1;
                    int idx1 = -1;
                    int idx2 = 0;
                    for (int i = 0; i < count; i++)
                    {
                        // Build column names
                        // first 26 have one letter, rest are two letters
                        // Order:  A...Z,AA...ZZ,AAA...ZZZ
                        if (idx1 < 0)
                            columnNames[i] = columnLetter[idx2];
                        else if (idx0 < 0)
                            columnNames[i] = columnLetter[idx1] + columnLetter[idx2];
                        else
                            columnNames[i] = columnLetter[idx0] + columnLetter[idx1] + columnLetter[idx2];
                        idx2++;
                        if (idx2 >= columnLetter.Length)
                        {
                            idx2 = 0;
                            idx1++;
                        }
                        if (idx1 >= columnLetter.Length)
                        {
                            idx2 = 0;
                            idx1 = 0;
                            idx0++;
                        }
                    }
                    // Step 2:  Build a row for wach formula
                    string[] formulaNames = new string[] { "MAX", "MIN", "AVERAGE", "STDEV", "RANGE" };
                    int firstDataRow = 4 + formulaNames.Length;
                    int lastDataRow = firstDataRow + dutCount;
                    foreach (string thisFormula in formulaNames)
                    {
                        headerString.Append(thisFormula + ",");
                        for (int i = 1; i < count - 1; i++)
                        {
                            // If the test name is blank, don't write a formula
                            if (testNames[i] == "")
                                headerString.Append(",");
                            else
                                if (thisFormula != "RANGE")
                                    headerString.Append("=" + thisFormula + "(" + columnNames[i] + firstDataRow.ToString()
                                        + ":" + columnNames[i] + lastDataRow.ToString() + ")" + ",");
                                else
                                    // Hack for range, no single formula in Excel
                                    headerString.Append("=" + columnNames[i] + "4"
                                         + "-" + columnNames[i] + "5" + ",");
                        }
                        headerString.Append(Environment.NewLine);
                        logLine(headerString.ToString());
                        headerString.Remove(0, headerString.Length);
                    }
                }

                // Write the current DUT line to file
                loggingString.Append(Environment.NewLine);
                logLine(loggingString.ToString());
                // Empty line and add a blank column to beginning of line
                loggingString.Remove(0, loggingString.Length);
                loggingString.Append(",");
            }

        }

        // Generic Array to Disk file Utility
        private void WriteArray(string filePath, string fileName, double[] dataArray)
        {
            string logFileName = Path.Combine(filePath, fileName);
            StreamWriter arrayFile = new StreamWriter(logFileName, false);
            for (int i = 0; i < dataArray.Length; i++)
            {
                arrayFile.WriteLine(dataArray[i].ToString("0.00"));
            }
            arrayFile.Close();
        }

        // Interleved IQ Data Array to 89600 Disk file Utility
        private void Write89600file(string filePath, string fileName, double[] dataArray, double centerFreq, double sampleRate)
        {
            string logFileName = Path.Combine(filePath, fileName);
            StreamWriter arrayFile = new StreamWriter(logFileName, false);

            // InputCenter\t%g\nInputZoom\tTRUE\nInputRefImped\t50.0\nXStart\t0.0\nXDelta\t%g\nYScale\t%g\n
            arrayFile.WriteLine("InputCenter\t" + centerFreq.ToString());
            arrayFile.WriteLine("InputZoom\tTRUE");
            arrayFile.WriteLine("InputRefImped\t50.0");
            arrayFile.WriteLine("XStart\t0.0");
            arrayFile.WriteLine("XDelta\t" + (1/sampleRate).ToString());
            arrayFile.WriteLine("YScale\t1.0");

            for (int i = 0; i < dataArray.Length; i=i+2)
            {
                arrayFile.WriteLine(dataArray[i].ToString("0.000000") + "\t" + dataArray[i+1].ToString("0.000000"));
            }
            arrayFile.Close();
        }

    }
}