using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace Monte_Carlo
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
            private System.Windows.Forms.Label lblXUpper;
            private System.Windows.Forms.Label lblPoints;
            private System.Windows.Forms.Label lblIntegralResult;
            private System.Windows.Forms.TextBox txtBoxXUpper;
            private System.Windows.Forms.TextBox txtBoxPoints;
            private System.Windows.Forms.TextBox txtBoxIntegralResult;
            private System.Windows.Forms.Button btnCalculate;
            private System.Windows.Forms.StatusBar statusBar1;
            private System.Windows.Forms.Label lblConstant;
            private System.Windows.Forms.TextBox txtBoxConstant;
            private System.Windows.Forms.TextBox txtBoxStatus;
            private System.Windows.Forms.Button btnReset;
            private System.Windows.Forms.Button btnExit;
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;

            public Form1()
            {
                    //
                    // Required for Windows Form Designer support
                    //
                    InitializeComponent();

                    //
                    // TODO: Add any constructor code after InitializeComponent call
                    //
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                    if( disposing )
                    {
                            if (components != null)
                            {
                                    components.Dispose();
                            }
                    }
                    base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
        this.lblXUpper = new System.Windows.Forms.Label();
        this.lblPoints = new System.Windows.Forms.Label();
        this.lblIntegralResult = new System.Windows.Forms.Label();
        this.txtBoxXUpper = new System.Windows.Forms.TextBox();
        this.txtBoxPoints = new System.Windows.Forms.TextBox();
        this.txtBoxIntegralResult = new System.Windows.Forms.TextBox();
        this.btnCalculate = new System.Windows.Forms.Button();
        this.statusBar1 = new System.Windows.Forms.StatusBar();
        this.lblConstant = new System.Windows.Forms.Label();
        this.txtBoxConstant = new System.Windows.Forms.TextBox();
        this.txtBoxStatus = new System.Windows.Forms.TextBox();
        this.btnReset = new System.Windows.Forms.Button();
        this.btnExit = new System.Windows.Forms.Button();
        this.SuspendLayout();
        //
        // lblXUpper
        //
        this.lblXUpper.Location = new System.Drawing.Point(38, 37);
        this.lblXUpper.Name = "lblXUpper";
        this.lblXUpper.Size = new System.Drawing.Size(120, 26);
        this.lblXUpper.TabIndex = 0;
        this.lblXUpper.Text = "Upper Bound";
        //
        // lblPoints
        //
        this.lblPoints.Location = new System.Drawing.Point(38, 83);
        this.lblPoints.Name = "lblPoints";
        this.lblPoints.Size = new System.Drawing.Size(120, 27);
        this.lblPoints.TabIndex = 1;
        this.lblPoints.Text = "Number of points";
        //
        // lblIntegralResult
        //
        this.lblIntegralResult.Location = new System.Drawing.Point(38, 175);
        this.lblIntegralResult.Name = "lblIntegralResult";
        this.lblIntegralResult.Size = new System.Drawing.Size(120, 27);
        this.lblIntegralResult.TabIndex = 2;
        this.lblIntegralResult.Text = "Integral result";
        //
        // txtBoxXUpper
        //
        this.txtBoxXUpper.Location = new System.Drawing.Point(182, 37);
        this.txtBoxXUpper.Name = "txtBoxXUpper";
        this.txtBoxXUpper.Size = new System.Drawing.Size(120, 22);
        this.txtBoxXUpper.TabIndex = 3;
        this.txtBoxXUpper.Text = "1000";
        //
        // txtBoxPoints
        //
        this.txtBoxPoints.Location = new System.Drawing.Point(182, 83);
        this.txtBoxPoints.Name = "txtBoxPoints";
        this.txtBoxPoints.Size = new System.Drawing.Size(120, 22);
        this.txtBoxPoints.TabIndex = 4;
        this.txtBoxPoints.Text = "1000";
        //
        // txtBoxIntegralResult
        //
        this.txtBoxIntegralResult.Location = new System.Drawing.Point(182, 175);
        this.txtBoxIntegralResult.Name = "txtBoxIntegralResult";
        this.txtBoxIntegralResult.ReadOnly = true;
        this.txtBoxIntegralResult.Size = new System.Drawing.Size(250, 22);
        this.txtBoxIntegralResult.TabIndex = 5;
        //
        // btnCalculate
        //
        this.btnCalculate.Location = new System.Drawing.Point(38, 231);
        this.btnCalculate.Name = "btnCalculate";
        this.btnCalculate.Size = new System.Drawing.Size(90, 26);
        this.btnCalculate.TabIndex = 6;
        this.btnCalculate.Text = "Calculate";
        this.btnCalculate.Click += new System.EventHandler(this.btnCalculate_Click);
        //
        // statusBar1
        //
        this.statusBar1.Location = new System.Drawing.Point(0, 289);
        this.statusBar1.Name = "statusBar1";
        this.statusBar1.Size = new System.Drawing.Size(458, 25);
        this.statusBar1.TabIndex = 7;
        this.statusBar1.Text = "Monte Carlo";
        //
        // lblConstant
        //
        this.lblConstant.Location = new System.Drawing.Point(38, 129);
        this.lblConstant.Name = "lblConstant";
        this.lblConstant.Size = new System.Drawing.Size(120, 27);
        this.lblConstant.TabIndex = 8;
        this.lblConstant.Text = "Coefficient";
        //
        // txtBoxConstant
        //
        this.txtBoxConstant.Location = new System.Drawing.Point(182, 129);
        this.txtBoxConstant.Name = "txtBoxConstant";
        this.txtBoxConstant.Size = new System.Drawing.Size(120, 22);
        this.txtBoxConstant.TabIndex = 9;
        this.txtBoxConstant.Text = "0.001";
        //
        // txtBoxStatus
        //
        this.txtBoxStatus.Location = new System.Drawing.Point(182, 231);
        this.txtBoxStatus.Name = "txtBoxStatus";
        this.txtBoxStatus.ReadOnly = true;
        this.txtBoxStatus.Size = new System.Drawing.Size(120, 22);
        this.txtBoxStatus.TabIndex = 10;
        this.txtBoxStatus.Text = "Status: Ready";
        //
        // btnReset
        //
        this.btnReset.Location = new System.Drawing.Point(346, 37);
        this.btnReset.Name = "btnReset";
        this.btnReset.Size = new System.Drawing.Size(90, 26);
        this.btnReset.TabIndex = 11;
        this.btnReset.Text = "Reset All";
        this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
        //
        // btnExit
        //
        this.btnExit.Location = new System.Drawing.Point(346, 249);
        this.btnExit.Name = "btnExit";
        this.btnExit.Size = new System.Drawing.Size(90, 27);
        this.btnExit.TabIndex = 12;
        this.btnExit.Text = "Exit";
        this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
        //
        // Form1
        //
        this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
        this.ClientSize = new System.Drawing.Size(458, 314);
        this.Controls.Add(this.btnExit);
        this.Controls.Add(this.btnReset);
        this.Controls.Add(this.txtBoxStatus);
        this.Controls.Add(this.txtBoxConstant);
        this.Controls.Add(this.lblConstant);
        this.Controls.Add(this.statusBar1);
        this.Controls.Add(this.btnCalculate);
        this.Controls.Add(this.txtBoxIntegralResult);
        this.Controls.Add(this.txtBoxPoints);
        this.Controls.Add(this.txtBoxXUpper);
        this.Controls.Add(this.lblIntegralResult);
        this.Controls.Add(this.lblPoints);
        this.Controls.Add(this.lblXUpper);
        this.Name = "Form1";
        this.Text = "Definite Integrals";
        this.Load += new System.EventHandler(this.Form1_Load);
        this.ResumeLayout(false);
        this.PerformLayout();

            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                    Application.Run(new Form1());
            }

            private void Form1_Load(object sender, System.EventArgs e)
            {
            
            }

            private void btnCalculate_Click(object sender, System.EventArgs e)
            {
                    //First check that required fields are not blank
                    if(txtBoxXUpper.Text == "" | txtBoxPoints.Text == "")
                    {
                            MessageBox.Show("Please enter a value for the upper bound and the number of points!");
                            return;
                    }
                    //ClearResult display
                    txtBoxIntegralResult.Text = "";
        txtBoxStatus.Text = "Status: Calculating";
        this.Refresh();
                    
                    //Obtain data from form
                    string upperBound = txtBoxXUpper.Text;
                    double xUpper = double.Parse(upperBound);
                    string numberPoints = txtBoxPoints.Text;
                    int points = int.Parse(numberPoints);

                    //Other variables required
                    double exponent = System.Math.E;
                    double rectangleArea = exponent * xUpper;
                    double constant = double.Parse(txtBoxConstant.Text);
                    int hits = 0;
                    int misses = 0;

                    //Generate random points
                    //Count number of points that fall on or below the curve
        DateTime date = DateTime.Now;
                    Random random = new Random(date.Millisecond);
                    for(int i = 0; i < points; i++)
                    {
                            double Xrandom = (random.NextDouble() * xUpper);
                            double Yrandom = (random.NextDouble() * exponent);
                            if(TestHit(Xrandom, Yrandom, constant) == true)
                                    hits = hits + 1;
                            else
                                    misses = misses + 1;
                    }
                    //Obtain area under curve
                    CalculateArea(hits, points, rectangleArea);
            }

            public void CalculateArea(int Hits, int Points, double RectangleArea)
            {
                    //Calculate area under curve
                    double curveAreaFraction;
                    curveAreaFraction = (double)Hits/Points;
                    double curveArea;
                    curveArea = (curveAreaFraction * RectangleArea);

                    //Display result of integration
                    txtBoxStatus.Text = "Status: Ready";
                    if(curveAreaFraction == 1)
                    {
                            txtBoxIntegralResult.Text = "All points below curve!";
                            return;
                    }
                    else
                    {
                            txtBoxIntegralResult.Text = curveArea.ToString();
                            return;
                    }
            }

            public bool TestHit (double X, double Y, double a)
            {
                    //Function to be integrated is y(x)
                    //Return true if Y less than or equal to y at X = x
                    
                    //Exponential function
                    //double y = Math.Exp(-a*X);
                    //Curve of growth
                    //double y = Math.Exp(1-Math.Exp(-a*X*X));
                    //Error Function
                    double y = (2 / Math.Sqrt(Math.PI)) * Math.Exp(-a * X * X);

                    if (Y <= y)
                            return true; //Hit on or below curve
                    else
                            return false;
            }

            private void btnReset_Click(object sender, System.EventArgs e)
            {
                    txtBoxIntegralResult.Text = "";
                    txtBoxConstant.Text = "0.001";
                    txtBoxPoints.Text = "1000";
                    txtBoxXUpper.Text = "1000";
                    txtBoxStatus.Text = "Status: Ready";
            }

            private void btnExit_Click(object sender, System.EventArgs e)
            {
                    if(MessageBox.Show("Are you sure that you wish to exit the Monte Carlo application?",
                            "Exit Application?", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2) == DialogResult.No)
                    {return;}
                    else
                    {this.Close();}                        
            }
    }
}