
// FireStats namespace.
// todo: move all the other functions and globals into it.
FS = {}
FS.loadCSS = function(url)
{
	var st = document.createElement("link");
	st.href = url;
	st.rel = "stylesheet";
	st.type = "text/css"; 
	var head = document.getElementsByTagName('head')[0];
	head.appendChild(st);
}

FS.loadJavaScript = function(url)
{
	var st = document.createElement("script");
	st.src = url;
	st.type = "text/javascript"; 
	var head = document.getElementsByTagName('head')[0];
	head.appendChild(st);
}


FS.archivingOldData = false;
FS.archiveOldData = function()
{
	FS.archivingOldData = true;
	if ($('fs_archive_button')) 
	{
		$('fs_archive_button').innerHTML = 'Stop';
		$('fs_archive_status').innerHTML = 'Compacting...';
		$('archive_method').disabled = true;
		$('archive_older_than').disabled = true;
	}
	sendSilentRequest('action=archiveOldData&max_days_to_archive=1',FS.archiveCallback);
}

FS.archiveCleanup = function()
{
	if (FS.archivingOldData)
	{
		FS.archivingOldData = false;
		if ($('fs_archive_button')) $('fs_archive_button').innerHTML = 'Stopping...';
		sendSilentRequest('action=updateFields&update=fs_archive_status',FS.archiveDoneCallback);
	}
}

FS.archiveDoneCallback = function(response)
{
	if ($('archive_method')) 
	{
		$('archive_method').disabled = false;
		$('archive_older_than').disabled = false;
		$('fs_archive_button').innerHTML = 'Compact now';
	}
}

FS.archiveCallback = function(response)
{
	if (response.status == 'ok')
	{
		if (FS.archivingOldData)
		{
			if (response.done)
			{
				FS.archiveCleanup();
			}
			else
			{
				if (!FS.archivingOldData) // if user canceled 
				{
					response.cancel = true;
					FS.archiveCleanup();
				}
				else
				{
					if ($('fs_archive_button')) $('fs_archive_button').innerHTML = 'Stop';
				}
			}
		}
		else
		{
			response.cancel = true;
			FS.archiveCleanup();
		}
	}
	else
	{
		FS.archiveCleanup();
	}
}

FS.operations = new Array();
FS.executeProcess = function(type, phpFile)
{
	if (FS.operations[type] == null)
	{
		FS.operations[type] = true;
		if ($(type+'_button')) $(type+'_button').innerHTML = "Abort";
		
	    var params = 'action=incrementalProcess&type='+type+ (phpFile != undefined ? '&file='+phpFile : "");
	    sendSilentRequest(params, function(response)
	    {
	    	if (response.status == 'ok')
	    	{
		    	var type = response['type'];
		    	if (type == null) alert("Type not specified in callback");
	    		var progress = $(type+"_process_progress");
				var progress_text = response['progress_text'];
				
		    	if (FS.operations[type] == null)
		    	{
		    		response.cancel = true;
		    		if ($(type+'_button')) $(type+'_button').innerHTML = "Start";
		    		if (progress) progress.innerHTML = "Canceled";
		    	}
		    	else
		    	{
		    		if ($(type+'_button')) $(type+'_button').innerHTML = "Abort";
		    		if (progress) progress.innerHTML = progress_text;
		    	}

		    	
				if (response.done == 'true')
				{
					if ($(type+'_button')) $(type+'_button').innerHTML= "Start";
					FS.operations[type] = null;
				}
	    	}
	    });
	}
	else
	{
		if ($(type+'_button')) $(type+'_button').innerHTML = "Start";
		FS.operations[type] = null;
	}
}


FS.getWindowSize = function() 
{
	var myWidth = 0, myHeight = 0;
	if( typeof( window.innerWidth ) == 'number' ) 
	{
		//Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
	} 
	else 
	if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) 
	{
		//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth;
		myHeight = document.documentElement.clientHeight;
	} 
	else
	if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
	{
		//IE 4 compatible
		myWidth = document.body.clientWidth;
		myHeight = document.body.clientHeight;
	}
	var res = new Object();
	res.width = myWidth;
	res.height = myHeight;
	return res;
}

FS.createWindowUrl = function(width,height,left,top, url)
{
	var myAjax = new Ajax.Request(
	url,
	{
		method: 'get', 
		onComplete: function(response)
		{
			FS.createWindow(width,height,left,top,response.responseText);
		}	
	});
}

