/** Click on an image - get a silly box
 * 
 * @requires common.js, prefindex.js,tag_searchbox.js
 * @version 1.0 24/02/2008
 * @author Erick S <esatire at gmail dot com>
 * 
 * TODO: Make it work :)
 */

/** Statics */
ImagePointer.MARKER_BORDERWIDTH = 3;
ImagePointer.CONTAINER_BORDERWIDTH = 2;
ImagePointer.CONTAINER_PADDING = 2;
/** Both padding and border width - for internal calculations */
ImagePointer.CONTAINER_TOTALPAD = 4;
/** Size of marker box compared to whole image. Higher ratio means smaller dimensions */
ImagePointer.MARKER_RATIO = 4;

/** Constructor
 * 
 * @param {string} elementId The DOM object that contains the image
 * @param {array} items Each item contains [0]->id and [1]->name. First item must be the User! 
 */
function ImagePointer(elementId,items)
{
	var me = this;

	this.element = document.getElementById(elementId);
	this.element.style.borderWidth = ImagePointer.CONTAINER_BORDERWIDTH + 'px';
	this.element.style.padding = ImagePointer.CONTAINER_PADDING + 'px';

	this.boxIsSet = false;
	this.items = items; // We don't index it YET
	this.limits = new Object(); // Marker positioning limits
	
	/** For internal use - Needs to be created before assignments */
	this._setRectangle = function(evt)
	{
		(window.event) ? window.event.cancelBubble=true : evt.cancelBubble=true;
		var pos = getEventPos(evt);
		// Pos marks the center of the marker, not top left
		// Also, in order to be compatible with manual setRectangle, we remove the image offsets.
		pos.x -= Math.floor(me.marker.offsetWidth/2) + me.limits.l;
		pos.y -= Math.floor(me.marker.offsetHeight/2) + me.limits.t;
		ImagePointer.prototype.setRectangle.call(me,pos.x,pos.y,null,null,true);
	}
	/** 
	 * Activates tagging
	 * Warning: Overwrites some event handlers
	 */
	this.enable = function()
	{
		// Assign our own event handlers
		document.documentElement.onmousedown = this.docHide;
		this.element.onclick = this._setRectangle;
		this.element.style.cursor = 'crosshair';
		// If enabled for the first time - prepare the search widget
		if (ImagePointer.prototype.friendsContainer == null)
		{
			ImagePointer.prototype.friendsContainer = document.createElement('DIV');
			this.friendsContainer.id = "ImagePointerFriendsContainer";
			document.body.appendChild(this.friendsContainer);
			ImagePointer.prototype.searchWidget = new TagSearchBox("ImagePointerFriendsContainer",this.items,32,null);
			this.items = null; delete(this.items);
		}
	}
	/** Disables tagging */
	this.disable = function()
	{
		this.element.onclick = null;
		this.element.style.cursor = 'auto';
		document.documentElement.onmousedown = null;
	}
	/** Calculates important dimension properties - required if page layout changes */
	this.calcDimensions = function()
	{
		var offset = getRealOffset(this.element);
		var diff = ImagePointer.CONTAINER_TOTALPAD - ImagePointer.MARKER_BORDERWIDTH;
		this.limits.l = offset.x + diff;
		this.limits.t = offset.y + diff;
		this.limits.r = offset.x + this.element.offsetWidth - diff;
		this.limits.b = offset.y + this.element.offsetHeight - diff;
		// console.log(this.limits.t + ' ' + this.limits.r + ' ' + this.limits.b + ' ' + this.limits.l);
	}

	/** When active - Document element click will hide the marker box */
	this.docHide = function(evt)
	{
		var target = getEventTarget(evt);
		if (target == me.element || target == me.friendsContainer || target.parentNode == me.friendsContainer)
		{
			return;
		}
		me.hideAll();
	}
	// initial dimension calculation
	this.calcDimensions();
	// Create the image marker, if one isn't available */
	if (ImagePointer.prototype.marker == null)
	{
		ImagePointer.prototype.marker = document.createElement('DIV');
		this.marker.className = 'imagePointerBoxy';
		document.body.appendChild(this.marker);
		this.marker.onmousedown = this._setRectangle;
		this.setMarkerSize();
	}
}
/* ### Shared/Public properties ### */
/** Search widget */
ImagePointer.prototype.searchWidget = null;
/** Floating element that holds the search widget list and input */
ImagePointer.prototype.friendsContainer = null;
/** Holds the rectangle that shows tag position */
ImagePointer.prototype.marker = null;

