function getCachedData(nameSpace){
	var cachedData = $(window).data(nameSpace)
	if(cachedData)
		return cachedData
	else
		logging("error","data is not available while calling getCachedData method for the give namespace "+this.nameSpace)
}

function getDataObject( nameSpace, jObject ){
	var dataObject = jObject.get(0)
	if (dataObject.id == null || dataObject.nameSpace == null){
		var cachedData = getCachedData(nameSpace);
		if(cachedData != null)
			dataObject = new DataObject(nameSpace, cachedData.instanceId)
	}
	return dataObject
}

function communicate(options, args){
	var settings = {
      dataType : "json",
      async : true,
      type : "GET",
      data : {},
      error : function(XMLHttpRequest, textStatus, errorThrown){
	   	exceptionMsg = XMLHttpRequest.getResponseHeader('ErrorMessage')
	   	exceptionTrace = XMLHttpRequest.responseText
       	if(exceptionMsg){
           alert(exceptionMsg+"\n"+exceptionTrace);
       	}
       	else if(XMLHttpRequest && XMLHttpRequest.status==401){
            alert("User session timed out. Please login again to continue...");
       	}else{
           	exceptionMsg = "Server returned an error"
            alert(exceptionMsg+"\n"+exceptionTrace);
       	}
      	/*
         switch (XMLHttpRequest.status) {
            case 404:
                alert('File not found');
                break;
            case 500:
                alert('Server error');
                break;
            case 0:
                alert('Request aborted');
                break;
            default:
                alert('Unknown error ' + error);
        }
        */
      }
    };

    for (property in args)
    {
		if(property == 'error' || property == 'beforeSend' || property == 'complete' || property == 'async')
			options[property] = args[property];
    }

    if (options.dataType == "jsonp" && options.type != "GET"){
    	if(!options.query)
    		options.query = {}
    	options.query["__method"] = options.type
    	options.type = "GET"
    }
	if(options.query){
		options.url = constructUrl(options)
		delete options.query
	}

    $.extend( settings, options );
    //console.info("********************** inside communicate**************************")
	//console.info(settings)
	if(window.studioWindow){
		var control = studioWindow.document.getElementById('SilverLight');
		var qs = ""
		if(settings["data"]){
			qs = addQueryString(settings["data"]);
			settings.url +="&"+qs
		}
		var jsonData = eval("studioWindow.control.Content.slwsgi.dispatch(settings.url, '', settings.type)")
		var data = JSON.parse(jsonData)
		settings.success(data)
	}else{
		$.ajax(settings)
	}
}

function constructUrl(options){
	var url = options.url;
	var queryString = options['query']
	var urlWithQs = url
	if (hasElement(queryString)){
		if (urlWithQs.indexOf("?")!= -1)
			urlWithQs += "&"
		else
			urlWithQs += "?"
		urlWithQs += addQueryString(queryString);
	}
	return urlWithQs
}

function addQueryString(query)
{
	var querystring = "";
	if (query) {
		for (name in query) {
			if (querystring.length != 0)
			{
				querystring += '&';
			}
			querystring += (encodeURIComponent(name) + '=' + encodeURIComponent(query[name]));
		}
	}
	return querystring
}

function constructBaseUrl(args, cachedData){
	var baseUrlList = new Array();
	if(cachedData != null){
		baseUrlList.push(cachedData.baseUrlList[0])
		baseUrlList.push(cachedData.baseUrlList[1])
		baseUrlList.push(cachedData.baseUrlList[2])
	}else{
		var hostName = args.hostName;
		var	port = args.port?":"+args.port:"";
		var	applicationId = args.applicationId;
		if (hostName != null && hostName != "/")
			baseUrlList.push("http://"+hostName+port)
		else
			baseUrlList.push("")
		baseUrlList.push(applicationId)
		if (args.metadataType)
			baseUrlList.push(args.metadataType)
		else
			baseUrlList.push("1")
	}
	return baseUrlList
}

