/******************************************************************************
 * Helper method for creating per-object callbacks
 * @param target object to invoke the callback on
 * @param callback method to be called on the object
 *****************************************************************************/
function delegate(target, callback) {
	var func = function() {
		callback.apply(target, arguments);
	}
	return func;
}

// Replaces all instances of the given substring.
String.prototype.replaceAll = function(strTarget, strSubString) {
    var strText = this;
    var intIndexOfMatch = strText.indexOf( strTarget );
 
    // Keep looping while an instance of the target string
    // still exists in the string.
    while (intIndexOfMatch != -1) {
        // Relace out the current instance.
        strText = strText.replace( strTarget, strSubString )

        // Get the index of any next matching substring.
        intIndexOfMatch = strText.indexOf( strTarget );
    }
 
    // Return the updated string with ALL the target strings
    // replaced out with the new substring.
    return( strText );
}

// WheelHelper class from http://adomas.org/javascript-mouse-wheel/
function WheelHelper() {
	this.delegate = delegate(this, this.handleMouseWheel);
	if (window.addEventListener) {
		// DOMMouseScroll is for mozilla.
		window.addEventListener('DOMMouseScroll', this.delegate, false);
	}
	// IE/Opera.
	window.onmousewheel = document.onmousewheel = this.delegate;
}

WheelHelper.prototype.wheelScrolled = null;
WheelHelper.prototype.delegate = null;

WheelHelper.prototype.handleMouseWheel = function(event) {
	var delta = 0;
    if (!event) // For IE.
		event = window.event;
		
    if (event.wheelDelta) { //IE/Opera.
		delta = event.wheelDelta/120;
		// In Opera 9, delta differs in sign as compared to IE.
		if (window.opera)
			delta = -delta;
    }
    else if (event.detail) { // Mozilla case.
		// In Mozilla, sign of delta is different than in IE.
		// Also, delta is multiple of 3.
		delta = -event.detail/3;
    }
	// If delta is nonzero, handle it.
	// Basically, delta is now positive if wheel was scrolled up,
	// and negative, if wheel was scrolled down.
	if (delta && this.wheelScrolled)
		this.wheelScrolled(delta);
		
	// Prevent default actions caused by mouse wheel.
	// That might be ugly, but we handle scrolls somehow
	// anyway, so don't bother here..
	if (event.preventDefault)
		event.preventDefault();
		
	event.returnValue = false;
}

WheelHelper.prototype.detach = function() {
	if (this.delegate != null) {
		if (window.removeEventListener) {
			window.removeEventListener('DOMMouseScroll', this.delegate, false);
		}
		
		// IE/Opera.
		window.onmousewheel = document.onmousewheel = null;
		
		this.delegate = null;
	}
}