//-----------------------------------------------------------------------
// Copyright (C) Totaljobs Group Ltd. All rights reserved.
//-----------------------------------------------------------------------

Type.registerNamespace("PJB.UI"); 

// Gets the width and height of viewport, excluding scroll offsets.
// http://www.quirksmode.org/viewport/compatibility.html
PJB.UI.getViewportDimensions = function() {
	var w, h;
	if (self.innerHeight) {
		// all except Explorer
		w = self.innerWidth;
		h = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight) {
		// Explorer 6 Strict Mode
		w = document.documentElement.clientWidth;
		h = document.documentElement.clientHeight;
	}
	else if (document.body) {
		// other Explorers
		w = document.body.clientWidth;
		h = document.body.clientHeight;
	}
	return {width:w, height:h};
};

// Gets the scroll offsets of the page.
// http://www.quirksmode.org/viewport/compatibility.html
PJB.UI.getPageScrollOffsets = function() {
	var x, y;
	if (self.pageYOffset) {
		// all except Explorer
		x = self.pageXOffset;
		y = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop) {
		// Explorer 6 Strict
		x = document.documentElement.scrollLeft;
		y = document.documentElement.scrollTop;
	}
	else if (document.body) {
		// all other Explorers
		x = document.body.scrollLeft;
		y = document.body.scrollTop;
	}
	return new Sys.UI.Point(x, y);
};

// Gets the width and height of the page.
// http://www.quirksmode.org/viewport/compatibility.html
PJB.UI.getPageDimensions = function() {
	var w = Math.max(document.body.scrollWidth, document.body.offsetWidth);
	var h = Math.max(document.body.scrollHeight, document.body.offsetHeight);
	return {width: w, height: h};
};

PJB.UI.getPosition = function(element) {
	var x = 0;
	var y = 0;
	do {
		y += element.offsetTop  || 0;
		x += element.offsetLeft || 0;
		element = element.offsetParent;
	} while (element);
	return new Sys.UI.Point(x, y);
};

PJB.UI.getBounds = function(element) {
	var p = PJB.UI.getPosition(element);
	return new Sys.UI.Bounds(p.x, p.y, element.offsetWidth || 0, element.offsetHeight || 0);
};

PJB.UI.setBounds = function(element, box) {
	Sys.UI.DomElement.setLocation(element, box.x, box.y);
    element.style.width = box.width.toString() + 'px';
	element.style.height = box.height.toString() + 'px';
};

PJB.UI.isVisible = function(element)
{
    while(element && element.tagName != "BODY")
    {
        if(element.style.display == "none" || element.style.visibility == "hidden")
            return false;
        element = element.parentNode;
    }
    return true;
};

PJB.UI.resolveElement = function(element)
{
    // Used by functions you can pass an element or a string to
	if(typeof(element) == "string")
	    return document.getElementById(element);
	return element;
};

PJB.UI.moveElement = function(element, newLocation, position)
{
	element = PJB.UI.resolveElement(element);
	newLocation = PJB.UI.resolveElement(newLocation);
	if(typeof(position) != "undefined" && newLocation.childNodes.length > position)
	    newLocation.insertBefore(element, newLocation.childNodes[position]);
	else
	    newLocation.appendChild(element);
};

PJB.UI.moveElements = function(elements, newLocation, position)
{
    for(var index=0; index<elements.length; index++)
    {
        var element = PJB.UI.resolveElement(elements[index]);
        PJB.UI.moveElement(element, newLocation, position);
    }
};

PJB.UI.moveChildren = function(parentElement, newLocation, position)
{
    parentElement = PJB.UI.resolveElement(parentElement);
    var children = [];
    for(var index=0; index<parentElement.childNodes.length; index++)
        children.push(parentElement.childNodes[index]);
    PJB.UI.moveElements(children, newLocation, position);
};

PJB.UI.raiseChangeEvent = function(element) {
	// raise change event
	if (document.createEventObject) {
		var ev = document.createEventObject();
		element.fireEvent("onchange", ev);
	} else if (document.createEvent) {
		var ev = document.createEvent("HTMLEvents");
		ev.initEvent("change", true, true);
		element.dispatchEvent(ev);
	} else {
		try {
			element["onchange"]();
		} catch (err) {}
	}
};

// Inserts newElement after element
PJB.UI.insertAfter = function(newElement, element) {
    if (element.nextSibling) {
		element.parentNode.insertBefore(newElement, element.nextSibling);
	} else {
		element.parentNode.appendChild(newElement);
	}
};

