/* Facebook tagger
   (C) 2007-2010 Thomas Winischhofer, Vienna, Austria
*/

var FBTags = {
	fbtgs: [],
	observer: [],

	register: function(fbtaghandler) {
		if(this.fbtgs.length == 0) {
			this.eventMouseUp   = this.endfbtag.bindAsEventListener(this);
			this.eventMouseMove = this.dohandlefbtag.bindAsEventListener(this);
			Event.observe(document, "mouseup", this.eventMouseUp);
			Event.observe(document, "mousemove", this.eventMouseMove);
		}
		this.fbtgs.push(fbtaghandler);
	},

	unregister: function(fbtaghandler) {
		this.fbtgs = this.fbtgs.reject(function(s) { return s==fbtaghandler });
		if(this.fbtgs.length == 0) {
			Event.stopObserving(document, "mouseup", this.eventMouseUp);
			Event.stopObserving(document, "mousemove", this.eventMouseMove);
		}
	},

	activate: function(fbtaghandler) {
		this.activeFBTagHandler = fbtaghandler;
	},

	deactivate: function() {
		this.activeFBTagHandler = null;
	},

	endfbtag: function(event) {
		if(!this.activeFBTagHandler) return;
		this._lastPointer = null;
		this.activeFBTagHandler.endfbtag(event);
		this.activeFBTagHandler = null;
	},

	dohandlefbtag: function(event) {
		if(!this.activeFBTagHandler) return;
		//if (this.activeFBTagHandler.showcoords) {
		//	document.getElementById(this.activeFBTagHandler.showcoords).innerHTML = Event.pointerX(event) + "x" + Event.pointerY(event);
		//}
		var pointer = [Event.pointerX(event), Event.pointerY(event)];
		// Mozilla-based browsers fire successive mousemove events with
		// the same coordinates, prevent needless redrawing (moz bug?)
		if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
		this._lastPointer = pointer;
		this.activeFBTagHandler.dohandlefbtag(event);
	}
}

var FBTagHandlers = Class.create();

