// vim: set ts=4 sts=4 sw=4 si noet:
// function from http://forums.devshed.com/t39065/s84ded709f924610aa44fff827511aba3.html
// author appears to be Robert Pollard

function sprintf()
{
	if (!arguments || arguments.length < 1 || !RegExp)
	{
		return;
	}
	var str = arguments[0];
	var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
	var a = b = [], numSubstitutions = 0, numMatches = 0;
	while (a = re.exec(str))
	{
		var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
		var pPrecision = a[5], pType = a[6], rightPart = a[7];

		numMatches++;
		if (pType == '%')
		{
			subst = '%';
		}
		else
		{
			numSubstitutions++;
			if (numSubstitutions >= arguments.length)
			{
				console.log('Error! Not enough function arguments (' + (arguments.length - 1)
				   + ', excluding the string)\n'
				   + 'for the number of substitution parameters in string ('
				   + numSubstitutions + ' so far).');
			}
			var param = arguments[numSubstitutions];
			var pad = '';

			if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
			else if (pPad) pad = pPad;

			var justifyRight = true;

			if (pJustify && pJustify === "-") justifyRight = false;

			var minLength = -1;
			if (pMinLength) minLength = parseInt(pMinLength);

			var precision = -1;
			if (pPrecision && pType == 'f')
				precision = parseInt(pPrecision.substring(1));

			var subst = param;
			switch (pType)
			{
			case 'b':
				subst = parseInt(param).toString(2);
				break;
			case 'c':
				subst = String.fromCharCode(parseInt(param));
				break;
			case 'd':
				subst = parseInt(param) ? parseInt(param) : 0;
				break;
			case 'u':
				subst = Math.abs(param);
				break;
			case 'f':
				subst = (precision > -1)
				 ? Math.round(parseFloat(param) * Math.pow(10, precision))
				  / Math.pow(10, precision)
				 : parseFloat(param);
				break;
			case 'o':
				subst = parseInt(param).toString(8);
				break;
			case 's':
				subst = param;
				break;
			case 'x':
				subst = ('' + parseInt(param).toString(16)).toLowerCase();
				break;
			case 'X':
				subst = ('' + parseInt(param).toString(16)).toUpperCase();
				break;
			}
			var padLeft = subst !== null ? minLength - subst.toString().length : 0;
			if (padLeft > 0)
			{
				var arrTmp = new Array(padLeft+1);
				var padding = arrTmp.join(pad?pad:" ");
			}
			else
			{
				var padding = "";
			}
		}
		str = leftpart + padding + subst + rightPart;
	}
	return str;
}


function date_format(dt, fmt) {
	var full_months = [
		'January', 'February', 'March', 'April', 'May', 'June',
		'July', 'August', 'September', 'October', 'November', 'December'
	];
	var short_months = [
		'Jan', 'Feb', 'Mar', 'Apr', 'May', 'June',
		'July', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
	];
	var full_days = [
		'Sunday', 'Monday', 'Tues', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
	];
	var short_days = [
		'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
	];
	var day = dt.getDay();
	var d = dt.getDate();
	var m = dt.getMonth();
	var y = dt.getYear();
	var Y = dt.getFullYear();
	var hh = dt.getHours();
	var mm = dt.getMinutes();
	var ss = dt.getSeconds();

	var sep = '-';
	if (fmt.indexOf('/') >= 0) {
		regex = /[:\/]/;
		sep = '/';
	} else if (fmt.indexOf(':') == 2) {
		regex = /[:]/; // assume user only wants time formatting
		sep = ':';
	} else if (fmt.indexOf(' ') >= 0) {
		regex = /[:\ ]/;
		sep = ' ';
	}
	var tokens = fmt.split(regex);
	var s = new Array();
	var t = new Array();
	for (i in tokens) {
		switch (tokens[i]) {
		case 'YYYY':
		case 'yyyy':
		case 'y':
		case 'Y':
			s.push(Y); break;
		case 'YY':
		case 'yy':
			s.push(y); break;
		case 'm':
		case 'mm':
			s.push(short_months[m]); break;
		case 'MMMMM':
			s.push(full_months[m]); break;
		case 'DDDDD,':
			s.push(full_days[day] + ','); break;
		case 'DDDDD':
			s.push(full_days[day]); break;
		case 'DDD,':
			s.push(short_days[day] + ','); break;
		case 'DDD':
			s.push(short_days[day]); break;
		case 'DDst':
			var ending;
			switch (d) {
			case 1:
			case 21:
			case 31:
				ending = 'st'; break;
			case 2:
			case 22:
				ending = 'nd'; break;
			case 3:
			case 13:
			case 23:
				ending = 'rd'; break;
			default:
				ending = 'th'; break;
			}
			s.push(d + ending); break;
		case 'dd':
		case 'd':
			s.push(d); break;

		case 'HH':
			t.push(sprintf('%02d', hh)); break;

		case 'MM':
			t.push(sprintf('%02d', mm)); break;

		case 'SS':
			t.push(sprintf('%02d', ss)); break;

		case 'A':
			var A = hh > 12 ? 'PM' : 'AM'; break;

		}
	}
	var result = s.join(sep);

	if (t.length > 0) {
		result = result + ' ' + t.join(':');
	}
	if (A !== undefined) {
		result += ' ' + A;
	}
	return result;
}

