//Object initializers.
ajax_filesize = Object;
ajax_filesize.batch = Array();
ajax_filesize.cache = Array();
ajax_filesize.pending = Array();
ajax_filesize.pending_reprocess_timer = Object();
ajax_filesize.pending_reprocess_timer.running = false;

//Program switches.
ajax_filesize.batch_mode = true; //Batch mode is used for streamlined processing and is recommended.
ajax_filesize.pending_reprocess_delay = ajax_filesize.batch_mode ? 0 : 100; //Delay before sending auto reprocessing (primarily used with single mode).
ajax_filesize.error_alerts = false; //If an error occurs should an alert box be displayed? Recommend turning on only for debugging.



//Top level functions.
//Process all PDF links on the page.
ajax_filesize.pdf_links_process_all = function()
{
	jQuery("a[href*=.pdf]").each(function()
	{
		ajax_filesize.link_element_process(jQuery(this));
	});
	
	if(ajax_filesize.batch_mode)
	{
		ajax_filesize.link_lookup_batch();
		ajax_filesize.link_lookup_batch_purge();
	}

	return true;
}

//Process the link with the given element id.
ajax_filesize.link_element_id_process = function(eid)
{
	return ajax_filesize.link_element_process(jQuery("#"+eid));
}

//Process the link specified by the passed jQuery object. If the jQuery object contains multiple references only the first will be proccessed.
ajax_filesize.link_element_process = function(j)
{
	var filename = unescape(j.attr("href"));
	var matched = false;

	if(ajax_filesize.is_cached(filename))
	{
		ajax_filesize.link_element_cache_tag(j);
	}
	else
	{
		if(!j.attr("id"))
		{
			ajax_filesize.element_generate_id(j);
		}

		ajax_filesize.pending_add(j.attr("id"));
		
		if(ajax_filesize.batch_mode)
		{
			ajax_filesize.link_lookup_batch_add(filename);
		}
		else
		{
			ajax_filesize.link_lookup(filename);
		}
	}

	return true;
}



//Batch functions.
ajax_filesize.link_lookup_batch_add = function(filename)
{
	ajax_filesize.batch.push(filename);
	return true;	
}

ajax_filesize.link_lookup_batch_purge = function()
{
	ajax_filesize.batch = Array();
	return true;	
}

ajax_filesize.link_lookup_batch = function()
{
	var i;
	var suffix;

	params = Object();
	params.mode = 'batch';
	params.human_readable = 1;
	params.count = ajax_filesize.batch.length;

	for(i = 0; i < params.count; i++)
	{
		suffix = "000";
		suffix = suffix.substr(0, 3 - i.toString().length)+i;
		params['filename'+suffix] = ajax_filesize.batch[i];
	}

	ajax_filesize.ajax_request(params);

	return true;
}



//Link processing functions.
ajax_filesize.link_lookup = function(filename)
{
	params = Object();
	params.mode = 'single';
	params.filename = filename;
	params.human_readable = 1;

	ajax_filesize.ajax_request(params);

	return true;
}

ajax_filesize.link_element_tag = function(j, tag)
{
	j.html(j.html()+tag);

	return true;
}

ajax_filesize.link_element_cache_tag = function(j)
{
	var href = unescape(j.attr('href'));

	if(ajax_filesize.is_cached(href))
	{
		ajax_filesize.link_element_tag(j, " <small>("+ajax_filesize.cache_lookup(href)+")</small>");
	}

	return true;
}

ajax_filesize.element_generate_id = function(j)
{
	var uuid;

	jQuery.UUID({prefix:''});
	uuid = jQuery.UUID();

	j.attr("id", uuid);

	return true;
}



//Cache functions
ajax_filesize.cache_update = function(filename, filesize)
{
	var i;
	var cache = ajax_filesize.cache;
	var count = cache.length;
	var ret = false;

	for(i = 0; i < count; i++)
	{
		if(cache[i][0] === filename)
		{
			cache[i][1] = filesize;
			ret = true;
			break;
		}
	}

	return ret;
}

ajax_filesize.cache_add = function(filename, filesize)
{
	var i;
	var cache = ajax_filesize.cache;
	var count = cache.length;
	var ret = false;


	if(!ajax_filesize.is_cached(filename))
	{
		cache[count] = Array(filename, filesize);
		ret = true;
	}

	return ret;
}

ajax_filesize.cache_locate = function(filename)
{
	var i;
	var cache = ajax_filesize.cache;
	var count = cache.length;
	var ret = false;

	for(i = 0; i < count; i++)
	{
		if(cache[i][0] === filename)
		{
			ret = i;
			break;
		}
	}

	return ret;
}

