// The layer we use for all tooltips displayed
var TOOLTIP_ELEMENT_ID = 'error_hover';

// After the div is created, keep a reference to it
var tooltipElement;
var errorHoverEnable = true;
var errorHover = new Object();
errorHover._getTooltipTable = function (tooltipText, tooltipWidth) {
    var tooltipTable = "<table border='0' cellpadding='0' cellspacing='0'";
    if (tooltipWidth && tooltipWidth > 0) {
        tooltipTable = tooltipTable + " width='" + tooltipWidth + "'";
    }
    tooltipTable = tooltipTable + ">"+
    "<tr height='2'>"+
    "<td style='padding-left:1px'><img src='images/errorMessageArrow.gif' width='7' height='9'></td>"+
    "<td colspan='2' rowspan='1' align='left' BGCOLOR='#920000' valign='center' class='error-message-layer' style='color:#FFFFFF'>&nbsp;" + tooltipText + "</td>"+
    "<td align=left>"+
        "<table border='0' cellpadding='0' cellspacing='0' height='100%'><tr>"+
        "<td height='2' align='left'><img src='images/s.gif' height='2' width='2'/></td>"+
        "</tr><tr>"+
        "<td valign='top' align='left' BGCOLOR='#240000'><img src='images/hoverShadow.gif' width='2' height='100%'/></td>"+
        "</tr></table>"+
    "</td>"+
    "</tr>"+
    "<tr><td></td></tr>"+
    "</table>";

    return tooltipTable;
}

errorHover._getDownArrowTooltipTable = function (tooltipText, tooltipWidth) {
    var tooltipTable = "<table border='0' cellpadding='0' cellspacing='0'";
    //var tooltipTable = "<table border=0 cellpadding='0' cellspacing='0' class='portlet-tooltip portlet-tooltip-border'";
    if (tooltipWidth && tooltipWidth > 0) {
        tooltipTable = tooltipTable + " width='" + tooltipWidth + "'";
    }
    tooltipTable = tooltipTable + ">"+
    "<tr height='2'>"+
    "<td colspan='1' rowspan='1' align='left' BGCOLOR='#920000'><img src='images/s.gif' height=2 width=2></td>"+
    "<td colspan='2' rowspan='1' align='left' BGCOLOR='#920000' valign='center' class='error-message-layer' style='color:#FFFFFF'>&nbsp;" + tooltipText + "</td>"+
    "<td align=left>"+
        "<table border='0' cellpadding='0' cellspacing='0' height=100%><tr>"+
        "<td height='2' align='left'><img src='images/s.gif' height='2' width='2'></td>"+
        "</tr><tr>"+
        "<td valign='top' align='left' BGCOLOR='#240000'><img src='images/hoverShadow.gif' width='2' height='100%'/></td>"+
        "</tr></table>"+
    "</td>"+
    "</tr>"+
    "<tr>"+
    "<td valign='top' width='2'><img src='/images/s.gif' height=2 width=2></td>"+
    "<td rowspan='2' align='right' width='32'><img border=0 hspace=0 vspace=0 src='images/errorMessageArrowDown.gif'></td>"+
    "<td valign='top' colspan='1'><img src='images/hoverShadow.gif' height='2' width='100%'></td>"+
    "<td valign='top' colspan='1'><img src='images/hoverShadow.gif' height='2' width='2'></td>"+
    "</tr>"+
    "<tr><td></td></tr>"+
    "</table>";

    return tooltipTable;
}

errorHover._getGrossOffsetLeft = function (elem) {
    var undefined;
    var offset = 0;
    while (elem.offsetParent) {
        elem = elem.offsetParent;
        offset += elem.offsetLeft;
        if (elem.tagName == "DIV" && elem.scrollLeft != undefined) {
            // if this is a scrollable div layer, we need to calculate
            // how much the user has scrolled and subtract it from the
            // offset. 
            offset -= elem.scrollLeft;
        }
    }
    return offset;
}

