// Spread the contents of a container horizontally. Contents are assumed to share
// the same element tag name. The optional filter parameter specifies a class to
// which an element must belong; this option is useful when handling pull-down menus
// implemented as nested lists. R. Abeles 11/16/2007.

function spread(container, elements, filter)
{
	container = $(container);
	elements = $A(container.getElementsByTagName(elements));
	var cWidth = container.getWidth();
	cWidth -= (parseInt(container.getStyle('padding-left')));
	var eWidth = 0;
	var eCtr = 0;
	
	elements.each(function (e) {
		e = $(e);
		if ((filter == null) || (e.hasClassName(filter))) {
			eCtr++;
			eWidth += e.getWidth();
			e.setStyle( {marginLeft: 0, marginRight: 0} );
		}
	});
	
	var cFill = cWidth - eWidth;
	
	if ((cFill > 0) && (eCtr > 1)) {
		var eMargin = Math.floor(cFill / (eCtr - 1));
		var lMargin = 0;
		var rMargin = 0;
		cFill -= eMargin * (eCtr - 1);
		if (cFill > 0) {
			rMargin = Math.floor(cFill / 2);
			lMargin = cFill - rMargin;
		}
		var first = true;
		elements.each(function (e) {
			if ((filter == null) || (e.hasClassName(filter))) {
				eCtr--;
				if (first) {
					first = false;
				}
				if (eCtr != 0) {
					e.setStyle( {marginRight: eMargin + 'px'} );
				} else {
					e.setStyle( {marginRight: rMargin + 'px'} );
				}
			}
		});
	}
}

function spread2(container, container2, etag, filter)
{
	container = $(container);
	container2 = $(container2);
	var elements = $A(container.getElementsByTagName(etag));
	var cWidth = container.getWidth();
	cWidth -= (parseInt(container.getStyle('padding-left')));
	var eWidth = 0;
	var eCtr = 0;
	
	elements.each(function (e) {
		e = $(e);
		if ((filter == null) || (e.hasClassName(filter))) {
			eCtr++;
			eWidth += e.getWidth();
			e.setStyle( {marginLeft: 0, marginRight: 0} );
		}
	});
	
	var cFill = cWidth - eWidth;
	
	if ((cFill > 0) && (eCtr > 1)) {
		var eMargin = Math.floor(cFill / (eCtr - 1));
		var lMargin = 0;
		var rMargin = 0;
		cFill -= eMargin * (eCtr - 1);
		if (cFill > 0) {
			rMargin = Math.floor(cFill / 2);
			lMargin = cFill - rMargin;
		}
		var first = true;
		elements.each(function (e) {
			if ((filter == null) || (e.hasClassName(filter))) {
				eCtr--;
				if (first) {
					first = false;
				}
				if (eCtr != 0) {
					e.setStyle( {marginRight: eMargin + 'px'} );
				} else {
					e.setStyle( {marginRight: rMargin + 'px'} );
				}
			}
		});

		elements = $A(container2.getElementsByTagName(etag));

		elements.each(function (e) {
			e = $(e);
			if ((filter == null) || (e.hasClassName(filter))) {
				e.setStyle( {marginLeft: 0, marginRight: eMargin + 'px'} );
			}
		});
	}
}

function balance(left, right, overhang) {
	left = $(left);
	right = $(right);
	
	var lBot = left.getHeight() + Position.cumulativeOffset(left)[1];
	var rBot = right.getHeight() + Position.cumulativeOffset(right)[1];
	
	if (rBot < (lBot + overhang)) {
		var rPad = parseInt(left.getStyle('padding-bottom'));
		var rAdj = lBot + overhang - rBot;
		rPad += rAdj;
		right.setStyle({paddingBottom: rPad + 'px'});
	}
}

function align(left, right) {
	left = $(left);
	right = $(right);
	
	var lTop = Position.cumulativeOffset(left)[1];
	var rTop = Position.cumulativeOffset(right)[1];
	
	if (rTop < lTop) {
		var rPad = parseInt(left.getStyle('padding-top'));
		rPad += (lTop - rTop);
		right.setStyle({paddingTop: rPad + 'px'});
	}
}

// Modified scriptaculous combined effect Pulsate. Now takes the following optional
//  parameters:
//	
//	startOpacity	element begins pulse at this opacity value
//	endOpacity		element ends half-cycle of pulse at this opacity value
//	oldOpacity		element opacity at end of pulse effect (usually same as startOpacity,
//					if omitted, behavior defaults to the original scriptaculous behavior
//					that exhibits odd artifacts if pulsate is started multiple times on
//					the same element.
//					already in progress on the selected element.
//	duration		floating-point total seconds in pulse effect
//	transition		transition effect (defaults to Effect.Transitions.sinoidal)
//	pulses			number of times pulse effect repeats
//	afterFinish		function(element) that fires after the effect finishes
Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { };
  var startOpacity = options.startOpacity || 0.0;
  var endOpacity = options.endOpacity || 1.0;
  var oldOpacity = options.oldOpacity || element.getInlineOpacity();
  var duration = options.duration || 2.0;
  var transition = options.transition || Effect.Transitions.sinoidal;
  var pulses = options.pulses || 3;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, pulses)) };
  reverser.bind(transition);
  var afterFinish = options.afterFinish || Prototype.emptyFunction;
  return new Effect.Opacity(element, 
	Object.extend(Object.extend({  duration: duration, from: endOpacity, to: startOpacity,
	  afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); afterFinish(effect.element);}
	}, options), {transition: reverser}));
};

// Event observer that begins pulsation. Serialized by this.__pulsate.
//
function pulsate(event) {
	if (Object.isUndefined(this.__pulsate) || !this.__pulsate) {
		this.__pulsate = true;
		Effect.Pulsate(this, {pulses: 2,
                              startOpacity: 0.45,
                              endOpacity: 1.0,
                              oldOpacity: 0.45,
                              duration: 3.0,
                              afterFinish: function(element) {element.__pulsate = false;}
		                     });	
	}	
}