/* ### Shared/Public methods ### */
ImagePointer.prototype.setRectangle = function(x,y,w,h,showSearch)
{
	// set width and height if needed
	if (w != null && h != null)
	{
		this.marker.style.width = w + 'px';
		this.marker.style.height = h + 'px';
	}

	x += this.limits.l;
	y += this.limits.t;
	
	// Bounds checking
	if (x < this.limits.l) x = this.limits.l;
	else if (x + this.marker.offsetWidth > this.limits.r) x = this.limits.r - this.marker.offsetWidth;

	if (y < this.limits.t) y = this.limits.t;
	else if (y + this.marker.offsetHeight > this.limits.b) y = this.limits.b - this.marker.offsetHeight;

	// value assignment
	this.marker.style.left = x + 'px';
	this.marker.style.top = y + 'px';
	this.marker.style.display = 'block';
	this.boxIsSet = true;
	// The search box	
	if (showSearch)
	{
		this.friendsContainer.style.display = 'block';
		// If on right half of image - pop on left side, and vice versa
		if (x > this.limits.l + Math.floor((this.element.offsetWidth-this.marker.offsetWidth)/2))
		{
			this.friendsContainer.style.left = (x - this.friendsContainer.offsetWidth - 2) + 'px';
		}
		else
			this.friendsContainer.style.left = (x + this.marker.offsetWidth + 2) + 'px';

		this.friendsContainer.style.top = y + 'px';
		this.searchWidget.resetListView();
		this.searchWidget.input.focus();
	}
}
/** Returns the rectangle dimensions as an Object with fields x,y,w,h */
ImagePointer.prototype.getDimensions = function()
{
	if (!this.boxIsSet) return '';
	var pos = new Object();

	pos.x = this.marker.offsetLeft - this.limits.l;
	pos.y = this.marker.offsetTop - this.limits.t;
	pos.w = this.marker.offsetWidth  - ImagePointer.MARKER_BORDERWIDTH*2;
	pos.h = this.marker.offsetHeight - ImagePointer.MARKER_BORDERWIDTH*2;

	return pos;
}

/** Hides the marker box 
 *
 * Note: To simplify, just moves it offscreen, but getData()/getDimensions() will return that position.
 * So, perform all the processing related to the box position BEFORE you're hiding it. 
 */
ImagePointer.prototype.hideAll = function()
{
	this.marker.style.left = (-this.marker.offsetWidth-5) + 'px'; 
	this.marker.style.top = (-this.marker.offsetHeight-5) + 'px';
	if (this.friendsContainer != null) this.friendsContainer.style.display = 'none';
}
/** Called when initing the marker box */
ImagePointer.prototype.setMarkerSize = function()
{
	// Get image sizes
	var w = Math.ceil((this.element.offsetWidth - ImagePointer.CONTAINER_TOTALPAD * 2) / ImagePointer.MARKER_RATIO);
	var h = Math.ceil((this.element.offsetHeight - ImagePointer.CONTAINER_TOTALPAD * 2) / ImagePointer.MARKER_RATIO);
	var size = (w >= h) ? w : h;

	this.marker.style.width = size + 'px';
	this.marker.style.height = size + 'px';

	this.marker.style.borderWidth = ImagePointer.MARKER_BORDERWIDTH + 'px';
}