FS.createWindow = function(width,height,left,top, content)
{
	var size = FS.getWindowSize();
	if (left == "center")
	{
		left = (size.width - width) / 2;
	}
	if (top == "center")
	{
		top = (size.height - height) / 2;
	}
	var divId = createNewWindow(width,height,left,top);
	document.getElementById('windowContent' + divId).innerHTML = content;
}

FS.openWindow = function(page, width, height)
{
	window.open (page, 'newwindow',"height="+height+",width="+width+",toolbar=no,menubar=no,location=no, directories=no, status=no,resizable=yes,scrollbars=yes");
}

function toggle_div_visibility(id)
{
	var disp = $(id).style.display;
	if (disp == "inline")
	{
		$(id).style.display = "none";
	}
	else
	{
		$(id).style.display = "inline";
	}
}


function hideFeedback()
{
	var e = document.getElementById("feedback_div").style.display = "none";
}

var messageTimerID;
function showFeedback(response, timeout)
{
	var e = $("feedback_zone");
	if (!e) return; // for dialogs etc
	if (!response.message) return;
	e.innerHTML = response.message;

	e = $("feedback_div");
	if (response.status == 'error')
	{
		e.style.background = '#f86262';
	}
	else
	{
		e.style.background = '#3aa9ff';
	}

	e.style.display = "block";
	
	if (timeout != null)
	{
		clearTimeout(messageTimerID);
		messageTimerID = setTimeout("hideFeedback()", timeout);
	}
}

function clearOptions(idlist,save,update)
{
	var a = idlist.split(',');
	a.each(function(item) 
	{
		var x = $(item);
		if(x.tagName.toLowerCase() == 'input')
		{
			x.value="";
		}
		else
		{
			x.innerHTML="";
		}
	});

	if(save == true) 
	{
		saveOptions(idlist,update);
	}
}

function saveSessionOptions(idlist,update,type)
{
	saveOptions_imp(idlist,"session",update,type);
}

function saveOptions(idlist,update,type)
{
	saveOptions_imp(idlist,"firestats",update,type);
}

function saveLocalOptions(idlist,update)
{
	saveOptions_imp(idlist,"local",update,null);
}

function saveOptions_imp(idlist,dest,update,type)
{
	// creates a list in the format list=key1,val1;key2,val2
	var a = idlist.split(',');
	var list = '';
	var missing = '';
	a.each(function(item) 
	{
		if ($(item))
		{
			list += encodeURIComponent(item) + "," + encodeURIComponent($F(item)) + (type != null ? "," + type : "") + ";";
		}
		else
		{
			if (missing == '') missing += item;
			else missing += "," + item;
		}
	});

	if (missing != '') alert("saveOptions: missing element(s): " + missing);

	var params = 'action=' + 'saveOptions' + '&list=' + encodeURIComponent(list) + 
				 (update != null ? "&update="+encodeURIComponent(update) : "") +
				 "&dest=" + encodeURIComponent(dest);
	sendRequest(params);
}

function saveSessionOptionValue(name, value, type, update)
{
	saveOptionImpl(name,value,type,update,"session");
}

function saveOptionValue(name, value, type)
{
	saveOptionImpl(name,value,type,null,"firestats");
}

function saveOption(inputID, optionName, type)
{
	saveOptionImpl(optionName,$F(inputID), type,null,"firestats");
}

function saveOption(inputID, optionName, type, update)
{
	saveOptionImpl(optionName, $F(inputID), type, update, "firestats");
}

function saveLocalOption(inputID, optionName, type, update)
{
	saveOptionImpl(optionName, $F(inputID),type, update, "local");
}

function saveSystemOptionValue(name, value, type)
{
	saveOptionImpl(name,value,type,null,"system");
}

function saveSystemOption(inputID, optionName, type, update)
{
	saveOptionImpl(optionName, $F(inputID), type, update, "system");
}

function saveOptionImpl(optionName, txt, type, update, dest)
{
	var params = 'action=' + 'saveOption' + '&key=' + encodeURIComponent(optionName) + 
				 "&value=" + encodeURIComponent(txt) +
				 (update != null ? "&update="+encodeURIComponent(update) : "") +
				 "&dest=" + encodeURIComponent(dest) + "&type=" + type;
	sendRequest(params);				 
}

function showMessage(msg)
{
	try
	{	
		var x = {};
		x['status'] = 'ok';
		x['message'] = msg;
		showFeedback(x);
	}
	catch (e2)	
	{	
		// if even this failed, use alert.
		alert('error : ' + errorMessage);
	}
}

function showError(errorMessage)
{
	try
	{	
		var x = {};
		x['status'] = 'error';
		x['message'] = errorMessage;
		clearTimeout(messageTimerID);
		showFeedback(x);
	}
	catch (e2)	
	{	
		// if even this failed, use alert.
		alert('error : ' + errorMessage);
	}
}

