if (!Array.indexOf) {
	Array.prototype.indexOf = function(obj) {
		for (i = 0; i < this.length; i++) {
			if (this[i] == obj) {
				return i;
			}
		}

		return -1;
	};
}

/**
 * Fade a feedback object out of the view and delete its node from the DOM.
 *
 * @param feedbackId dojo.byId(feedbackId) object to hide
 * @param hideDelay Num milliseconds to keep object in view before hiding.
 */
function hideFeedback(feedbackId, hideDelay)
{

	if ('undefined' === typeof hideDelay) {
		delay = 0;
	}

	dojo.fadeOut({node: feedbackId
	            , duration: 500
	            , delay: hideDelay
	            , onEnd: function() {
	            	dojo.animateProperty({
	            		  node: feedbackId
	            		, duration: 500
	            		, properties: {
	            			border: { end: '0', unit: 'px' },
	            			height: { end: '0', unit: 'px' },
	            			padding: { end: '0', unit: 'px' }
	            		},
	            		onEnd: function() {
		            		dojo.query('#' + feedbackId).orphan();
	            		}
	            	}).play();
	            }
	}).play();

	return false;

}

/**
 * Create a new DOM object for a feedback message, adding it before the object
 * passed to the function.
 *
 * @param message String to display in a newly generated feedback view.
 * @param insertBefore Id of object to insert new feedback object before
 * @param keepShown Pass true to keep feedback on screen rather than hiding
 *                  after 5 seconds.
 * @return The DOM feedback object created or already showing on the page.
 *         null if there was no message passed
 */
function showFeedback(message, insertBefore, keepShown)
{
/*
	<div id="feedback0" class="feedback" style="display: none;">
		<div class="feedbackMessage">
			<a name="feedback0"></a>
			<a href="#" onclick="return hideFeedback('feedback0')" class="close" title="Close this message">X</a>
			<span></span>
		</div>
	</div>
*/
	if (message.length > 0) {
		// Don't display the same message twice. It will only display again when
		// the previous feedback is closed.
		var duplicateFeedback = findFeedback(message, insertBefore);
		if (duplicateFeedback) {
			return duplicateFeedback;
		}

		for(i = 0; dojo.byId('feedback' + i); i++);
		var feedbackId = 'feedback' + i;

		var feedback = document.createElement('div');
		feedback.id = feedbackId;
		feedback.className = 'feedback';
		feedback.style.display = 'none';

		var feedbackMessage = document.createElement('div');
		feedbackMessage.className = 'feedbackMessage';

		var feedbackAnchor = document.createElement('a');
		feedbackAnchor.name = feedbackId;

		var feedbackClose = document.createElement('a');
		feedbackClose.href = '#';
		feedbackClose.onclick = function() {
			return hideFeedback(feedbackId);
		}
		feedbackClose.className = 'close';
		feedbackClose.title = 'Close this message';
		feedbackClose.innerHTML = 'X';

		var feedbackContent = document.createElement('span');
		feedbackContent.innerHTML = message;

		feedbackMessage.appendChild(feedbackAnchor);
		feedbackMessage.appendChild(feedbackClose);
		feedbackMessage.appendChild(feedbackContent);
		feedback.appendChild(feedbackMessage);

		var insertBefore = dojo.byId(insertBefore);
		insertBefore.parentNode.insertBefore(feedback, insertBefore);

		dojo.query('#' + feedbackId).style('opacity', '0');
		dojo.query('#' + feedbackId).style('display', 'block');

		dojo.fadeIn({node: feedbackId
		           , duration: 500
		           , onEnd: function() {
		           		if (!keepShown) {
		           			// hide after showing feedback for 5 seconds
		           			hideFeedback(feedbackId, 5000);
		           		}
		           }
		}).play();

		return feedback;
	}

	return null;

}

/**
 * Find whether a feedback DOM object exists on a page with a certain message.
 *
 * @param message String which is displayed in the feedback.
 * @param siblingOf DOM object that the message should be a sibling of. This is
 *                  a method of matching only feedback within a certain block
 *                  on the page. To match feedback on the whole page, do not
 *                  pass anything as the second parameter.
 * @return DOM object of the matching feedback if it exists, null if not string
 *         match was found.
 */
function findFeedback(message, siblingOf)
{

	if (message.length > 0) {
		var feedbackFound = null;
		dojo.forEach(dojo.query('div[id^=feedback] .feedbackMessage span'), function(feedbackMessage) {
			feedbackBlock = feedbackMessage.parentNode.parentNode;

			if (feedbackMessage.innerHTML == message) {
				if (dojo.byId(siblingOf).id) {
					for (var i = 0; i < feedbackBlock.parentNode.childNodes.length; i++) {
						if (feedbackBlock.parentNode.childNodes[i].id &&
						    feedbackBlock.parentNode.childNodes[i].id == dojo.byId(siblingOf).id) {
							feedbackFound = feedbackBlock;
						}
					}
				} else {
					feedbackFound = feedbackBlock;
				}
			}
		});

		return feedbackFound;
	} else {
		return null;
	}

}