function constructExtendedArgument(args ,cachedData){
	var extendedArguments = {}
	if (cachedData != null){
		$.extend(extendedArguments, cachedData.baseArguments)
	}
	if(args.data){
		for( name in args.data)
            extendedArguments['$'+name] = args.data[name];
	}
	if(args.asc)
		extendedArguments['asc'] =  "['"+ args.asc.join('\',\'')+"']"
	else if(args.desc)
		extendedArguments['desc'] = "['"+ args.desc.join('\',\'')+"']"
	return extendedArguments
}

function getDataType(args, cachedData){
	if(cachedData != null)
		return cachedData.dataType
	else if(args.hostName != null && args.hostName != "/")
		return "jsonp"
	return "json"
}

function getMenuJson(cachedData){
	if(cachedData != null)
		return cachedData.menuJson
	return {}

}

function getModelId(args, cachedData, methodName){
	var modelId;
	if(args.modelId)
		modelId = args.modelId
	else if(args.modelName && cachedData !=null)
		modelId = findModelId(args.modelName, cachedData.menuJson);
	else
		logging("error","modelName parameter is missing while calling "+methodName+" command");
	return modelId
}

function getActivityId(args, cachedData, methodName){
	var  activityId;
	if(args.activityId)
		activityId = args.activityId
	else if(cachedData !=null){
		var activityName = args.activityName?args.activityName:"Start"
		activityId = findActivityId(activityName, args.modelId, cachedData.menuJson);
	}
	else
		logging("error","activityName parameter is missing while calling "+methodName+" command");
	return activityId
}

function getReportId(args, cachedData, methodName){
	var  reportId = checkReportId(args, cachedData);
	if(reportId)
		return reportId;
	logging("error","reportName parameter is missing while calling "+methodName+" command");
}

function checkReportId(args, cachedData){
	if(args.reportId)
		return args.reportId
	else if(args.reportName && cachedData !=null)
		return findReportId(args.reportName, args.modelId, cachedData.menuJson);
}

function getCellId( args, modelId, cachedData, methodName){
	var referenceCellId;
	if(args.referenceCellId)
		referenceCellId = args.referenceCellId
	else if(args.referenceCellName && cachedData !=null)
		referenceCellId = findCellId(args.referenceCellName, modelId, cachedData.menuJson);
	else
		logging("error","referenceCellName parameter is missing while calling "+methodName+" command");
	return referenceCellId
}

function findModelId(modelName, json){
	var application = json[json['root']];
	var models = application['Application.SheetMetadata'];
	for(model in models){
		if(modelName == models[model])
			return model;
	}
	logging("error","ModelId not found for the model named " + modelName);
}

function findActivityId(activityName, modelId, json){
	var modeldefinition = json[modelId];
	if(modeldefinition == undefined ){
		logging("error","Model information not found, while trying to find ActivityId for the activity named " + activityName);
		return;
	}
	var activities = modeldefinition['SheetMetadata.ActivityDefinition'];
	for(activity in activities){
		if(activityName == activities[activity])
			return activity;
	}
	logging("error","ActivityId not found for the activity named " + activityName);
}

function findReportId(reportName, modelId, json){
	var modeldefinition = json[modelId];
	if(modeldefinition == undefined ){
		logging("error","Model information not found, while trying to find ReportId for the report named " + reportName);
		return;
	}
	var reportList = modeldefinition['SheetMetadata.SearchDefinition'];
	for(reportId in reportList){
		if(reportName == reportList[reportId])
			return reportId;
	}
	logging("error","reportId not found for the report named " + reportName);
}

function findCellId(cellName, modelId, json){
	var modelDefinition = json[modelId];
	var cellList = modelDefinition['SheetMetadata.CellMetadata'];
	for (cellId in cellList) {
		var splitdata = refCellList[cellId].split("-");
		if(cellName == splitdata[1])
			return cellId;
	}
	logging("error","cellId not found for the cell '"+cellName+"' in the model named"+modelDefinition.SheetName);

}

function logging(level, message) {
	if(window.console){
	    if(level == 'error')
	        console.error(message);
	    else if(level=='warn')
			console.warn(message)
		else if(level=='info')
			console.info(message);
		else if(level=='debug')
			console.debug?console.debug(message):console.info(message)
	    else if (level == 'log')
	        console.log(message);
	}
}

function arrayContains(arrayElement, value){
	for(var i in arrayElement)
		if (arrayElement[i] == value)
			return true
	return false
}