function sendSilentRequest(params,callback)
{
	sendRequest2(params,true,callback);
}

function sendRequest(params,callback)
{
	sendRequest2(params,false,callback);
}

var fs_network_status_count = 0;
function sendRequest2(params,silent,callback)
{
	if (!isIE6OrOlder())
	{
		if (!silent)
		{
			fs_network_status_count++;
			var net = $('network_status');
			if (net) net.style.display = "block";
		}
	}
	params += ("&sid=");
	var ajaxUrl = "php/ajax-handler.php?sid=";
	var myAjax = new Ajax.Request(
	ajaxUrl,
	{
		method: 'post', 
		parameters: params, 
		onComplete: function(response)
		{
			handleResponse(response,silent,callback);
			if (!isIE6OrOlder())
			{
				if (!silent)
				{
					fs_network_status_count--;
					if (fs_network_status_count == 0)
					{
						var net = $('network_status');
						if (net) net.style.display = "none";
					}
				}
			}
		}	
	});
}


function stripslashes(value)
{
	str = "" + value;
	str = str.replace(/\\"/g,'"' );
	str = str.replace(/\\\'/g,'\'' );
	return str;
}


FS.trapEnter = function(e, enterFunction)
{
	if (!e) e = window.event;
	if (e.keyCode == 13)
	{
		e.cancelBubble = true;
		if (e.returnValue) e.returnValue = false;
		if (e.stopPropagation) e.stopPropagation();
		if (enterFunction) eval(enterFunction);
		return false;
	} 
	else 
	{

		return true;
	}     
}


function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";

	if(typeof(arr) == 'object') { //Array/Hashes/Objects
		for(var item in arr) {
			var value = arr[item];

			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}

function isIE6OrOlder()
{
    return isIEXOrOlder(6);
}

function isIEXOrOlder(x)
{
	var ua = navigator.userAgent;
	var i = ua.indexOf("MSIE");
	if (i != -1)
	{
		var ver = parseFloat(ua.substring(i + 5, i + 8));
        return ver <= x;
	}
    return false;
}


function applyResponse(data)
{
	applyResponse2(data,false);
}

function applyResponse2(data,silent)
{
	var fields = data['fields'];
	if (fields)
	{
		for (var key in fields) 
		{
			try
			{	
				var txt =  stripslashes(fields[key]);
				var e = $(key);
				if(e)
				{
					if (data['type'] && data['type'][key] == 'tree') 
					{
						replaceTree(key, txt);
					}
					else
					if(e.tagName.toLowerCase() == 'input')
					{
						e.value=txt;
					}
					else
					{
						e.innerHTML=txt;
					}
				}
				else
				{
					if (!silent) alert('Element not found: ' + key);
				}
			}
			catch(e)
			{
				alert(dump(e));	
			}
		}
	}
	
	var styles = data['styles'];
	for (var key in styles) 
	{
		var style  = styles[key];
	
		for (var prop in style) 
		{
			try
			{
				var e = $(key);
				if(e) 
				{	
					e.style[prop]=style[prop];
				}
				else
				{
					if (!silent) alert('Element not found: ' + key);
				}
			}
			catch(ex)
			{
				alert(ex);
			}
		}
	}

}

var disableResponses = false;
function handleResponse(response,silent,callback)
{
	if (disableResponses) return;
	try
	{
		eval("var r = " + response.responseText);
	}
	catch (e)
	{
		showError("error evaluating response : Response text:<br/>" + response.responseText);
		var r = new Object();
		r.message = 'Error evaluating response';
		r.status = 'error';
		if (typeof callback == 'function') callback(r);
		return;
	}

	try
	{
		if (r.status == 'error')
		{	
			showError(r.message);
			if (typeof callback == 'function') 
			{
				callback(r);
			}
		}
		else if (r.status == 'ok')
		{
			//alert(dump(r));
			if (typeof callback == 'function') 
			{
				callback(r);
				// check if callback canceled the response.
				if (r.cancel) return; 
			}
			
			switch (r.action)
			{
			case 'createNewDatabase':
			case 'upgradeDatabase':
			case 'attachToDatabase':
			case 'installDBTables':
				if (r.db_status == 'ok')
				{
					window.location.reload(); // no ideal, but it will have to do for now.
				}
				else
				{
					showFeedback(r,5000);
					applyResponse2(r,silent);
				}
			break;
			default:
				showFeedback(r,5000);
				applyResponse2(r,silent);
			}

			if (r.cookies != null && r.cookies.length > 0)
			{
				for(var i=0;i < r.cookies.length;i++)
				{
					var c = r.cookies[i];
					createCookie(c.name, c.value, c.days);
				}
			}
			
			if (r.reload == 'true' || r.refresh == 'true')
			{
				window.location.reload();
			}
			
			/* 
			caused problems with WP 2.5, need to investigate.
			if (r.refresh == 'true')
			{
				// a bit of dark magic to fight firefox's cache.
				// this code appends rand=RANDOM to the url, but make sure it only does so once.
				window.location.href = FS.addRandToURL(window.location.href);
			}
			*/
			
			if (r.redirect)
			{
				window.location = r.redirect;
			}			
			
			if (r.send_request)
			{
				sendRequest2(r.send_request, silent, callback);
			}
			
			if (r.new_floating_window)
			{
				if (r.content != undefined)
				{
					FS.createWindow(r.width,r.height,r.left,r.top,r.content);
				}
				else
				if (r.url != undefined)
				{
					FS.createWindowUrl(r.width,r.height,r.left,r.top,r.url);
				}
			}
			
			if (r.execute)
			{
				var exec = r.execute;
				try
				{
					eval(exec);
				}
				catch(e)
				{
					showError('Error executing ' + exec);
				}
			}
			
		}
		else if (r.status == 'session_expired')
		{
			disableResponses = true; // ignore futher responses
			alert("Session expired, press ok to reload");
			window.location.reload();
		}
		else
		{
			showError('Unknown response type ' + r.status);
		}
	}
	catch (e)
	{
		showError('error processing response : ' + dump(e));	
	}
}

function replaceTree(id,tree)
{
	var str = stripslashes(tree);
	var tree = convertTreeString(str);
	var treeDiv = $(id);
	treeDiv.replaceChild(tree, treeDiv.getElementsByTagName('div')[0]);
}

// selects the select item with the speficied text
function selectByText(selectId, text)
{
	var children = $(selectId).childNodes;
	for (var i = 0; i < children.length; i++)
	{
		var child = children[i];
		if (child.text == text)
		{
			$(selectId).selectedIndex = i;
			break;
		}
	}
}

/**
 * cookie scripts from http://www.quirksmode.org/js/cookies.html
 */
function createCookie(name,value,days) 
{
	if (days) 
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else 
		var expires = "";
	document.cookie = name+"="+value+expires;//+"; path=/"; //
}

function readCookie(name) 
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) 
	{
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) 
{
	createCookie(name,"",-1);
}

FS.updateAllStats = function()
{
	// todo: move rss_subscribers out of this list.
	sendRequest('action=updateFields&update=stats_total_count,stats_total_unique;stats_total_count_last_day,stats_total_unique_last_day;rss_subscribers,fs_recent_referers,fs_search_terms,popular_pages;countries_list,fs_browsers_tree,fs_os_tree;records_table');
}

// add some functions to string.
String.prototype.trim = function() 
{
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() 
{
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() 
{
	return this.replace(/\s+$/,"");
}	


FS.openDonationWindow = function()
{
	FS.createWindowUrl(400,370,'center','center','php/window-donation.php?sid=');
}

/**
 * the ugly function from hell.
 * adds a rand=RANDOM to the url, if it's already exists it updates. 
 */
FS.addRandToURL = function(url1)
{
	var rand = "rand=" + Math.random();
				
	var url = url1; // url without the params
	var params = ''; // parameters without the ?
	var qindex = url.indexOf("?");
	if (qindex != -1) // if we have a ?
	{
		params = url.substring(qindex + 1);
		url = url.substring(0, qindex);
	}
				
	var start = params.indexOf("rand=");
	if (start != -1) // if we have rand=
	{
		var end = params.indexOf("&", start);
		if (end == -1)
		{
			end = params.length;
		}
		else end++; // grab next & as well
		if (start > 0) start--; // greb previous & as well 
		var left = params.substr(0, start);
		var right = params.substr(end);
		if (left.length == 0) left = rand;
		else left += "&" + rand;
		if (right.length > 0) right = "&" + right;
		new_params = left + right;
	}
	else
	{
		if (params.length == 0) new_params = rand;
		else new_params = params += "&" + rand;
	}
	return url + "?" + new_params;
}

FS.getMultipleSelectionIndex = function(id)
{
	selected = new Array(); 
	var list = $(id);
	if (!list) return null;
	 
	for (var i = 0; i < list.options.length; i++) 
		if (list.options[i].selected) 
			selected.push(list.options[i].value);
	return selected;
}