errorHover._getGrossOffsetTop = function (elem) {
    var undefined;
    var offset = 0;
    while (elem.offsetParent) {
        elem = elem.offsetParent;
        offset += elem.offsetTop;
        if (elem.tagName == "DIV" && elem.scrollTop != undefined) {
            // if this is a scrollable div layer, we need to calculate
            // how much the user has scrolled and subtract it from the
            // offset. 
            offset -= elem.scrollTop;
        }
    }
    return offset;
}

errorHover._isHoverDisplayedTop = function (element) {
    if(element.id && element.id.indexOf('inlineId') >= 0) {
        return true;
    }
    return false;
}

errorHover.onload = function () {
	if(!tooltipElement) {
	    tooltipElement = document.createElement("div");
	    tooltipElement.id = TOOLTIP_ELEMENT_ID;
	    tooltipElement.style.position = 'absolute';
	    tooltipElement.className = 'error-hover-text';
	    document.body.appendChild(tooltipElement);
    }
}

errorHover.showErrorHover = function (tooltipText, event, tooltipWidth) {
    if(!errorHoverEnable) {
        return;
    }
    var element;
    if (commonUtil.browserIsIE()) {
        element = event.srcElement;
    } else {
        element = event.target;
    }
    var xOffset = 0;
    var yOffset = 0;
    if(errorHover._isHoverDisplayedTop(element)) {
        tooltipElement.innerHTML = errorHover._getDownArrowTooltipTable(tooltipText, tooltipWidth);
    } else {
        tooltipElement.innerHTML = errorHover._getTooltipTable(tooltipText, tooltipWidth);
    }

    var dLeft = 0;
    var dTop = 0;
    var stackSize = dialogUtil.visibleDialogStack.length;
    if (stackSize > 0 && dialogUtil.visibleDialogStack[stackSize - 1].display) {
        var currDialog = dialogUtil.visibleDialogStack[stackSize - 1];
        var temp = currDialog.display.style.left;
        temp = temp.substring(0,temp.length - 2);
        dLeft = temp*1;
        dTop = currDialog.display.style.top;
        temp = currDialog.display.style.top;
        temp = temp.substring(0,temp.length - 2);
        dTop = temp*1;
    }

    if (commonUtil.browserIsIE()) {
        // IE event location is relative
        if ((event.clientX + xOffset + tooltipElement.clientWidth) > document.body.clientWidth) {
            xOffset = document.body.clientWidth - tooltipElement.clientWidth - event.clientX;
        }
        
        if ((event.clientY + yOffset + tooltipElement.clientHeight) > document.body.clientHeight) {
            yOffset = 0 - yOffset - tooltipElement.clientHeight;
        }
         
        if(errorHover._isHoverDisplayedTop(element)) { 
            tooltipElement.style.posLeft =  dLeft + event.clientX - 30;
            tooltipElement.style.posTop = dTop + element.offsetTop + errorHover._getGrossOffsetTop(element) - 30 ;
        } else {
            tooltipElement.style.posLeft =  dLeft + element.offsetLeft + errorHover._getGrossOffsetLeft(element) + element.offsetWidth  + 25;
            tooltipElement.style.posTop = dTop + element.offsetTop + errorHover._getGrossOffsetTop(element) + 2;
        }
    } else {
        // Firefox event location is absolute
        // Netscape does not support clientWidth or clientHeight so we cannot really get the size
        // of the tooltip.  offsetWidth and offsetHeight are the closest attributes that may help us
        // guess how big the tooltip is, but it is not always exact.
        if ((event.pageX + xOffset + tooltipElement.offsetWidth) > (window.innerWidth + window.pageXOffset)) {
            xOffset = window.innerWidth + window.pageXOffset - tooltipElement.offsetWidth - event.pageX - 20;
        }
        if ((event.pageY + yOffset + tooltipElement.offsetHeight) > (window.pageYOffset + window.innerHeight)) {
            yOffset = 0 - yOffset - tooltipElement.offsetHeight;
        }
        if(dLeft != 0) {
        	dLeft += 140;
        }
        if(dTop != 0) {
        	dTop += 60;
        }
        if(errorHover._isHoverDisplayedTop(element)) {
            tooltipElement.style.left = dLeft + event.pageX + xOffset;
            tooltipElement.style.top = dTop + event.pageY + yOffset;
        } else {        
            tooltipElement.style.left =  dLeft + element.offsetLeft + errorHover._getGrossOffsetLeft(element) + element.offsetWidth  + 25;
            tooltipElement.style.top = dTop + element.offsetTop + errorHover._getGrossOffsetTop(element) + 2;
        }
    }

    tooltipElement.style.visibility = "visible";
    tooltipElement.style.borderColor = '#ff0000'
}
    
