function $id(v) { return doc.getElementById(v); }
function $cls(v) { var n = doc.getElementsByTagName('body')[0], a = [], re = new RegExp('\\b' + v + '\\b'), es = n.getElementsByTagName('*'), i = es.length - 1; for(i; i >= 0; i--) { if(re.test(es[i].className)) { a.push(es[i]); } } return a; }
function $rel(v) { var n = doc.getElementsByTagName('body')[0], a = [], re = new RegExp('\\b' + v + '\\b'), es = n.getElementsByTagName('*'), i = es.length - 1; for(i; i >= 0; i--) { if(re.test(es[i].rel)) { a.push(es[i]); } } return a; }

function VSMulti() {
	var obj = this, ajax = new Ajax(), timer = new Timer(18), feature = new Feature(2, 150, 10, timer), ticker = new Ticker(16, 300, 996, timer), map = null, map_overlay_colour = 0;

	this.init_calls = function() { var calls = $rel('call'), c = calls.length - 1; for(c; c >= 0; c--) { calls[c].onclick = obj.call; } }
	this.call = function() { var func = this.rel.split('|')[1]; return obj[func](this.name.split('|')[0], this.name.split('|')[2], this.name.split('|')[1], this.href.split('order=')[1]); };
	this.order_gallery = function(site, catorloc, clid, order) { var sorts = $cls('sort')[0].getElementsByTagName('a'), a = sorts.length - 1; for(a; a >= 0; a--) { sorts[a].className = sorts[a].className.replace('active', ''); if(sorts[a].href.indexOf(order) != -1) { sorts[a].className += ' active'; } } ajax.call('/dat/ajax.php?action=list_escorts&' + catorloc + '=' + clid + '&site=' + site + '&order=' + order, obj.display_gallery); return false; }
	this.display_gallery = function(r) { var gallery = $cls('gallery')[0]; if((gallery) && (r)) { gallery.innerHTML = r; } return false; }

	this.init_toggles = function() { var toggles = $cls('toggle'), c = toggles.length - 1; for(c; c >= 0; c--) { toggles[c].onclick = obj.toggle; } }
	this.toggle = function() { var el = $id(this.rel.split('|')[0]), cls = this.rel.split('|')[1]; if(el.className.indexOf(cls) == -1) { el.className += ' ' + cls; } else { el.className = el.className.replace(cls, ''); } return false; }

	this.init_externals = function() { var externals = $rel('external'), l = externals.length - 1; for(l; l >= 0; l--) { externals[l].onclick = function() { this.target = '_blank'; return true; } } return false; }
	this.init_review_ratings = function() {
		var anchors = $cls('review_meter'), a = anchors.length - 1;
		for(a; a >= 0; a--) {
			anchors[a].onclick = function() {
				var review_rating = this.parentNode, x = 5;
				for(x; x >= 1; x--) { review_rating.className = review_rating.className.replace('rating_' + x, ''); }
				review_rating.className += ' rating_' + this.rel;
				review_rating.parentNode.getElementsByTagName('input')[0].value = this.rel;
				return false;
			}
		}
		return false;
	}

	this.initMap = function(mapID, z, type, overlaycolour, overlayalpha) {
		var myOptions = { zoom: z, mapTypeId: type };
		obj.map = new google.maps.Map(document.getElementById(mapID), myOptions);
		obj.map_overlay_colour = overlaycolour; obj.map.overlay_alpha = overlayalpha;
		return false;
	}

	this.addMapMarker = function(lat, lng, radius) {
		var latlng = new google.maps.LatLng(lat, lng);
		obj.map.setCenter(latlng);
		var marker = new google.maps.Marker({ map: obj.map, position: latlng });
		if(radius > 0) {
			obj.addOverlayToMarker(marker, radius);
		}
		return false;
	}

	this.addOverlayToMarker = function(marker, radius) {
		var circle = new google.maps.Circle({ map: obj.map, strokeWeight: 0, fillColor: obj.map_overlay_colour, fillOpacity: obj.map.overlay_alpha / 100, radius: radius * 1000 });
		circle.bindTo('center', marker, 'position');
	}

	this.init_bookmarker = function() {
		var bookmark = $id('bookmark');
		if(bookmark) { bookmark.onclick = function() {
			if(window.sidebar) { window.sidebar.addPanel(this.title, this.href, ""); } else if(window.opera && window.print) { var elem = document.createElement('a'); elem.setAttribute('href', this.href); elem.setAttribute('title', this.title); elem.setAttribute('rel', 'sidebar'); elem.click(); } else if(document.all) { window.external.AddFavorite(this.href, this.title); }
			return false;
		}; }
		return false;
	}

	this.init_calls(); this.init_toggles(); this.init_bookmarker(); this.init_externals(); this.init_review_ratings();
}

