package JAKJ . RedstoneInMotion ;

public class CarriageControllerEntity extends CarriageDriveEntity implements dan200 . computer . api . IPeripheral
{
	public Object ThreadLockObject = new Object ( ) ;

	public boolean Simulating ;

	public Directions MotionDirection ;

	public CarriageMotionException Error ;

	public boolean Obstructed ;

	public int ObstructionX ;
	public int ObstructionY ;
	public int ObstructionZ ;

	@Override
	public void HandleToolUsage ( int Side , boolean Sneaking )
	{
	}

	@Override
	public synchronized void updateEntity ( )
	{
		if ( worldObj . isRemote )
		{
			return ;
		}

		if ( Stale )
		{
			HandleNeighbourBlockChange ( ) ;
		}

		if ( MotionDirection == null )
		{
			return ;
		}

		try
		{
			Move ( ) ;
		}
		catch ( CarriageMotionException Error )
		{
			this . Error = Error ;

			if ( Error instanceof CarriageObstructionException )
			{
				Obstructed = true ;

				ObstructionX = ( ( CarriageObstructionException ) Error ) . X ;
				ObstructionY = ( ( CarriageObstructionException ) Error ) . Y ;
				ObstructionZ = ( ( CarriageObstructionException ) Error ) . Z ;
			}
		}

		MotionDirection = null ;

		notify ( ) ;
	}

	public boolean Anchored ;

	@Override
	public boolean Anchored ( )
	{
		return ( Anchored ) ;
	}

	@Override
	public String getType ( )
	{
		return ( "JAKJ_RIM_CarriageController" ) ;
	}

	@Override
	public boolean canAttachToSide ( int Side )
	{
		return ( true ) ;
	}

	@Override
	public void attach ( dan200 . computer . api . IComputerAccess Computer )
	{
	}

	@Override
	public void detach ( dan200 . computer . api . IComputerAccess Computer )
	{
	}

	@Override
	public String [ ] getMethodNames ( )
	{
		return ( new String [ ] { "move" } ) ;
	}

	@Override
	public synchronized Object [ ] callMethod ( dan200 . computer . api . IComputerAccess Computer , int MethodIndex , Object [ ] Arguments ) throws Exception
	{
		if ( MethodIndex == 0 )
		{
			if ( Arguments . length < 3 )
			{
				throw ( new Exception ( "too few arguments" ) ) ;
			}

			if ( Arguments . length > 3 )
			{
				throw ( new Exception ( "too many arguments" ) ) ;
			}

			try
			{
				Simulating = ( Boolean ) Arguments [ 1 ] ;
			}
			catch ( Throwable Throwable )
			{
				throw ( new Exception ( "invalid simulation flag" ) ) ;
			}

			try
			{
				Anchored = ( Boolean ) Arguments [ 2 ] ;
			}
			catch ( Throwable Throwable )
			{
				throw ( new Exception ( "invalid anchoring flag" ) ) ;
			}

			try
			{
				MotionDirection = Directions . values ( ) [ ( int ) Math . round ( ( Double ) Arguments [ 0 ] ) ] ;
			}
			catch ( Throwable Throwable )
			{
				throw ( new Exception ( "invalid direction" ) ) ;
			}

			Error = null ;

			Obstructed = false ;

			try
			{
				do
				{
					wait ( ) ;
				}
				while ( MotionDirection != null ) ;
			}
			catch ( Throwable Throwable )
			{
				throw ( new Exception ( Throwable ) ) ;
			}

			if ( Error == null )
			{
				return ( new Object [ ] { true } ) ;
			}

			if ( Obstructed == false )
			{
				return ( new Object [ ] { false , Error . getMessage ( ) } ) ;
			}

			return ( new Object [ ] { false , Error . getMessage ( ) , ObstructionX , ObstructionY , ObstructionZ } ) ;
		}

		throw ( new Exception ( "no such command" ) ) ;
	}

	public void Move ( ) throws CarriageMotionException
	{
		if ( Active )
		{
			throw ( new CarriageMotionException ( "controller already active" ) ) ;
		}

		if ( CarriageDirection == null )
		{
			throw ( new CarriageMotionException ( "no carriage or too many carriages attached to controller" ) ) ;
		}

		CarriagePackage Package = PreparePackage ( MotionDirection ) ;

		if ( Simulating )
		{
			return ;
		}

		InitiateMotion ( Package ) ;
	}

	@Override
	public CarriagePackage GeneratePackage ( CarriageEntity Carriage , Directions CarriageDirection , Directions MotionDirection ) throws CarriageMotionException
	{
		CarriagePackage Package ;

		if ( Anchored )
		{
			if ( MotionDirection == CarriageDirection )
			{
				throw ( new CarriageMotionException ( "cannot push carriage away from controller in anchored mode" ) ) ;
			}

			if ( MotionDirection == CarriageDirection . Opposite ( ) )
			{
				throw ( new CarriageMotionException ( "cannot pull carriage into controller in anchored mode" ) ) ;
			}

			Package = new CarriagePackage ( this , Carriage , MotionDirection ) ;

			Carriage . FillPackage ( Package ) ;

			if ( Package . Blocks . contains ( Package . DriveRecord ) )
			{
				throw ( new CarriageMotionException ( "carriage is attempting to move controller while in anchored mode" ) ) ;
			}

			if ( Package . Blocks . contains ( Package . DriveRecord . NextInDirection ( MotionDirection . Opposite ( ) ) ) )
			{
				throw ( new CarriageMotionException ( "carriage is obstructed by controller while in anchored mode" ) ) ;
			}
		}
		else
		{
			Package = new CarriagePackage ( this , Carriage , MotionDirection ) ;

			Package . AddBlock ( Package . DriveRecord ) ;

			if ( MotionDirection != CarriageDirection )
			{
				Package . AddPotentialObstruction ( Package . DriveRecord . NextInDirection ( MotionDirection ) ) ;
			}

			Carriage . FillPackage ( Package ) ;
		}

		Package . Finalize ( ) ;

		return ( Package ) ;
	}
}
