//
//	BlockResize v1.0
//	http://stfw.hu
//	01/06/08
//
//	Copyright (C) 2008, Attila Magyar
//	
//	All rights reserved.
//
//	Based on Andras Barthazi's textarea-resize script. See http://barthazi.hu
//
//	Redistribution and use in source and binary forms, with or without
//	modification, are permitted provided that the following conditions are met:
//		* Redistributions of source code must retain the above copyright notice,
//		  this list of conditions and the following disclaimer.
//		* Redistributions in binary form must reproduce the above copyright
//		  notice, this list of conditions and the following disclaimer in th
//		  documentation and/or other materials provided with the distribution.
//		* Neither the name of the <ORGANIZATION> nor the names of its
//		  contributors may be used to endorse or promote products derived from
//		  this software without specific prior written permission.
//
//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//	A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
//	OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

//
//	USAGE:
//	Set autoInitialize to true and in the class attribute of any element that
//		should be resizeable, place the word: "resizeable". It's strongly
//		recommended to make only block-elements resizeable.
//	See the "Configuration" section to control the auto-resizeable object's
//		behavior.
//	From JavaScript, use
//		BlockResize.attachResizers(oElement, nResizers, oMaxSize, oMinSize)
//		to add or change resizers dinamically, where
//			nResizers must be a number:
//				1 for horizontal
//				2 for vertical
//				3 for both resizeable-edges
//			oMaxSize and oMinSize must be an object of the following form:
//				{ width : Number, height : Number }
//		
//		You can use the constants BlockResize.HORIZONTAL, BlockResize.VERTICAL
//		and BlockResize.BOTH.
//	