// Hides the tooltip upon mouse out.
errorHover.hideErrorHover = function () {
    if (tooltipElement) {
        tooltipElement.style.visibility = 'hidden';
    }
}
    
errorHover.disableHover = function () {
    errorHoverEnable = false;
}
    
errorHover.enableHover = function () {
    errorHoverEnable = true;
}


/**
 * Helper class for immitating browser collections
 */
function Collection (element) {
    this.element = element;
    this.length = 1;
}

Collection.prototype.item = function (index) {
    return this.element;
}


var errorHighLightHandler = new Object();

/**
 * Form to which the validated fields belong.
 * Set this *before* peforming a partial-update if:
 * - You have a page with multiple forms, and
 * - These forms have fields with identical names
 */
errorHighLightHandler.form = null;

errorHighLightHandler._getElement = function (val) {
    if (errorHighLightHandler.form != null) {
        e = errorHighLightHandler.form.elements[val];
        if (e) {
            if (! e.type) {
                // Multiple matches - return first one
                return e.item(0);
            }

            return e;
        }
    }

    var e = document.getElementById(val);
    if(e) {
        return e;   
    }
    e = document.getElementsByName(val);
    if(e) {
        // Return first match
        return e.item(0);
    }
    return undefined;
}

errorHighLightHandler._isHighLight = function (element) {
    if(element.className) {
        return (element.className.indexOf("field-value-error") == 0 
               || element.className.indexOf("field-value-error-selected") == 0);
    }
    return false;
}

errorHighLightHandler._getAllElement = function (val) {
    if (errorHighLightHandler.form != null) {
        e = errorHighLightHandler.form.elements[val];
        if (e) {
            if (! e.length) {
                // Single match - wrap in collection
                return new Collection(e);
            }

            return e;
        }
    }
    var e = document.getElementById(val);
    if (e) {
        // Wrap in collection
        return new Collection(e);
    }
    e = document.forms[0].elements[val];
    if(e) {
    	return new Collection(e);
    }
    return undefined;
}

errorHighLightHandler.ensureVisible = function(){
    if(errorHighLightHandler.focusElement != null){
        // make sure the first error is always visible
        var parentE = errorHighLightHandler.focusElement.parentNode;
        while(parentE != null && parentE.style != null && parentE.style.display != 'none'){
            parentE = parentE.parentNode;
        }
        if(parentE != null){
            if(self.handleDisplayError){
                self.handleDisplayError(parentE.id)
            }else{
                if(parentE.style != null){
                    parentE.style.display = '';
                }
            }
        }
     }
}
errorHighLightHandler.showElementHighLight = function (eName) {
    elements = errorHighLightHandler._getAllElement(eName);
    if(elements) {
        for(var j = 0; j < elements.length; j++) {
            var e = elements.item(j);
            if(errorHighLightHandler._isSupportedType(e) 
               && !errorHighLightHandler._isHighLight(e)) {
                errorHighLightHandler._showHighLight(e);
            }
        }
    }       
}

