/**
 * @author f.deeg
 */
function Utilities(){
	
}
Utilities.showLoading = function(el){
	if (Object.isString(el)) {
		el = $(el);
	}
	if (el) {
		var content = "<div><center>" +
		"<img src='/images/default/loading/Loading.gif' />" +
		"</center></div>";
		el.update(content);
	}
}
Utilities.console_log = function(data){
	if(document.domain.include('test.videotaxi') || document.domain.include('baustelle.videotaxi') || document.domain.include('vt-testserver')){
		if(!(typeof console == 'undefined') && Object.isFunction(console.log)){
			console.log(data);
		}else{
			return false;
		}
	}else{
		return false;
	}
}
Utilities.nl2br = function nl2br (str, is_xhtml) {
	var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';

	return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}
Utilities.killNewline = function(str) {
	return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1 $2').replace(/\s+/g,' ');
}

Utilities.bug_tracking = function(e, func, prio, quiet){
//	alert(this.name);
	var self = this;
	var message;
	if (Object.isString(e)) {
		message = e;
	} else if (e.message && e.stack) {
		message = e.message + "\n\n" + e.stack;
	} else if (Object.isArray(e)) {
		message =  e.inspect();
	}
	if (!quiet) {
		alert(message);
	}
	
	var browser=navigator.appCodeName;
	var b_version=navigator.appVersion;
	var version=parseFloat(b_version);
	
	
	var url = "http://" + location.hostname + "/" + com.videotaxi.kunden.vtid + "/ajax_bug_tracking/index";
	
	var paramArr = new Array();
	paramArr.push(message);
	paramArr.push(func);
	paramArr.push(prio);
	paramArr.push(browser);
	paramArr.push(version);
	paramArr.push(navigator.userAgent);
	paramArr.push(com.videotaxi.kunden.vtid);
	
	try {
		var ajaxcall = new Ajax.RPCRequest(url, {
			methodName: 'write_log',
			methodParams: paramArr,
			contentType: 'text/xml',
			onComplete: function(transport){
				var erg = ajaxcall.responseObject;
				if (erg && erg.length > 0) {
					erg.each(function(child){
						self.console_log(child);
					});
				}
			 },
			 onException: function(transport, e){
				alert(e.message + "\n" + e.stack);
			}
		});
	} catch (e) {
		if (Object.isString(e)) {
			alert(e);
		}
		else if (e.message && e.stack) {
			alert(e.message + "\n\n" + e.stack);
		}
		else if (Object.isArray(e)) {
			alert(e.inspect());
		}
	}
};
Utilities.get_gaTrackerId = function(){
	var gaTrackerId = "UA-3214434-2";
	try {
		if (document.domain.include('baustelle.videotaxi') || com.videotaxi.kunden.vtid == '88888') {
			gaTrackerId = "UA-3214434-3";
		} else if (document.domain.include('test.videotaxi.de')) {
			gaTrackerId = "UA-3214434-4";
		}
	} catch (e) {
		this.bug_tracking(e, 'get_gaTrackerId',1);
	}

	return gaTrackerId;
},
Utilities.trackConversion = function(orderId, affiliation, total, dataArray, prefix_orderId){
	try {
		if (this.get_gaTrackerId()) {
			var matchArray = new Hash();
			matchArray.set(0, 'Verleih');
			matchArray.set(1, 'Neu');
			matchArray.set(2, 'Gebraucht');
			matchArray.set(3, 'Vorbestellung');
			matchArray.set(4, 'Beschaffung');
			var prefix;
			
			if ((typeof prefix_orderId === 'object') && Object.isArray(prefix_orderId)) {
				prefix = '';
				if (prefix_orderId.length > 0) {
					prefix_orderId.each(function(id){
						prefix += id;
						
					});
				}
			}
			else {
				prefix = matchArray.get(prefix_orderId) + "_" + orderId;
			}
			
			if (_gat) {
				var pageTracker = _gat._getTracker(this.get_gaTrackerId());
				pageTracker._setVar(com.videotaxi.kunden.vtid);
				pageTracker._trackPageview("/auftrag/done");
				
				//		_addTrans(orderId, affiliation, total, tax, shipping, city, state, country)
				pageTracker._addTrans(prefix, // order ID - required
					 "VTMS: " + affiliation, // affiliation or store name
					 total // total - required
					);
				if (dataArray) {
					dataArray.each(function(row){
						if (row.get('position')) {
							positionArray = row.get('position');
							positionArray.each(function(position){
								var preis = new Number(Math.abs(position.get('preis')) / Math.abs(position.get('anzahl')));
								preis = preis.toFixed(2);
								//								console.log(current_url);
								if (document.domain.include('baustelle.videotaxi')) {
									console.log(position.inspect());
									console.log("orderID: " + prefix + "\n" +
									"ArtikelNr: " +
									position.get('artikelNr') +
									"\n" +
									"Titel: " +
									decodeURIComponent(position.get('titel')) +
									"\n" +
									"Art: " +
									matchArray.get([position.get('art')]) +
									"\n" +
									"Preis: " +
									preis +
									"\n" +
									"Anzahl: " +
									position.get('anzahl'));
								//	 	_addItem(orderId, sku, name, category, price, quantity)
								//		pageTracker._addItem(
								//			"1234", // order ID - necessary to associate item with transaction
								//			"DD44", // SKU/code - required
								//			"T-Shirt", // product name
								//			"Olive Medium", // category or variation
								//			"11.99", // unit price - required
								//			"1" // quantity - required
								//		);
								}
								pageTracker._addItem(prefix, position.get('artikelNr'), decodeURIComponent(position.get('titel')), matchArray.get([position.get('art')]), preis, position.get('anzahl'));
							});
						}
					});
				}
			}
			pageTracker._trackTrans();
		}
	} 
	catch (e) {
		this.bug_tracking(e, 'trackConversion',2,true);
	}
}
Utilities.trackEvent = function(category, action, optional_label, optional_value){
	if (this.get_gaTrackerId()) {
		try{
			var eventTracker = _gat._getTracker(this.get_gaTrackerId());
			eventTracker._setVar(com.videotaxi.kunden.vtid);
			if (!optional_label || optional_label == '') {
				optional_label = 'no_titel';
			}
			//			if(!optional_value || optional_value == ''){optional_value = 'no_link';}
			//			_trackEvent(category, action, optional_label, optional_value)
			//			optional_value muss offenbar vom typ integer sein
			eventTracker._trackEvent(category, action, optional_label);
		}catch(e){
			this.bug_tracking(e, 'trackEvent',2,true);
		}
	}
}
Utilities.cloneContainer = function(element){
	try{
		var ret = new Element(element.tagName);
		ret.update(element.innerHTML);
		return ret;
	}catch(e){
		this.bug_tracking(e, 'cloneContainer',3,false);
	}
}
Utilities.errCont = function(message, id, el){
	try{
		message = "<div id='"+id+"' style='border-color: orange; border-width: 1px;' class='formular_rahmen error'>"
			+"<span class='kasse_error'>"
			+"<center>" 
			+message
			+"</center></span></div>";
		el.insert(message);
	}catch(e){
		this.bug_tracking(e, 'errCont',3,false);
	}
}
//Utilities.clone = function(el) {
//	try{
//		var newObj = (el instanceof Array) ? [] : {};
//		for (i in el) {
//			if (i == 'clone') continue;
//			if (el[i] && typeof el[i] == "object") {
//				newObj[i] = el[i].clone();
//			} else {
//				newObj[i] = el[i];
//			}
//		}
//		return newObj;
//	}catch(e){
//		this.bug_tracking(e, 'clone',3,false);
//	}
//}
Utilities.formatDate = function(date, format){
}
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
//              | NNN (abbr.)        |
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Day of Week  | EE (name)          | E (abbr)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//

