using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace distribution_explorer
{
  /// <summary>
  /// Main distribution explorer.
  /// </summary>
  public partial class DistexForm : Form
  {

    EventLog log = new EventLog();
    /// <summary>
    /// Main form
    /// </summary>
    public DistexForm()
    {
      if (!EventLog.SourceExists("EventLogDistex"))
      {
        EventLog.CreateEventSource("EventLogDistex", "Application");
      }
      log.Source = "EventLogDistex";
      log.WriteEntry("DistexForm");

      InitializeComponent();

      Application.DoEvents();
    }

    private void Form_Load(object sender, EventArgs e)
    { // Load distribution & parameters names, and default values.
      try
      {
        // Create and show splash screen:
        this.Hide();
        distexSplash frmSplash = new distexSplash();
        frmSplash.Show();
        frmSplash.Update();
        // Now load our data while the splash is showing:
        if (boost_math.any_distribution.size() <= 0)
        {
          MessageBox.Show("Problem loading any distributions, size = " + boost_math.any_distribution.size().ToString());
        }
        for (int i = 0; i < boost_math.any_distribution.size(); ++i)
        {
          distribution.Items.Add(boost_math.any_distribution.distribution_name(i));
        }
        distribution.SelectedIndex = 0; // 1st in array, but could be any other.
        // All parameters are made zero by default, but updated from chosen distribution.
        parameter1.Text = boost_math.any_distribution.first_param_default(0).ToString();
        parameter2.Text = boost_math.any_distribution.second_param_default(0).ToString();
        parameter3.Text = boost_math.any_distribution.third_param_default(0).ToString();
        //
        // Sleep and then close splash;
        Thread.Sleep(3000);
        frmSplash.Close();
        this.Visible = true;
      }
      catch
      { //
        log.WriteEntry("DistexForm_load exception!");
        MessageBox.Show("Problem loading distributions, size = " + boost_math.any_distribution.size().ToString());
      }
    }

    private void distribution_SelectedIndexChanged(object sender, EventArgs e)
    {
      int i = distribution.SelectedIndex; // distribution tab.
      parameter1Label.Text = boost_math.any_distribution.first_param_name(i);
      parameterLabel1.Text = boost_math.any_distribution.first_param_name(i); // properties tab.
      parameter2Label.Text = boost_math.any_distribution.second_param_name(i);
      parameter3Label.Text = boost_math.any_distribution.third_param_name(i);
      if (boost_math.any_distribution.first_param_name(i).Length.CompareTo(0) != 0)
      { // Actually all the distributions have at least one parameters,
        parameter1.Visible = true; // so should always be true.
        parameterLabel1.Visible = true;
      }
      else
      { // If distribution chosen has no parameter name(s) then hide.
        parameter1.Visible = false;
        parameterLabel1.Visible = false;
      }
      parameter1.Text = boost_math.any_distribution.first_param_default(i).ToString();
      // Update parameter default to match distribution.
      if (boost_math.any_distribution.second_param_name(i).Length.CompareTo(0) != 0)
      {
        parameter2.Visible = true;
        parameterLabel2.Visible = true;
        parameter2ValueLabel.Visible = true;
      }
      else
      { // hide
        parameter2.Visible = false;
        parameterLabel2.Visible = false;
        parameter2ValueLabel.Visible = false;

      }
      parameter2.Text = boost_math.any_distribution.second_param_default(i).ToString();
      if (boost_math.any_distribution.third_param_name(i).Length.CompareTo(0) != 0)
      {
        parameter3.Visible = true;
        parameterLabel3.Visible = true;
        parameter3ValueLabel.Visible = true;
      }
      else
      { // hide
        parameter3.Visible = false;
        parameterLabel3.Visible = false;
        parameter3ValueLabel.Visible = false;
      }
      parameter3.Text = boost_math.any_distribution.third_param_default(i).ToString();
      // Update tool tips to show total and supported ranges.
      PropertiesTabPage.ToolTipText = "Shows properties and ranges of chosen distribution.";
    }

    private boost_math.any_distribution dist;

    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    { // Display a grid of pdf, cdf... values from user's random variate x value.
      try
      {
        if (e.ColumnIndex == 0)
        { // Clicked on left-most random variate x column to enter a value.
          int i = e.RowIndex;
          string s = CDF_data.Rows[i].Cells[0].Value.ToString();
          double x = double.Parse(s); // Get value of users random variate x.
          double pdf = dist.pdf(x); // Compute pdf values from x
          double cdf = dist.cdf(x); // & cdf
          double ccdf = dist.ccdf(x); // & complements.
          CDF_data.Rows[i].Cells[1].Value = pdf; // and display values.
          CDF_data.Rows[i].Cells[2].Value = cdf;
          CDF_data.Rows[i].Cells[3].Value = ccdf;
        }
      }
      catch (SystemException se)
      {
          MessageBox.Show("Error in random variable value: " + se.Message, "Calculation Error");
      }
    }

    private void tabPage2_Enter(object sender, EventArgs e)
    { // Properties tab shows distribution's mean, mode, median...
      try
      { // Show chosen distribution name, and parameter names & values.
        int i = distribution.SelectedIndex;
        distributionValueLabel.Text = boost_math.any_distribution.distribution_name(i).ToString();
        parameterLabel1.Text = boost_math.any_distribution.first_param_name(i).ToString();
        parameter1ValueLabel.Text = double.Parse(parameter1.Text).ToString();
        parameterLabel2.Text = boost_math.any_distribution.second_param_name(i).ToString();
        parameter2ValueLabel.Text = double.Parse(parameter2.Text).ToString();
        parameterLabel3.Text = boost_math.any_distribution.third_param_name(i).ToString();
        parameter3ValueLabel.Text = double.Parse(parameter3.Text).ToString();

        // Show computed properties of distribution.
        try
        {
            mean.Text = dist.mean().ToString();
        }
        catch
        {
            mean.Text = "Undefined.";
        }
        try
        {
            mode.Text = dist.mode().ToString();
        }
        catch
        {
            mode.Text = "Undefined.";
        }
        try
        {
            median.Text = dist.median().ToString();
        }
        catch
        {
            median.Text = "Undefined.";
        }
        try
        {
            variance.Text = dist.variance().ToString();
        }
        catch
        {
            variance.Text = "Undefined.";
        }
        try
        {
            standard_deviation.Text = dist.standard_deviation().ToString();
        }
        catch
        {
            standard_deviation.Text = "Undefined.";
        }
        try
        {
            skewness.Text = dist.skewness().ToString();
        }
        catch
        {
            skewness.Text = "Undefined.";
        }
        try
        {
            kurtosis.Text = dist.kurtosis().ToString();
        }
        catch
        {
            kurtosis.Text = "Undefined.";
        }
        try
        {
            kurtosis_excess.Text = dist.kurtosis_excess().ToString();
        }
        catch
        {
            kurtosis_excess.Text = "Undefined.";
        }
        try
        {
            coefficient_of_variation.Text = dist.coefficient_of_variation().ToString();
        }
        catch
        {
            coefficient_of_variation.Text = "Undefined.";
        }

        rangeLowestLabel.Text = dist.lowest().ToString();
        rangeGreatestLabel.Text = dist.uppermost().ToString();
        supportLowerLabel.Text = dist.lower().ToString();
        supportUpperLabel.Text = dist.upper().ToString();
        cdfTabPage.ToolTipText = "Random variate can range from " + rangeLowestLabel.Text
          + " to " + rangeGreatestLabel.Text
          + ",\nbut is said to be supported from " + supportLowerLabel.Text
          + " to " + supportUpperLabel.Text
          + "\nWithin this supported range the PDF and CDF have values between 0 and 1,\nbut below " + supportLowerLabel.Text + " both are zero, and above "
          +  supportUpperLabel.Text + " both are unity";
      }
      catch (SystemException se)
      {
        MessageBox.Show(se.Message, "Calculation Error!");
      }
    }

    private void properties_tab_Deselecting(object sender, TabControlCancelEventArgs e)
    {
      try
      {
        if (e.TabPageIndex == 0)
        {   // Update selected distribution object:
          double x = double.Parse(parameter1.Text);
          double y = double.Parse(parameter2.Text);
          double z = double.Parse(parameter3.Text);
          int i = distribution.SelectedIndex;
          dist = new boost_math.any_distribution(i, x, y, z);
          // Clear existing CDF data (has to be a better way?):
          while (CDF_data.Rows.Count > 1)
          {
            CDF_data.Rows.Remove(CDF_data.Rows[0]);
          }
          // Clear existing quantile data (has to be a better way?):
          while (QuantileData.Rows.Count > 1)
          {
            QuantileData.Rows.Remove(QuantileData.Rows[0]);
          }
        }
      }
      catch (SystemException se)
      {
          MessageBox.Show(se.Message +
              " Please check the distribution's parameters and try again.", "Distribution Error");
          this.propertiesTab.SelectedIndex = 0;
          e.Cancel = true;
      }
    }

    private void QuantileData_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    { // aka Risk & critical values tab.
      try
      {
        if (e.ColumnIndex == 0)
        {
          int i = e.RowIndex;
          string s = QuantileData.Rows[i].Cells[0].Value.ToString();
          double x = double.Parse(s);
          // Remember x is alpha: 1 - the probability:
          double lcv = dist.quantile(x);
          double ucv = dist.quantile_c(x);
          QuantileData.Rows[i].Cells[1].Value = lcv;
          QuantileData.Rows[i].Cells[2].Value = ucv;
        }
      }
      catch (SystemException se)
      {
        // TODO add some proper handling here!
        MessageBox.Show("Error in probability value: " + se.Message, "Calculation Error");
      }
    }

    private void QuantileTab_Enter(object sender, EventArgs e)
    { // Evaluate critical values (quantiles) for pre-chosen risk level.
      // and then, optionally, for other user-provided risk levels.
      try
      {
        if (QuantileData.Rows.Count == 1)
        {
          // Add some defaults:
          QuantileData.Rows.Add(5); // 5 Risk levels.
          QuantileData.Rows[0].Cells[0].Value = "0.001"; // Risk values as text,
          QuantileData.Rows[0].Cells[1].Value = dist.quantile(0.001); // & as double.
          QuantileData.Rows[0].Cells[2].Value = dist.quantile_c(0.001);
          QuantileData.Rows[1].Cells[0].Value = "0.01";
          QuantileData.Rows[1].Cells[1].Value = dist.quantile(0.01); // 99% confidence.
          QuantileData.Rows[1].Cells[2].Value = dist.quantile_c(0.01);
          QuantileData.Rows[2].Cells[0].Value = "0.05";
          QuantileData.Rows[2].Cells[1].Value = dist.quantile(0.05);
          QuantileData.Rows[2].Cells[2].Value = dist.quantile_c(0.05);
          QuantileData.Rows[3].Cells[0].Value = "0.1";
          QuantileData.Rows[3].Cells[1].Value = dist.quantile(0.1);
          QuantileData.Rows[3].Cells[2].Value = dist.quantile_c(0.1);
          QuantileData.Rows[4].Cells[0].Value = "0.33333333333333333";
          QuantileData.Rows[4].Cells[1].Value = dist.quantile(0.33333333333333333);
          QuantileData.Rows[4].Cells[2].Value = dist.quantile_c(0.33333333333333333);
        }
      }
      catch (SystemException se)
      {
        // TODO add some proper handling here!
        MessageBox.Show(se.Message, "Calculation Error");
      }
    }


    private void properties_tab_SelectedIndexChanged(object sender, EventArgs e)
    {
    }

    private void tabPage1_Click(object sender, EventArgs e)
    {
    }

    private void CDF_data_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
    }

    distexAboutBox DistexAboutBox = new distexAboutBox();

    private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    {
      DistexAboutBox.ShowDialog();
    }

    private void DistexForm_Activated(object sender, EventArgs e)
    {
    }

    /// get AssemblyDescription
    public string AssemblyDescription
    {
      get
      {
        // Get all Description attributes on this assembly
        object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
        // If there aren't any Description attributes, return an empty string
        if (attributes.Length == 0)
          return "";
        // If there is a Description attribute, return its value
        return ((AssemblyDescriptionAttribute)attributes[0]).Description;
      }
    }

    private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
    {
      using (StreamWriter sw = new StreamWriter(this.saveFileDialog.FileName))
      { // Write distribution info and properties to file.
        sw.WriteLine( AssemblyDescription);
        sw.WriteLine("Version " + Assembly.GetExecutingAssembly().GetName().Version.ToString());
        // Get parameter names (null "" if no parameter).
        int i = distribution.SelectedIndex;
        distributionValueLabel.Text = boost_math.any_distribution.distribution_name(i).ToString();
        sw.WriteLine(distributionValueLabel.Text + " distribution");
        parameterLabel1.Text = boost_math.any_distribution.first_param_name(i).ToString();
        parameterLabel2.Text = boost_math.any_distribution.second_param_name(i).ToString();
        parameterLabel3.Text = boost_math.any_distribution.third_param_name(i).ToString();
        string separator = "\t "; // , or tab or space?
        // Write parameter name & value.
        sw.WriteLine(parameterLabel1.Text + separator + this.parameter1.Text);
        if (boost_math.any_distribution.second_param_name(i).Length.CompareTo(0) != 0)
        { // Is a 2nd parameter.
          sw.WriteLine(parameterLabel2.Text + separator +  this.parameter2.Text);
        }
        if (boost_math.any_distribution.third_param_name(i).Length.CompareTo(0) != 0)
        { // Is a 3rd parameter.
          sw.WriteLine(parameterLabel3.Text + separator + this.parameter3.Text);
        }
        sw.WriteLine();
        sw.WriteLine("Properties");
        // Show computed properties of distribution.
        double x = double.Parse(parameter1.Text);
        double y = double.Parse(parameter2.Text);
        double z = double.Parse(parameter3.Text);
        dist = new boost_math.any_distribution(i, x, y, z);
        // Note global dist might not have been calculated yet if no of the tabs clicked.
        try
        {
            mean.Text = dist.mean().ToString();
        }
        catch
        {
            mean.Text = "Undefined";
        }
        sw.WriteLine("Mean" + separator + mean.Text);
        try
        {
            mode.Text = dist.mode().ToString();
        }
        catch
        {
            mode.Text = "Undefined";
        }
        sw.WriteLine("mode" + separator + mode.Text);
        try
        {
            median.Text = dist.median().ToString();
        }
        catch
        {
            median.Text = "Undefined";
        }
        sw.WriteLine("Median" + separator + median.Text);
        try
        {
            variance.Text = dist.variance().ToString();
        }
        catch
        {
            variance.Text = "Undefined";
        }
        sw.WriteLine("Variance" + separator + variance.Text);
        try
        {
            standard_deviation.Text = dist.standard_deviation().ToString();
        }
        catch
        {
            standard_deviation.Text = "Undefined";
        }
        sw.WriteLine("Standard Deviation" + separator + standard_deviation.Text);
        try
        {
            skewness.Text = dist.skewness().ToString();
        }
        catch
        {
            skewness.Text = "Undefined";
        }
        sw.WriteLine("Skewness" + separator + skewness.Text);
        try
        {
            coefficient_of_variation.Text = dist.coefficient_of_variation().ToString();
        }
        catch
        {
            coefficient_of_variation.Text = "Undefined";
        }
        sw.WriteLine("Cofficient of variation" + separator + coefficient_of_variation.Text);
        try
        {
            kurtosis.Text = dist.kurtosis().ToString();
        }
        catch
        {
            kurtosis.Text = "Undefined";
        }
        sw.WriteLine("Kurtosis" + separator + kurtosis.Text);
        try
        {
            kurtosis_excess.Text = dist.kurtosis_excess().ToString();
        }
        catch
        {
            kurtosis_excess.Text = "Undefined";
        }
        sw.WriteLine("Kurtosis excess" + separator + kurtosis_excess.Text);
        sw.WriteLine();

        sw.WriteLine("Range from" + separator + dist.lowest().ToString() + separator +
        "to" + separator + dist.uppermost().ToString());
        sw.WriteLine("Support from " + separator + dist.lower().ToString() +separator+
        "to " + separator + dist.upper().ToString());
        sw.WriteLine();

        //
        sw.WriteLine("Quantiles");
        if (QuantileData.Rows.Count == 1)
        { // Add some defaults:
          QuantileData.Rows.Add(5); // 5 Risk levels.
          QuantileData.Rows[0].Cells[0].Value = "0.001"; // Risk values as text,
          QuantileData.Rows[0].Cells[1].Value = dist.quantile(0.001); // & as double.
          QuantileData.Rows[0].Cells[2].Value = dist.quantile_c(0.001);
          QuantileData.Rows[1].Cells[0].Value = "0.01";
          QuantileData.Rows[1].Cells[1].Value = dist.quantile(0.01); // 99% confidence.
          QuantileData.Rows[1].Cells[2].Value = dist.quantile_c(0.01);
          QuantileData.Rows[2].Cells[0].Value = "0.05";
          QuantileData.Rows[2].Cells[1].Value = dist.quantile(0.05);
          QuantileData.Rows[2].Cells[2].Value = dist.quantile_c(0.05);
          QuantileData.Rows[3].Cells[0].Value = "0.1";
          QuantileData.Rows[3].Cells[1].Value = dist.quantile(0.1);
          QuantileData.Rows[3].Cells[2].Value = dist.quantile_c(0.1);
          QuantileData.Rows[4].Cells[0].Value = "0.33333333333333333";
          QuantileData.Rows[4].Cells[1].Value = dist.quantile(0.33333333333333333);
          QuantileData.Rows[4].Cells[2].Value = dist.quantile_c(0.33333333333333333);
        }
        // else have already been calculated by entering the quantile tab.
        for (int r = 0; r < QuantileData.Rows.Count-1; r++)
        { // Show all the rows of quantiles, including any optional user values.
          sw.WriteLine(QuantileData.Rows[r].Cells[0].Value.ToString() + separator +
            QuantileData.Rows[r].Cells[1].Value.ToString() + separator +
            QuantileData.Rows[r].Cells[2].Value.ToString());
        }
        sw.WriteLine();
        sw.WriteLine("PDF, CDF & complement(s)");
        for (int r = 0; r < CDF_data.Rows.Count-1; r++)
        { // Show all the rows of pdf, cdf, including any optional user values.
          sw.WriteLine(CDF_data.Rows[r].Cells[0].Value.ToString() + separator + // x value.
            CDF_data.Rows[r].Cells[1].Value.ToString() + separator + // pdf
            CDF_data.Rows[r].Cells[2].Value.ToString() + separator + // cdf
            CDF_data.Rows[r].Cells[3].Value.ToString());// cdf complement.
        }
        sw.WriteLine();
    }

    } // saveFileDialog1_FileOk

    private void saveToolStripMenuItem_Click(object sender, EventArgs e)
    {
      this.saveFileDialog.ShowDialog();
    }

    private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
    { // Same as Save.
      this.saveFileDialog.ShowDialog();
    }

    private void contentsToolStripMenuItem_Click(object sender, EventArgs e)
    { // In lieu of proper help.
      string helpText = "\n" + AssemblyDescription +
      "Version " + Assembly.GetExecutingAssembly().GetName().Version.ToString() +
      "\nA Windows utility to show the properties of distributions" +
      "\n and permits calculation of probability density (or mass) function (PDF)" +
      "\nand cumulative distribution function (CDF) and complement from values provided." +
      "\nQuantiles are also calculated for typical risk (alpha) probabilities" +
      "\nand for probabilities provided by the user." +
      "\n" +
      "\nResults can be saved to text files using Save or SaveAs." +
      "\nAll the values on the four tabs are output to the file chosen," +
      "\nand are tab separated to assist input to other programs," +
       "\nfor example, spreadsheets or text editors." +
      "\nNote: when importing to Excel only 10 decimal digits are shown by default:" +
      "\nit is necessary to format all cells to display the full 15 decimal digits," +
      "\nalthough not all computed values will be as accurate as this.\n" +
      "\nValues shown as NaN cannot be calculated from the value given," +
      "\nmost commonly because the value is outside the range for the distribution." +
      "n" +
      "\nFor more information, including downloads see " +
      "\nhttp://boost-consulting.com/vault/index.php?action=downloadfile&filename=math_toolkit.html&directory=Math%20-%20Numerics&" +
      "\n(Note that .NET framework 2.0 and VCredist are requirements for this program.)" +
      "\n\nCopyright John Maddock & Paul A. Bristow 2007, 2009";

      MessageBox.Show("Statistical Distribution Explorer\n" + helpText);
    }

    private void newToolStripMenuItem_Click(object sender, EventArgs e)
    {
      MessageBox.Show("New is not yet implemented.");
    }

    private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
      MessageBox.Show("Open is not yet implemented.");
    }

    private void printToolStripMenuItem_Click(object sender, EventArgs e)
    {
      MessageBox.Show("Print is not yet implemented." +
        "\nSave all values to a text file and print that file.");
    }

    private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
    {
      MessageBox.Show("Print Preview is not yet implemented." +
        "\nSave all values to a text file and print that file.");
    }




    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    { // exit DistexForm
        this.Close();
    }
  } // class DistexForm
} // namespace distribution_explorer