var BlockResize = {
	/* CONFIGURATION */
	autoInitialize : true , // if set to false, call BlockResize.initialize() manually
	resizers : 3 , // 1: horizontal, 2: vertical, 3: both
	resizerWidth : 4 ,
	resizerCornerSize : 10 ,
	resizerColor : '#100b09' ,
	resizerOpacity : 0 ,
	indicatorBorderWidth : 2 ,
	indicatorBackgroundColor : '#806040' ,
	indicatorBorderColor : '#f0e8e0' ,
	indicatorOpacity : 0.3 ,
	maxSize :
	{
		width : 600 ,
		height : 700
	} ,
	minSize :
	{
		width : 300 ,
		height : 100
	} ,
	
	/* End of CONFIGURATION */

	indicator : null,
	body : null,
	
	HORIZONTAL : 1,
	VERTICAL : 2,
	BOTH : 3,
	
	getElementPosition : function (oElement)
	{
		var h = 0;
		var w = 0;
		var ex;
		try
		{
			w = oElement.offsetWidth ? oElement.offsetWidth : (oElement.clip ? oElement.clip.width : oElement.style.pixelWidth);
			h = oElement.offsetHeight ? oElement.offsetHeight : (oElement.clip ? oElement.clip.height : oElement.style.pixelHeight);
		}
		catch (ex)
		{
		}
		try
		{
			var ret = {
				top : oElement.offsetTop,
				left : oElement.offsetLeft,
				width : w * 1,
				height : h * 1
			};
			while (oElement = oElement.offsetParent)
			{
				ret.top += oElement.offsetTop;
				ret.left += oElement.offsetLeft;
			}
			return ret;
		}
		catch (ex)
		{
			return false;
		}
	},
	
	addEventHandler : function (oObject, sEventName, fHandler)
	{
		if (oObject.addEventListener)
		{
			oObject.addEventListener(sEventName, fHandler, false);
			return true;
		}
		else
		{
			if (oObject.attachEvent)
			{
				oObject.attachEvent('on' + sEventName, fHandler);
				return true;
			}
		}
		return false;
	},
	
	removeEventHandler : function (oObject, sEventName, fHandler)
	{
		if (oObject.removeEventListener)
		{
			oObject.removeEventListener(sEventName, fHandler, false);
			return true;
		}
		else
		{
			if (oObject.detachEvent)
			{
				oObject.detachEvent('on' + sEventName, fHandler);
				return true;
			}
		}
		return false;
	},
	
	updatePosition : function (oElement, pos)
	{
		oElement.style.top = pos.top + 'px';
		oElement.style.left = pos.left + 'px';
		oElement.style.height = pos.height + 'px';
		oElement.style.width = pos.width + 'px';
	},
	
	moveResizers : function (oElement, oPos)
	{
		var pos = oPos ? oPos : BlockResize.getElementPosition(oElement);
		var h, v, ch, cv;
		var corner = oElement.rsCorner;
		var cornerSize = BlockResize.resizerCornerSize;
		if (pos)
		{
			if (h = oElement.rsHoriz)
			{
				h.rsDim = {
					top : pos.top + pos.height,
					left : pos.left,
					height : BlockResize.resizerWidth,
					width : pos.width - (oElement.rsCorner ? cornerSize : 0)
				};
				BlockResize.updatePosition(h, h.rsDim);
			}
			if (v = oElement.rsVert)
			{
				v.rsDim = {
					top : pos.top,
					left : pos.left + pos.width,
					height : pos.height - (oElement.rsCorner ? cornerSize : 0),
					width : BlockResize.resizerWidth
				};
				BlockResize.updatePosition(v, v.rsDim);
			}
			if (ch = oElement.rsCornerHoriz)
			{
				ch.rsDim = {
					top : pos.top + pos.height,
					left : pos.left + pos.width - cornerSize,
					height : BlockResize.resizerWidth,
					width : cornerSize + BlockResize.resizerWidth
				};
				BlockResize.updatePosition(ch, ch.rsDim);
			}
			if (cv = oElement.rsCornerVert)
			{
				cv.rsDim = {
					top : pos.top + pos.height - cornerSize,
					left : pos.left + pos.width,
					height : cornerSize,
					width : BlockResize.resizerWidth
				};
				BlockResize.updatePosition(cv, cv.rsDim);
			}
		}
	},
	
	showIndicator : function ()
	{
		var pos = BlockResize.indicator.rsPos ? BlockResize.indicator.rsPos : BlockResize.getElementPosition(BlockResize.indicator.rsAttached);
		if (!BlockResize.indicator.rsPos) BlockResize.indicator.rsPos = pos;
		BlockResize.indicator.style.display = 'block';
		BlockResize.updatePosition(
			BlockResize.indicator,
			{
				top : pos.top - BlockResize.indicatorBorderWidth,
				left : pos.left - BlockResize.indicatorBorderWidth,
				width : pos.width,
				height : pos.height
			}
		);
		if (BlockResize.indicator.rsAttached) BlockResize.moveResizers(BlockResize.indicator.rsAttached, BlockResize.indicator.rsPos);
	},
	
	getMouseCoords : function (oEvent)
	{
		if (null != oEvent.pageX)
		{
			return { top : oEvent.pageY, left : oEvent.pageX };
		}
		else
		{
			return { top : oEvent.clientY, left : oEvent.clientX };
		}
	},
	
	begin : function (e)
	{
		if (!e) e = window.event;
		BlockResize.indicator.rsAttached = this.rsAttached;
		BlockResize.indicator.rsType = this.rsType;
		BlockResize.indicator.rsPos = false;
		BlockResize.indicator.style.cursor = ['crosshair', 's-resize', 'e-resize', 'se-resize'][this.rsType];
		BlockResize.indicator.rsOffset = BlockResize.getMouseCoords(e);
		BlockResize.addEventHandler(document, 'mousemove', BlockResize.doResize);
		BlockResize.addEventHandler(document, 'mouseup', BlockResize.end);
		BlockResize.showIndicator();
		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
		return false;
	},
	
	doResize : function (e)
	{
		if (!e) e = window.event;
		var mc = BlockResize.getMouseCoords(e);
		var min = BlockResize.indicator.rsAttached.rsMinSize;
		var max = BlockResize.indicator.rsAttached.rsMaxSize;
		if (0 < (BlockResize.indicator.rsType & BlockResize.VERTICAL))
		{
			BlockResize.indicator.rsPos.width = Math.max(Math.min(BlockResize.indicator.rsPos.width + (mc.left - BlockResize.indicator.rsOffset.left), max.width), min.width);
		}
		if (0 < (BlockResize.indicator.rsType & BlockResize.HORIZONTAL))
		{
			BlockResize.indicator.rsPos.height = Math.max(Math.min(BlockResize.indicator.rsPos.height + (mc.top - BlockResize.indicator.rsOffset.top), max.height), min.height);
		}
		BlockResize.indicator.rsOffset = mc;
		BlockResize.showIndicator();
		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
		return false;
	},
	
	end : function (e)
	{
		BlockResize.removeEventHandler(document, 'mousemove', BlockResize.doResize);
		BlockResize.removeEventHandler(document, 'mouseup', BlockResize.end);
		if (0 < (BlockResize.indicator.rsType & BlockResize.HORIZONTAL))
		{
			BlockResize.indicator.rsAttached.style.height = BlockResize.indicator.rsPos.height + 'px';
		}
		if (0 < (BlockResize.indicator.rsType & BlockResize.VERTICAL))
		{
			BlockResize.indicator.rsAttached.style.width = BlockResize.indicator.rsPos.width + 'px';
		}
		BlockResize.indicator.rsType = 0;
		BlockResize.indicator.rsPos = false;
		BlockResize.indicator.rsOffset = false;
		BlockResize.moveResizers(BlockResize.indicator.rsAttached);
		BlockResize.indicator.rsAttached = false;
		BlockResize.indicator.style.display = 'none';
		if (!e) e = window.event;
		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
		BlockResize.reInitialize();
		return false;
	},
	
	attachResizers : function (oElement, nResizers, oMaxSize, oMinSize)
	{
		if (!oMaxSize)
		{
			oMaxSize = BlockResize.maxSize;
		}
		if (!oMinSize)
		{
			oMinSize = BlockResize.minSize;
		}
		var pos;
		if (pos = BlockResize.getElementPosition(oElement))
		{
			oElement.rsResizing = false;
			oElement.rsCorner = BlockResize.BOTH == (nResizers & BlockResize.BOTH);
			oElement.rsMaxSize = oMaxSize;
			oElement.rsMinSize = oMinSize;
			if (oElement.rsHoriz) BlockResize.body.removeChild(oElement.rsHoriz);
			if (oElement.rsVert) BlockResize.body.removeChild(oElement.rsVert);
			if (oElement.rsCornerHoriz) BlockResize.body.removeChild(oElement.rsCornerHoriz);
			if (oElement.rsCornerVert) BlockResize.body.removeChild(oElement.rsCornerVert);
			if (0 < (nResizers & BlockResize.HORIZONTAL))
			{
				var h = document.createElement('div');
				h.rsType = BlockResize.HORIZONTAL;
				h.rsAttached = oElement;
				h.style.position = 'absolute';
				h.style.borderStyle = 'none';
				h.style.zIndex = 1000;
				h.style.backgroundColor = BlockResize.resizerColor;
				h.style.cursor = 's-resize';
				h.style.opacity = BlockResize.resizerOpacity;
				h.style.filter = 'alpha(opacity=' + Math.round(100 * BlockResize.resizerOpacity) + ')';
				oElement.rsHoriz = BlockResize.body.appendChild(h);
				oElement.rsHoriz.onmousedown = BlockResize.begin;
			}
			else oElement.rsHoriz = false;
			if (0 < (nResizers & BlockResize.VERTICAL))
			{
				var v = document.createElement('div');
				v.rsType = BlockResize.VERTICAL;
				v.rsAttached = oElement;
				v.style.position = 'absolute';
				v.style.borderStyle = 'none';
				v.style.zIndex = 1000;
				v.style.backgroundColor = BlockResize.resizerColor;
				v.style.cursor = 'e-resize';
				v.style.opacity = BlockResize.resizerOpacity;
				v.style.filter = 'alpha(opacity=' + Math.round(100 * BlockResize.resizerOpacity) + ')';
				oElement.rsVert = BlockResize.body.appendChild(v);
				oElement.rsVert.onmousedown = BlockResize.begin;
			}
			else oElement.rsVert = false;
			if (oElement.rsCorner)
			{
				var ch = document.createElement('div');
				ch.rsType = BlockResize.BOTH;
				ch.rsAttached = oElement;
				ch.style.position = 'absolute';
				ch.style.borderStyle = 'none';
				ch.style.zIndex = 1000;
				ch.style.backgroundColor = BlockResize.resizerColor;
				ch.style.cursor = 'se-resize';
				ch.style.opacity = BlockResize.resizerOpacity;
				ch.style.filter = 'alpha(opacity=' + Math.round(100 * BlockResize.resizerOpacity) + ')';
				oElement.rsCornerHoriz = BlockResize.body.appendChild(ch);
				var cv = document.createElement('div');
				cv.rsType = BlockResize.BOTH;
				cv.rsAttached = oElement;
				cv.style.position = 'absolute';
				cv.style.borderStyle = 'none';
				cv.style.zIndex = 1000;
				cv.style.backgroundColor = BlockResize.resizerColor;
				cv.style.cursor = 'se-resize';
				cv.style.opacity = BlockResize.resizerOpacity;
				cv.style.filter = 'alpha(opacity=' + Math.round(100 * BlockResize.resizerOpacity) + ')';
				oElement.rsCornerVert = BlockResize.body.appendChild(cv);
				oElement.rsCornerVert.onmousedown = BlockResize.begin;
				oElement.rsCornerHoriz.onmousedown = BlockResize.begin;
			}
			else
			{
				oElement.rsCornerHoriz = false;
				oElement.rsCornerVert = false;
			}
			BlockResize.moveResizers(oElement, pos);
		}
	},
	
	reInitialize : function ()
	{
		var r = document.getElementsByTagName('*');
		for (var i = 0; i < r.length; ++i)
		{
			var cls = r[i].className ? r[i].className : r[i].getAttribute('class');
			if (cls && (-1 < cls.indexOf('resizeable')))
			{
				BlockResize.moveResizers(r[i]);
			}
		}
	},
	
	initialize : function ()
	{
		BlockResize.body = document.getElementsByTagName('body')[0];
		var r = document.getElementsByTagName('*');
		for (var i = 0; i < r.length; ++i)
		{
			var cls = r[i].className ? r[i].className : r[i].getAttribute('class');
			if (cls && (-1 < cls.indexOf('resizeable')))
			{
				BlockResize.attachResizers(r[i], BlockResize.resizers);
			}
		}
		r = document.createElement('div');
		r.style.position = 'absolute';
		r.style.display = 'none';
		r.style.borderWidth = BlockResize.indicatorBorderWidth + 'px';
		r.style.borderStyle = 'dashed';
		r.style.borderColor = BlockResize.indicatorBorderColor;
		r.style.zIndex = 1001;
		r.style.backgroundColor = BlockResize.indicatorBackgroundColor;
		r.style.opacity = BlockResize.indicatorOpacity;
		r.style.filter = 'alpha(opacity=' + Math.round(100 * BlockResize.indicatorOpacity) + ')';
		BlockResize.indicator = BlockResize.body.appendChild(r);
	}
}

if (BlockResize.autoInitialize && (!BlockResize.addEventHandler(window, 'load', BlockResize.initialize)))
{
	var onld = function () {};
	if (window.onload) onld = window.onload;
	window.onload = function () { BlockResize.initialize(); onld(); };
}
