var BlockResize = {
	autoInitialize : true ,
	resizers : 3 ,
	resizerWidth : 4 ,
	resizerCornerSize : 10 ,
	resizerColor : '#ffffff' ,
	resizerOpacity : 0 ,
	indicatorBorderWidth : 2 ,
	indicatorBackgroundColor : '#40d000' ,
	indicatorBorderColor : '#002000' ,
	indicatorOpacity : 0.3 ,
	maxSize :
	{
		width : 800 ,
		height : 600
	} ,
	minSize :
	{
		width : 100 ,
		height : 40
	} ,
	
	doResizeHandler : null,
	endHandler : null,
	indicator : null,
	body : null,
	
	HORIZONTAL : 1,
	VERTICAL : 2,
	BOTH : 3,
	
	updatePosition : function (oElement, pos)
	{
		var ex;
		try
		{
			oElement.style.top = pos.top + 'px';
			oElement.style.left = pos.left + 'px';
			oElement.style.height = pos.height + 'px';
			oElement.style.width = pos.width + 'px';
		}
		catch (ex)
		{
		}
	},
	
	moveResizers : function (oElement, oPos)
	{
		var pos = oPos ? oPos : Utils.Screen.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 : Utils.Screen.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.doResizeHandler = Utils.Events.addListener(document, 'mousemove', BlockResize.doResize);
		BlockResize.endHandler = Utils.Events.addListener(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)
	{
		Utils.Events.removeEventHandler(document, 'mousemove', BlockResize.doResizeHandler);
		Utils.Events.removeEventHandler(document, 'mouseup', BlockResize.endHandler);
		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 = Utils.Screen.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 = $C('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 = $C('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 = $C('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 = $C('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, l = r.length; i < l; ++i)
		{
			var cls = new String(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, l = r.length; i < l; ++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 = $C('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 && (!Utils.Events.addListener(window, 'load', BlockResize.initialize)))
{
	var onld = function () {};
	if (window.onload) onld = window.onload;
	window.onload = function () { BlockResize.initialize(); onld(); };
}