// --- Class: Timer ---
function Timer(interval) {
	var obj = this;
	this.interval = interval; this.timer = null; this.todoList = [];

	this.start = function() { clearTimeout(obj.timer); obj.timer = setTimeout(obj.run, obj.interval); return false; }

	this.addTodo = function(func, interval, length) {
		var todo = [ func, interval, length, 0 ];
		this.todoList.push(todo);
		return false;
	};

	this.run = function() {
		var debug = $id('debug'), l = obj.todoList.length - 1, toSplice = [];

		for(l; l >= 0; l--) {
			if(obj.todoList[l][3] > 0) {
				obj.todoList[l][3]--;
			} else {
				if((obj.todoList[l][2] > 0) || (obj.todoList[l][2] == -1)) {
					//debug.innerHTML += 'ticks: ' + obj.todoList[l][3] + ' - func: ' + obj.todoList[l][0] + ' interval: ' + obj.todoList[l][1] + ' length: ' + obj.todoList[l][2];
					var c = setTimeout(obj.todoList[l][0], 0);
				} else {
					toSplice.push(l);
				}
				obj.todoList[l][3] = obj.todoList[l][1];
				if(obj.todoList[l][2] != -1) { obj.todoList[l][2]--; }
			}
		}
		
		var l = toSplice.length - 1;
		for(l; l >= 0; l--) {
			obj.todoList.splice(toSplice[l], 1);
		}
		obj.start();
	}

	this.start();
}

// --- Class: Ticker ---
function Ticker(inc, pause, li_width, timer) {
	var obj = this;
	this.div = $id('ticker'); this.lis = null; this.inc = inc; this.w = li_width; this.pauseMode = pause; this.pauseTime = pause; this.timer = timer;

	this.init = function() {
		if(obj.div) {
			obj.lis = obj.div.getElementsByTagName('li'); var l = obj.lis.length - 1;
			if(l > 1) {
				for(l; l >= 0; l--) { obj.lis[l].style.position = 'absolute'; obj.lis[l].style.top = '0'; obj.lis[l].style.left = (l * obj.w) + 'px'; }
				obj.timer.addTodo(obj.anim, 1, -1);
			}
		}
		return false;
	}

	this.anim = function() {
		var l = obj.lis.length - 1, intLeft = 0, t_width = obj.w, newLeft = 0;
		if(obj.pauseMode == 0) {
			for(l; l >= 0; l--) {
				intLeft = parseInt(obj.lis[l].style.left);
				newLeft = (intLeft - obj.inc) + 'px';
				if(((intLeft - obj.inc) > 0) && ((intLeft - obj.inc) <= obj.inc)) { obj.pauseMode = obj.pauseTime; }
				if(intLeft < -t_width) { newLeft = (obj.w * (obj.lis.length - 1)) + 'px'; }
				obj.lis[l].style.left = newLeft;
			}
		} else {
			obj.pauseMode--;
		}
		return false;
	}
	this.init();
}

// --- Class: Feature ---
function Feature(inc, li_width, li_margin, timer) {
	var obj = this;
	this.div = $id('feature'); this.lis = null; this.inc = inc; this.w = li_width; this.m = li_margin; this.timer = timer;

	this.init = function() {
		if(obj.div) {
			obj.lis = obj.div.getElementsByTagName('li'); var l = obj.lis.length - 1;
			for(l; l >= 0; l--) { obj.lis[l].style.position = 'absolute'; obj.lis[l].style.top = '0'; obj.lis[l].style.left = ((l * obj.w) + obj.m) + 'px'; }
			obj.timer.addTodo(obj.anim, 3, -1);
		}
		return false;
	}

	this.anim = function() {
		var l = obj.lis.length - 1, intLeft = 0, t_width = obj.w + obj.m;
		for(l; l >= 0; l--) {
			intLeft = parseFloat(obj.lis[l].style.left);
			obj.lis[l].style.left = (intLeft - obj.inc) + 'px';
			if(intLeft < -t_width) { obj.lis[l].style.left = (obj.w * (obj.lis.length - 1)) + 'px'; }
		}
		return false;
	}
	this.init();
}

// --- Class: Ajax ---

function Ajax() {
	var obj = this; this.http = new XMLHttpRequest();

	this.call = function(url, func) {
		obj.http.open('GET', url, true);
		obj.http.send(null);
		obj.http.onreadystatechange = function() { if((this.readyState === 4) && (this.status === 200)) { return (func) ? func(this.responseText) : false; } };
	};
}

var doc = document, vsMulti = new VSMulti();
