import de.simflex.gui.windows.SfxHtmlPanel;
import de.simflex.simulator.scheduler.Event;
import de.simflex.units.ModelNode;
import de.simflex.units.PermanentUnit;
import de.simflex.units.TemporaryUnit;

/**
* @author mg
*
* Diese Einheit ist Bestandteil des Wagens. Sie ist für das Abholen in
* Leerfahrt zuständig
*/
public class Get extends PermanentUnit {
	
	/**
	* die Einheit von welcher eine Temporäre Einheit abgeholt werden soll
	*/
	protected PermanentUnit destpu;
        
	public Get( ){
		setVrmlFile( "null.wrl" );
	}

	/**
	* @param pu - die vorhergehende Einheit
	*/
	public void announce( PermanentUnit pu ){
		if(debug)System.out.println( this + " somebody announcing...");
		incomingBuffer.insertBottom( pu );
		scheduler.setRelativeEvent( new Event( 0 , this , PermanentUnit.RECEIVE ) );
	}

	protected void receive( ){
		if(debug)System.out.println( this + " trying to receive... " );
		if( ! ((PermanentUnit)getParent( )).getOccupied( ) ){
			if(debug)System.out.println( this + " receving... " );
			//PU, wo die TU abgeholt wird
			destpu = searchForPU( );
			if(debug)System.out.println( this + " Dest: " + destpu );
			if( destpu != null ){
				((PermanentUnit)getParent( )).setOccupied( true );
				setState( RECEIVED );
				scheduler.setRelativeEvent( new Event( 0 , this , PermanentUnit.WORK_BEGIN ) );
			}
		}
		else{
			if(debug)System.out.println( this + " cannot receiving because car is occupied." );
		}
	}

	protected void work_begin( ){    
		if(debug)System.out.println( this + " starts driving.... " );  
        double length = ((Car)getParent( )).moveTo( destpu );    
		double fahrzeit = Math.abs( length ) * 2;       
		scheduler.setRelativeEvent( new Event( fahrzeit , this , PermanentUnit.WORK_END ) );
	}

	protected  void work_end( ){
		if(debug)System.out.println( this + " ends driving ...." );
		scheduler.setRelativeEvent( new Event( 4 , this , PermanentUnit.CANCEL ) );
	}

	public void cancel( ){
		if(debug)System.out.println( this + " cancelling..." ); 
		setState( EMPTY );       
		((PermanentUnit)((ModelNode)getParent( )).getChild( 1 )).announce( destpu );
	}

	/**
	* Die Liste mit angemeldeten PUs (incomingBuffer)
	* muss durchgegangen werden, und nach einem möglichen Auftrag gesucht werden
	*
	*/
	protected PermanentUnit searchForPU( ){
		if( debug ) System.out.println( "buffer " + incomingBuffer );
		PermanentUnit pu = null;
		for( int  i= 0; i < incomingBuffer.size( ); i++ ){
			pu = (PermanentUnit)incomingBuffer.get( i );
			TemporaryUnit tu = pu.getTemporaryUnit( );
			if( tu != null ){
				String dest = tu.getWorkingPlan( ).getAction( tu ).getPermanentUnit( ).getIdentity( );
				if( debug ) System.out.println( "dest: " +  dest );
				if( matrix.isReachable( this.getIdentity( ) , dest ) ){
					if( debug ) System.out.println( "Dest is reachable " + dest );
					incomingBuffer.remove( i );
					return pu;
				}
			}
		}
		return null;
	}
	
	//Static Methods
	public static String description( ){
		return ""+
			   "<br><br>" +
			   "See also: " + SfxHtmlPanel.addDocHyperlink( Get.class );
	}
}