ajax_filesize.cache_lookup = function(filename)
{
	var cache = ajax_filesize.cache;
	var cache_id;
	var ret = false;

	cache_id = ajax_filesize.cache_locate(filename);
	if(cache_id !== false)
	{
		ret = cache[cache_id][1];
	}

	return ret;
}

ajax_filesize.is_cached = function(filename)
{
	return (ajax_filesize.cache_locate(filename) === false) ? false : true;
}




//Queue functions.
ajax_filesize.pending_add = function(eid)
{
	ajax_filesize.pending.push(eid);
	
	return true;
}

ajax_filesize.pending_remove = function(eid)
{
	var i;
	var pending = ajax_filesize.pending;
	var count = pending.length;
	var ret = false;

	for(i = 0; i < count; i++)
	{
		if(pending[i] === eid)
		{
			pending.splice(i, 1);
			ret = true;
			break;
		}
	}

	return ret;
}

ajax_filesize.pending_process = function()
{
	var i;
	var j;
	var filename;
	var pending = ajax_filesize.pending;
	var count = pending.length;

	for(i = 0; i < count; i++)
	{
		j = jQuery("#"+pending[i]);
		filename = unescape(j.attr("href"));

		if(ajax_filesize.is_cached(filename))
		{
			ajax_filesize.link_element_cache_tag(j);
			ajax_filesize.pending_remove(j.attr("id"));
			count = pending.length;
			i--;
		}
	}
}

ajax_filesize.pending_reprocess_fire = function()
{
	ajax_filesize.pending_reprocess_timer.running = false;
	ajax_filesize.pending_process();

	return true;
}

ajax_filesize.pending_reprocess = function()
{
	if(ajax_filesize.pending_reprocess_timer.running === true)	
	{
		jQuery(ajax_filesize.pending_reprocess_timer).stopTime();
		jQuery(ajax_filesize.pending_reprocess_timer).oneTime(ajax_filesize.pending_reprocess_delay, ajax_filesize.pending_reprocess_fire);
	}
	else
	{
		ajax_filesize.pending_reprocess_timer.running = true;
		jQuery(ajax_filesize.pending_reprocess_timer).oneTime(ajax_filesize.pending_reprocess_delay, ajax_filesize.pending_reprocess_fire);
	}

	return true;
}



//AJAX functions.
ajax_filesize.ajax_request = function(params)
{
	jQuery.ajax({
		type: "POST",
		url: "ajax_filesize.php",
		cache: false,
		complete: ajax_filesize.ajax_complete,
		success: ajax_filesize.ajax_success,
		data: params,
		dataType: "json"
	});
	
	return true;
}

ajax_filesize.ajax_complete = function(XMLHttpRequest, status)
{
	if(status !== "success")
	{
		ajax_filesize.ajax_fail();
	}

	return true;
}

ajax_filesize.ajax_fail = function()
{
	if(ajax_filesize.error_alerts)
	{
		alert('The server returned an invalid response. Please try again.');
	}

	return true;
}

ajax_filesize.ajax_success = function(json, status, XMLHttpRequest)
{
	var i;
	var cache = ajax_filesize.cache;
	var count = cache.length;
	var matched = false;
	var error;

	if(json && json.code == '0')
	{
		if(json.mode === 'single')
		{
			if(ajax_filesize.is_cached(json.filename))
			{
				ajax_filesize.cache_update(json.filename, json.filesize);
			}
			else
			{
				ajax_filesize.cache_add(json.filename, json.filesize);
			}
			
			ajax_filesize.pending_reprocess();
		}
		else
		{
			for(i = 0; i < json.count; i++)
			{
				suffix = "000";
				suffix = suffix.substr(0, 3 - i.toString().length)+i;

				if(ajax_filesize.is_cached(json['filename'+suffix]))
				{
					ajax_filesize.cache_update(json['filename'+suffix], json['filesize'+suffix]);
				}
				else
				{
					ajax_filesize.cache_add(json['filename'+suffix], json['filesize'+suffix]);
				}
			}

			ajax_filesize.pending_reprocess();			
		}
	}
	else
	{
		if(ajax_filesize.error_alerts)
		{
			if(!json.error_count)
			{
				alert("The server returned an invalid response. Please try again.");
			}
			else
			{
				error = "One or more unrecoverable errors encountered while requesting data from server.";
				
				for(i = 0; i < json.error_count; i++)
				{
					error += "\nError "+(i+1)+": "+json.error_strings[i];
				}
	
				alert(error);
			}
		}
	}

	return true;
}