FBTagHandlers.prototype = {

initialize: function(myelementid, containerid, phototags, options) {
	var fbtaghandler = this;

	if(this.initialized) {
		this.dispose();
	}

	this.myelementid = myelementid;

	this.myelement = document.getElementById(myelementid);
	this.container = document.getElementById(containerid);

	this.options = options || {};

	this.imgw = this.options.iwidth || this.myelement.offsetWidth;
	this.imgh = this.options.iheight || this.myelement.offsetHeight;

	this.maskid = this.options.mask || this.myelementid + '_mask';

	this.fbtagimageid = this.options.fbtag || this.myelementid + '_fbtag';

	this.imgsrc = this.myelement.src;
	this.fbtag = null;
	this.curroffsx = 0;
	this.curroffsy = 0;
	this.startcoords = null;
	this.startleft = 0;
	this.starttop = 0;
	this.layercoords = null;
	this.oldabscoords = { x: 0, y: 0 };
	this.newabscoords = null;

	this.pevent = {};

	this.onChange = this.options.onChange || Prototype.emptyFunction;

	this.ns6 = document.getElementById && !document.all;
	this.ie = document.all;

	this.eventMouseDown = this.newfbtag.bindAsEventListener(this);
	this.eventMouseUp   = this.endfbtag.bindAsEventListener(this);
	this.eventMouseDown2 = this.startmovefbtag.bindAsEventListener(this);
	this.eventOnClick = this.updatefbtag.bindAsEventListener(this);
	
	this.ptags = phototags || "";
	
	this.eventMouseOver = this.showtags.bindAsEventListener(this);
	this.eventMouseOut = this.hidetags.bindAsEventListener(this);
	
	this.offsetxpoint=-20;
	this.offsetypoint=25;
	this.enabletip=false;
	if (this.ie || this.ns6) {
		this.tipobj = document.all ? document.all["phototagdiv"] : document.getElementById ? document.getElementById("phototagdiv") : "";
	}

	if(this.imgw > 0) {
		this.initfbtag();
		this.fbtagimage =  document.getElementById(this.fbtagimageid);
		Event.observe(this.fbtagimage, "mousedown", this.eventMouseDown2);

		this.init();
		this.initialized = true;

	} else {
		this.eventOnLoad = this.myonload.bindAsEventListener(this);
		/* Event.observe(window, "load", this.eventOnLoad); */
		Event.observe(document.getElementById(myelementid), "load", this.eventOnLoad);
	}

	Event.observe(this.container, "mousedown", this.eventMouseDown);
	Event.observe(this.container, "mouseup", this.eventMouseUp);
	Event.observe(this.container, "click", this.eventOnClick);
	
	Event.observe(this.myelement, "mousemove", this.eventMouseOver);
	Event.observe(this.myelement, "mouseout", this.eventMouseOut);

	Event.observe(window, 'unload', Event.unloadCache, false);

	FBTags.register(this);
},

myonload: function(event) {
	this.imgw = this.myelement.offsetWidth;
	this.imgh = this.myelement.offsetHeight;

	this.initfbtag();
	this.fbtagimage =  document.getElementById(this.fbtagimageid);
	Event.observe(this.fbtagimage, "mousedown", this.eventMouseDown2);

	this.init();

	this.initialized = true;
},

destroy: function() {
	var fbtaghandler = this;
	Event.stopObserving(this.container, "mousedown", this.eventMouseDown);
	Event.stopObserving(this.container, "mouseup", this.eventMouseUp);
	Event.stopObserving(this.fbtagimage, "mousedown", this.eventMouseDown2);
	Event.stopObserving(this.container, "click", this.eventOnClick);

	Event.stopObserving(this.myelement, "mousemove", this.eventMouseOver);
	Event.stopObserving(this.myelement, "mouseout", this.eventMouseOut);

	Event.stopObserving(window, "unload", Event.unloadCache);
	if(this.eventOnLoad) {
		Event.stopObserving(window, "load", this.eventOnLoad);
	}
	FBTags.unregister(this);
},

iebody: function () {
	return (document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body
},

getcoordX: function(event) {
	var clientX;
	if(event.pseudo) {
		clientX = event.clientX;
	} else {
		clientX = (this.ns6) ? event.pageX : event.clientX + this.iebody().scrollLeft;
	}
	return clientX;
},

getcoordY: function(event) {
	var clientY;
	if(event.pseudo) {
		clientY = event.clientY;
	} else {
		clientY = (this.ns6) ? event.pageY : event.clientY + this.iebody().scrollTop;
	}
	return clientY;
},

getScrollingPosition: function() {
	var position=[0,0];
	if (typeof window.pageYOffset != 'undefined') {
		position = [window.pageXOffset,window.pageYOffset];
	} else if (typeof document.documentElement.scrollTop != 'undefined' && document.documentElement.scrollTop > 0) {
		position = [document.documentElement.scrollLeft,document.documentElement.scrollTop];
	} else if (typeof document.body.scrollTop != 'undefined') {
		position = [document.body.scrollLeft,document.body.scrollTop];
	}
	return position;
},

getViewportSize: function() {
	var size=[0,0];
	if (typeof window.innerWidth != 'undefined') {
		size = [window.innerWidth,window.innerHeight];
	} else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0){
		size = [document.documentElement.clientWidth,document.documentElement.clientHeight];
	} else {
		size = [document.getElementsByTagName('body')[0].clientWidth,document.getElementsByTagName('body')[0].clientHeight];
	}
	return size;
},

positiontag: function(e) {
	if (this.enabletip) {
		var viewportSize = getViewportSize(); 
		var scrollPos = getScrollingPosition();
		var curPos = [0, 0];
		curPos[0] = (this.ns6) ? e.pageX : event.clientX + scrollPos[0];
		curPos[1] = (this.ns6) ? e.pageY : event.clientY + scrollPos[1];

		var leftedge = (offsetxpoint < 0) ? offsetxpoint*(-1) : -1000;

		if (curPos[0] - scrollPos[0] + offsetxpoint + this.tipobj.offsetWidth > viewportSize[0] - 20)
 			this.tipobj.style.left = scrollPos[0] + viewportSize[0] - 20 - this.tipobj.offsetWidth + "px";
		else if (curPos[0] < leftedge)
 			this.tipobj.style.left = "5px";
		else
 			this.tipobj.style.left = curPos[0]+offsetxpoint+"px";

		if (curPos[1] - scrollPos[1] + offsetypoint + this.tipobj.offsetHeight > viewportSize[1] - 20)
 			this.tipobj.style.top = curPos[1] - this.tipobj.offsetHeight - offsetypoint+"px";
		else
 			this.tipobj.style.top = curPos[1] + offsetypoint+"px";

		this.tipobj.style.visibility="visible";
	}
},

showfbtag: function(mytext) {
	if (this.ns6 || this.ie) {
		this.tipobj.innerHTML = mytext;
		this.enabletip = true;
	}
},

hidefbtag: function() {
	if (this.ns6 || this.ie) {
		this.enabletip = false;
		this.tipobj.style.visibility = "hidden";
		this.tipobj.style.left="-1000px";
		this.tipobj.style.backgroundColor = '';
		this.tipobj.style.width = '';
	}
},

updatefbtag: function(event) {
	if(event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
	if(event.stopPropagation) {
		event.stopPropagation();
	} else {
		event.cancelBubble = true;
	}
	return false;
},

newfbtag: function(event) {
	if(event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
	if(event.stopPropagation) {
		event.stopPropagation();
	} else {
		event.cancelBubble = true;
	}
	
	this.hidefbtag();

	// Prevent caching issues: Re-do the mask in case the image dimensions have changed
	if(this.imgw != this.myelement.offsetWidth || this.imgh != this.myelement.offsetHeight) {
		this.imgw = this.myelement.offsetWidth;
		this.imgh = this.myelement.offsetHeight;
		this.imgsrc = this.myelement.src;
		var themask = document.getElementById(this.maskid);
		if(!themask) {
			// panic --- what happended?? not intialized???
			this.initfbtag();
			this.fbtagimage =  document.getElementById(this.fbtagimageid);
			Event.observe(this.fbtagimage, "mousedown", this.eventMouseDown2);
			this.init();
			this.initialized = true;
			themask = document.getElementById(this.maskid);
		}
		themask.style.width = this.fbtagimage.style.width = this.imgw + "px";
		themask.style.height = this.fbtagimage.style.height = this.imgh + "px";
	}

	if(this.fbtag.getvisible() != "visible") {
		var x;
		var y;
		var clientX = this.getcoordX(event);
		var clientY = this.getcoordY(event);
		if(!document.all && event.layerX) {
			x = event.layerX;
			y = event.layerY;
		} else {
			x = event.offsetX;
			y = event.offsetY;
		}
		this.oldabscoords.x = clientX;
		this.oldabscoords.y = clientY;
		this.newabscoords = {x: clientX, y: clientY};
		this.layercoords  = {x: x + 1, y: y + 1};
		this.fbtag.draw(x, y, Math.max(this.imgw, this.imgh) / 4, this.imgw, this.imgh);
		
		var themask = document.getElementById(this.maskid);
		themask.style.visibility = "visible";
		
		this.startcoords = {x: clientX, y: clientY};
		this.startleft = this.fbtag.getLeft();
		this.starttop = this.fbtag.getTop();
		this.fbtag.drag = true;
	}

	FBTags.activate(this);

	return false;
},

endfbtag: function(event) {
	if(event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
	if(event.stopPropagation) {
		event.stopPropagation();
	} else {
		event.cancelBubble = true;
	}
	var themask = document.getElementById(this.maskid);

	if(!document.all) {
		targetid = event.target.id;
	} else {
		targetid = event.srcElement.id;
	}

	if(this.fbtag.track) {
		var clientX = this.getcoordX(event);
		var clientY = this.getcoordY(event);
		
		themask.style.visibility = "visible";
		this.fbtag.setcursor("default");

		this.oldabscoords.x = clientX;
		this.oldabscoords.y = clientY;
		
	} else if(this.fbtag.resize) {

	} else if(targetid == this.maskid || targetid == this.myelementid) {
		this.init();
	}

	this.fbtag.drag = false;
	this.fbtag.track = false;
	themask = null;

	this.updatefinished();

	FBTags.deactivate(this);
	
	this.hidefbtag();

	return false;
},

dohandlefbtag: function(event) {
	var clientX = this.getcoordX(event);
	var clientY = this.getcoordY(event);
	if(this.fbtag.track || this.fbtag.drag) {
		if(event.preventDefault) {
			event.preventDefault();
		} else {
			event.returnValue = false;
		}
		this.pevent.clientX = clientX;
		this.pevent.clientY = clientY;
		this.pevent.pseudo = true;
		if(this.fbtag.drag) {
			this.dragfbtag(this.pevent);
		} 
	}
	this.oldabscoords.x = clientX;
	this.oldabscoords.y = clientY;

	return false;
},

startmovefbtag: function(event) {
	if(event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
	var clientX = this.getcoordX(event);
	var clientY = this.getcoordY(event);
	this.startcoords = {x: clientX, y: clientY};
	this.startleft = this.fbtag.getLeft();
	this.starttop = this.fbtag.getTop();
	this.fbtag.drag = true;
	return false;
},

dragfbtag: function(event) {
	var clientX = this.getcoordX(event);
	var clientY = this.getcoordY(event);
	var left = this.startleft + clientX - this.startcoords.x;
	var top = this.starttop + clientY - this.startcoords.y;
	var width = this.fbtag.getWidth();
	var height = this.fbtag.getHeight();

	if(left < (-(width / 2))) left = -(width / 2);

	if(top < -(height / 2)) top = -(height / 2);
	
	var maxright = this.imgw - (width / 2) - left;
	if(maxright < 0) left += maxright;
	
	var maxbottom = this.imgh - (height / 2) - top;
	if(maxbottom < 0) top += maxbottom;

	this.fbtag.dragto(left, top);
},


initfbtag: function() {
	this.fbtag = {
		left:		undefined,
		top:		undefined,
		width: 		undefined,
		height:		undefined,
		idLeft: 	"js_fbtagleft",
		idTop:		"js_fbtagtop",
		idRight:	"js_fbtagright",
		idBottom:	"js_fbtagbottom",
		idMid:	"js_fbtagmiddle",
		visible:	false,
		myparent:	this
	};
	
	this.hidefbtag();

	var left = document.createElement("div");
	var right = document.createElement("div");
	var top = document.createElement("div");
	var bottom = document.createElement("div");
	
	top.className = "fbthor";
	bottom.className = "fbthor";
	left.className = "fbtver";
	right.className = "fbtver";
	
	left.id = this.fbtag.idLeft;
	right.id = this.fbtag.idRight;
	top.id = this.fbtag.idTop;
	bottom.id = this.fbtag.idBottom;

	this.container.appendChild(top);
	this.container.appendChild(bottom);
	this.container.appendChild(left);
	this.container.appendChild(right);
	
	var mid = document.createElement("div");
	mid.className = "fbtmid";
	mid.id = this.fbtag.idMid;
	this.container.appendChild(mid);

	var mask = document.createElement("div");
	mask.id = this.maskid;
	mask.className = "image_fbmask";
	mask.style.width = this.imgw + "px";
	mask.style.height = this.imgh + "px";
	this.container.appendChild(mask);

	var image = document.createElement("img");
	image.id = this.fbtagimageid;
	image.className = "image_fbtag";
	image.src = this.imgsrc;
	image.style.width = this.imgw + "px";
	image.style.height = this.imgh + "px";
	this.container.appendChild(image);

	this.fbtag.reset = function() {
		this.left = undefined;
		this.top = undefined;
		this.width = undefined;
		this.height = undefined;
		this.setvisible("hidden");
		this.setcursor("crosshair");
		this.track = false;
		this.drag = false;
	};

	this.fbtag.draw = function(left, top, imgwidth, imgw, imgh) {
		this.width = width = this.height = height = imgwidth;
		this.left = left = left - (width / 2);
		this.top =  top = top - (height / 2);
		
		var clip = "rect(" + top + "px, " + (left + width) + "px, " + (top + height) + "px, " + left + "px)";
		this.myparent.fbtagimage.style.clip = clip;
	
		var dtop = document.getElementById(this.idTop);
		var dbottom = document.getElementById(this.idBottom);
		var dleft = document.getElementById(this.idLeft);
		var dright = document.getElementById(this.idRight);
		
		dleft.style.left = left + "px";
		dright.style.left = (left + width - 1) + "px";
		dtop.style.left = left + "px";
		dbottom.style.left = left + "px";

		dleft.style.top = top + "px";
		dright.style.top = top + "px";
		dtop.style.top = top + "px";
		dbottom.style.top = (top + height - 1) + "px";

		dleft.style.height = height + "px";
		dright.style.height = height + "px";
		dtop.style.width = width + "px";
		dbottom.style.width = width + "px";
		
		var dmid = document.getElementById(this.idMid);
		dmid.style.left = left + "px";
		dmid.style.top = top + "px";
		dmid.style.height = height + "px";
		dmid.style.width = width + "px";
		
		this.setvisible("visible");

		dleft = null;
		dtop = null;
		dright = null;
		dbottom = null;
		dmid = null;

		blkw = 6;
		if(width < 6) blkw = width;
		blkh = 6;
		if(height < 6) blkw = height;

	};

	this.fbtag.dragto = function(left, top) {
		this.left = left;
		this.top = top;
		var width = this.getWidth();
		var height = this.getHeight();

		var dl = document.getElementById(this.idLeft);
		var dr = document.getElementById(this.idRight);
		var dt = document.getElementById(this.idTop);
		var db = document.getElementById(this.idBottom);

		dl.style.left = left + "px";
		dr.style.left = left + width - 1 + "px";
		dt.style.left = left + "px";
		db.style.left = left + "px";

		dl.style.top = top + "px";
		dr.style.top = top + "px";
		dt.style.top = top + "px";
		db.style.top = top + height - 1 + "px";
		
		var dm = document.getElementById(this.idMid);
		dm.style.left = left + "px";
		dm.style.top = top + "px";
		dm = null;
		
		var myclip = "rect(" + top + "px, " + (left + width) + "px, " + (top + height) + "px, " + left + "px)";
		this.myparent.fbtagimage.style.clip = myclip;
		
		dl = null;
		dt = null;
		dr = null;
		db = null;
	};

	this.fbtag.setLeft = function(left) {
		this.left = left;
	};
	this.fbtag.getLeft = function() {
		return this.left;
	};

	this.fbtag.setTop = function(top) {
		this.top = top;
	};
	this.fbtag.getTop = function() {
		return this.top;
	};

	this.fbtag.setWidth = function(width) {
		this.width = width;
	};
	this.fbtag.getWidth = function() {
		return this.width;
	};

	this.fbtag.setHeight = function(height) {
		this.height = height;
	};
	this.fbtag.getHeight = function() {
		return this.height;
	};

	this.fbtag.setvisible = function(vis) {
		document.getElementById(this.idTop).style.visibility = vis;
		document.getElementById(this.idLeft).style.visibility = vis;
		document.getElementById(this.idRight).style.visibility = vis;
		document.getElementById(this.idBottom).style.visibility = vis;
		document.getElementById(this.idMid).style.visibility = vis;
		document.getElementById(this.myparent.fbtagimageid).style.visibility = vis;
		this.visibility = vis;
	};
	this.fbtag.getvisible = function() {
		return this.visibility;
	};

	this.fbtag.setcursor = function(cursor) {
		document.getElementById(this.idTop).style.cursor = cursor;
		document.getElementById(this.idLeft).style.cursor = cursor;
		document.getElementById(this.idRight).style.cursor = cursor;
		document.getElementById(this.idBottom).style.cursor = cursor;
		document.getElementById(this.myparent.fbtagimageid).style.cursor = cursor;
	};

},

init: function() {
	themask = document.getElementById(this.maskid);
	if(themask) {
		document.getElementById(this.maskid).style.visibility = "hidden";
	}
	this.layercoords = null;
	this.newabscoords = null;
	if(this.fbtag) {
		this.fbtag.reset();
	}
},

showtags: function(event) {
	if(event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
	
	if (this.ptags.length == 0) {
		this.hidefbtag();
		return; 
	}
	
	if(!document.all && event.layerX) {
		x = event.layerX;
		y = event.layerY;
	} else {
		x = event.offsetX;
		y = event.offsetY;
	}
	
	tags = "";
	
	for(i=0; i<this.ptags.length; i++) {
		if (x >= this.ptags[i][0] && y >= this.ptags[i][1] && x <= this.ptags[i][2] && y <= this.ptags[i][3]) {
			if (tags.length > 0) tags = tags + "; ";
			tags = tags + this.ptags[i][4];
		}
	}
	
	if (tags.length > 0) {
		this.showfbtag(tags);
	} else {
		this.hidefbtag();
	}
	
	this.positiontag(event);
},

hidetags: function(event) {
	this.hidefbtag();
},

updatefinished: function() {
	if(this.initialized && this.onChange)  {
		tempw = Math.max(this.imgw, this.imgh) / 4;
		myleft = this.fbtag.left + (tempw / 2);
		if (myleft > 0) myleft = myleft / (this.imgw / 100);
	 	mytop = this.fbtag.top + (tempw / 2);
		if (mytop > 0) mytop = mytop / ( this.imgh / 100);
		if (isNaN(myleft) || isNaN(mytop)) { myleft = mytop = -1; }
		this.onChange(myleft, mytop);
	}
	this.event = null;
} 

};