var MONTH_NAMES=new Array('Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember','Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez');
var DAY_NAMES=new Array('Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','So','Mo','Di','Mi','Do','Fr','Sa');
function LZ(x) {
	return(x<0||x>9?"":"0")+x
}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
Utilities.formatDate = function(date, format){
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
}

/**
 * Zusätzliche Funktionen die zur Zeit nicht in Gebrauch sind.
 * Für die Aktivierung der Funktionen ggfls. den Methodennamen anpassen und zum "Utilities"-Namespace hinzufügen. 
 */
//// ------------------------------------------------------------------
//// isDate ( date_string, format_string )
//// Returns true if date string matches format of format string and
//// is a valid date. Else returns false.
//// It is recommended that you trim whitespace around the value before
//// passing it to this function, as whitespace is NOT ignored!
//// ------------------------------------------------------------------
//function isDate(val,format) {
//	var date=getDateFromFormat(val,format);
//	if (date==0) { return false; }
//	return true;
//}

//// -------------------------------------------------------------------
//// compareDates(date1,date1format,date2,date2format)
////   Compare two date strings to see which is greater.
////   Returns:
////   1 if date1 is greater than date2
////   0 if date2 is greater than date1 of if they are the same
////  -1 if either of the dates is in an invalid format
//// -------------------------------------------------------------------
//function compareDates(date1,dateformat1,date2,dateformat2) {
//	var d1=getDateFromFormat(date1,dateformat1);
//	var d2=getDateFromFormat(date2,dateformat2);
//	if (d1==0 || d2==0) {
//		return -1;
//		}
//	else if (d1 > d2) {
//		return 1;
//		}
//	return 0;
//	}
//// ------------------------------------------------------------------
//// Utility functions for parsing in getDateFromFormat()
//// ------------------------------------------------------------------
//function _isInteger(val) {
//	var digits="1234567890";
//	for (var i=0; i < val.length; i++) {
//		if (digits.indexOf(val.charAt(i))==-1) { return false; }
//		}
//	return true;
//	}
//function _getInt(str,i,minlength,maxlength) {
//	for (var x=maxlength; x>=minlength; x--) {
//		var token=str.substring(i,i+x);
//		if (token.length < minlength) { return null; }
//		if (_isInteger(token)) { return token; }
//		}
//	return null;
//	}
//	
//// ------------------------------------------------------------------
//// getDateFromFormat( date_string , format_string )
////
//// This function takes a date string and a format string. It matches
//// If the date string matches the format string, it returns the 
//// getTime() of the date. If it does not match, it returns 0.
//// ------------------------------------------------------------------
//function getDateFromFormat(val,format) {
//	val=val+"";
//	format=format+"";
//	var i_val=0;
//	var i_format=0;
//	var c="";
//	var token="";
//	var token2="";
//	var x,y;
//	var now=new Date();
//	var year=now.getYear();
//	var month=now.getMonth()+1;
//	var date=1;
//	var hh=now.getHours();
//	var mm=now.getMinutes();
//	var ss=now.getSeconds();
//	var ampm="";
//	
//	while (i_format < format.length) {
//		// Get next token from format string
//		c=format.charAt(i_format);
//		token="";
//		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
//			token += format.charAt(i_format++);
//			}
//		// Extract contents of value based on format token
//		if (token=="yyyy" || token=="yy" || token=="y") {
//			if (token=="yyyy") { x=4;y=4; }
//			if (token=="yy")   { x=2;y=2; }
//			if (token=="y")    { x=2;y=4; }
//			year=_getInt(val,i_val,x,y);
//			if (year==null) { return 0; }
//			i_val += year.length;
//			if (year.length==2) {
//				if (year > 70) { year=1900+(year-0); }
//				else { year=2000+(year-0); }
//				}
//			}
//		else if (token=="MMM"||token=="NNN"){
//			month=0;
//			for (var i=0; i<MONTH_NAMES.length; i++) {
//				var month_name=MONTH_NAMES[i];
//				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
//					if (token=="MMM"||(token=="NNN"&&i>11)) {
//						month=i+1;
//						if (month>12) { month -= 12; }
//						i_val += month_name.length;
//						break;
//						}
//					}
//				}
//			if ((month < 1)||(month>12)){return 0;}
//			}
//		else if (token=="EE"||token=="E"){
//			for (var i=0; i<DAY_NAMES.length; i++) {
//				var day_name=DAY_NAMES[i];
//				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
//					i_val += day_name.length;
//					break;
//					}
//				}
//			}
//		else if (token=="MM"||token=="M") {
//			month=_getInt(val,i_val,token.length,2);
//			if(month==null||(month<1)||(month>12)){return 0;}
//			i_val+=month.length;}
//		else if (token=="dd"||token=="d") {
//			date=_getInt(val,i_val,token.length,2);
//			if(date==null||(date<1)||(date>31)){return 0;}
//			i_val+=date.length;}
//		else if (token=="hh"||token=="h") {
//			hh=_getInt(val,i_val,token.length,2);
//			if(hh==null||(hh<1)||(hh>12)){return 0;}
//			i_val+=hh.length;}
//		else if (token=="HH"||token=="H") {
//			hh=_getInt(val,i_val,token.length,2);
//			if(hh==null||(hh<0)||(hh>23)){return 0;}
//			i_val+=hh.length;}
//		else if (token=="KK"||token=="K") {
//			hh=_getInt(val,i_val,token.length,2);
//			if(hh==null||(hh<0)||(hh>11)){return 0;}
//			i_val+=hh.length;}
//		else if (token=="kk"||token=="k") {
//			hh=_getInt(val,i_val,token.length,2);
//			if(hh==null||(hh<1)||(hh>24)){return 0;}
//			i_val+=hh.length;hh--;}
//		else if (token=="mm"||token=="m") {
//			mm=_getInt(val,i_val,token.length,2);
//			if(mm==null||(mm<0)||(mm>59)){return 0;}
//			i_val+=mm.length;}
//		else if (token=="ss"||token=="s") {
//			ss=_getInt(val,i_val,token.length,2);
//			if(ss==null||(ss<0)||(ss>59)){return 0;}
//			i_val+=ss.length;}
//		else if (token=="a") {
//			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
//			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
//			else {return 0;}
//			i_val+=2;}
//		else {
//			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
//			else {i_val+=token.length;}
//			}
//		}
//	// If there are any trailing characters left in the value, it doesn't match
//	if (i_val != val.length) { return 0; }
//	// Is date valid for month?
//	if (month==2) {
//		// Check for leap year
//		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
//			if (date > 29){ return 0; }
//			}
//		else { if (date > 28) { return 0; } }
//		}
//	if ((month==4)||(month==6)||(month==9)||(month==11)) {
//		if (date > 30) { return 0; }
//		}
//	// Correct hours value
//	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
//	else if (hh>11 && ampm=="AM") { hh-=12; }
//	var newdate=new Date(year,month-1,date,hh,mm,ss);
//	return newdate.getTime();
//	}
//
//// ------------------------------------------------------------------
//// parseDate( date_string [, prefer_euro_format] )
////
//// This function takes a date string and tries to match it to a
//// number of possible date formats to get the value. It will try to
//// match against the following international formats, in this order:
//// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
//// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
//// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
//// A second argument may be passed to instruct the method to search
//// for formats like d/M/y (european format) before M/d/y (American).
//// Returns a Date object or null if no patterns match.
//// ------------------------------------------------------------------
//function parseDate(val) {
//	var preferEuro=(arguments.length==2)?arguments[1]:false;
//	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
//	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
//	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
//	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
//	var d=null;
//	for (var i=0; i<checkList.length; i++) {
//		var l=window[checkList[i]];
//		for (var j=0; j<l.length; j++) {
//			d=getDateFromFormat(val,l[j]);
//			if (d!=0) { return new Date(d); }
//			}
//		}
//	return null;
//	}



