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

namespace MasterList
{
	class Program
	{
		// insert the IP of your SP-ICE-3 
		readonly string _CardIp = "192.168.2.111";
		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 settings to the values that were last saved on the card, eg:
			// - 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();


			ushort squareBitmask = 0x1;
			ushort circleBitmask = 0x2;
			ushort triangleBitmask = 0x4;

			int listIdMaster = 0;
			int listIdSquare = 1;
			int listIdCircle = 2;
			int listIdTriangle = 3;

			bool createLists = true;

			if ( createLists )
			{
				// create lists
				CommandList square = p.createSquareList();
				CommandList circle = p.createCircleList();
				CommandList triangle = p.createTriangleList();

				// send lists to card
				p._Client.List.Set( listIdSquare, square );
				p._Client.List.Set( listIdCircle, circle );
				p._Client.List.Set( listIdTriangle, triangle );

				// store list on card for stand-alone
				p._Client.List.Store( listIdSquare );
				p._Client.List.Store( listIdCircle );
				p._Client.List.Store( listIdTriangle );
			}
			else
			{
				// load stored lists from card
				p._Client.List.Load( listIdSquare );
				p._Client.List.Load( listIdCircle );
				p._Client.List.Load( listIdTriangle );
			}

			CommandList masterList = new CommandList();

			masterList.AppendSwitch( IOPort.PortC, true );

			masterList.AppendCaseCallList( listIdSquare, squareBitmask );
			masterList.AppendCaseCallList( listIdCircle, circleBitmask );
			masterList.AppendCaseCallList( listIdTriangle, triangleBitmask );
			masterList.AppendDefaultRel( 1 ); // necessary (dummy) default case			

			masterList.AppendBranchAbs( 0 ); // jump to start		


			p._Client.List.Set( listIdMaster, masterList );
			p._Client.List.Store( listIdMaster );

			// enabling stand-alone mode
			SystemConfig systemConfig = p._Client.System.GetConfig();
			systemConfig.StandAloneListID = listIdMaster;
			systemConfig.EnableStandAloneMode = true;
			p._Client.System.SetConfig( systemConfig );

			p._Client.List.Execute( listIdMaster );
		}

		CommandList createSquareList()
		{
			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( 32000 );
			list.AppendScalingFactor( 2, 2 );

			list.AppendJumpAbs( -5000, -5000 );
			list.AppendMarkAbs( 5000, -5000 );
			list.AppendMarkAbs( 5000, 5000 );
			list.AppendMarkAbs( -5000, 5000 );
			list.AppendMarkAbs( -5000, -5000 );
			list.AppendLaserOff();

			return list;
		}
		CommandList createTriangleList()
		{
			CommandList list = new CommandList();
			list.AppendJumpSpeed( 5 );
			list.AppendJumpDelay( 0 );
			list.AppendMarkSpeed( 0.2 );
			list.AppendMarkDelay( 0 );
			list.AppendPolyDelay( 0 );
			list.AppendLmFrequency( 1.0 / 50 );
			list.AppendLmWidth( 35 );
			list.AppendScalingFactor( 2, 2 );

			list.AppendJumpAbs( -5000, -5000 );
			list.AppendMarkAbs( 5000, -5000 );
			list.AppendMarkAbs( 0, 5000 );
			list.AppendMarkAbs( -5000, -5000 );

			return list;
		}

		CommandList createCircleList()
		{
			CommandList list = new CommandList();
			list.AppendJumpSpeed( 5 );
			list.AppendJumpDelay( 0 );
			list.AppendMarkSpeed( 0.2 );
			list.AppendMarkDelay( 0 );
			list.AppendPolyDelay( 0 );
			list.AppendLmFrequency( 1.0 / 50 );
			list.AppendLmWidth( 35 );

			list.AppendJumpAbs( 0, -10000 );
			list.AppendArcRel( 0, 10000, 2 * Math.PI );

			return list;
		}
	}
}