(function( $ ){
  $.fn.osInvoke = function(nameSpace, method , args) {
  	if( methods[method] ){
		return methods[ method ].apply( this, new Array(nameSpace, args));
	 } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.osInvoke' );
    }

  };

  var methods = {
  	"update" : function( nameSpace, args ) {
  		var This = this;
		var dataObject = getDataObject(nameSpace, This);
		dataObject.update(args);
		return $(dataObject);
  	},
    "send" : function( nameSpace, args ) {
    	var This = this;
    	var dataObject = getDataObject(nameSpace, This);
  		var cachedData = getCachedData(nameSpace);
  		if(cachedData != null){
    		var changeSummary = cachedData.changeSummary;
			var baseUrlList = cachedData.baseUrlList;
			var baseUrl = baseUrlList.join("/")
			var options = {'url': baseUrl + "?mimetype=application/json"}
			options["dataType"] = cachedData.dataType
			options['success'] = function(result){
				cachedData.changeSummary= {"update":{},"create":{},"remove":{},"invoke":{}};
				cachedData.serverGraph = result
				args.success($(dataObject), dataObject, result);
			}
			var batchData = JSON.stringify(changeSummary);
			options["type"] = "POST"
			options['data'] = {'batchJson':batchData}
			options['query'] = {'action':'invoke','invoke':'orangescape.model.server.services.runtime.invoke','method':'batchUpdate'}
			$.extend(options['query'], cachedData.baseArguments)
			communicate(options, args);
		}else{
			logging("error","data is not available while calling send command for given namespace "+nameSpace);
		}
    },
    "create" : function( nameSpace, args ) {
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var createdDataObject = dataObject.create(args);
		return $(createdDataObject);
    },
    "delete" : function( nameSpace, args ) {
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		dataObject.remove(args);
		return $(dataObject);
    },
    "invoke" : function( nameSpace, args ) {
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		dataObject.invoke(args);
		return $(dataObject);
    },
    "move" : function( nameSpace, args ){
		var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
  		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;
			baseUrlList.pop()
			baseUrlList.pop()
			var pageNumber = args.pageNumber?args.pageNumber:1;
			var pageSize = args.pageSize?args.pageSize:20;
			baseUrlList.push("p"+pageNumber)
			baseUrlList.push(pageSize)

			var baseUrl = baseUrlList.join("/")
			var options = {"url":baseUrl + "?mimetype=application/json"}
			options["dataType"] = cachedData.dataType
			options["type"] = "GET"
			options['query'] = cachedData.baseArguments
			options['success'] = function(result){
				cachedData.changeSummary= {"update":{},"create":{},"remove":{},"invoke":{}};
				cachedData.serverGraph = result

				var rootObject = result[result["root"]]
				var listValue = new Array()
				for (var key in rootObject){
					if(key.indexOf("ModifiedBy.") != -1){
						for(var id in rootObject[key])
							listValue.push(new DataObject(nameSpace, id))
						break;
					}
				}
				args.success($(listValue), dataObject, result);
			}
			communicate(options, args);
		}else{
			logging("error","data is not available while calling move command for given namespace "+nameSpace);
		}
    },
    "filter": function( nameSpace, args ){
		var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
  		if(cachedData != null){
  			var baseUrlList = cachedData.baseUrlList;

  			var extendedArguments = constructExtendedArgument(args , cachedData)
  			//Filter Arguments added part of base arguments
  			$.extend(cachedData.baseArguments, extendedArguments)

			var baseUrl = baseUrlList.join("/")
			//mimetype=application/json is removed because filter method also used for aggreate report also,need to revisit
  			var options = {"url":baseUrl}
			options["dataType"] = cachedData.dataType
			options["type"] = "GET"
			options['query'] = extendedArguments
			options['success'] = function(result){
				cachedData.changeSummary= {"update":{},"create":{},"remove":{},"invoke":{}};
				cachedData.serverGraph = result

				var rootObject = result[result["root"]]
				var listValue = new Array()
				for (var key in rootObject){
					if(key.indexOf("ModifiedBy.") != -1){
						for(var id in rootObject[key])
							listValue.push(new DataObject(nameSpace, id))
						break;
					}
				}
				args.success($(listValue), dataObject, result);
			}
			communicate(options, args);
  		}else{
			logging("error","data is not available while calling filter command for given namespace "+nameSpace);
		}
    },
    "updateAttach" : function( nameSpace, args ){
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;
			var baseUrl = baseUrlList.join("/")
			if(dataObject.id != cachedData.instanceId)
				baseUrl+= "/"+dataObject.getValue("SheetMetadataId")+"/"+dataObject.id
			var options = {"url":baseUrl+"/attachment?mimetype=application/json"}
			options["dataType"] = cachedData.dataType
			options['query'] = cachedData.baseArguments
			options["success"] = function (result, status){
				cachedData.serverGraph = result
				args.success($(dataObject), dataObject, result);
			}
			if(args.fileId){
				options["secureuri"] = false
				options["fileElementId"] = args.fileId
				options["error"] = function (data, status, e){
					alert("attachment failed");
				}
				$.ajaxFileUpload(options)
			}else if(args.fileName && args.fileContent!=null){
				options["type"] = "POST"
				options['data'] = {"fileName":args.fileName, "fileContent":args.fileContent}
				communicate(options, args);
			}else{
				logging("error","file param is missing while calling attach command");
			}
		}else{
			logging("error","data is not available while calling attach command for given namespace "+nameSpace);
		}
    },
    "deleteAttach": function( nameSpace, args ){
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;
			var baseUrl = baseUrlList.join("/")
			if(dataObject.id != cachedData.instanceId)
				baseUrl+= "/"+dataObject.getValue("SheetMetadataId")+"/"+dataObject.id
			var options = {"url":baseUrl+"/attachment?mimetype=application/json"}
			options["type"] = "DELETE"
			options["dataType"] = cachedData.dataType
			options['query'] = cachedData.baseArguments
			options["success"] = function (result){
				cachedData.serverGraph = result
				args.success($(dataObject), dataObject, result);
			}
			communicate(options, args);
		}else{
			logging("error","data is not available while calling attach command for given namespace "+nameSpace);
		}
    },
    "readAttach": function( nameSpace, args ){
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;
			var baseUrl = baseUrlList.join("/")
			if(dataObject.id != cachedData.instanceId)
				baseUrl+= "/"+dataObject.getValue("SheetMetadataId")+"/"+dataObject.id
			var options = {"url":baseUrl+"/attachment"}
			options["type"] = "GET"
			options["dataType"] = "text"
			options['query'] = cachedData.baseArguments
			options["success"] = function (result){
				args.success(result);
			}
			communicate(options, args);
		}else{
			logging("error","data is not available while calling attach command for given namespace "+nameSpace);
		}
    },
    "csvimport" : function(nameSpace, args){
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;
			var baseUrl = baseUrlList.join("/")
			if(dataObject.id != cachedData.instanceId)
				baseUrl+= "/"+dataObject.getValue("SheetMetadataId")+"/"+dataObject.id
			if(args.referenceCellName && args.childModelId){
				baseUrl+="/"+args.referenceCellName+"/"+args.childModelId
			}else{
				logging("error","referenceCellName or childModelId param is missing while calling import command");
			}
			baseUrl = baseUrl+"/csvimport?mimetype=application/json"
			if(args.mappingId)
				baseUrl = baseUrl+"&gridCellId="+args.mappingId
			var options = {"url":baseUrl}
			options["dataType"] = cachedData.dataType
			options["success"] = function (result, status){
				cachedData.serverGraph = result
				args.success($(dataObject), dataObject, result);
			}
			if(args.fileId){
				options["secureuri"] = false
				options["fileElementId"] = args.fileId
				options["dataType"] = cachedData.dataType
				options["error"] = function (data, status, e){
					alert("import failed");
				}
				$.ajaxFileUpload(options)
			}else{
				logging("error","fileId param is missing while calling import command");
			}
		}else{
			logging("error","data is not available while calling import command for given namespace "+nameSpace);
		}
    },
    "search" : function(nameSpace, args){
    	var This = this;
		var dataObject = getDataObject(nameSpace, This);
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null){
			var baseUrlList = cachedData.baseUrlList;

  			var extendedArguments = constructExtendedArgument(args, cachedData)
  			//Filter Arguments added part of base arguments
  			$.extend(cachedData.baseArguments, extendedArguments)

  			if(extendedArguments.form){
  				delete extendedArguments.form
  			}

			var baseUrl = baseUrlList.join("/")
			if(dataObject.id != cachedData.instanceId)
				baseUrl+= "/"+dataObject.getValue("SheetMetadataId")+"/"+dataObject.id
			if(args.cellName){
				baseUrl += "/"+args.cellName+"/search"
				var pageNumber = args.pageNumber?"p"+args.pageNumber:null;
				var pageSize = args.pageSize?args.pageSize:null;
				if(pageNumber && pageSize){
					baseUrl += "/"+pageNumber+"/"+pageSize
				}
				var options = {"url":baseUrl+"?mimetype=application/json"}
				options["dataType"] = cachedData.dataType
				options["type"] = "GET"
				options['query'] = extendedArguments
				options["success"] = function (result){
					args.success($(result), null, result);
				}
				communicate(options, args);
			}else{
				logging("error","cellName param is missing while calling search command");
			}
		}else{
			logging("error","data is not available while calling attach command for given namespace "+nameSpace);
		}
    }
  };


})( jQuery );