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 gmRTL.GUI;
using Microsoft.VisualBasic.CompilerServices;
using System.Linq;
using System.Collections.Generic;

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

         //
         // TODO: Add any constructor code after InitializeComponent call
         //
         if (DesignMode) return;
         SurfaceImage = new System.Collections.Generic.SortedList<int, System.Windows.Forms.PictureBox>();
         SurfaceImage.Add(1, _SurfaceImage_1);
         Form_Load(null, null);
      }

      /// <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);
      }

      private const int EyeR = 10;
      private const double EyeTheta = basWaves.PI * 0.2;
      private const double EyePhi = basWaves.PI * 0.1;
      private const int FocusX = 0;
      private const int FocusY = 0;
      private const int FocusZ = 0;
      float[,] Projector = new float[5,5];
      objPicture ThePicture = null;
      ObjGrid3D TheGrid = null;
      int Running = 0;
      //  Draw the surface.
      private void DrawData(System.Windows.Forms.PictureBox pic)
      {
         float x = 0.0F;
         float y = 0.0F;
         float z = 0.0F;
         float[,] S = new float[5,5];
         float[,] t = new float[5,5];
         float[,] ST = new float[5,5];
         float[,] PST = new float[5,5];


         try
         {

            //  Scale and translate so it looks OK in pixels.
            basWaves.m3Scale(S,35,-35,1);
            basWaves.m3Translate(t,230,175,0);
            basWaves.m3MatMultiplyFull(ST,S,t);
            basWaves.m3MatMultiplyFull(PST,Projector,ST);

            //  Transform the points.
            ThePicture.ApplyFull(PST);

            //  Display the data.
            gmRTL.GUI.ControlHelper.PictureCls(pic);
            ThePicture.Draw(pic,EyeR);
            pic.Refresh();

         }
         catch{}

      }
      private void CmdDisplay_Click(object sender, EventArgs e)
      {
         Pict.Visible = true;
         if (Running != 0)
         {
            cmdDisplay.Text = "Stopped";
            cmdDisplay.Enabled = false;
            Running = false.ToInt();
         }
         else
         {
            Running = true.ToInt();
            cmdDisplay.Text = "Stop";
            ShowFrames();
            cmdDisplay.Text = "Run";
            cmdDisplay.Enabled = true;
         }
      }
      private void cmdExit_Click(object sender, EventArgs e)
      {
         if (cmdDisplay.Text == "Stop")
         {
            System.Windows.Forms.MessageBox.Show("Stop the Function first !", "Waves", MessageBoxButtons.OK,MessageBoxIcon.Information);
            return;
         }
         else
         {
            this.Close();
         }
      }
      private void Form_Load(object sender, EventArgs e)
      {
         gmRTL.GUI.ControlHelper.SetAutoRedraw(Pict,true);
         //  Initialize the projection transformation.
         basWaves.m3PProject(Projector,basWaves.m3Perspective,(float)(EyeR),(float)(EyePhi),(float)(EyeTheta),(float)(FocusX),(float)(FocusY),(float)(FocusZ),0,1,0);

         //  Load empty image controls for later reproduction of saved image transformation
         int i = 0;
         for(i = 2; i <= 20; i += 1)
         {
            gmRTL.GUI.ControlHelper.LoadCtl(SurfaceImage,i);
         }

         cmdDisplay.Enabled = false;
      }
      public void CmdCreate_click(object sender, EventArgs e)
      {
         cmdDisplay.Enabled = true;
         lblCounter.Visible = true;
         txtCounter.Visible = true;
         Pict.Visible = false;
         const double PI_10 = basWaves.PI / 10.0;
         const int xmin = -5;
         const int Zmin = -5;
         const double dx = 0.3;
         const double dz = 0.3;
         const double NumX = -2 * xmin / dx;
         const double NumZ = -2 * Zmin / dz;
         const double Amp = 0.25;

         int num = 0;
         float offset = 0.0F;
         int i = 0;
         int j = 0;
         float x = 0.0F;
         float y = 0.0F;
         float z = 0.0F;
         float D = 0.0F;

         System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
         this.Refresh();
         // Save 20 positions of grid(net) as images
         for(num = 1; num <= 20; num += 1)
         {
            int count = 0;
            count = (20 - num) / 2;
            lblCounter.Text = "\r\n" + "Loading ... ";
            txtCounter.Text = count.ToStr();
            ThePicture = new objPicture();
            TheGrid = new ObjGrid3D();
            TheGrid.SetBounds((float)(xmin),(float)(dx),NumX.ToInt(),(float)(Zmin),(float)(dz),NumZ.ToInt());
            ThePicture.objects.Add(TheGrid,null,null,null);

            offset = (float)(num * PI_10);
            x = xmin;
            for(i = 1; i <= NumX.ToInt(); i += 1)
            {
               z = Zmin;
               for(j = 1; j <= NumZ.ToInt(); j += 1)
               {
                  D = (float)(Math.Sqrt(x * x + z * z));

                  // This is a Function that can be modified , You can test various
                  // formulas and even ,( I think it is possible ) to get data from Db and
                  // set the function to show graphical ( 3D ) report.
                  // If you perform testing , take care about OVERFLOW error
                  y = (float)(Amp * Math.Sin(3 * D - offset));

                  TheGrid.SetValue(x,y,z);
                  z = (float)(z + dz);

               }

               x = (float)(x + dx);
            }

            //  Display the data.
            DrawData(Pict);

            //  Save the bitmap for later.
            SurfaceImage[num].Image = Pict.GetPaintedImage();
            System.Windows.Forms.Application.DoEvents();

         }
         txtCounter.Visible = false;
         lblCounter.Visible = false;
         Pict.Visible = true;
         cmdCreate.Enabled = false;
         cmdDisplay.Enabled = true;
         this.AcceptButton = cmdDisplay;
         System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;

      }
      private void Form_Unload(object sender, EventArgs e)
      {
         Environment.Exit(0);
      }
      //  Show the images.
      private static int ShowFrames_num = 0;
      private void ShowFrames()
      {
         const int ms_per_frame = 50;
         int next_time = 0;

         while (Running != 0)
         {
            ShowFrames_num = ShowFrames_num + 1;
            if (ShowFrames_num > 20)
            {
               ShowFrames_num = 1;
            }
            next_time = basWaves.GetTickCount() + ms_per_frame;
            Pict.BackgroundImage = SurfaceImage[ShowFrames_num].Image;
            System.Windows.Forms.Application.DoEvents();
            basWaves.WaitTill(next_time);
         }
      }
   }
}
