var commonspot = window.commonspot || parent.commonspot;

/**
 * commonspot.ajax: ajax package
 */
if(!commonspot.ajax) // commonspot.ajax not already loaded
{
	commonspot.ajax = {};
	
	commonspot.ajax.COMMAND_OK = 200;
	commonspot.ajax.LOGIN_ERROR = 401;
	// Errors that invalidate a whole collection
	commonspot.ajax.COLLECTION_ERRORS = {400:true, 401:true, 403:true, 404:true, 503.1:true, 503.2:true};
	commonspot.ajax.DEVNETCF = 1; //at least check once
	// other
	commonspot.ajax.IE_FREED_SCRIPT_ERROR = -2146823277;
	commonspot.ajax.DEFAULT_TIMEOUT = 120000;

	/**
	 * Command engine package
	 */
	commonspot.ajax.commandEngine = {};
	
	/**
	 * Singleton, object factory for commandCollection
	 */
	commonspot.ajax.commandEngine.commandCollectionFactory = {};
	
	/**
	 * Factory method for commandCollection
	 * @param loaderUrl  (string). Required
	 * @param options (object) optional:
	 * 	@param options.onCompleteCallback (function). Optional. method to run after running response handlers for all cmds
	 * 		options as 2nd arg is new.
	 * 		we also support older syntax, where 2nd arg was onCompleteCallback, not options object that now contains it.
	 * 	@param options.closeOnError (boolean): if true, closes top lightbox dlg if there's an error
	 * 		useful for dlgs that call cmds while they're opening; dlg can't run if cmds failed
	 * 	@param options.closeOnSuccess (boolean): if true, closes top lightbox dlg if there's NO error
	 * 		useful for save cmds that close the dlg unless there's an error
	 * 	@param options.overlayElementID (string): if passed, id of DOM element to position "Loading" overlay over
	 * 		we also support passing this as an argument to the collection's send cmd
	 *	 	@param options.onCollectionError (function): if passed, gets called if there's a collection error
	 *			onCompleteCallback is NOT called in that case
	 * @return an instance of a commandCollection object
	 */
	commonspot.ajax.commandEngine.commandCollectionFactory.getInstance = function(loaderUrl, options)
	{
		var collectionObj = {};
		collectionObj.commands = [];
		collectionObj.url = loaderUrl;
		collectionObj.mustLogIn = false;
		collectionObj.hasAnyError = false;
		if(typeof options === "function") // old-style call, with onCompleteCallback as 2nd arg
			collectionObj.options = {onCompleteCallback: options};
		else
			collectionObj.options = options || {};
	
		/**
		 * Add a command to a collection
		 * @param target             (string). Required
		 * @param method             (string). Required
		 * @param commandArgs        (object). Optional. Object holding optional arguments for the command (pageid etc)
		 * @param options            (object). Optional. Object holding optional instructions for the command engine
		 * Options available are: 
		 * 	datasetRoot:            (object)    Namespace where the dataset is located. Default to commonspot.data
		 * 	datasetName:			   (string)    Name of dataset to populate. Default to target_method
		 * 	commandResponseHandler: (function, string, or false) Function that will process the response, signature should be function(command, xmlStr).
		 * 													Defaults to commonspot.ajax.commandEngine.commandResponseHandlers.populateDataset
		 * 													Can pass a function reference, which will be used
		 * 													Can pass a string, meaning a function by that name in commonspot.ajax.commandEngine.commandResponseHandlers
		 * 													Can pass false, in which case no cmd-level handler will run beyond the engine's generic one
		 * 	commandErrorHandler:    (function)	Function to be invoked in case of commad error
		 * 	fieldErrorMap:			   {object}		Object keyed by locase server-side argument name, w entries like this:
		 * 														{friendName: 'foo', highlightIDs: 'bar'}
		 * 													If a validation error on that argument occurs, alert w that name and highlight those IDs
		 * 	errorCodeMap				{object}		Object keyed by reasonCode code, w entries like this:
		 *															{itemTitle: 'foo', highlightIDs: 'bar'}
		 * 													If a cmd refusal w a matching reason code occurs, alert like a field, w that title, and highlight those IDs
		 */
		collectionObj.add = function(target, method, commandArgs, options)
		{
			var command = {};
			command.target = target;
			command.method = method;
			command.commandArgs = commandArgs || null;
			command.options = options || {};
			command.responseStatus = null;
			collectionObj.commands.push(command);
		}
	
		/**
		 * Send a command collection to the server
		 */	
		collectionObj.send = function(overlayElementID)
		{
			if (collectionObj.commands.length < 1)
			{
				commonspot.dialog.client.alert(commonspot.err.EMPTY_COLLECTION_MSG);
				return;	
			}
			// show msg overlay if an ID to position it over was set, track that ID
			// may be passed here (old style), or in collection options (new style)
			if(overlayElementID)
				collectionObj.options.overlayElementID = overlayElementID;
			if(collectionObj.options.overlayElementID)
			{
				var lightboxWindow = top.commonspot.lightbox.getCurrentWindow();
				// in some situations, an html alert is the top window, and it doesn't have the overlay tools
				if(lightboxWindow && lightboxWindow.commonspotNonDashboard)
					lightboxWindow.commonspotNonDashboard.util.displayMessageOverlay(collectionObj.options.overlayElementID);	
			}
			
			var urlSeparator = collectionObj.url.indexOf('?') >= 0 ? '&' : '?';
			var requestUrl = collectionObj.url + urlSeparator + 'csModule=components/dashboard/dashboard&' + commonspot.util.generateRandomInt();
			var cmdCollectionXML = commonspot.ajax.commandEngine.serializeCommandCollection(collectionObj.commands);
							
			var contextData =
					{
						commands: collectionObj.commands,
						options: collectionObj.options,
						mustLogIn: collectionObj.mustLogIn,
						hasAnyError: collectionObj.hasAnyError
					};
			
			if(document.location.search.indexOf('cs_showDashboardCmds') >= 0)
				top.commonspot.cs_showDashboardCmds = true;
				
			if(top.commonspot.cs_showDashboardCmds && typeof commonspotLocal != 'undefined' )
				commonspotLocal.util.log(collectionObj.commands);
			
			tmt.net.httpRequest
				(
					{
						url: requestUrl,
						loadCallback: collectionObj.responseHandler,
						method: 'POST',
						params: 'cmdCollectionXML=' + cmdCollectionXML,
						contextData: contextData,
						errback: commonspot.ajax.commandEngine.httpErrorHandler,
						timeout: commonspot.ajax.DEFAULT_TIMEOUT
					}
				);
			// Help garbage collector
			collectionObj.commands = [];
		}
	
		/**
		 * Split the XML for responsecollection into single XML chunks (one for each command) 
		 * and dispatch them to the relevant command handlers
		 */
		collectionObj.responseHandler = function()
		{
			// get contextData attached to cmd collection
			var contextData = this.response.contextData;
			
			// dismiss msg overlay if we put it up
			if (contextData.options.overlayElementID) 
			{
				var lightboxWindow = top.commonspot.lightbox.getCurrentWindow();
				if (lightboxWindow && lightboxWindow.commonspotNonDashboard) 
					lightboxWindow.commonspotNonDashboard.util.hideMessageOverlay(contextData.options.overlayElementID);
			}
			
			/*
			 The XPath evaluator returns an array of document fragments.
			 Later on we will turn them into strings to manage them as single entities
			 */

			var responsexml = this.response.responseXML;
			if(!responsexml)
			{
				top.commonspot.dialog.client.alert('We\'re sorry, an error has occurred.\nThe server returned an unexpected non-XML response.', {hideClose: false, width: 200});
				return;
			}
						
			if (commonspot.ajax.DEVNETCF > 0)
			{
				var cfDevNetStr = '<META NAME="ColdFusionMXEdition" CONTENT="ColdFusion DevNet Edition - Not for Production Use.">';
				var string = this.response.responseText;
				var chkDevNet = string.indexOf(cfDevNetStr);
				
				if (chkDevNet == 0) 
				{
					string = string.substring(cfDevNetStr.length, string.length);
					responsexml =  tmt.xml.stringToDOM(string);
				}
				else if (chkDevNet == -1)
					commonspot.ajax.DEVNETCF = -1;  //check once only.... 
				else
				{
					//alert('something is wrong...'); //in the middle, it should not happen...
				}		
			}
	
			var itemNodes = tmt.xml.evaluateXPath(responsexml, '/responsecollection/item');
			if (itemNodes.length < 1)
			{
				top.commonspot.dialog.client.alert(commonspot.err.EMPTY_RESPONSE_MSG);
				return;
			}
			
			// Check the status of the first command response
			var xmlStr = tmt.xml.nodeToString(itemNodes[0]);
			var xmlDoc = tmt.xml.stringToDOM(xmlStr);
			var responseStatus = commonspot.ajax.commandEngine.parseResponseStatus(xmlDoc);
			
			// Must login
			if (responseStatus.mustLogIn)
			{
				contextData.mustLogIn = true;
				if(commonspot && commonspot.clientUI && commonspot.clientUI.login)
					top.commonspot.clientUI.login.show(responseStatus.text);
				else
				{
					// how do you get here? has to be an ajax call when commonspot.clientUI.login doesn't exist.
					// TODO (if kept): if user cancels, leaves only white screen. forgotten and change pw dlgs allow cancel.
					top.commonspot.lightbox.openDialog(collectionObj.url + '?csModule=security/login&bNewWindow=1&bAllowCancel=0&ShowEmailLogin=0&HideChangePassword=0&frmCmds=1', true, 'userlogindlg');
				}
				return;
			}
			
			// Fatal errors coming from the server side
			if (responseStatus.hasCollectionError)
			{
				contextData.hasAnyError = true;
				if(contextData.options.onCollectionError)
					contextData.options.onCollectionError();
				if(contextData.options.closeOnError)
					commonspot.lightbox.closeCurrent();
				if (responseStatus.code == 503.1 || responseStatus.code == 503.2)
					top.commonspot.dialog.client.alert(responseStatus.text, {hideClose: true, width: 200});
				else if (responseStatus.text)
					top.commonspot.dialog.client.alert(responseStatus.text);
				else
					top.commonspot.dialog.client.alert('Error code: ' + responseStatus.code + '\nNo further information is available.');
				return;
			}
			
			// Dispatch each command response to the relevant handler
			var commands = contextData.commands;
			var errors = new commonspot.err.ErrorCollection();
			for (var i = 0; i < itemNodes.length; i++)
			{
				// A handler requires a full XML document. In order to use only a fragment of the document, we turn it into a string first
				// skip if first item, which we already did above, so we could check collection status
				if(i > 0)
				{
					xmlStr = tmt.xml.nodeToString(itemNodes[i]);
					xmlDoc = tmt.xml.stringToDOM(xmlStr);
					responseStatus = commonspot.ajax.commandEngine.parseResponseStatus(xmlDoc);
				}
				
				commands[i].responseStatus = responseStatus;
				var cmd = commands[i];
				
				// set contextData overall flags 
				contextData.hasAnyError = contextData.hasAnyError || responseStatus.hasCollectionError || responseStatus.hasCommandError
				contextData.mustLogIn = contextData.mustLogIn || responseStatus.mustLogIn;
		
				// clear validation notification from any fields we might add it to if they don't validate
				var fieldErrorMap = cmd.options.fieldErrorMap;
				var errorCodeMap = cmd.options.errorCodeMap;
				if(fieldErrorMap || errorCodeMap)
					commonspot.err.clearFieldErrorDisplay(fieldErrorMap, errorCodeMap);
				
				// collect error if there is one
				if(responseStatus.hasCommandError) // server cmd error
				{
					// do default error handling unless there's a custom handler and it returned true
					if(typeof cmd.options.commandErrorHandler != "function" || !cmd.options.commandErrorHandler.call(responseStatus))
						errors.addError(new commonspot.err.CmdError(responseStatus, fieldErrorMap, errorCodeMap));
				}
				else // server cmd is ok, check for response handler
				{
					// use custom handler spec if there is one, else default
					var handler = commonspot.ajax.commandEngine.commandResponseHandlers.populateDataset; // default handler
					switch(typeof cmd.options.commandResponseHandler)
					{
						case "undefined": // use default set above
							break;
						case "string": // use function by that name from commonspot.ajax.commandEngine.commandResponseHandlers
							handler = commonspot.ajax.commandEngine.commandResponseHandlers[cmd.options.commandResponseHandler];
							break;
						case "function": // use passed function itself
						case "boolean": // use passed boolean, which we'll detect below as not a function, and not run anything
							handler = cmd.options.commandResponseHandler;
							break;
						default: // oops
							throw new Error("[CommandCollection.responseHandler] Unexpected command response handler type: " + typeof cmd.options.commandResponseHandler);
					}
					// if handler is a function, run it; lets you pass false if all you need is status check, which engine does
					if(typeof handler == "function")
						handler(cmd, xmlStr, xmlDoc, responseStatus, errors);
				}
			}
			
			// alert and highlight errors, if any
			errors.displayErrors();
			
			// call final onComplete callback if there is one
			// callback sees cmd collection's contextData as 'this', ex: can check this.hasAnyError
			if(contextData.options.onCompleteCallback)
			{
				try
				{
					contextData.options.onCompleteCallback.call(contextData);
				}
				catch(e)
				{
					// ignore "Can't execute code from a freed script" error, it's IE complaining about obj in closed window
					if(!(e.number && e.number == commonspot.ajax.IE_FREED_SCRIPT_ERROR))
						throw(e);
				}
			}
			
			// if contextData.options.closeOnError or closeOnSuccess are true, obey them
			if(contextData.options.closeOnError && contextData.hasAnyError)
				commonspot.lightbox.closeParent(); // error alert is current, dlg is parent
			else if(contextData.options.closeOnSuccess && !contextData.hasAnyError)
				commonspot.lightbox.closeCurrent();
			
			// Help garbage collector
			contextData = null;
			errors = null;
		}
		
		return collectionObj;
	};
	
	
	/**
	 * Simplified API to send a single command. See commandCollection for details about parameters
	 * here, collectionOptions is the same as the options arg to getInstance()
	 * 	new style is it's an object, one of whose elements can be overlayElementID
	 * 	old style, still supported, is that it's overlayElementID
	 * 
	 */
	commonspot.ajax.commandEngine.sendOneCommand = function(loaderUrl, target, method, commandArgs, cmdOptions, collectionOptions)
	{
		if(typeof collectionOptions === "string") // old-style call, where that arg is overlayElementID, which is now an option
			collectionOptions = {overlayElementID: collectionOptions};
		else
			collectionOptions = collectionOptions || {};
		var commandCollection = commonspot.ajax.commandEngine.commandCollectionFactory.getInstance(loaderUrl, collectionOptions);
		commandCollection.add(target, method, commandArgs, cmdOptions);
		commandCollection.send();
		commandCollection = null;
	};
	
	/**
	 * Default handler for HTTP errors
	 */
	commonspot.ajax.commandEngine.httpErrorHandler = function()
	{
		var msg;
		if(this.response.statusText && this.response.status)
			msg = '<h2>' + this.response.statusText + ' [' + this.response.status + ']</h2>';
		else if(this.response.errorcode)
			msg = '<h2>'+ getTmtErrorMsg(this.response.errorcode) + '</h2>';
		else
			msg = '<h2>Unknown request error, code ' + errorcode + '.</h2>';
		msg += '<p>URL: ' + this.response.url + '</p>';
		msg += '<p>The CommonSpot logs may have more information.</p>';
		commonspot.clientUI.isURLError = true;
		commonspot.clientUI.showError(msg);
		
		function getTmtErrorMsg(errorcode)
		{
			switch(errorcode)
			{
				case tmt.net.REQUEST_FAILED: // 100
					return 'Request failed.';
				case tmt.net.REQUEST_ABORTED: // 101;
					return 'Request aborted.';
				case tmt.net.REQUEST_TIMEOUT: // 102;
					return 'Request timed out.';
				case tmt.net.REQUEST_OK: // 200;
					return '';
				default:
					return 'Unknown request error, code ' + errorcode + '.';
			}
		}
	};
	
	
	/**
	 * Check the status of a command response, returning errors and other relevant info as an object
	 * @param xmlDoc: (XML document). Required. The XML returned by the server for a specific commad request
	 * @return (object): status object returned from server, possibly w other flags:
	 * 	mustLogIn, hasCollectionError, hasCommandError, hasFieldErrors
	 */
	commonspot.ajax.commandEngine.parseResponseStatus = function(xmlDoc)
	{
		// parse xml response, omitting data and status.data.cmd nodes
		var responseObj = commonspot.util.xml.nodeToObject(xmlDoc, "item.data,item.status.data.cmd");
		var responseStatus = responseObj.item.status;
		
		if(responseStatus.code)
		{
			responseStatus.code = parseFloat(responseStatus.code);
			if(responseStatus.code == commonspot.ajax.LOGIN_ERROR)
				responseStatus.mustLogIn = true;
			if(commonspot.ajax.COLLECTION_ERRORS[responseStatus.code])
				responseStatus.hasCollectionError = true;
			else if(responseStatus.code != commonspot.ajax.COMMAND_OK)
				responseStatus.hasCommandError = true;
			if(responseStatus.data)
			{
				if(responseStatus.data.fielderrors && commonspot.util.hasMembers(responseStatus.data.fielderrors))
					responseStatus.hasFieldErrors = true;
			}
		}
		else // Not even able to figure out the code out of the XML, assume everything is wrong
			responseStatus.hasCollectionError = true;
		
		return responseStatus;
	};
	
	/**
	 * Serialize an array of command objects into a string to be used for the HTTP request
	 * @param commands  (array). Required
	 * @return an XML string
	 */
	commonspot.ajax.commandEngine.serializeCommandCollection = function(commands)
	{
		var str = '<commandcollection class="array">';
		for (var i=0; i<commands.length; i++)
			str += commonspot.ajax.commandEngine.serializeCommand(commands[i]);
		str += '</commandcollection>';
		/*
			need to escape ampersands to pass this str to tmt.net.httpRequest
			otherwise, they're taken as field separators, resulting in bizarrely-named phantom fields
				cf throws a 500 at the java level trying to parse the form scope, before we get called at all
			note that we're not undoing this on the server -- something else we don't know somewhere in the chain is
			for that reason, we also need to escape percent signs, to keep '%25' etc in the data from getting unwound
		*/
		//str = str.replace(/%/g, '%25');
		//str = str.replace(/&/g, '%26');
		str = encodeURIComponent(str);
											//alert(str);
		return str;
	};
	
	/**
	 * Serialize a single command object into an XML string
	 * @param command  (object). Required
	 * @return an XML string
	 */
	commonspot.ajax.commandEngine.serializeCommand = function(command)
	{
		var xml =
			'<command>' +
			'<target>' + command.target + '</target>' +
			'<method>' + command.method + '</method>';
		if(command.commandArgs)
			xml += commonspot.util.xml.objectToXml(command.commandArgs, 'args');
		xml += '</command>';
											//alert(xml);
		return xml;
	};
	
	/**
	 * Namespace for command response handlers.
	 * These handle the response from an individual command.
	 * No handler is needed to handle status-only responses, the main collection response handler does that.
	 * 	In that case, pass false as the responseHandler option for the cmd.
	 */
	
	commonspot.ajax.commandEngine.commandResponseHandlers = {};
	
	/**
	 * Default response handler for a single command. Populate a dataset out of the response data
	 */
	commonspot.ajax.commandEngine.commandResponseHandlers.populateDataset = function(command, xmlStr, xmlDoc, responseStatus, errorCollection)
	{
		// Default namespace holding datasets, to commonspot.data
		var datasetRoot = command.options.datasetRoot || commonspot.data;
		// And dataset name, to target_method
		var datasetName = command.options.datasetName || command.target + '_' + command.method;
		
		// Populate the dataset
		if (!datasetRoot[datasetName])
		{
			var error = new commonspot.err.CmdHandlerError(command.target + '.' + command.method, commonspot.err.MISSING_DATASET_ERROR_MSG + ': ' + datasetName);
			errorCollection.addError(error);
			return;
		}
		else
		{
			datasetRoot[datasetName].responseStatus = responseStatus;
			datasetRoot[datasetName].setDataFromDoc(xmlDoc);
		}
	};
	
	/**
	 * response handler that populates a javascript object with the results of the cmd
	 * datasetRoot and datasetName are defaulted and used as in the default spry dataset handler
	 * spec'd result var gets only the data node from the server response, no status
	 * if there's any server error, spec'd result var is deleted, for easy detection of that fact
	 * supports 'skip' in cmd options, which is a list of dot-pathed nodes to ignore, relative to 'data' node root
	 */
	commonspot.ajax.commandEngine.commandResponseHandlers.populateJSObject = function(command, xmlStr, xmlDoc, responseStatus, errorCollection)
	{
		// Default namespace holding data, to commonspot.data, same as for datasets
		var datasetRoot = command.options.datasetRoot || commonspot.data;
		// And data object name, to target_method, same as for datasets
		var datasetName = command.options.datasetName || command.target + '_' + command.method;
		
		// default skip str to empty str
		// if it's real, prefix it w "item.data." so it's relative to the data part of the result
		var skip = "";
		if(command.options.skip && command.options.skip != "")
			skip = "item.data." + command.options.skip;
		
		// convert server data to js obj
		var data = commonspot.util.xml.nodeToObject(xmlDoc, skip);
		
		// populate it, either as an object with setValue support, or a dumb js {}
		if(!datasetRoot[datasetName])
			throw new Error("[populateJSObject] Requested dataset not found: " + datasetName);
		else if(datasetRoot[datasetName].setValue)
		{
			try
			{
				// set result var if server data has a data node, else reset it if available, or set it to null
				if(data && data.item && (typeof data.item.data != "undefined"))
					datasetRoot[datasetName].setValue(data.item.data);
				else if(datasetRoot[datasetName].resetValue)
					datasetRoot[datasetName].resetValue();
				else
					datasetRoot[datasetName].setValue(null);
			}
			catch(e)
			{
				// ignore "Can't execute code from a freed script" error, it's IE complaining about obj in closed window
				if(!(e.number && e.number == commonspot.ajax.IE_FREED_SCRIPT_ERROR))
					throw(e);
			}
		}
		else // dumb object, just do it
		{
			// set result var if server data has a data node, else delete result var
			if(data && data.item && (typeof data.item.data != "undefined"))
				datasetRoot[datasetName] = data.item.data;
			else
				delete(datasetRoot[datasetName]);
		}
	}
	
	/*
	 * TODO: write this
	 */
	commonspot.ajax.commandEngine.Command = function(target, method, options)
	{
		this.target = target;
		this.method = method;
		this.options = options || {};
		this.options.fieldErrorMap = {};
		this.args = {};
		this._fieldPosition = 0;
		return this;
	};
	
	/*
	 * TODO: write this
	 */
	commonspot.ajax.commandEngine.Command.prototype.addFormArguments = function(form, skipList)
	{
		if(!form)
			throw new Error("[Command.addFormArguments] Requested form cannot be found.");
		
		// default getValue function needs to be one from window where form is, which may not be this one
		var formWindow = form.ownerDocument.defaultView || form.ownerDocument.parentWindow; // firefox and IE properties
		var getValue = formWindow.commonspotLocal.util.getValue;
		
		// getValue for checkboxes and radios does all items w that name, don't want to repeat them at this level
		var skipList = "," + skipList + ",";
		
		for(var i = 0; i < form.elements.length; i++)
		{
			var field = form.elements[i];
			if((!field.name) || skipList.indexOf("," + field.name + ",") >= 0)
				continue;
			// if obj has a getValueMethod spec'd, use it, else use formWindow's getValue function
			var getValueMethod = commonspotLocal.util.getGetValueMethod(field, formWindow, getValue);
			this.addArgument(field.name, getValueMethod(field), getFriendlyName(field), getHighlighIDs(field))
			skipList = skipList + field.name + ","
		}

		function getFriendlyName(field)
		{
			return commonspotLocal.util.getInheritableAttribute(field, "friendlyName", "input,label");
		}
		function getHighlighIDs(field)
		{
			return commonspotLocal.util.getInheritableAttribute(field, "highlightIDs", "input,label");
		}
	};
	
	/*
	 * TODO: write this
	 */
	commonspot.ajax.commandEngine.Command.prototype.addArgument = function(name, value, friendlyName, highlightIDs)
	{
		this.args[name] = value;
		if(friendlyName || highlightIDs)
			this.options.fieldErrorMap[name.toLowerCase()] = {friendlyName: friendlyName, highlightIDs: highlightIDs, position: this._getNextFieldPosition()};
	};
	
	/*
	 * sets commandResponseHandler for this cmd object
	 * rarely used, since commandResponseHandler can be given in options passed to constructor
	 * if cmd object isn't built in window where it runs, run window can call this, passing a function from that window
	 */
	commonspot.ajax.commandEngine.Command.prototype.setResponseHandler = function(commandResponseHandler)
	{
		this.options.commandResponseHandler = commandResponseHandler;
	};
	
	/*
	 * TODO: write this
	 */
	commonspot.ajax.commandEngine.Command.prototype.addToCollection = function(cmdCollection)
	{
		cmdCollection.add(this.target, this.method, this.args, this.options);
	};
	
	/*
	 * TODO: write this
	 */
	commonspot.ajax.commandEngine.Command.prototype._getNextFieldPosition = function()
	{
		return this._fieldPosition++;
	};

} // commonspot.ajax not already loaded

