using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Data;
using VBNET = Microsoft.VisualBasic;
using gmRTL.Core;
using Microsoft.VisualBasic.CompilerServices;
using System.Linq;
using System.Collections.Generic;

namespace Calculator
{
   public partial class frmCalcu : System.Windows.Forms.Form
   {
      private bool _disposed = false;
      public frmCalcu()
      {
         //
         // Required for Windows Form Designer support
         //
         InitializeComponent();

         //
         // TODO: Add any constructor code after InitializeComponent call
         //
         if (DesignMode) return;
         cmdCancel = new System.Collections.Generic.SortedList<int, System.Windows.Forms.Button>();
         cmdCancel.Add(2, _cmdCancel_2);
         cmdCancel.Add(1, _cmdCancel_1);
         cmdCancel.Add(0, _cmdCancel_0);
         cmdFunction = new System.Collections.Generic.SortedList<int, System.Windows.Forms.Button>();
         cmdFunction.Add(3, _cmdFunction_3);
         cmdFunction.Add(2, _cmdFunction_2);
         cmdFunction.Add(1, _cmdFunction_1);
         cmdFunction.Add(0, _cmdFunction_0);
         cmdMemory = new System.Collections.Generic.SortedList<int, System.Windows.Forms.Button>();
         cmdMemory.Add(3, _cmdMemory_3);
         cmdMemory.Add(2, _cmdMemory_2);
         cmdMemory.Add(1, _cmdMemory_1);
         cmdMemory.Add(0, _cmdMemory_0);
         operator_migname = new System.Collections.Generic.SortedList<int, System.Windows.Forms.Button>();
         operator_migname.Add(3, _operator_3);
         operator_migname.Add(2, _operator_2);
         operator_migname.Add(1, _operator_1);
         operator_migname.Add(0, _operator_0);
         numero = new System.Collections.Generic.SortedList<int, System.Windows.Forms.Button>();
         numero.Add(9, _numero_9);
         numero.Add(8, _numero_8);
         numero.Add(7, _numero_7);
         numero.Add(6, _numero_6);
         numero.Add(5, _numero_5);
         numero.Add(4, _numero_4);
         numero.Add(3, _numero_3);
         numero.Add(2, _numero_2);
         numero.Add(1, _numero_1);
         numero.Add(0, _numero_0);
      }

      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
      protected override void Dispose(bool disposing)
      {
         if (_disposed)
         {
            return;
         }
         if (disposing)
         {
            if (components != null)
            {
               components.Dispose();
            }
         }
         _disposed = true;
         base.Dispose(disposing);
      }

      bool tama = false;
      double firstnum = 0.0;
      double secondnum = 0.0;
      string sign = "";
      double memory = 0.0;
      bool memrelease = false;
      private void cmdCancel_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Button cmdCancel;
         cmdCancel = (System.Windows.Forms.Button)sender;
         int Index = this.cmdCancel.Keys[this.cmdCancel.IndexOfValue(cmdCancel)];
         switch(Index)
         {
         case 0:
            // if any other button has been click
            // except for the numbers
            // dont do anything
            if (tama)
            {
               return;
            }
            // make sure that the last number be equal to 0
            if (txtDisplay.Text.Len() == 1)
            {
               txtDisplay.Text = "0";
               cmdEqual.Focus();
               return;
            }
            // erase the last inputed number
            gmRTL.Core.ErrorHandling.ResumeNext(() =>
            {
               txtDisplay.Text = txtDisplay.Text.Mid(1, txtDisplay.Text.Len() - 1);
               cmdEqual.Focus();
            });
            break;
         case 1:
            // make firstnum and secondnum equal to 0
            // so that every operation will be equal to 0
            firstnum = 0;
            secondnum = 0;
            txtDisplay.Text = "0";
            cmdEqual.Focus();
            break;
         case 2:
            // clear display and set text to 0
            txtDisplay.Text = "0";
            cmdEqual.Focus();
            break;
         }
         cmdEqual.Focus();


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

