
var sfCmd_none = 0;
var sfCmd_unlock = 1;
var sfCmd_update = 2;
var sfCmd_start = 3;
var sfCmd_complete = 4;
var sfCmd_stop = 5;

function SurfacePipe( id, rootSf, debugLog )
{


	this.construct = function( id, rootSf, debugLog )
	{
		this._id = id;
		this._cmd = new Queue();
		this._dbg = debugLog;

		this._rootSf = rootSf;

	}
	this._started = false;
	this._paused = false;

	this._id = '';

	this.rootSf = null;

	this._dbg = null;

	this._stopCallback = null;
	this._doneCallback = null;
	this._timer = null;
	this._cmd = null;
	this._lastCmd = null;

	this._atomSwitch = false;
	this._lastAtomAdded = false;

	this.getId = function()
	{
		return this._id;
	}

	this.queueCmd = function( cmd, opt, obj )
	{
		this._cmd.queue({ cmd: cmd, opt: opt, obj: obj, atom: this._lastAtomAdded });

		this._lastAtomAdded = !this._lastAtomAdded;
	}

	this.start = function( full )
	{

		if( this._paused == true ) {
			this._paused = false;
		}
		else {

			if( this._started == false ) {

				//this.queueCmd( sfCmd_stop, null, null ); 

				// --- DEBUG
				if( this._dbg ) {
					var dbg = '';
					this._dbg.message( this.getId(), 'start', 'Started' + dbg, 'heading' );
					this._dbg.indent();
				}
				// --- DEBUG	

				if( this._cmd.count() > 0 ) {

					var self = this;

				
					if( !full ) {

						this._timer = $.timer( 1, function( timer ) {
							if( self._started == false ) {
								self._started = true;
								self._timer = timer;
							}

							self.tick( self, timer );
						});
					}
					else {
						while( this._cmd.count() > 0 ) {
							self.process( self );
						}

						if( this._doneCallback != null ) {
							this._doneCallback( this );
							this._doneCallback = null;
						}
					}
				}
				else {
					if( this._doneCallback != null ) {
						this._doneCallback( this );
						this._doneCallback = null;
					}
				}
			}
		 }

	}

	this.stop = function()
	{

		if( this._dbg ) {
			// --- DEBUG
			this._dbg.undent();
			this._dbg.message( this.getId(), 'process', 'Stopped.', 'priority' );
			// --- DEBUG
		}

		if( this._started == true ) {
			//window.status += ( ' STOP ' + this.getId() );


			this._started = false;

			this._timer.stop();
			this._timer = null;


			


			if( this._stopCallback != null ) {
				this._stopCallback( this );
				this._stopCallback = null;
			}


			if( this._cmd.count() == 0 ) {
				if( this._doneCallback != null ) {
					this._doneCallback( this );
					this._doneCallback = null;
				}
			}
			
			this._rootSf.checkComplete();



		}
	}

	this.onStop = function( callback )
	{
		this._stopCallback = callback;
	}

	this.onDone = function( callback )
	{
		this._doneCallback = callback;
	}

	this.process = function( self )
	{	
		var cmd = self._cmd.peek( 0 );


		if( cmd ) {
			//if( cmd.atom == self._atomSwitch ) {

		
				try {

					if( cmd.cmd == sfCmd_unlock ) {
						cmd.obj.__doUnlock( cmd.opt.recursive );
						//window.status += ( ' UNLOCK: ' + self.getId() );

		
						// --- DEBUG
						if( this._dbg ) {
							this._dbg.message( cmd.obj.getId(), 'process', 'sfCmd_unlock' );
						}
						// --- DEBUG

					}
					else if( cmd.cmd == sfCmd_update ) {
						cmd.obj.__doUpdate( cmd.opt.force );
						//window.status += ( ' UPDATE: ' + self.getId() );

						// --- DEBUG
						if( this._dbg ) {
							this._dbg.message( cmd.obj.getId(), 'process', 'sfCmd_update', 'blue' );
						}
						// --- DEBUG
					}
					else if( cmd.cmd == sfCmd_complete ) {
						cmd.obj.__doComplete();

						// --- DEBUG
						if( this._dbg ) {
							this._dbg.message( cmd.obj.getId(), 'process', 'sfCmd_complete', 'reverseBlue' );
						}
						// --- DEBUG
					}
					else if( cmd.cmd == sfCmd_stop ) {
						self.stop();
					}

				}
				catch( ex ) {
				

				
					if( this._dbg ) {
						this._dbg.message( cmd.obj.getId(), 'process','<p /> ' + ex, 'error' );
					}

					self.stop();
					throw ex + ' [ from SurfacePipe.process() ]';
				}
				self._atomSwitch = !self._atomSwitch;
			
				//cmd.obj.checkComplete();

				
			//}

			self._cmd.advance();
		}

		

		return cmd;

	}

	this.tick = function( self, timer )
	{

        	if( self._started == true ) {
	        	if( self._cmd.count() > 0 ) {

				if( self._paused == false ) {

					var lastCmd = sfCmd_none;

					while( ( self._started == true ) && ( self._cmd.count() > 0 ) && ( lastCmd != sfCmd_update ) ) {
						lastCmd = self.process( self )
					}
				}
			}
			else {
			    self.stop();
			}

		}


	}

	this.pause = function()
	{
		this._paused = true;
	}

	this.construct( id, rootSf, debugLog );

}