errorHighLightHandler.showHighLight = function (errorList) {
    for (var i = 0; i < errorList.length; i++) {
        e = errorHighLightHandler._getElement(errorList[i].nameOrId);
        if(e && errorHighLightHandler._isSupportedType(e)
             && !errorHighLightHandler._isHighLight(e)) {
            if((errorList[i].errorValue != null && errorList[i].errorValue == e.value)
               || errorList[i].errorValue == null) { 
                errorHighLightHandler._showHighLight(e);
                errorHighLightHandler.focusElement = e;                   
            }
        }
    }
}

errorHighLightHandler.showAllHighLight = function (errorList) {
	for (var i = 0; i < errorList.length; i++) {
        elements = errorHighLightHandler._getAllElement(errorList[i].nameOrId);
        if(elements) {
            for(var j = 0; j < elements.length; j++) {
                var e = elements.item(j);
                if(errorHighLightHandler._isSupportedType(e)
                   && !errorHighLightHandler._isHighLight(e)) {
                    if((errorList[i].errorValue != null && errorList[i].errorValue == e.value)
                       || errorList[i].errorValue == null) { 
                        errorHighLightHandler._showHighLight(e);
                        errorHighLightHandler.focusElement = e;
                    }
                }
            }
        }
    }
    if(errorHighLightHandler.focusElement != null){
       errorHighLightHandler.ensureVisible();
    }
}

errorHighLightHandler.hideHighLight = function (errorList) {
    for (var i = 0; i < errorList.length; i++) {
        var e = errorHighLightHandler._getElement(errorList[i].nameOrId);
        if(e && errorHighLightHandler._isSupportedType(e)) {
            var index = e.className.indexOf(" ");
            if(index > 0 && errorHighLightHandler._isHighLight(e)) {
                errorHighLightHandler._hideHighLight(e);
            }       
        }   
    }
}

errorHighLightHandler.hideAllHighLight = function (errorList) {
    for (var i = 0; i < errorList.length; i++) {
        var elements = errorHighLightHandler._getAllElement(errorList[i].nameOrId);
        if(elements) {
            for(var j = 0; j < elements.length; j++) {
                var e = elements.item(j);
                if(errorHighLightHandler._isSupportedType(e)) {
                    var index = e.className.indexOf(" ");
                    if(index > 0  && errorHighLightHandler._isHighLight(e)) {
                        errorHighLightHandler._hideHighLight(e);
                    }
                }
            }
        }
    }
}

errorHighLightHandler.hideElementHighLight = function (element) {
    var e = element;
    var index = e.className.indexOf(" ");
    if(index > 0 && errorHighLightHandler._isHighLight(e)) {
        errorHighLightHandler._hideHighLight(e);
    }
}

errorHighLightHandler._hideHighLight = function(e) {
    var index = e.className.indexOf(" ");
    e.className = e.className.substring(index + 1);
    if(e.type == 'select-one' ||
       e.type == 'select-multiple') {
        var div = document.getElementById(e.id + ".span");
        if(div) {
            div.className = div.className.substring(index + 1);     
        }       
     }
}

errorHighLightHandler._showHighLight = function(e) {
	e.className = 'field-value-error ' + e.className;
    if(e.type == 'select-one' ||
       e.type == 'select-multiple') {
        var div = document.getElementById(e.id + ".span");
        if(div) {
            div.className = 'field-value-error ' + div.className;   
        }       
     }
}

errorHighLightHandler.hideElementHighLightByName = function (val) {
    var e = errorHighLightHandler._getElement(val); 
    if(e) {
        errorHighLightHandler.hideElementHighLight(e);
    }
}

errorHighLightHandler.showErrorHover = function (element,evt) {     
    var err = errorHighLightHandler._getError(element);
    if(err) {
    	errorHighLightHandler.hideSelectControl(element);
        errorHover.showErrorHover(err.errorMesg,evt,undefined);
    }
}

errorHighLightHandler.deleteErrorHover = function (element) {
    if (errorHandler) {
        errorHandler.deleteError(element.id);
    }   
}

