using RAYLASE.SPICE3;
using RAYLASE.SPICE3.ClientLib;
using System;

namespace PingPong
{
	class Program
	{
		// insert the IP of your SP-ICE-3
		readonly string _CardIp = "192.168.2.138";
		ClientAPI _Client = new ClientAPI();
		readonly int _MaxPendingLists = 2;
		int _PendingCount;
		int _ListId = 0;

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

			DateTime start = DateTime.Now;

			for ( int i = 0; i < 10; i++ )
			{
				p.markSquarePingPong( i );
			}

			DateTime end = DateTime.Now;

			TimeSpan duration = start - end;

			Console.Out.WriteLine( duration );

			//result: 0.592 s
		}

		/// <summary>
		/// by using two lists, the waiting time is minimized
		/// as the second list can be prepared while the first list is beeing executed
		/// </summary>
		void markSquarePingPong( int offset )
		{
			ScannerConfig scanner = _Client.Scanner.GetConfig();
			double fieldSize = scanner.FieldSize.X;
			double sizeX = 0.1 * fieldSize;
			double sizeY = 0.05 * fieldSize;

			CommandList list = new CommandList();
			list.AppendJumpSpeed( 5 );
			list.AppendJumpDelay( 0 );
			list.AppendMarkSpeed( 0.2 );
			list.AppendMarkDelay( 0 );
			list.AppendPolyDelay( 0 );
			list.AppendLmFrequency( 1.0 / 200 );
			list.AppendLmWidth( 200 );
			list.AppendPower( 25000 );

			list.AppendJumpAbs( -10000, 0.4 * fieldSize - offset * 10000 );
			list.AppendMarkRel( sizeX, -sizeY );
			list.AppendMarkRel( sizeX, sizeY );
			list.AppendMarkRel( -sizeX, sizeY );
			list.AppendMarkRel( -sizeX, -sizeY );

			list.AppendLaserOff();

			// only wait for list done, if both lists are busy
			if ( _PendingCount >= _MaxPendingLists )
			{
				Console.Out.WriteLine( "Waiting for list idle..." );
				int? doneID;
				_Client.List.WaitForListIdle( out doneID );
				Console.Out.WriteLine( "ListIdle: {0}", doneID );

				_PendingCount--;
			}

			_Client.List.Set( _ListId, list );
			_Client.List.Execute( _ListId );
			_PendingCount++;
			_ListId = ( _ListId + 1 ) % 2;
		}
	}
}