// Given a unique serverId, returns the corresponding clientId.
// Requires the control to be registered using PageUtility.RegisterControlClientIds().
// If the id isn't specified in the ServerIds[] array, then the passed id is returned.
// If a server control sits within a naming container, the clientid of the control will be different to the server side id.
// This method looks to see if the clientid was regsitered server side.
$getClientId = PJB.UI.getClientId = function(serverId) {
    if (typeof AspNetControlIDs === "object") {
        var clientId = AspNetControlIDs[serverId];
        if (clientId) {
            return clientId;
        }
    }
	return serverId;
};

/**********************************************************************/
/* Methods for dealing with controls */

Type.registerNamespace("PJB.UI.Controls");

PJB.UI.Controls.getValidators = function(parentElement)
{
    parentElement = PJB.UI.resolveElement(parentElement);
    // get a reference to all the validators in the content panel
    // I think currently all validators are div elements
    var divElements = parentElement.getElementsByTagName("div");
    var validators = [];
    for(var valIndex=0; valIndex<divElements.length; valIndex++)
    {
	    if(typeof(divElements[valIndex].getAttribute("evaluationfunction")) !== "undefined")
		    validators.push(divElements[valIndex]);
    }
    return validators;
};

PJB.UI.Controls.enableValidators = function(validators, enabled)
{
    var hasValidationHappened = PJB.UI.Controls.hasValidationHappened();
    for(var x=0; x<validators.length; x++)
    {
        validators[x].setAttribute("enabled", enabled);
        // We don't want the validation messages to appear unless the page is
        // already showing validation messages.
        // One way to check this is whether the summary is visible or not
        if(hasValidationHappened)
        {
            ValidatorValidate(validators[x]);
            ValidatorUpdateIsValid();
        }
    }
};

PJB.UI.Controls.enableChildValidators = function(parentElement, enabled)
{
    var validators = PJB.UI.Controls.getValidators(parentElement);
    PJB.UI.Controls.enableValidators(validators, enabled);
};

PJB.UI.Controls.enableChildValidatorsByVisibility = function(parentElement)
{
    var validators = PJB.UI.Controls.getValidators(parentElement);
    var visibleValidators = [];
    var hiddenValidators = [];
    for(var x=0; x<validators.length; x++)
    {
        var validator = validators[x];
        if(PJB.UI.isVisible(validator.parentElement))
            visibleValidators.push(validator);
        else if(!PJB.UI.isVisible(validator.parentElement))
            hiddenValidators.push(validator);
    }
    PJB.UI.Controls.enableValidators(visibleValidators, true);
    PJB.UI.Controls.enableValidators(hiddenValidators, false);
};

PJB.UI.Controls.hasValidationHappened = function()
{
    if (typeof(Page_ValidationSummaries) == "undefined" || Page_ValidationSummaries.length === 0) 
        return true;
    return Page_ValidationSummaries[0].offsetHeight > 0;
};


/**********************************************************************/
/* Methods for walking the DOM */

Type.registerNamespace("PJB.UI.Find");
PJB.UI.Find.childByTag = function(element, tagName, recursive)
{
    if(recursive)
    {
        // Returns the first child at any depth found with a particular tag name
        var children = element.getElementsByTagName(tagName);
        if(children && children.length > 0)
            return children[0];
    } 
    else
    {
        // Returns the first direct child found with a particular tag name
	    for(var index=0; index<element.childNodes.length; index++)
	    {
	        if(element.childNodes[index].tagName == tagName)
	            return element.childNodes[index];
	    }
	}
	return null;
};

PJB.UI.Find.childByClass = function(element, className)
{
    // Returns the first child found with a class name
	for(var index=0; index<element.childNodes.length; index++)
	{
	    var child = element.childNodes[index];
	    if(PJB.UI.CSS.hasClass(child, className))
	        return child;
	    
	    var possibleMatch = PJB.UI.Find.childByClass(child, className);
	    if(possibleMatch !== null)
	        return possibleMatch;
	}
	return null;
};

PJB.UI.Find.siblingByClass = function(element, className, direction)
{
    // Next sibling with a class name
	var sibling = element.nextSibling;
	while(sibling !== null && !PJB.UI.CSS.hasClass(sibling, className))
		sibling = sibling.nextSibling;
	return sibling;
};

PJB.UI.Find.prevSiblingByTag = function(element, tagName)
{
    // Next sibling with a tag name
	var sibling = element.previousSibling;
	while(sibling !== null && sibling.tagName != tagName)
		sibling = sibling.previousSibling;
	return sibling;
};

PJB.UI.Find.siblingByTag = function(element, tagName)
{
    // Next sibling with a tag name
	var sibling = element.nextSibling;
	while(sibling !== null && sibling.tagName != tagName)
		sibling = sibling.nextSibling;
	return sibling;
};