var Cookies = Class.create({
	initialize: function(path, domain){
		this.path = path || '/';
		this.domain = domain || null;
	},
	// Sets a cookie
	set: function(key, value, days){
		if (typeof key != 'string') {
			throw "Invalid key";
		}
		if (typeof value != 'string' && typeof value != 'number') {
			throw "Invalid value";
		}
		if (days && typeof days != 'number') {
			throw "Invalid expiration time";
		}
		var setValue = key + '=' + escape(new String(value));
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			var setExpiration = "; expires=" + date.toGMTString();
		}
		else 
			var setExpiration = "";
		var setPath = '; path=' + escape(this.path);
		var setDomain = (this.domain) ? '; domain=' + escape(this.domain) : '';
		var cookieString = setValue + setExpiration + setPath + setDomain;
		document.cookie = cookieString;
	},
	// Returns a cookie value or false
	get: function(key){
		var keyEquals = key + "=";
		var value = false;
		document.cookie.split(';').invoke('strip').each(function(s){
			if (s.startsWith(keyEquals)) {
				value = unescape(s.substring(keyEquals.length, s.length));
				throw $break;
			}
		});
		return value;
	},
	// Clears a cookie
	clear: function(key){
		this.set(key, '', -1);
	},
	// Clears all cookies
	clearAll: function(){
		document.cookie.split(';').collect(function(s){
			return s.split('=').first().strip();
		}).each(function(key){
			this.clear(key);
		}
		.bind(this));
	}
});