         // determine if period is already present
         if (!tama)
         {
                 // equal sign was not click
            // already present exit
            if (txtDisplay.Text.InStr(".",1,StringComparison.CurrentCulture) > 0)
            {
               cmdEqual.Focus();
               return;
            }
            // not present append
            cmdEqual.Focus();
            txtDisplay.Text = txtDisplay.Text + cmdDot.Text;
         }
         else if (tama)
         {
                 // equal sign was click
            txtDisplay.Text = "0.";
            tama = false;
            cmdEqual.Focus();
         }
         cmdEqual.Focus();
      }
      private void cmdEqual_Click(object sender, EventArgs e)
      {
         double answer = 0.0;
         secondnum = txtDisplay.Text.ToVal();     // store the second variable
         try
         {
            gmRTL.Core.GlobalException.Clear();
            // perform operation
            if (sign == "+")
            {
               answer = firstnum + secondnum;
            }
            if (sign == "-")
            {
               answer = firstnum - secondnum;
            }
            if (sign == "*")
            {
               answer = firstnum * secondnum;
            }
            if (sign == "/" && secondnum != 0)
            {
               answer = firstnum / secondnum;
            }
            txtDisplay.Text = answer.ToStr();
            tama = true;
            firstnum = answer;
            return;
         }
         catch(System.Exception exc)
         {
            gmRTL.Core.GlobalException.Initialize(exc);
            txtDisplay.Text = "Error";
            System.Windows.Forms.MessageBox.Show(gmRTL.Core.GlobalException.Instance.Description, "Operation Aborted", MessageBoxButtons.OK,MessageBoxIcon.Warning);
            tama = true;
         }
      }
      private void cmdEqual_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
      {
         int KeyAscii;
         KeyAscii = (int)e.KeyChar;
         int i = 0;
         int x = 0;
         // this is for the operator
         for(x = 0; x <= 3; x += 1)
         {
            if (KeyAscii.Char() == operator_migname[x].Text)
            {
               operator_migname[x].Focus();
               operator_Click(operator_migname[x],new EventArgs());
            }
         }

         // this is for the period
         if (KeyAscii.Char() == ".")
         {
            cmdDot.Focus();
            cmdDot_Click(cmdDot,new EventArgs());
         }

         // this is for the numbers
         if (txtDisplay.Text.Left(1) == "0")
         {
            // if there is already a period
            if (txtDisplay.Text.InStr(".",1,StringComparison.CurrentCulture) > 0)
            {
               // append digits and exit so that
               // it wont append twice
               for(i = 48; i <= 57; i += 1)
               {
                  // simulate a press of numbers
                  if (KeyAscii == i)
                  {
                          // ascii = 0 to 9
                     numero[((KeyAscii.Char()).ToStr()).ToInt()].Focus();
                     numero_Click(numero[((KeyAscii.Char()).ToStr()).ToInt()],new EventArgs());
                     return;
                  }
               }
            }
            else
            {
               // else dont put anything
               txtDisplay.Text = "";
            }
         }
         // simulate a press of numbers
         for(i = 48; i <= 57; i += 1)
         {
                 // ascii = 0 to 9
            if (KeyAscii == i)
            {
               numero[((KeyAscii.Char()).ToStr()).ToInt()].Focus();
               numero_Click(numero[((KeyAscii.Char()).ToStr()).ToInt()],new EventArgs());
               return;
            }
         }

         // this is for the cancel
         if (KeyAscii.ToVal() == 0x8)
         {
            _cmdCancel_0.Focus();
            cmdCancel_Click(_cmdCancel_0,new EventArgs());
         }


         if (KeyAscii.Char() == "=")
         {
            cmdEqual_Click(cmdEqual,new EventArgs());
         }

      }
      private void cmdFunction_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Button cmdFunction;
         cmdFunction = (System.Windows.Forms.Button)sender;
         int Index = this.cmdFunction.Keys[this.cmdFunction.IndexOfValue(cmdFunction)];
         switch(Index)
         {
         case 0:     // case positve to negative
            txtDisplay.Text = (-txtDisplay.Text.ToVal()).ToStr();
            break;
         case 1:     // case 1/x
            if (txtDisplay.Text.ToVal() != 0)
            {
               txtDisplay.Text = (1 / txtDisplay.Text.ToVal()).ToStr();
            }
            break;
         case 2:     // case percentage
            txtDisplay.Text = (txtDisplay.Text.ToVal() / 100).ToStr();
            break;
         case 3:     //  case squareroot
            if (txtDisplay.Text.ToVal() == 0)
            {
               txtDisplay.Text = "Error";
               return;
            }
            else
            {
               txtDisplay.Text = Math.Sqrt(txtDisplay.Text.ToVal()).ToStr();
            }
            break;
         }
      }
      private void cmdMemory_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Button cmdMemory;
         cmdMemory = (System.Windows.Forms.Button)sender;
         int Index = this.cmdMemory.Keys[this.cmdMemory.IndexOfValue(cmdMemory)];
         switch(Index)
         {
         case 0:     //  clear memory (MC)
            memory = 0;
            lblMem.Text = "";
            break;
         case 1:     //  add number to memory (M+)
            if (txtDisplay.Text == "0")
            {
               return;
            }
            memory = memory + txtDisplay.Text.ToVal();
            lblMem.Text = "M";
            break;
         case 2:     //  get value of memory (MC)
            if (txtDisplay.Text == "0")
            {
               return;
            }
            // if operator are click release value of memory
            if (memrelease)
            {
               lblMem.Text = "";
               memory = 0;
               // if numbers are click get value of memory
            }
            else if (!memrelease)
            {
               lblMem.Text = "M";
               memory = txtDisplay.Text.ToDbl();
            }
            break;
         case 3:     // get value of memory (MR)
            txtDisplay.Text = memory.ToStr();
            break;
         }
      }
      private void mnuCopy_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Clipboard.SetText(txtDisplay.Text);
      }
      private void mnuPaste_Click(object sender, EventArgs e)
      {
         Paste();
      }
      private void Paste()
      {
         string str = "";
         str = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text);

         str = str.ReplaceStr(" ","",1,-1,StringComparison.CurrentCulture);

         int i = 0;
         string s = "";

         for(i = 1; i <= str.Len(); i += 1)
         {
            s = str.Mid(i, 1);
            cmdEqual_KeyPress(null,new System.Windows.Forms.KeyPressEventArgs((char)((int)((s)[0]))));
         }
      }
      private void numero_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Button numero;
         numero = (System.Windows.Forms.Button)sender;
         int Index = this.numero.Keys[this.numero.IndexOfValue(numero)];
         memrelease = false;     // toggle the memory
         if (tama)
         {
                 // toggle the answer
            txtDisplay.Text = "";
            tama = false;
         }
         // determine if the first digit is zero
         if (txtDisplay.Text.Left(1) == "0")
         {
            // if there is already a period
            if (txtDisplay.Text.InStr(".",1,StringComparison.CurrentCulture) > 0)
            {
               // append digits and exit so that
               // it wont append twice
               txtDisplay.Text = txtDisplay.Text + numero.Text;
               cmdEqual.Focus();
               return;
            }
            else
            {
               // else dont put anything
               txtDisplay.Text = "";
               cmdEqual.Focus();
            }
         }
         // if first digit is zero
         // erase 0 and append digits
         txtDisplay.Text = txtDisplay.Text + numero.Text;
         cmdEqual.Focus();
      }
      private void operator_Click(object sender, EventArgs e)
      {
         System.Windows.Forms.Button operator_migname;
         operator_migname = (System.Windows.Forms.Button)sender;
         int Index = this.operator_migname.Keys[this.operator_migname.IndexOfValue(operator_migname)];
         memrelease = true;     // toggle memory
         firstnum = txtDisplay.Text.ToVal();     // store value txtdisplay.text to variable
         // store operations to variable
         switch(Index)
         {
         case 0:
            sign = "/";
            break;
         case 1:
            sign = "+";
            break;
         case 2:
            sign = "-";
            break;
         case 3:
            sign = "*";
            break;
         }
         tama = true;     // toggle answer
         cmdEqual.Focus();
      }
      private void txtDisplay_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
      {
         int KeyCode;
         KeyCode = e.KeyValue;
         // Override default paste so that we turn the string into button presses
         if (KeyCode == 86)
         {
            Paste();
            // We handled paste so disable textbox paste
            KeyCode = 0;
         }
      }
   }
}