errorHighLightHandler.clearAllErrorHighLight = function () {
    if (errorHandler){
        errorHighLightHandler.hideAllHighLight(errorHandler.getAllErrors());
        errorHover.hideErrorHover();
    }
}

errorHighLightHandler._handleOnclick = function (element) {
    if(element.className) {
        var err = errorHighLightHandler._getError(element);
        if(err) {
            var index = element.className.indexOf(" ");
            if(index > 0 && errorHighLightHandler._isHighLight(element)) {
                element.className = "field-value-error-selected " + element.className.substring(index + 1);
                if(element.type == 'select-one' ||
                   element.type == 'select-multiple') {
                    var div = document.getElementById(element.id + ".span");
                    if(div) {
                        div.className = 'field-value-error ' + div.className;   
                    }       
                 }
            }
        }
    }
}

errorHighLightHandler._handleOnBlur = function (element) {
    if(element.className) {
        var err = errorHighLightHandler._getError(element);
        if(err) {
            var index = element.className.indexOf(" ");
            if(index > 0 && errorHighLightHandler._isHighLight(element)) {
                element.className = "field-value-error " + element.className.substring(index + 1);
            }
        }
    }
}

errorHighLightHandler._isSupportedType = function (element) {
    if(!element || !element.type) {
        return false;   
    }
    return (element.type == 'text' ||
            element.type == 'textarea' ||
            element.type == 'select-one' ||
            element.type == 'select-multiple' ||
            element.type == 'password' ||
            element.type == 'file' ||
            element.type == 'checkbox' ||
            element.type == 'radio');
}

errorHighLightHandler._getElementFromEvent = function (evt) {
    if (commonUtil.browserIsIE()) {
        return evt.srcElement;
    } else {
        return evt.target;
    }
}

errorHighLightHandler._getError = function (element) {
    if (errorHandler) 
    {
        var errorList = errorHandler.getAllErrors();
        for (var i = 0; i < errorList.length; i++) {            
            if (typeof element == "object" && errorHighLightHandler._isSupportedType(element)) {
                if(element.id == errorList[i].nameOrId || element.name == errorList[i].nameOrId) {
                   return errorList[i];
               }
            } else if (typeof element == "string") {
                if (element == errorList[i].nameOrId) {
                   return errorList[i];
               }
            }
        }
    }

    return undefined;
}

errorHighLightHandler.handleOnClick = function (e) {
    if(!e) {
        e = window.event;
    }
    var element = errorHighLightHandler._getElementFromEvent(e);
    if(!errorHighLightHandler._isSupportedType(element)) {
        return true;    
    }
    errorHighLightHandler._handleOnclick(element);
    return true;
}

errorHighLightHandler.handleOnBlur = function (e) {
    if(!e) {
        e = window.event;
    }
    var element = errorHighLightHandler._getElementFromEvent(e);
    if(!errorHighLightHandler._isSupportedType(element)) {
        return true;    
    }
    errorHighLightHandler._handleOnBlur(element);
    return true;
}

errorHighLightHandler.findSiblingSelectControl = function(element) {
	//try to findout the sibling element is a select control
	//by going through elements array of the form
	//this work for most the time except the select control is
	//in seperate table
	var form = element.form;
	elements = form.elements;
	for(i = 0; i < elements.length; i++) {
		if(element.name == elements[i].name) {
			i++;
			//skip all hidden elements
			while(i < elements.length && elements[i].type == 'hidden'){i++;}			
			if(i < elements.length) {
				if(elements[i].type == 'select-one' ||
            		elements[i].type == 'select-multiple') {
            		return elements[i];	
            	}		
			} 	
		} 	
	}
	return undefined; 	
}

errorHighLightHandler.hideSelectControl = function(element) {
	var hideElement = errorHighLightHandler.findSiblingSelectControl(element);
	if(hideElement) {
		hideElement.style.visibility = 'hidden';	
	}	   	
}