PJB.UI.Find.parentByTag = function(element, tagName)
{
    // Next sibling with a tag name
	var parentElement = element.parentNode;
	while(parentElement !== null)
    {
        if(parentElement.tagName == tagName)
            return parentElement;
		parentElement = parentElement.parentNode;
    }
	return parentElement;
};

/**********************************************************************/
/* Methods for doing things with CSS */

Type.registerNamespace("PJB.UI.CSS");

PJB.UI.CSS.hasClass = function(element, className)
{
	if(!element.className) return false;
	return element.className.indexOf(className) > -1;
};

/**********************************************************************/

// Sets element opacity.
// value = 0 to 100.
switch(Sys.Browser.agent) {
    case Sys.Browser.InternetExplorer:
		PJB.UI.setOpacity = function(element, value) {
			element.style.filter = "alpha(opacity=" + value + ")";
		};
        break;
    case Sys.Browser.Firefox:
		PJB.UI.setOpacity = function(element, value) {
			element.style.MozOpacity = value / 100;
		};
        break;
    case Sys.Browser.Safari:
		PJB.UI.setOpacity = function(element, value) {
			element.style.KhtmlOpacity = value / 100;
		};
        break;
    case Sys.Browser.Opera:
		PJB.UI.setOpacity = function(element, value) {
			element.style.opacity = value / 100;
		};
        break;
    default:
		PJB.UI.setOpacity = function(element, value) {
			element.style.opacity = value / 100;
		};
		break;
}

// Standard CSS class names.
PJB.UI.CSS_HEAD = "hd";
PJB.UI.CSS_BODY = "bd";
PJB.UI.CSS_FOOT = "ft";
PJB.UI.CSS_TOP_LEFT = "tl";
PJB.UI.CSS_TOP_RIGHT = "tr";
PJB.UI.CSS_BOTTOM_LEFT = "bl";
PJB.UI.CSS_BOTTOM_RIGHT = "br";

/* QueryString */
PJB.UI._QueryString = function() {
	PJB.UI._QueryString.initializeBase(this);
	this._queryString = {};
};
PJB.UI._QueryString.prototype = {
    initialize: function() {
        PJB.UI._QueryString.callBaseMethod(this, "initialize");
		var query = window.location.search.substring(1);
		var pairs = query.split("&");
		for (var i=0; i<pairs.length; i++) {
			var pair = pairs[i].split('=');
			var name = pair[0];
			var value = pair[1];
			if (!(name in this._queryString)) {
				this._queryString[name] = [];
			}
			this._queryString[name].push(unescape(value));
		}
    },
	dispose: function() {
		this._queryString = null;
        PJB.UI._QueryString.callBaseMethod(this, "dispose");
    },
    getValue: function(name) {
		if (this._queryString[name].length > 0) {
			return this._queryString[name][0];
		}
		return null;
    },
    getValues: function(name) {
		return this._queryString[name];
    }
}
PJB.UI._QueryString.registerClass("PJB.UI._QueryString", Sys.Component);

Sys.Application.add_init(function() {
	PJB.UI.QueryString = $create(PJB.UI._QueryString, null, null, null, null);
});

/* Cookies */
PJB.UI._Cookies = function() {
	PJB.UI._Cookies.initializeBase(this);
	this._cookies = {};
};
PJB.UI._Cookies.prototype = {
    initialize: function() {
        PJB.UI._Cookies.callBaseMethod(this, "initialize");
		var query = document.cookie;
		var pairs = query.split(";");
		for (var i=0; i<pairs.length; i++) {
			var pair = pairs[i].split('=');
			var name = pair[0];
			var value = pair[1];
			if (!(name in this._cookies)) {
				this._cookies[name] = [];
			}
			this._cookies[name].push(unescape(value));
		}
    },
	dispose: function() {
		this._cookies = null;
        PJB.UI._Cookies.callBaseMethod(this, "dispose");
    },
	setCookie: function(name, value, expires, path, domain, secure) {
		var cookieString = name + "=" + escape(value);
		if (!!expires) {
			cookieString += "; expires=" + expires.toUTCString();
		}
		if (!!path) {
			cookieString += "; path=" + path;
		}
		if (!!domain) {
			cookieString += "; domain=" + domain;
		}
		if (!!secure) {
			cookieString += "; secure";
		}
		document.cookie = cookieString;
	},
    getCookie: function(name) {
		if (this._cookies[name].length > 0) {
			return this._cookies[name][0];
		}
		return null;
    },
    getValues: function(name) {
		return this._cookies[name];
    }
}
PJB.UI._Cookies.registerClass("PJB.UI._Cookies", Sys.Component);

Sys.Application.add_init(function() {
	PJB.UI.Cookies = $create(PJB.UI._Cookies, null, null, null, null);
});

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

