// JavaScript Document
/*
	Author: Willy
	Modified: 2008/11/28
*/
tagala.packs.push('view');
tagala.Splitter = Class.create(tagala.DispatchHandler,
{
	initialize:function ($super)
	{
		$super();
		// Create onresize handle
		var body = $(document.body);
		this.resizeBar = body.appendDiv(null, 'splitteronResize').hide();
		this.resizeBar.appendTag('SPAN');
		this.transparentDiv = body.appendDiv(null, 'divTransparentForResize').hide();

		$(document).observe('mouseup', this.endResize.bind(this));
		$(document).observe('mousemove', this.onResizing.bindAsEventListener(this));

		// Only for IE and Safari
		$(document).observe('selectstart', (function() { return (this.resizeMode == null); }).bind(this));
	},

	createResizeHandles:function (el, mode)
	{
		var verticleMode;

		if (!(el = $(el))) return;
		if (typeof(mode) != 'string' || !(/^(left|right|top|bottom)\b(\s+\bnoresize)?$/i.test(mode)))
			return;
		else
			mode = RegExp.$1.toLowerCase();
		verticleMode = ['left', 'right'].include(mode);
		el.setStyle({ overflow:'hidden' });

		var position = el.getStyle('position');
		if (position != 'absolute' && position != 'relative') el.setStyle({ position:'relative' });

		var splitterNode = $(document.body).appendDiv(null, 'splitter-' + mode);
		splitterNode.writeAttribute(verticleMode ? 'topFx' : 'leftFx', el.identify());
		splitterNode.writeAttribute(verticleMode ? 'heightFx' : 'widthFx', el.identify());
		splitterNode.writeAttribute(mode + 'Fx', el.identify());

		if (RegExp.$2) splitterNode.addClassName(verticleMode ? 'splitter_vertical_noresize' : 'splitter_horizontal_noresize');
		splitterNode.observe('mousedown', this.initResizePane.bindAsEventListener(this)).appendTag('SPAN');

		var resizeNode = splitterNode.appendDiv(el.id + '-CollapseButton', 'resizeButton-' + mode)
		resizeNode.observe('click', this.toggleCollapseExpandButton.bindAsEventListener(this));
		resizeNode.observe('mouseover', this.mouseoverCollapseButton);
		resizeNode.observe('mouseout', this.mouseoutCollapseButton).appendTag('SPAN');

		var styles = {};
		styles[('padding-' + mode).camelize()] = (verticleMode ? splitterNode.getWidth() : splitterNode.getHeight()) + 'px';
		el.setStyle(styles);
	},

	initResizePane:function (e)
	{
		var el = e.element();
		if (!el || !/\bsplitter-(left|right|top|bottom)\b/i.test(el.className) || !this.getResizePane(el)) return;
		var verticalMode = ['left', 'right'].include(this.resizeMode);
		var boundryMode = ['left', 'top'].include(this.resizeMode);
		var position = this.resizePane.cumulativeOffset();
		var dMax, dMin;
		this.maxValue = this.minValue = (verticalMode ? position.left : position.top)
																	+ ((this.resizeMode == 'left') ? this.resizePane.getWidth() :
																		(this.resizeMode == 'top') ? this.resizePane.getHeight() : 0);
		dMax = (dMax = parseInt(this.resizePane.getStyle(verticalMode ? 'maxWidth' : 'maxHeight'))) >= 0 ? dMax : NaN;
		dMin = (dMin = parseInt(this.resizePane.getStyle(verticalMode ? 'minWidth' : 'minHeight'))) >= 0 ? dMin : NaN;
		if (boundryMode)
		{
			// IE 5~6 max-width, min-width
			this.minValue -= dMax;
			this.maxValue -= dMin;
		}
		else
		{
			this.minValue += dMin;
			this.maxValue += dMax;
		}
		this.showResizeBarForResize(el);
		this.transparentDiv.show();
	},

	endResize:function ()
	{
		switch (this.resizeMode)
		{
			case 'left':
				this.resizePane.setStyle({ width:(this.resizePane.getWidth() + this.resizePane.cumulativeOffset().left - this.resizeBar.cumulativeOffset().left - this.resizeBar.getWidth()) + 'px' });
				break;
			case 'right':
				this.resizePane.setStyle({ width:(this.resizeBar.cumulativeOffset().left - this.resizePane.cumulativeOffset().left - this.resizeBar.getWidth()) + 'px' });
				break;
			case 'top':
				this.resizePane.setStyle({ height:(this.resizePane.getHeight() + this.resizePane.cumulativeOffset().top - this.resizeBar.cumulativeOffset().top - this.resizeBar.getHeight()) + 'px' });
				break;
			case 'bottom':
				this.resizePane.setStyle({ height:(this.resizeBar.cumulativeOffset().top - this.resizePane.cumulativeOffset().top - this.resizeBar.getHeight()) + 'px' });
				break;
			default:
				return;
		}
		this.dispatch('onResize');
		this.resizeBar.hide();
		this.transparentDiv.hide();
		this.clearResizePane();
	},

	onResizing:function (e)
	{
		var style;
		if (!this.resizeMode)
			return;
		else if (['left', 'right'].include(this.resizeMode))
			style = { left:this.between(this.maxValue, this.minValue, e.pointerX() - (this.resizeBar.getWidth() / 2).round()) + 'px' };
		else if (['top', 'bottom'].include(this.resizeMode))
			style = { top:this.between(this.maxValue, this.minValue, e.pointerY() - (this.resizeBar.getHeight() / 2).round()) + 'px' };
		this.resizeBar.setStyle(style);
	},

	toggleCollapseExpandButton:function (e)
	{
		var el, buttonDir, collapsed, noResize, cFlag = 'clap', styles, parentNode, parentDimension, paneDimension, mode;
		if (!(el = e.element()) || !/\bresizeButton-(left|right|top|bottom)\b/i.test(el.className) || !(mode = RegExp.$1) || !this.getResizePane(el)) return;
		switch (mode)
		{
			case 'left':
				el.className = el.className.replace('left','right');
				break;
			case 'right':
				el.className = el.className.replace('right','left');
				break;
			case 'top':
				el.className = el.className.replace('top','bottom');
				break;
			case 'bottom':
				el.className = el.className.replace('bottom','top');
				break;
		}

		paneDimension = this.resizePane.getDimensions();
		parentNode = el.up();
		parentDimension = parentNode.getDimensions();
		collapsed = this.resizePane.getAttribute(cFlag);
		noResize = (this.resizePane.getAttribute('splitter') || '').indexOf('noresize') >= 0;

		if (['left', 'right'].include(this.resizeMode))
		{
			if (!noResize) parentNode.toggleClassName('splitter_vertical_noresize');
			if (collapsed)
			{
				styles =
				{
					minWidth:null,
					width:collapsed + 'px'
				};
				styles[('padding-' + this.resizeMode).camelize()] = parentDimension.width + 'px';
				this.resizePane.removeAttribute(cFlag);
			}
			else
			{
				this.resizePane.writeAttribute(cFlag, paneDimension.width - parentDimension.width);
				styles =
				{
					padding:0,
					minWidth:parentDimension.width + 'px',
					width:parentDimension.width + 'px'
				};
			}
			this.resizePane.setStyle(styles);
		}
		else
		{
			if (!noResize) parentNode.toggleClassName('splitter_horizontal_noresize');
			if (collapsed)
			{
				styles =
				{
					minHeight:null,
					height:collapsed + 'px'
				}
				styles[('padding-' + this.resizeMode).camelize()] = parentDimension.height + 'px';
				this.resizePane.removeAttribute(cFlag);
			}
			else
			{
				this.resizePane.writeAttribute(cFlag, paneDimension.height - parentDimension.height);
				styles =
				{
					padding:0,
					minHeight:parentDimension.height + 'px',
					height:parentDimension.height + 'px'
				}
			}
		}
		this.resizePane.setStyle(styles);
		this.dispatch('onResize');
		this.clearResizePane();
	},

	mouseoverCollapseButton:function (e)
	{
		e.element().addClassName('collapseExpandOver');
	},

	mouseoutCollapseButton:function (e)
	{
		e.element().removeClassName('collapseExpandOver');
	},

	getResizePane:function (el)
	{
		var result;
		if ((el.match('[class^=splitter-]') || (el = el.up('[class^=splitter-]'))) && /\bsplitter-(left|right|top|bottom)\b/i.test(el.className))
			$$('[splitter~=' + (result = this.resizeMode = RegExp.$1.toLowerCase()) + ']').each(function (node)
			{
				this.resizePane = node;
				throw $break;;
			}, this);
		return result;
	},

	showResizeBarForResize:function (el)
	{
		if (!(el = $(el))) return;
		var position = el.cumulativeOffset();
		var dimension = el.getDimensions();
		this.resizeBar.setStyle(
		{
			top:position.top + 'px',
			left:position.left + 'px',
			width:dimension.width + 'px',
			height:dimension.height + 'px'
		}).show();
		var cursor = el.getStyle('cursor');
		this.transparentDiv.setStyle({ cursor:cursor });
		this.resizeBar.setStyle({ cursor:cursor });
	},

	clearResizePane:function()
	{
		this.minValue = -1;
		this.maxValue = -1;
		this.resizePane = null;
		this.resizeMode = null;
	},

	between:function (max, min, value)
	{
		return (value > max) ? max : (value < min) ? min : value;
	}
});