// Copyright (C) 2009 AvantLogic Corporation: http://www.mapsalive.com

function maLiveDataSetCustomError(message, color, backgroundColor, showDetails)
{
	// Call this function to override the default appearance of error messages.
	maClient.liveDataErrorSettings = new maLiveDataErrorSettings(message, color, backgroundColor, showDetails);
}

function maLiveDataRequest(slide, url, parameters, xhr, cachePeriodSeconds)
{
	// This class holds the information needed to make a request.
	this.slide = slide;
	this.url = url;
	this.parameters = parameters;
	this.xhr = xhr;
	this.cachePeriodSeconds = cachePeriodSeconds;
}

function maLiveDataSendRequest(cachePeriodSeconds, url)
{
	// Get the slide that this request is for. If the user's mouse if hovering over a directory
	// entry, we know the request is for the entry's preview image. Otherwise we assume it is
	// for the current slide.
	var slide = maClient.dirPreviewSlide === null ? maClient.slide : maClient.dirPreviewSlide;
	
	// The cache period must be specified as the first parameter as a value in seconds.
	// This value is set on a slide-by-slide basis so that volatile data can be updated
	// more frequently than data that does not change very often.
	cachePeriodSeconds = parseInt(cachePeriodSeconds, 10);
	if (isNaN(cachePeriodSeconds))
	{
		maClient.reportLiveDataError(slide, null, "A cache-period in seconds was not provided as the first parameter to maLiveDataSendRequest().");
		return;
	}
	
	// Set the slide's cache period in milleseconds. A cache period of zero means
	// only call the server once so set the ms value to the largest number.
	slide.liveDataCachePeriodMs = cachePeriodSeconds === 0 ? Number.MAX_VALUE : cachePeriodSeconds * 1000;
		
	// This method takes an optional list of name/value pairs following the url. Parse
	// the arguments and construct a parameter list from them.
	var parameters = maLiveDataParseParameters(arguments);
		
	// See if the slide was updated from the server within the cache period. If so, ignore this request.
	// If the update time is zero, this slide has never gotten data from the server.
	if (slide.liveDataUpdateTime !== 0)
	{
		var ms = (new Date()).getTime();
		if (ms - slide.liveDataUpdateTime < slide.liveDataCachePeriodMs)
			return;
	}
	
	// Create the actual HTTP request object.
	var xhr = null;
	if (window.XMLHttpRequest)
		xhr = new XMLHttpRequest();
	else if (window.ActiveXObject)
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	
	if (xhr === null)
	{
		// This should never happen, but just in case...
		maClient.reportLiveDataError(slide, null, "maLiveDataSendRequest() could not create an HTTP request.");
		return;
	}
	
	// Create our request object that remembers what the request is for.
	var request = new maLiveDataRequest(slide, url, parameters, xhr, cachePeriodSeconds);
	
	// Make the actual request. Note that the sequence of statements of below is important.
	// In particular, the open call should precede setting the onreadystatechange property.
	xhr.open("POST", url);
	xhr.onreadystatechange = function() { maOnLiveDataResponse(request);};
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhr.send(parameters);
}

function maOnLiveDataResponse(request)
{
    // Handle responses from the server. 
    if (request.xhr.readyState != 4)
		return;
		
	// Get the slide that the request was made for.
	var slide = request.slide;
    
	if (request.xhr.status == 200)
	{
		// Get the XML from the response.
		var xml = request.xhr.responseXML;
		var data;

		data = maGetLiveDataFromXml(xml, 'serverError');
		if (data)
		{
			slide.htmlText = unescape(data);
			maClient.reportLiveDataError(slide, request, data);
			return;
		}

		data = maGetLiveDataFromXml(xml, 'text');
		if (data)
			slide.htmlText = unescape(data);

		data = maGetLiveDataFromXml(xml, 'previewImage');
		if (data)
			slide.dirPreviewImageUrl = data;

		data = maGetLiveDataFromXml(xml, 'previewText');
		if (data)
			slide.dirPreviewText = unescape(data);

		maClient.setLiveData(slide);
	}
	else
	{
		// Something went wrong. Report the error by returning a message as Live Data.
		var error = "Error " +  request.xhr.status + " - " + request.xhr.statusText;
		maClient.reportLiveDataError(slide, request, error);
	}
}

function maGetLiveDataFromXml(xml, tagName)
{
	// Return the data for an XML element returned from the server. If the element
	// is not found, return null.
	var data = null;
	try
	{
		data = xml.getElementsByTagName(tagName)[0].firstChild.data;
	}
	catch (error)
	{
	}
	return data;
}

function maLiveDataParseParameters(args)
{
	// Construct a name/value parameter list of the form "name1=value1&name2=value2" from a
	// variable length parameter list of the form "'name1', value1, 'name2', value2". Note
	// that the first two arguments are the cache period and the url. So we start with the
	// third argument which is at index 2. Bump the index by 2 after parsing each pair.
	var parameters = "";
	var argsCount = args.length;
	for (var arg = 2; arg < argsCount; arg += 2)
	{
		// Make sure there are a pair of args left.
		if (arg + 2 > argsCount)
			break;
		
		if (parameters.length > 0)
			parameters += "&";
		
		parameters += args[arg] + "=" + args[arg + 1];
	}
	return parameters;
}

