/**
 *	MiniBatteryLogger Shared Battery Data Archive (ShaBaDA)
 *
 *	JavaScript library
 *	lib.js
 */

	function strip_tags(text)
	{
		// Removes tags from argument
		
		var p = 0, q = 0, r = 0, b = '';
		while (p < text.length)
		{
			p = text.indexOf('<', r);
			if (p != -1)
			{
				b += text.substring(r, p);
				q = text.indexOf('>', p);
				if (q != -1)
				{
					r = q + 1;
				}
			}
			else
			{
				b += text.substring(r);
				break;
			}
		}
		return b;
	}
	
	/**
	 *	Cross-browser HTTP request object
	 */
	function XMLHttp()
	{
		if (window.XMLHttpRequest)
		{
			return new XMLHttpRequest();
		}
		else if (window.ActiveXObject)
		{
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
		else return null;
	}

	/**
	 *	Asynchronous HTTP request handler
	 */
	var Servo = {
		load: function(params)
		{
			var xmlhttp = new XMLHttp();
			if (xmlhttp)
			{
				xmlhttp.onreadystatechange = function()
				{
					if (xmlhttp.readyState == 4)
					{
						if (xmlhttp.status == 200)
						{
							if (params["target"])
								params["target"].innerHTML = xmlhttp.responseText;
						}
						else
						{
							if (params["target"])
								params["target"].innerHTML = "Failed. Status:" + xmlhttp.status;
						}
						// Execute anyway. Is it really a Good Thing??
						if (params["oncomplete"])
						{
							params["oncomplete"](xmlhttp.responseText);
						}
					}
				};
				xmlhttp.open("GET", params["url"], true);
				xmlhttp.send(null);
				return true;
			}
			return false;
		},
		download: function(params)
		{
			var xmlhttp = new XMLHttp();
			if (xmlhttp)
			{
				xmlhttp.open("GET", params["url"], false);
				xmlhttp.send(null);
				if (xmlhttp.status == 200)
				{
					return xmlhttp.responseText;
				}
			}
		},
		post: function(params)
		{
			var xmlhttp = new XMLHttp();
			if (xmlhttp)
			{
				xmlhttp.onreadystatechange = function()
				{
					if (xmlhttp.readyState == 4)
					{
						if (xmlhttp.status == 200)
						{
							if (params["target"])
								params["target"].innerHTML = xmlhttp.responseText;
						}
						else
						{
							if (params["target"])
								params["target"].innerHTML = "Failed. Status:" + xmlhttp.status;
						}
						// Execute anyway. Is it really a Good Thing??
						if (params["oncomplete"])
						{
							params["oncomplete"](xmlhttp.responseText);
						}
					}
				};
				xmlhttp.open("POST", params["url"], true);
				xmlhttp.send(params["data"]);
			}
		}
	};

	/**
	 *	Our nice progress indicator
	 */
	function Throbber(id)
	{
		this.throbber = document.getElementById(id);
		this.stop = function()
		{
			this.throbber.className = "throbber_paused";
		};
		this.setIndeterminate = function(really)
		{
			if (really)
			{
				this.throbber.className = "throbber_indeterminate";
			}
			else
			{
				this.throbber.className = "throbber_paused";
			}
		};
		this.start = function()
		{
			this.throbber.className = "throbber_active";
		};
	}
	
	/**
	 *	Extensions
	 */

	String.prototype.strtotime = function()
	{
		var digits = this.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
		var d = new Date();
		d.setFullYear(parseInt(digits[1], 10));
		d.setMonth(parseInt(digits[2], 10) - 1);
		d.setDate(parseInt(digits[3], 10));
		d.setHours(parseInt(digits[4], 10));
		d.setMinutes(parseInt(digits[5], 10));
		d.setSeconds(parseInt(digits[6], 10));
		return d.getTime();
	};
	
	Date.prototype.friendly_date = function()
	{
		var elapsed = new Date().getTime() - this.getTime();
		if (elapsed < 60 * 1000)
		{
			return Math.round(elapsed / 1000) + " seconds ago";
		}
		if (elapsed < 60 * 60 * 1000)
		{
			return Math.round(elapsed / (60 * 1000)) + " minutes ago";
		}
		if (elapsed < 24 * 60 * 60 * 1000)
		{
			return Math.round(elapsed / (60 * 60 * 1000)) + " hours ago";
		}
		return this.toString();
	};

	Date.prototype.sql_date = function()
	{
		function pad(num, cyp)
		{
			var s = new String(num);
			while (s.length < cyp)
			{
				s = "0" + s;
			}
			return s;
		}
		return this.getFullYear() + "-" +
			pad(this.getMonth() + 1, 2) + "-" +
			pad(this.getDate(), 2) + " " +
			pad(this.getHours(), 2) + ":" +
			pad(this.getMinutes(), 2) + ":" +
			pad(this.getSeconds(), 2);
	};
	
	Date.prototype.before_date = function(other)
	{
		return this.getTime() < other.getTime();
	};
	
	Date.prototype.after_date = function(other)
	{
		return this.getTime() > other.getTime();
	};
	
	Number.prototype.to_date = function()
	{
		return new Date(this);
	};