
/*
	Creates a popup on demand, based on a template and an object containing data for the popup.
	Positions based on mouse position, unless a set position is specified.
	Callback is called as callback(d) where d is the div element containing the popup
*/

function PopupMaker(callback, pos, fadeId){
	this.defPos = pos && pos[0] && pos[1] ? pos : [200,100];
	this.d = null;
	this.callback = callback || function(){};
	this.fadeId = fadeId;
};

PopupMaker.prototype.init = function(){

};

PopupMaker.prototype.setPaths = function(template){
	this.template = template;
};

// makes the popup
PopupMaker.prototype.build = function(data, e){
	
	//console.log(data);
	
	// kill existing popup
	if (this.d)
		this.destroy();
	
	// get desired position for popup
	if (e && e.clientX && e.clientY)
		e = [e.clientX, e.clientY];
	else if (!e || !e[0] || !e[1])
		e = this.defPos;
	
	// make the container
	this.d = document.createElement('div');
	this.d.style.visibility = 'hidden';
	this.d.style.zIndex = 9999;
	this.d.style.position = 'absolute';
	this.d.className = 'popup';
	
	// fill container
	this.d.innerHTML = this.parseText(this.template, data.id ? data.id : '', data);

	// show fadeLayer
	if (this.fadeId)
		$(this.fadeId).style.display = 'block';

	// add to page
	document.body.appendChild(this.d);
	
	
	// position container (must be done after adding to page)
	var	vp = domProperties.viewportDim(),
			el = domProperties.elementDim(this.d);
	
	// make sure its not overlapping the edge of the page
	e[0] = e[0] - Math.max(0, (el.x + e[0] + 10 - vp.x));
	e[1] = e[1] - Math.max(0, (el.y + e[1] + 10 - vp.y));
	
	this.d.style.left = e[0] + 'px';
	this.d.style.top = e[1] + 'px';
	
	
	// add events
	this.addEvents(this.d);
	
	// apply callback function
	this.callback(this.d);
	
	// display
	this.d.style.visibility = 'visible';
};

// removes the popup
PopupMaker.prototype.destroy = function(){
	if (this.d){
		document.body.removeChild(this.d);
		this.d = null;
	}
	// hide fadeLayer
	if (this.fadeId)
		$(this.fadeId).style.display = 'none';

};






// PRIVATE

// adds events to elements that have the 'popup_event' attribute. Events are listed in the switch statement- just 'close' to start with
PopupMaker.prototype.addEvents = function(node){
	var els = node.getElementsByTagName('*'), i, il, events, event, f, that = this;
	for (i = 0, il = els.length; i< il; i++){
		if (event = els[i].getAttribute('popup_event')){
			event = event.split(';');
			for (var j = 0; j < event.length; j++){
				event[j] = event[j].split('|');
				switch(event[j][1]){
					case 'close':
						f = function(){ that.destroy() };
					break;
				}
				if (f)
					addEvent(els[i], event[j][0], f);
			}
		}
	}
};






// tags for building regex- NOTE: regexp special chars must be *double escaped*
PopupMaker.prototype.tags = {
	'sTag' : "\\{\\{",
	'eTag' : "\\}\\}",
	'sCond' : "\\(\\(\\(",
	'eCond' : "\\)\\)\\)",
	'alt' : "\\(\\?\\)",
	'sep' : "\\(\\:\\)"
};

PopupMaker.prototype.parseText = function(t,id,data){

	//if (!data){
	//	alert(t + ' ' + id);
	//}

	// parse for conditionals
	var regExp = new RegExp(this.tags.sCond + "([^(?:" + this.tags.alt + ")]*)" + this.tags.alt + "(.*?)" + this.tags.sep + "(.*?)" + this.tags.eCond, "g");
	t = String(t).replace(regExp,function(s,c,t,f){with(data) return eval(c) ? t : f;});
	
	// parse for id
	t = t.replace(new RegExp(this.tags.sTag + 'id' + this.tags.eTag, "g"),id);

	// parse for variables
	for (i in data){
		regExp = new RegExp(this.tags.sTag + i + this.tags.eTag, "g");
		t = t.replace(regExp,data[i]);
	}
	return t;	
};