/**
 * deprecated
 */
//function unserialize(data){
//	// http://kevin.vanzonneveld.net
//	// +	 original by: Arpad Ray (mailto:arpad@php.net)
//	// +	 improved by: Pedro Tainha (http://www.pedrotainha.com)
//	// +	 bugfixed by: dptr1988
//	// +	  revised by: d3x
//	// +	 improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
//	// +		input by: Brett Zamir (http://brett-zamir.me)
//	// +	 improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
//	// +	 improved by: Chris
//	// +	 improved by: James
//	// %			note: We feel the main purpose of this function should be to ease the transport of data between php & js
//	// %			note: Aiming for PHP-compatibility, we have to translate objects to arrays
//	// *	   example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
//	// *	   returns 1: ['Kevin', 'van', 'Zonneveld']
//	// *	   example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
//	// *	   returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
//	
//	var error = function(type, msg, filename, line){
//		throw new this.window[type](msg, filename, line);
//	};
//	var read_until = function(data, offset, stopchr){
//		var buf = [];
//		var chr = data.slice(offset, offset + 1);
//		var i = 2;
//		while (chr != stopchr) {
//			if ((i + offset) > data.length) {
//				error('Error', 'Invalid');
//			}
//			buf.push(chr);
//			chr = data.slice(offset + (i - 1), offset + i);
//			i += 1;
//		}
//		return [buf.length, buf.join('')];
//	};
//	var read_chrs = function(data, offset, length){
//		var buf;
//		
//		buf = [];
//		for (var i = 0; i < length; i++) {
//			var chr = data.slice(offset + (i - 1), offset + i);
//			buf.push(chr);
//		}
//		return [buf.length, buf.join('')];
//	};
//	var _unserialize = function(data, offset){
//		var readdata;
//		var readData;
//		var chrs = 0;
//		var ccount;
//		var stringlength;
//		var keyandchrs;
//		var keys;
//		
//		if (!offset) {
//			offset = 0;
//		}
//		var dtype = (data.slice(offset, offset + 1)).toLowerCase();
//		
//		var dataoffset = offset + 2;
//		var typeconvert = new Function('x', 'return x');
//		
//		switch (dtype) {
//			case 'i':
//				typeconvert = function(x){
//					return parseInt(x, 10);
//				};
//				readData = read_until(data, dataoffset, ';');
//				chrs = readData[0];
//				readdata = readData[1];
//				dataoffset += chrs + 1;
//				break;
//			case 'b':
//				typeconvert = function(x){
//					return parseInt(x, 10) !== 0;
//				};
//				readData = read_until(data, dataoffset, ';');
//				chrs = readData[0];
//				readdata = readData[1];
//				dataoffset += chrs + 1;
//				break;
//			case 'd':
//				typeconvert = function(x){
//					return parseFloat(x);
//				};
//				readData = read_until(data, dataoffset, ';');
//				chrs = readData[0];
//				readdata = readData[1];
//				dataoffset += chrs + 1;
//				break;
//			case 'n':
//				readdata = null;
//				break;
//			case 's':
//				ccount = read_until(data, dataoffset, ':');
//				chrs = ccount[0];
//				stringlength = ccount[1];
//				dataoffset += chrs + 2;
//				
//				readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
//				chrs = readData[0];
//				readdata = readData[1];
//				dataoffset += chrs + 2;
//				if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
//					error('SyntaxError', 'String length mismatch');
//				}
//				break;
//			case 'a':
//				readdata = {};
//				
//				keyandchrs = read_until(data, dataoffset, ':');
//				chrs = keyandchrs[0];
//				keys = keyandchrs[1];
//				dataoffset += chrs + 2;
//				
//				for (var i = 0; i < parseInt(keys, 10); i++) {
//					var kprops = _unserialize(data, dataoffset);
//					var kchrs = kprops[1];
//					var key = kprops[2];
//					dataoffset += kchrs;
//					
//					var vprops = _unserialize(data, dataoffset);
//					var vchrs = vprops[1];
//					var value = vprops[2];
//					dataoffset += vchrs;
//					
//					readdata[key] = value;
//				}
//				
//				dataoffset += 1;
//				break;
//			default:
//				error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
//				break;
//		}
//		return [dtype, dataoffset - offset, typeconvert(readdata)];
//	};
//	return _unserialize((data + ''), 0)[2];
//}
