(function( $ ){
  $.fn.osInit = function(nameSpace, method ,args) {
  	//to avoid extending properties into the dataobject, arguments.applicationId is checked
  	var arguments = this.get(0)
  	if(arguments instanceof Object && arguments.applicationId != null)
  		$.extend(arguments, args)
  	else
  		arguments = args
  	if( methods[method] ){
		return methods[ method ].apply( this, new Array(nameSpace, arguments));
	 } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.osInit' );
    }

  };

  var methods = {
    "signin" : function( nameSpace, args ) {
    	var This = this
    	var baseUrlList = constructBaseUrl( args )
    	var dataType = getDataType( args )
		var baseUrl = baseUrlList.join("/")
		var options = {}
		if (dataType == 'jsonp'){
			options["url"] = baseUrl+"/authenticate?mimetype=application/json"
			if(args.Authorization)
				options["query"] = {"Authorization": args.Authorization}
		}else{
			options["url"] = baseUrl+"/menu?mimetype=application/json"
		}
    	options["dataType"] = dataType
    	options["type"] = "GET"
		options["success"] = function(result){
			var appId = result.root
			var dataObject = new DataObject(nameSpace, appId)
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			$(window).data(nameSpace, {serverGraph: result, menuJson : result, changeSummary: changeSummary, dataObject: dataObject, baseUrlList: baseUrlList, dataType: dataType})
			args.success($(dataObject), dataObject, result);
		};
		communicate(options, args);
    },
    "logout" : function( nameSpace, args ){
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			dataType = getDataType( args, cachedData );

    	var baseUrlList = constructBaseUrl( args, cachedData )
    	var baseUrl = baseUrlList.join("/")
    	var options = {"url":baseUrl + "/logout?mimetype=application/json"}
		options["dataType"] = dataType
		communicate(options, args);
		$(window).data(appNameSpace, null)

    },
    "new" : function( nameSpace, args ) {
    	var This = this
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			menuJson = getMenuJson(cachedData),
			dataType = getDataType( args, cachedData );

		var baseUrlList = constructBaseUrl( args, cachedData )
		var modelId = getModelId(args, cachedData, "new")
		args["modelId"] = modelId
		var activityId = getActivityId(args, cachedData, "new")

		baseUrlList.push(modelId)
		baseUrlList.push(activityId)
		baseUrlList.push(modelId)

		var baseUrl = baseUrlList.join("/")

		var baseArguments = {}
		if(args.form)
			baseArguments["form"] = args.form

		var updateDict = {}
		if(args.data)
			$.extend(updateDict, args.data)

		var options = {"url":baseUrl + "?mimetype=application/json"}
		options["dataType"] = dataType
		options["type"] = "POST"
		options["query"] = updateDict
		options['success'] = function(result){
			var instanceId = result.root
			var dataObject = new DataObject(nameSpace, instanceId)
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			baseUrlList.push(instanceId)
			$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, dataObject: dataObject, menuJson : menuJson, baseUrlList: baseUrlList, baseArguments: baseArguments, dataType: dataType, modelId: modelId, activityId: activityId, instanceId: instanceId})
			args.success($(dataObject), dataObject, result);
		}
		communicate(options, args);

    },
    "list" : function( nameSpace, args ) {
		var This = this
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			menuJson = getMenuJson(cachedData),
			dataType = getDataType( args, cachedData ),
			pageNumber = args.pageNumber?args.pageNumber:1,
			pageSize = args.pageSize?args.pageSize:20;

		var baseUrlList = constructBaseUrl( args, cachedData )
		var modelId = getModelId(args, cachedData, "list")
		args["modelId"] = modelId
		var activityId = checkReportId(args, cachedData)
		if(!activityId)
			activityId = getActivityId(args, cachedData, "list")
		else
			activityId = "report/"+activityId

		baseUrlList.push(modelId)
		baseUrlList.push(activityId)
		baseUrlList.push("p"+pageNumber)
		baseUrlList.push(pageSize)
		var baseUrl = baseUrlList.join("/")

		var baseArguments = {}
		if(args.form)
			baseArguments["form"] = args.form

		var extendedArguments = constructExtendedArgument(args)
		$.extend(baseArguments, extendedArguments)

		var options = {"url":baseUrl + "?mimetype=application/json"}
		options["dataType"] = dataType
		options["type"] = "GET"
		options["query"] = baseArguments
		options['success'] = function(result){
			var instanceId = result.root
			var dataObject = new DataObject(nameSpace, instanceId)
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, dataObject: dataObject, menuJson: menuJson, baseUrlList: baseUrlList, baseArguments: baseArguments, dataType: dataType, modelId: modelId, activityId: activityId, instanceId: instanceId})

			var rootObject = result[instanceId]
			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);
    },
    "read" : function( nameSpace, args) {
    	var This = this
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			menuJson = getMenuJson(cachedData),
			dataType = getDataType( args, cachedData );

		var baseUrlList = constructBaseUrl( args, cachedData )
		var modelId = getModelId(args, cachedData, "read")
		args["modelId"] = modelId
		var activityId = checkReportId(args, cachedData)
		if(!activityId)
			activityId = getActivityId(args, cachedData, "read")
		else
			activityId = "report/"+activityId
		var instanceId;
		if(args.instanceId)
			instanceId = args.instanceId
		else
			logging("error","instanceId Parameters is missig while calling read command");

		baseUrlList.push(modelId)
		baseUrlList.push(activityId)
		baseUrlList.push(modelId)
		baseUrlList.push(instanceId)

		var baseUrl = baseUrlList.join("/")

		var baseArguments = {}
		if(args.form)
			baseArguments["form"] = args.form

		var options = {"url":baseUrl + "?mimetype=application/json"}
		options["dataType"] = dataType
		options["type"] = "GET"
		options["query"] = baseArguments
		options['success'] = function(result,reqstatus,xmlreq){
			var dataObject = new DataObject(nameSpace, instanceId)
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, dataObject: dataObject, menuJson: menuJson, baseUrlList: baseUrlList,baseArguments: baseArguments, dataType: dataType, modelId: modelId, activityId: activityId, instanceId: instanceId})
			args.success($(dataObject), dataObject, result,{status:reqstatus,xmlHttpRequest:xmlreq});
		}
		communicate(options, args);
    },
    "report" : function( nameSpace, args ) {
    	var This = this
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			menuJson = getMenuJson(cachedData),
			dataType = getDataType( args, cachedData ),
			pageNumber = args.pageNumber?args.pageNumber:1,
			pageSize = args.pageSize?args.pageSize:20;

		var baseUrlList = constructBaseUrl( args, cachedData )
		var modelId = getModelId(args, cachedData, "report")
		args["modelId"] = modelId
		var reportId = getReportId(args, cachedData, "report")

		baseUrlList.push(modelId)
		baseUrlList.push("report")
		baseUrlList.push(reportId)
		baseUrlList.push("p"+pageNumber)
		baseUrlList.push(pageSize)

		var baseUrl = baseUrlList.join("/")
		var baseArguments = {}
		if(args.form)
			baseArguments["form"] = args.form

		var extendedArguments = constructExtendedArgument(args)
		$.extend(baseArguments, extendedArguments)

		var options = {"url":baseUrl + "?mimetype=application/json"}
		options["dataType"] = dataType
		options["type"] = "GET"
		options["query"] = baseArguments
		options['success'] = function(result){
			var instanceId = result.root
			var dataObject = new DataObject(nameSpace, instanceId)
			//for report not to update the result namespace,because invoke opertions will be done from report.....,any way just updating, need to revisit
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, dataObject: dataObject, menuJson: menuJson, baseUrlList: baseUrlList, baseArguments: baseArguments, dataType: dataType, modelId: modelId, reportId: reportId})

			var rootObject = result[instanceId]
			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);
    },
	"aggregate": function( nameSpace, args ){
		var This = this
	    var appNameSpace = nameSpace.split(".")[0],
				cachedData = $(window).data(appNameSpace),
				menuJson = getMenuJson(cachedData),
				dataType = getDataType( args, cachedData ),
				options = {},
				baseArguments = {},
				baseUrlList;
		if(args.dimensions && args.measures && args.operations){
			baseUrlList = constructBaseUrl( args, cachedData )
			var modelId = getModelId(args, cachedData, "report")
			args["modelId"] = modelId
			var reportId = getReportId(args, cachedData, "report")

			baseUrlList.push(modelId)
			baseUrlList.push("report")
			baseUrlList.push(reportId)
			var baseUrl = baseUrlList.join("/")

			if(args.form)
				baseArguments["form"] = args.form

			var extendedArguments = constructExtendedArgument(args)
			$.extend(baseArguments, extendedArguments)

			var dimensions = args.dimensions.length <=0?"[]":"['"+ args.dimensions.join('\',\'')+"']"
           	var measures = args.measures.length <=0?"[]":"['"+ args.measures.join('\',\'')+"']"
           	var operations = args.operations.length <=0?"[]":"['"+ args.operations.join('\',\'')+"']"

			baseArguments["dimensions"] = dimensions
			baseArguments["measures"] = measures
			baseArguments["operations"] = operations
			options["url"] = baseUrl + "/aggregate?mimetype=application/json"
			options["query"] = baseArguments
		}else if(args.url){
			//need to revisit, since worktop used aggreage on advanced search
			baseUrlList = new Array()
			baseUrlList.push(args.url)
			options["url"] = args.url
		}
		options["dataType"] = dataType
		options["type"] = "GET"
		options['success'] = function(result){
			//need to revisit after removing the args.url options
			var changeSummary = {"update":{},"create":{},"remove":{},"invoke":{}}
			$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, menuJson: menuJson, baseUrlList: baseUrlList, baseArguments: baseArguments, dataType: dataType})
			args.success($(result), null, result);
		}
		communicate(options, args);
	},
    "advancedSearch" : function( nameSpace, args ) {
    	var This = this
    	var appNameSpace = nameSpace.split(".")[0],
			cachedData = $(window).data(appNameSpace),
			menuJson = getMenuJson(cachedData),
			dataType = getDataType( args, cachedData ),
			pageNumber = args.pageNumber?args.pageNumber:1,
			pageSize = args.pageSize?args.pageSize:20;

		var baseUrlList = constructBaseUrl( args, cachedData )
		var modelId = getModelId(args, cachedData, "read")
		args["modelId"] = modelId
		var activityId = getActivityId(args, cachedData, "read")
		var instanceId;
		if(args.instanceId)
			instanceId = args.instanceId
		else
			logging("error","instanceId Parameters is missig while calling read command");

		baseUrlList.push(modelId)
		baseUrlList.push(activityId)
		baseUrlList.push(modelId)
		baseUrlList.push(instanceId)

		if(args.cellName){
			if(args.referenceInstanceId && args.referenceModelId){
				baseUrlList.push(args.referenceModelId)
				baseUrlList.push(args.referenceInstanceId)
			}
			baseUrlList.push(args.cellName);
			baseUrlList.push("search");
			baseUrlList.push("p"+pageNumber)
			baseUrlList.push(pageSize)

			var baseUrl = baseUrlList.join("/")

			var baseArguments = {}
			if(args.form)
				baseArguments["form"] = args.form

			var extendedArguments = constructExtendedArgument(args)
			$.extend(baseArguments, extendedArguments)

			var options = {"url":baseUrl+"?mimetype=application/json"}
			options["dataType"] = dataType
			options["type"] = "GET"
			options['query'] = baseArguments
			options["success"] = function (result){
				var instanceId = result.root
				var dataObject = new DataObject(nameSpace, instanceId)
				var changeSummary= {"update":{},"create":{},"remove":{},"invoke":{}};
				$(window).data(nameSpace, {serverGraph: result, changeSummary: changeSummary, dataObject: dataObject, menuJson: menuJson, baseUrlList: baseUrlList, baseArguments: baseArguments,dataType: dataType, modelId: modelId, activityId: activityId, instanceId: instanceId, cellName: args.cellName})

				var rootObject = result[instanceId]
				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","cellName param is missing while calling advanced search command");
		}
    }
    //yet to impl advanced methods like CRUD,Invoke & Submit
  };


})( jQuery );