using RAYLASE.SPICE3;
using RAYLASE.SPICE3.ClientLib;
using System;
using System.Diagnostics;
using System.Drawing;

namespace Sprint
{
	class Program
	{
		// insert the IP of your SP-ICE-3
		readonly string _CardIp = "192.168.2.138";
		ClientAPI _Client = new ClientAPI();

		static void Main( string[] args )
		{
			Program p = new Program();

			p._Client.Connect( p._CardIp );
			// Reset the card to its default settings:
			// This restores the following settings to the values that were last saved on the card:
			// - scanner configuration (such as field size, field correction, etc.)
			// - laser configuration (such as gate/LM timing parameters, power target, etc.)
			// - process variables (such as jump speed, settling times, mark speed, etc.)
			p._Client.System.ResetToDefaults();
			p._Client.Laser.ArmLaser( true );
			LaserConfig lc = p._Client.Laser.GetConfig();
			lc.PowerScale = 1.0;
			p._Client.Laser.SetConfig( lc );

			p.markUnidirectionally();
		}

		/// <summary>
		/// mark the bitmap mit the sprint algorithm
		/// the marking direction stays the same for every line (unidirectionally)
		/// </summary>
		void markUnidirectionally()
		{
			int listIndex = 0;
			double jumpSpeed = 1;
			double markSpeed = 1;

			// load a test image, and mark it on the 30% of the field
			string filename = "tiger.bmp";
			Bitmap image = new Bitmap( filename );

			ScannerConfig config = _Client.Scanner.GetConfig();
			double maxX = 0.3 * config.FieldSize.X;
			double maxY = maxX * image.Height / image.Width;

			CommandList list = new CommandList();
			list.AppendJumpSpeed( jumpSpeed );
			list.AppendMarkSpeed( markSpeed );
			list.AppendLmFrequency( 1.0 / 200 );
			list.AppendLmWidth( 200 );

			ushort[] powerValues = new ushort[image.Width];
			double y = -maxY;
			double dy = ( image.Height > 1 ) ? ( 2.0 * maxY ) / ( image.Height - 1 ) : 0;
			// iterate through the bitmap and append the lines to the list
			for ( int row = image.Height; --row >= 0; )
			{
				for ( int column = 0; column < image.Width; column++ )
					powerValues[column] = (ushort)( ushort.MaxValue * image.GetPixel( column, row ).GetBrightness() );

				list.AppendBitmapLineAbs( -maxX, y, maxX, y, powerValues );
				y += dy;
			}
			list.AppendLaserOff();

			Stopwatch sw = new Stopwatch();
			sw.Start();
			_Client.List.Set( listIndex, list );
			sw.Stop();
			Console.WriteLine( "{0}ms have elapsed to transfer list", sw.ElapsedMilliseconds );

			// estimate the mark time of one bitmap (assume top-right corner as the start point)
			double executionTime = Math.Sqrt( config.FieldSize.X * config.FieldSize.X + config.FieldSize.Y * config.FieldSize.Y ) / jumpSpeed;
			executionTime += image.Height * ( config.FieldSize.X / markSpeed );
			executionTime += ( image.Height - 1 ) * Math.Sqrt( config.FieldSize.X * config.FieldSize.X + dy * dy ) / jumpSpeed;
			_Client.Timeout = (int)( 0.001 * executionTime ) + 2000;

			// mark the bitmap several times, if desired
			LaserConfig lc = _Client.Laser.GetConfig();
			lc.PowerScale = 1.0;
			_Client.Laser.SetConfig( lc );
			for ( int iteration = 0; ++iteration <= 1; )
			{
				Console.Out.WriteLine( "Iteration {0}: Beginning to mark...", iteration );
				_Client.List.Execute( listIndex );
				int? id;
				_Client.List.WaitForListDone( out id );
				Console.Out.WriteLine( "Execution done. ID={0}", id );
			}
			_Client.List.Delete( listIndex );
		}
	}
}
