/*
 * ess-error.js
 * ---
 * EZEL 05/2010
 * show error messages in 'popup' element
 * ---
 * requires:
 *   jquery.js
 *   ess-window.js
 * ---
 */

/*jslint browser: true */
/*global $: false, ESSENCE: true, window: false */
/**/

if (typeof ESSENCE === 'undefined') { 
	ESSENCE = {}; 
}
ESSENCE.ErrorPopup = (function () {
    'use strict';
    var CONST, MAIN;
	
	CONST = {
		selErrors: '.Error,.Message',
		datZoom: 'zoom',
		cssOuter: {
			position: 'absolute',
			width: '500px',
			top: 0,
			right: 0,
			margin: 0,
			padding: '1em',
			display: 'none'
		},
		cssInner: {
			clear: 'both'
		},
		cssClose: {
			position: 'absolute',
			fontSize: '16px',
			right: 2,
			top: 0,
			cursor: 'pointer',
			display: 'none'
		},
		cssButton: {
			display: 'inline',
			position: 'relative',
			'float': 'right',
			color: 'blue',
			cursor: 'pointer'
		},
		cssDetail: {
			marginTop: '.5em',
			display: 'block',
			width: '100%',
			border: 'solid 1px black',
			height: '200px'
		},
		speed: 750,
		speed2: 250
	};

	MAIN = {};
	
	function makeClosable(qel) {
		var button, pos;
		button = $('<span>&times;</span>').css(CONST.cssClose);
		pos = qel.css('position');
		if (pos !== 'absolute' && pos !== 'relative') {
			qel.css('position', 'relative');
		}
		qel.append(button);
		button.click(function () {
			qel.fadeOut(CONST.speed, function () {
				qel.remove();
			});
			return false;
		});
		button.mouseenter(function () {
			button.css({fontWeight: 'bold'});
		});
		button.mouseleave(function () {
			button.css({fontWeight: 'normal'});
		});
		qel.mouseenter(function () {
			button.fadeIn(CONST.speed2);
		});
		qel.mouseleave(function () {
			button.fadeOut(CONST.speed2);
		});
	}
	
	function createErrorPopup() {
		if (MAIN.popup) {
			MAIN.popup.remove();
			MAIN.popup = null;
		}
		MAIN.popup = $('<div class="ErrorPopup"></div>').css(CONST.cssOuter);
		makeClosable(MAIN.popup);
		$(window).scroll(function () {
			var qdoc = $(document);
			MAIN.popup.css({
				left: qdoc.scrollLeft(),
				top: qdoc.scrollTop()
			});
		});
		MAIN.popup.appendTo($('body'));
		return MAIN.popup;
	}
	
	function getComments(qel, bDeep) {
		var aComments = [], aNodes = [], eChild, eNode;
		if (typeof bDeep === 'undefined') {
			bDeep = false;
		}
		qel.each(function () {
			aNodes.push(this);
		});
		while (aNodes.length > 0) {
			eNode = aNodes.pop();
			eChild = eNode.firstChild;
			while (eChild) {
				if (eChild.nodeType === 8) {
					aComments.push(eChild.nodeValue);
				} else if (bDeep && (eChild.nodeType === 1)) {
					aNodes.push(eChild);
				}
				eChild = eChild.nextSibling;
			}
		}
		return aComments;
	}
	
	function makeZoomable(qel, qnew) {
		var par, qbtn;
		qbtn = $('<span title="detail"></span>').css(CONST.cssButton);
		qbtn.click(function () {
			if (!qbtn.data(CONST.datZoom)) {
				qbtn.html('&hellip;');
				qel.hide();
				qbtn.data(CONST.datZoom, true);
			} else {
				qbtn.html('&hellip;');
				qel.show();
				qbtn.data(CONST.datZoom, false);
			}
			return false;
		});
		if (!qnew) {
			qel.before(qbtn);
		} else {
			qnew.append(qbtn);
		}
		qbtn.click();
	}
	
	function processError() {
		var qerr, qnew, qin;
		qerr = $(this);
		qin = qerr.clone();
		qnew = $('<div></div>').append(qin).css(CONST.cssInner);
		$(getComments(qerr)).each(function () {
			var stext = this, qcom;
			qcom = $('<textarea readonly="readonly" wrap="off"></textarea>');
			qcom[0].innerHTML = stext.replace('\n', '<br/>');
			qcom.css(CONST.cssDetail);
			qcom.appendTo(qnew);
			qcom.click(function () {
				qcom[0].select();
				return false;
			});
			qcom.keydown(function (event) {
				return (event.keyCode !== 27);
			});
			makeZoomable(qcom, qin);
		});
		MAIN.popup.append(qnew);
		qerr.hide();
	}
	
	function initErrors() {
		var errs;
		errs = $(CONST.selErrors);
		if (errs.length > 0) {
			createErrorPopup();
			errs.each(processError);
			MAIN.popup.fadeIn(CONST.speed);
		}
	}
	
	$(initErrors);
	
	MAIN = {};
	MAIN.init = initErrors;
	return MAIN;
}());