errorHighLightHandler.showSelectControl = function(element) {
	var hideElement = errorHighLightHandler.findSiblingSelectControl(element);
	if(hideElement) {
		hideElement.style.visibility = 'visible';	
	}
}
errorHighLightHandler.handleOnMouseOver = function (e) {
    if(!e) {
        e = window.event;
    }
    var element = errorHighLightHandler._getElementFromEvent(e);
    if(!errorHighLightHandler._isSupportedType(element)) {
        return true;    
    }
    errorHighLightHandler.showErrorHover(element,e);
    return true;
}

errorHighLightHandler.handleOnMouseOut = function (e) {
    if(!e) {
        e = window.event;
    }
    var element = errorHighLightHandler._getElementFromEvent(e);
    if(!errorHighLightHandler._isSupportedType(element)) {
        return true;    
    }
    errorHighLightHandler.showSelectControl(element);
    errorHover.hideErrorHover(element,e);
    return true;
}

errorHighLightHandler.handleOnMouseDown = function (e) {
    errorHover.disableHover();
    return true;
}

errorHighLightHandler.handleOnMouseUp = function (e) {
    errorHover.enableHover();
    return true;
}

errorHighLightHandler._attachEventToElement = function(element, fn, evtName) {
	if (errorHighLightHandler._isSupportedType(element)) {       
        if (window.attachEvent) {
            element.attachEvent("on" + evtName, fn);
        } else if (window.addEventListener) {
            element.addEventListener(evtName, fn, false); 
        }                  
    }
}

errorHighLightHandler._attachEvent = function (evtName, fn, form) {
    for(i = 0; i < form.elements.length; i++) {
    	this._attachEventToElement(form.elements[i], fn, evtName);
    }
}

errorHighLightHandler.attachEvent = function (evtName, fn, formName) {
    if (formName) {
        var form = document.forms[formName];
        errorHighLightHandler._attachEvent(evtName,fn, form);
    } else {
        for(j = 0; j < document.forms.length; j++) {
            errorHighLightHandler._attachEvent(evtName, fn, document.forms[j]);
        }
    }
}

errorHighLightHandler.attachAllEvent = function(formName) {
    errorHighLightHandler.attachEvent("blur", errorHighLightHandler.handleOnBlur, formName);
    errorHighLightHandler.attachEvent("click", errorHighLightHandler.handleOnClick, formName);
    errorHighLightHandler.attachEvent("mouseover", errorHighLightHandler.handleOnMouseOver, formName);
    errorHighLightHandler.attachEvent("mouseout", errorHighLightHandler.handleOnMouseOut, formName);
}

errorHighLightHandler.attachAllEventToComponent = function(elementName) {
	if (elementName && elementName != "") {
		var elements = document.getElementsByName(elementName);
		if (elements) {
			for (var i = 0; i < elements.length; i++) {
				errorHighLightHandler._attachEventToElement(elements[i], errorHighLightHandler.handleOnBlur, "blur");
				errorHighLightHandler._attachEventToElement(elements[i], errorHighLightHandler.handleOnClick, "click");
				errorHighLightHandler._attachEventToElement(elements[i], errorHighLightHandler.handleOnMouseOver, "mouseover");
				errorHighLightHandler._attachEventToElement(elements[i], errorHighLightHandler.handleOnMouseOut, "mouseout");
			}
		}
	}
}

errorHighLightHandler.focus = function (formName) {
    if (errorHighLightHandler.focusElement && errorHighLightHandler.focusElement != null) {
        errorHighLightHandler.focusElement.select();
    }
}

errorHighLightHandler.focusElement = null;

errorHighLightHandler.onload = function (msg) {
        if(msg.type == MessageType.ONLOAD) {
            errorHighLightHandler.attachAllEvent(undefined);
        }
}

messageController.addListener(errorHighLightHandler.onload);
messageController.addListener(errorHover.onload);
