

// This code is from the book JavaScript: The Definitive Guide, 5th Edition,
// by David Flanagan. Copyright 2006 O'Reilly Media, Inc. (ISBN #0596101996)
/*
 * Handler.js -- Portable event handler registration functions
 *
 * This module defines event handler registration and deregistration functions
 * Handler.add() and Handler.remove(). Both functions take three arguments:
 * 
 *   element: the DOM element, document, or window on which the handler
 *      is to be added or removed.
 * 
 *   eventType: a string that specifies the type of event for which the
 *      handler is to be invoked.  Use DOM-standard type names, which do
 *      not include an "on" prefix. Examples: "click", "load", "mouseover".
 *
 *   handler: The function to be invoked when an event of the specified type
 *      occurs on the specified element.  This function will be invoked as
 *      a method of the element on which it is registered, and the "this"
 *      keyword will refer to that element.  The handler function will be
 *      passed an event object as its sole argument.  This event object will
 *      either be a DOM-standard Event object or a simulated one. If a 
 *      simulated event object is passed, it will have the following DOM-
 *      compliant properties: type, target, currentTarget, relatedTarget,
 *      eventPhase, clientX, clientY, screenX, screenY, altKey, ctrlKey,
 *      shiftKey, charCode, stopPropagation(), and preventDefault()
 * 
 * Handler.add() and Handler.remove() have no return value.
 * 
 * Handler.add() ignores duplicate registrations of the same handler for
 * the same event type and element.  Handler.remove() does nothing if called
 * to remove a handler that has not been registered.
 *
 * Implementation notes:
 * 
 * In browsers that support the DOM standard addEventListener() and
 * removeEventListener() event registration functions, Handler.add() and
 * Handler.remove() simply invoke these functions, passing false as the 
 * third argument (meaning that the event handlers are never registered as
 * capturing event handlers).
 * 
 * In versions of Internet Explorer that support attachEvent(), Handler.add()
 * and Handler.remove() use attachEvent() and detachEvent(). To
 * invoke the handler function with the correct this keyword, a closure is
 * used.  Since closures of this sort cause memory leaks in Internet Explorer,
 * Handler.add() automatically registers an onunload handler to deregister
 * all event handlers when the page is unloaded. To keep track of
 * registered handlers, Handler.add() creates a property named _allHandlers on
 * the window object and creates a property named _handlers on any element on
 * which a handler is registered.
 */
var Handler = {};

// In DOM-compliant browsers, our functions are trivial wrappers around
// addEventListener() and removeEventListener().
if (document.addEventListener) {
    Handler.add = function(element, eventType, handler) {
        element.addEventListener(eventType, handler, false);
    };

    Handler.remove = function(element, eventType, handler) {
        element.removeEventListener(eventType, handler, false);
    };
}
// In IE 5 and later, we use attachEvent() and detachEvent(), with a number of
// hacks to make them compatible with addEventListener and removeEventListener.
else if (document.attachEvent) {
    Handler.add = function(element, eventType, handler) {
        // Don't allow duplicate handler registrations
        // _find() is a private utility function defined below.
        if (Handler._find(element, eventType, handler) != -1) return;
        
        // To invoke the handler function as a method of the
        // element, we've got to define this nested function and register
        // it instead of the handler function itself.
        var wrappedHandler = function(e) {
            if (!e) e = window.event;

            // Create a synthetic event object with partial compatibility
            // with DOM events.
            var event = {
                _event: e,    // In case we really want the IE event object
                type: e.type,           // Event type
                target: e.srcElement,   // Where the event happened
                currentTarget: element, // Where we're handling it
                relatedTarget: e.fromElement?e.fromElement:e.toElement,
                eventPhase: (e.srcElement==element)?2:3,

                // Mouse coordinates
                clientX: e.clientX, clientY: e.clientY,
                screenX: e.screenX, screenY: e.screenY,
                
                // Key state
                altKey: e.altKey, ctrlKey: e.ctrlKey,
                shiftKey: e.shiftKey, charCode: e.keyCode,

                // Event management functions
                stopPropagation: function() {this._event.cancelBubble = true;},
                preventDefault: function() {this._event.returnValue = false;}
            }

            // Invoke the handler function as a method of the element, passing
            // the synthetic event object as its single argument.
            // Use Function.call() if defined; otherwise do a hack
            if (Function.prototype.call) 
                handler.call(element, event);
            else {
                // If we don't have Function.call, fake it like this
                element._currentHandler = handler;
                element._currentHandler(event);
                element._currentHandler = null;
            }
        };

        // Now register that nested function as our event handler.
        element.attachEvent("on" + eventType, wrappedHandler);
        
        // Now we must do some record keeping to associate the user-supplied
        // handler function and the nested function that invokes it.

        // We have to do this so that we can deregister the handler with the
        // remove() method and also deregister it automatically on page unload.

        // Store all info about this handler into an object
        var h = {
            element: element,
            eventType: eventType,
            handler: handler,
            wrappedHandler: wrappedHandler
        };

        // Figure out what document this handler is part of.
        // If the element has no "document" property, it is not
        // a window or a document element, so it must be the document
        // object itself.
        var d = element.document || element;
        // Now get the window associated with that document
        var w = d.parentWindow;

        // We have to associate this handler with the window,
        // so we can remove it when the window is unloaded
        var id = Handler._uid();  // Generate a unique property name
        if (!w._allHandlers) w._allHandlers = {};  // Create object if needed
        w._allHandlers[id] = h; // Store the handler info in this object

        // And associate the id of the handler info with this element as well
        if (!element._handlers) element._handlers = [];
        element._handlers.push(id);

        // If there is not an onunload handler associated with the window,
        // register one now.
        if (!w._onunloadHandlerRegistered) {
            w._onunloadHandlerRegistered = true;
            w.attachEvent("onunload", Handler._removeAllHandlers);
        }
    };

    Handler.remove = function(element, eventType, handler) {
        // Find this handler in the element._handlers[] array.
        var i = Handler._find(element, eventType, handler);
        if (i == -1) return;  // If the handler was not registered, do nothing

        // Get the window of this element
        var d = element.document || element;
        var w = d.parentWindow;

        // Look up the unique id of this handler
        var handlerId = element._handlers[i];
        // And use that to look up the handler info
        var h = w._allHandlers[handlerId];
        // Using that info, we can detach the handler from the element
        element.detachEvent("on" + eventType, h.wrappedHandler);
        // Remove one element from the element._handlers array
        element._handlers.splice(i, 1);
        // And delete the handler info from the per-window _allHandlers object
        delete w._allHandlers[handlerId];
    };

    // A utility function to find a handler in the element._handlers array
    // Returns an array index or -1 if no matching handler is found
    Handler._find = function(element, eventType, handler) {
        var handlers = element._handlers;
        if (!handlers) return -1;  // if no handlers registered, nothing found

        // Get the window of this element
        var d = element.document || element;
        var w = d.parentWindow;

        // Loop through the handlers associated with this element, looking
        // for one with the right type and function.
        // We loop backward because the most recently registered handler
        // is most likely to be the first removed one.
        for(var i = handlers.length-1; i >= 0; i--) {
            var handlerId = handlers[i];        // get handler id
            var h = w._allHandlers[handlerId];  // get handler info
            // If handler info matches type and handler function, we found it.
            if (h.eventType == eventType && h.handler == handler) 
                return i;
        }
        return -1;  // No match found
    };

    Handler._removeAllHandlers = function() {
        // This function is registered as the onunload handler with 
        // attachEvent.  This means that the this keyword refers to the
        // window in which the event occurred.
        var w = this;

        // Iterate through all registered handlers
        for(id in w._allHandlers) {
            // Get handler info for this handler id
            var h = w._allHandlers[id]; 
            // Use the info to detach the handler
            h.element.detachEvent("on" + h.eventType, h.wrappedHandler);
            // Delete the handler info from the window
            delete w._allHandlers[id];
        }
    }

    // Private utility to generate unique handler ids
    Handler._counter = 0;
    Handler._uid = function() { return "h" + Handler._counter++; };
}





// This code is from the book JavaScript: The Definitive Guide, 5th Edition,
// by David Flanagan. Copyright 2006 O'Reilly Media, Inc. (ISBN #0596101996)
/*
 * runOnLoad.js: portable registration for onload event handlers.
 * 
 * This module defines a single runOnLoad() function for portably registering
 * functions that can be safely invoked only when the document is fully loaded
 * and the DOM is available.
 *
 * Functions registered with runOnLoad() will not be passed any arguments when
 * invoked. They will not be invoked as a method of any meaningful object, and
 * the this keyword should not be used.  Functions registered with runOnLoad()
 * will be invoked in the order in which they were registered.  There is no
 * way to deregister a function once it has been passed to runOnLoad().
 *
 * In old browsers that do not support addEventListener() or attachEvent(),
 * this function relies on the DOM Level 0 window.onload property and will not
 * work correctly when used in documents that set the onload attribute
 * of their <body> or <frameset> tags.
 */
function runOnLoad(f) {
    if (runOnLoad.loaded) f();    // If already loaded, just invoke f() now.
    else runOnLoad.funcs.push(f); // Otherwise, store it for later
}

runOnLoad.funcs = []; // The array of functions to call when the document loads
runOnLoad.loaded = false; // The functions have not been run yet.

// Run all registered functions in the order in which they were registered.
// It is safe to call runOnLoad.run() more than once: invocations after the
// first do nothing. It is safe for an initialization function to call
// runOnLoad() to register another function.
runOnLoad.run = function() {
    if (runOnLoad.loaded) return;  // If we've already run, do nothing
    for(var i = 0; i < runOnLoad.funcs.length; i++) {
        try { runOnLoad.funcs[i](); }
        catch(e) { /* An exception in one function shouldn't stop the rest */ }
    }
    
    runOnLoad.loaded = true; // Remember that we've already run once.
    delete runOnLoad.funcs;  // But don't remember the functions themselves.
    delete runOnLoad.run;    // And forget about this function too!
};

// Register runOnLoad.run() as the onload event handler for the window
if (window.addEventListener)
    window.addEventListener("load", runOnLoad.run, false);
else if (window.attachEvent) window.attachEvent("onload", runOnLoad.run);
else window.onload = runOnLoad.run;






function CNT_ScrollBar(scrollAreaId, scrollBarId, autoHide)
{
	/* self-referencing instance variable; needed for event handling and execution contexts
	where 'this' refers to something else */
	var myself = this;

	this.scrollActiveIntervalId = null;
	this.scrollInterval = 50;
	this.scrollStep = 50;
	this.autoHide = (autoHide == null) ? false : autoHide;
	this.isScrollBarHidden = false;	
	this.scrollJumpOffsetFactor = 0.5;
	
	this.doScrollUp_interval = function()
	{
		with (myself) {
			scrollArea.scrollTop = Math.max(scrollArea.scrollTop - scrollStep, 0);
			doAdjustScrollBar();
		}
	}

	
	
	this.doScrollDown_interval = function()
	{
		with (myself) {
			scrollArea.scrollTop = Math.min(scrollArea.scrollHeight - scrollArea.clientHeight, scrollArea.scrollTop + scrollStep);
			doAdjustScrollBar();
		}
	}

	
	
	this.handleDocumentEvent = function(e)
	{		
		e.preventDefault();
		e.stopPropagation();
		
		with (myself) {
			if (e.type == "mousemove") {
				event_document_mousemove(e);
			}
			else if (e.type == "mouseup") {
				event_document_mouseup(e);
			}
		}
	
	}	

	
	
	this.handleScrollAreaEvent = function(e)
	{		
		var className = e.target.className;
		if (!className)
			className = "";
		
		with (myself) {
			if (!myself.isScrollBarHidden && (e.type == "DOMMouseScroll" || e.type == "mousewheel")) {
				e.preventDefault();
				e.stopPropagation();
				event_scrollArea_wheel(e);
			}
		}
	}

	this.handleScrollBarEvent = function(e)
	{
		var className = e.target.className;
		if (!className)
			className || "";

		e.preventDefault();
		e.stopPropagation();

		with (myself) {
			/* need to handle thumb first before trough, because thumb is a descendant of trough */
			if (/\bcnt-scroll-thumb\b/.test(className) || isNodeOrDescendant(e.target, scrollThumb)) {
				if (e.type == "mousedown")
					event_thumb_mousedown(e);
			}
			else if (/\bcnt-scroll-trough\b/.test(className) || isNodeOrDescendant(e.target, scrollTrough)) {
				if (e.type == "mousedown")
					event_trough_mousedown(e);
			}
			else if (/\bcnt-scroll-button-up\b/.test(className) || isNodeOrDescendant(e.target, scrollButtonUp)) {
				if (e.type == "mousedown")
					event_buttonUp_mousedown(e);
			}
			else if (/\bcnt-scroll-button-down\b/.test(className) || isNodeOrDescendant(e.target, scrollButtonDown)) {
				if (e.type == "mousedown")
					event_buttonDown_mousedown(e);
			}
		}
	}

	this.scrollAreaId = scrollAreaId;
	this.scrollBarId = scrollBarId;
	this.scrollArea = document.getElementById(scrollAreaId);
	this.scrollArea.scrollBar = this;
	this.scrollBar = document.getElementById(scrollBarId);

	this.scrollButtonUp = getElementsByClass("scroll-button-up", this.scrollBar, "div")[0];
	this.scrollButtonDown = getElementsByClass("scroll-button-down", this.scrollBar, "div")[0];
	this.scrollTrough = getElementsByClass("scroll-trough", this.scrollBar, "div")[0];
	this.scrollThumb = getElementsByClass("scroll-thumb", this.scrollTrough, "div")[0];

	Handler.add(this.scrollBar, "mousedown", this.handleScrollBarEvent);

	Handler.add(this.scrollArea, "DOMMouseScroll", this.handleScrollAreaEvent);
	Handler.add(this.scrollBar, "DOMMouseScroll", this.handleScrollAreaEvent);
	Handler.add(this.scrollArea, "mousewheel", this.handleScrollAreaEvent);
	Handler.add(this.scrollBar, "mousewheel", this.handleScrollAreaEvent);
	this.scrollArea.onmousewheel = this.scrollBar.onmousewheel = function()
	{
		myself.event_scrollArea_wheel(window.event);
	}
		
	this.doAdjustScrollBar();
}

CNT_ScrollBar.prototype.doScrollUp = function()
{
	this.scrollActiveIntervalId = setInterval(this.doScrollUp_interval, this.scrollInterval);
}

CNT_ScrollBar.prototype.doScrollDown = function()
{
	this.scrollActiveIntervalId = setInterval(this.doScrollDown_interval, this.scrollInterval);
}

CNT_ScrollBar.prototype.doScrollJump = function(y)
{
	this.scrollArea.scrollTop = y;
	this.doAdjustScrollBar();
}

CNT_ScrollBar.prototype.doScrollJumpToId = function(id)
{
	var element = document.getElementById(id);
	if (element && element != this.scrollArea && isNodeOrDescendant(element, this.scrollArea))
		this.doScrollJump(getOffsetFrom(element, this.scrollArea) - this.scrollArea.clientHeight * this.scrollJumpOffsetFactor);
}

CNT_ScrollBar.prototype.doAdjustScrollBar = function()
{
	if ((this.scrollArea.clientHeight >= this.scrollArea.scrollHeight) || this.scrollArea.clientHeight == 0) {
		this.scrollThumb.style.height = this.scrollTrough.clientHeight + "px";
		if (this.autoHide) {
			this.isScrollBarHidden = true;
			this.scrollBar.style.display = "none";
			if (isSafari) {  // workaround for Safari float layout flow bug
				this.scrollArea.style.width = "100%";
			}
		}
	}
	else {
		var thumbHeightFrac = this.scrollArea.clientHeight / this.scrollArea.scrollHeight;
	
		if (isNaN(thumbHeightFrac) || !isFinite(thumbHeightFrac))
			thumbHeight = 1.0;
			
		thumbHeightFrac = Math.max(0.1, thumbHeightFrac);
		
		
		if (thumbHeightFrac == 1.0 && this.autoHide) {
			this.isScrollBarHidden = true;
			this.scrollBar.style.display = "none";
			if (isSafari) { // workaround for Safari float layout flow bug
				this.scrollArea.style.width = "100%";
			}
		}
		else {
			this.isScrollBarHidden = false;
			this.scrollBar.style.display = "block";
			if (isSafari) { // workaround for Safari float layout flow bug
				this.scrollArea.style.width = "";
			}
		}
	
		var thumbHeightPx = Math.round(this.scrollTrough.clientHeight * thumbHeightFrac);
		this.scrollThumb.style.height = thumbHeightPx + "px";
	}

	var scrollAreaPercent = this.scrollArea.scrollTop / (this.scrollArea.scrollHeight - this.scrollArea.clientHeight);

	var thumbTop = scrollAreaPercent * (this.scrollTrough.clientHeight - this.scrollThumb.clientHeight);

	/* if thumb is at the bottom, align it exactly with the bottom */
	thumbTop = Math.min(thumbTop, this.scrollTrough.clientHeight - this.scrollThumb.clientHeight);
	/* if thumb is at the top, align it exactly with the top */
	if (this.scrollArea.scrollTop == 0)
		thumbTop = 0;
	
	thumbTop = Math.round(thumbTop);

	this.scrollThumb.style.top = thumbTop + "px";

}

CNT_ScrollBar.prototype.stopScroll = function()
{
	clearInterval(this.scrollActiveIntervalId);
}

CNT_ScrollBar.prototype.event_trough_mousedown = function(e)
{
	var absoluteY = e.clientY + document.documentElement.scrollTop;
	if (isIE && (isIE < 7))
		absoluteY += document.body.scrollTop;
	var relativeY = absoluteY - getTotalOffset(this.scrollTrough); // relative to trough
	var relativeThumbOffset = Math.round(Math.max(Math.min(relativeY - this.scrollThumb.clientHeight / 2.0, this.scrollTrough.clientHeight - this.scrollThumb.clientHeight), 0));
	var scrollAreaPercent = relativeThumbOffset / (this.scrollTrough.clientHeight - this.scrollThumb.clientHeight);
	var scrollAreaScrollTop = Math.round((this.scrollArea.scrollHeight - this.scrollArea.clientHeight) * scrollAreaPercent);
	this.scrollArea.scrollTop = scrollAreaScrollTop;
	this.scrollThumb.style.top = "" + relativeThumbOffset + "px";
	this.event_thumb_mousedown(e);
}

CNT_ScrollBar.prototype.event_scrollArea_wheel = function(e)
{
	if (e.detail) {
		if (e.detail < 0)
			this.doScrollUp_interval();
		else
			this.doScrollDown_interval();
	}
	else if (e.wheelDelta) {
		if (e.wheelDelta > 0)
			this.doScrollUp_interval();
		else
			this.doScrollDown_interval();
	}
}

CNT_ScrollBar.prototype.event_buttonDown_mousedown = function(e)
{
	Handler.add(document, "mouseup", this.handleDocumentEvent);
	this.doScrollDown();	
}

CNT_ScrollBar.prototype.event_buttonUp_mousedown = function(e)
{
	Handler.add(document, "mouseup", this.handleDocumentEvent);
	this.doScrollUp();
}



/**
 * This function handles the mouseup event when it is registered on the document
 * element.  In the CNT_ScrollBar object, this event is only triggered for 
 * the scroll up and down buttons, or when the thumb is released from being
 * dragged.  The code is the same for all three cases, so no checking is 
 * necessary to see which case occurred.
 */
CNT_ScrollBar.prototype.event_document_mouseup = function(e)
{
	/*
	The mousemove event is registered only for the duration of a thumb drag;
	if the thumb has been released, the event handler should be removed.
	if the thumb is not being dragged, removing the (non-existant) event is
	harmless.
	*/
	Handler.remove(document, "mousemove", this.handleDocumentEvent);

	/*
	The mouseup event is registered only when a corresponding mousedown event
	is triggered over the scroll buttons or the thumb.  When the mouse button
	is released, the event is no longer needed and should be removed.
	*/
	Handler.remove(document, "mouseup", this.handleDocumentEvent);

	/* in case the scroll buttons were pressed, so that the scrollarea was
	being scrolled at scrollInterval intervals, stop the scrolling */
	this.stopScroll();
}



CNT_ScrollBar.prototype.event_thumb_mousedown = function(e)
{
	Handler.add(document, "mousemove", this.handleDocumentEvent);
	Handler.add(document, "mouseup", this.handleDocumentEvent);
	this.scrollThumb.dragThumbOffsetY = e.clientY - getTotalOffset(this.scrollThumb) + document.documentElement.scrollTop;
}



/**
 * This function handles the mousemove event when it is registered on the document
 * element.  In the CNT_ScrollBar object, this only happens when the thumb is being
 * dragged, so this code assumes that is the case.
 */
CNT_ScrollBar.prototype.event_document_mousemove = function(e)
{
	var absoluteY = e.clientY + document.documentElement.scrollTop;
	var relativeY = absoluteY - getTotalOffset(this.scrollTrough); // relative to trough
	var relativeThumbOffset = Math.round(Math.max(Math.min(relativeY - this.scrollThumb.dragThumbOffsetY, this.scrollTrough.clientHeight - this.scrollThumb.clientHeight), 0));
	var scrollAreaPercent = relativeThumbOffset / (this.scrollTrough.clientHeight - this.scrollThumb.clientHeight);
	var scrollAreaScrollTop = Math.round((this.scrollArea.scrollHeight - this.scrollArea.clientHeight) * scrollAreaPercent);
	this.scrollArea.scrollTop = scrollAreaScrollTop;
	this.scrollThumb.style.top = "" + relativeThumbOffset + "px";
}




/**
 * Rev: 18/07/2007
 * Author: Benjamin Black
 */
var DHTMLRollovers = {
	
	groups: {},
	overImage_suffix: "_over",
	onImage_suffix: "_on",
	classRegEx: /\bDHTMLRollover(?:Toggle|Passive)?\b/i,
	
	windowOnLoad: function()
	{
		DHTMLRollovers.setup();
	},

	setup: function()
	{
		var DHTMLRolloverImages = getElementsByClass(this.classRegEx);

		for (var i = 0; i < DHTMLRolloverImages.length; ++i) {
			var img = DHTMLRolloverImages[i];
			var groupName = this.getGroupName(img);
			var group = (this.groups[groupName]) ? this.groups[groupName] : (this.groups[groupName] = []);
			group[group.length] = img;
			this.setupRollover(group[group.length - 1]);
		}
	},

	setupRollover: function(img)
	{
		if (img.DHTMLRollover_setup) {
			return;
		}
			
		img.DHTMLRollover_isOn = false;
		img.extension = img.src.substring(img.src.lastIndexOf("."), img.src.length);
		img.srcOut = img.src;
		img.srcOver = img.src.replace(img.extension, this.overImage_suffix + img.extension);
		img.srcOn = img.src.replace(img.extension, this.onImage_suffix + img.extension);

		preloadImage(img.srcOver);
		preloadImage(img.srcOn);
		
		img.DHTMLRollover_setup = true;
		
		Handler.add(img, "mouseover", this.event_mouseOver);
		Handler.add(img, "mouseout", this.event_mouseOut);
		if (!/\bDHTMLRolloverPassive\b/.test(img.className))
			Handler.add(img, "click", this.event_click);
	},

	getGroupName: function(img)
	{
		var classes = img.className.split(" ");
		var groupName = "";
		for (var i = 0; i < classes.length; ++i)
			if (this.classRegEx.test(classes[i]) && i < classes.length - 1)
				groupName = classes[i+1];
		return groupName;
	},

	setActive: function(img)
	{	
		this.toggleActive(img);
	},
	
	toggleActive: function(img)
	{
		if (!img.DHTMLRollover_setup) {
			if (!img.className.match(this.classRegEx))
				return;
			this.setupRollover(img);
		}

		var rolloverGroupName = DHTMLRollovers.getGroupName(img);
		
		var rolloverGroup = DHTMLRollovers.groups[rolloverGroupName];
		
		var isAlreadyOn = img.DHTMLRollover_isOn;
		
		for (var i = 0; i < rolloverGroup.length; ++i) {
			if (rolloverGroup[i].DHTMLRollover_isOn) {	
				rolloverGroup[i].DHTMLRollover_isOn = false;
				rolloverGroup[i].src = rolloverGroup[i].srcOut;
			}
		}
		
		img.DHTMLRollover_isOn = (/\bDHTMLRolloverToggle\b/.test(img.className)) ? !isAlreadyOn : true;
		
		if (img.DHTMLRollover_isOn)
			img.src = img.srcOn;
		else
			img.src = img.srcOut;
	},
	
	event_mouseOver: function(e)
	{
		if (!e.target.DHTMLRollover_isOn) {
			e.target.src = e.target.srcOver;
		}
	},

	event_mouseOut: function(e)
	{
		if (!e.target.DHTMLRollover_isOn) {
			e.target.src = e.target.srcOut;
		}
	},
	
	event_click: function(e)
	{	
		DHTMLRollovers.setActive(e.target);
	}
};


function preloadImage(imgSrc)
{
	if (!preloadImage.preloads)
		preloadImage.preloads = new Array();
	(preloadImage.preloads[preloadImage.preloads.length] = new Image()).src = imgSrc;
}
	



var Navigator = {
	_getVersion: function (a, b) {
		var t = navigator.userAgent.split(a)[1];
		return (t) ? t.split(b)[0] : false;
	},
	isOpera: function () {
		return (
			(window.opera) ?
				(document.createElementNS) ?
					(document.createCDATASection) ?
						(document.styleSheets) ? 9 : 8
					: 7
				: 6
			: false
		);
	},
	isSafari: function () {
		return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('AppleWebKit/', '(') : false;
	},
	isKDE: function () {
		return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('Konqueror/', ';') : false;
	},
	isGecko: function () {
		return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('Gecko/', ' ') : false;
	},
	isNN4: function () {
		return (document.layers && typeof document.layers == 'object') ? true : false;
	},
	isWinIE: function () {
		return (
			/*@cc_on @if (@_win64 || @_win32 || @_win16)
			(document.getElementsByTagName) ?
				(@_jscript_version > 5.6) ? 7 :
				(@_jscript_version == 5.6) ? 6 :
				(@_jscript_version == 5.5) ? 5.5 :
				5
			: 4
			@else@*/false/*@end @*/
		);
	},
	isMacIE: function () {
		return (
			/*@cc_on @if (@_mac && (@_PowerPC || @_mc680x0))
				(document.getElementsByTagName) ? 5 : 4
			@else@*/false/*@end @*/
		);
	}
};

var isSafari = Navigator.isSafari();
var isIE = Navigator.isWinIE();





function getElementsByClass(searchClass, node, tag) {
	if (!(searchClass instanceof RegExp))
		searchClass = new RegExp("\\b" + searchClass + "\\b");
	var classElements = new Array();
	if (node == null)
		node = document;
	if (tag == null)
		tag = '*';
	var els = node.getElementsByTagName(tag);
	for (i = 0, j = 0; i < els.length; i++) {
		if (searchClass.test(els[i].className)) {
			classElements[j] = els[i];
			j++;
		}
	}
  	return classElements;
} /* aliases: */ var getElementsByClassName = getElementsByClass;



function getTotalOffset(element) {
	var total = 0;
	if (element.offsetParent)
		total += element.offsetTop + getTotalOffset(element.offsetParent);
	return total;
} /* aliases: */ var getOffset = getTotalOffset; var findPosY = getTotalOffset;



function isNodeOrDescendant(node, ancestor) {
	if (!node)
		return false;
	else if (node == ancestor)
		return true;
	else
		return isNodeOrDescendant(node.parentNode, ancestor);
} /* aliases: */ var isNodeOrDescendent = isNodeOrDescendant; var isDescendant = isNodeOrDescendant; var isDescendent = isNodeOrDescendant;



function getOffsetFrom(element, ancestor)
{
	var offset = 0;
	while (element != ancestor && element != null) {
		offset += element.offsetTop;
		element = element.offsetParent;
	}
	if (element == ancestor)
		return offset;
	else
		throw new Error("getOffsetFrom: node specified as ancestor not found in hierarchy");
}



function getText(n, joiner)
{
	var strings = [];
	getStrings(n, strings);
	return strings.join(joiner ? joiner : "");
	
	function getStrings(n, strings)
	{
		if (n.nodeType == 3)
			strings.push(n.data);
		else if (n.nodeType == 1)
			for (var m = n.firstChild; m != null; m = m.nextSibling)
				getStrings(m, strings);
	}
}



/* css drop downs */
var totalLists = 1;
var ua = navigator.userAgent.toLowerCase();
var av = navigator.appVersion.toLowerCase();
var mac = ( av.indexOf( 'mac' ) != -1 );
var saf = ( ua.indexOf( 'safari' ) != -1 );
var ie5x = ( document.all && document.getElementById );
var ie5mac = ( mac && ie5x );

function calcHeight() {
	var myHeight = 0;
	if( typeof( window.innerWidth ) == 'number' ) {
		/*Non-IE*/
		myHeight = window.innerHeight;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		/*IE 6+ in 'standards compliant mode'*/
		myHeight = document.documentElement.clientHeight;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		/*IE 4 compatible*/
		myHeight = document.body.clientHeight;
	}
	return myHeight;
}


function hideall(ListNum) {
	divItem = document.getElementById('Lst'+ListNum);
	divItem.style.display="none";
	document.getElementById('dropPlus'+ListNum).className = "dropPlus"; // change the drop down icon
}

/* css drop downs - modified js */

var LastListNum = "";

function checkHeightNew(listNum)
{
	var list = document.getElementById("Lst" + listNum);	
  	list.parentNode.style.position = "relative";
  	list.parentNode.style.zIndex = "2000";
  	
	var winHeight = calcHeight();
	var scrollOffset = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
	list.style.overflow = "auto";
	list.style.height = "";
			
	var drop = document.getElementById("Drp" + listNum);
	var dropPos = getTotalOffset(drop);
	var dropHeight = drop.offsetHeight;
	var magicNumber = 30; // ????
	var spaceBelow = winHeight - (dropPos + dropHeight - scrollOffset) - magicNumber;
	var spaceAbove = dropPos - scrollOffset - magicNumber;

	var maxSpace = Math.max(spaceAbove, spaceBelow);
	var lstHeight = (list.offsetHeight > maxSpace)? maxSpace : list.offsetHeight;
            

    // decrease height of footer subscription links dropdown on video archive pages to prevent overlap of video and dhtml            
	if (document.URL.indexOf('videoarchives/?designer') != -1 && ListNum == 10) 
		lstHeight = lstHeight - 140;

	var magicNumber2 = -2;
	list.style.width = (drop.offsetWidth + magicNumber2) + "px";            
	list.style.height = lstHeight + "px"; // adjust the menu height according to the space available

	var lstTop = dropHeight;  
	list.style.bottom = "";
	list.style.top = dropHeight + "px";
	
	if(spaceBelow < lstHeight) { // Display above
		list.style.top = "";
		list.style.bottom = dropHeight + "px";
	}

  	var listTable = document.getElementById("LstTable" + listNum);
  	listTable.style.width = "";
	if (isIE && list.offsetHeight > maxSpace) {
		var magicNumber3 = -17;
		listTable.style.width = (listTable.offsetWidth + magicNumber3) + "px";
	}
}

function showListNew(listNum)
{
  	if (LastListNum == listNum)
		closeDropDownNew();
	else {
		closeDropDownNew();
		LastListNum = listNum;
		var listId = "Lst" + listNum;
		var list = document.getElementById(listId);
		if (list) {
			list.style.display = "block";	

			var dropdown_iframe = document.getElementById("dropdown_iframe");
			if (document.all && dropdown_iframe) {
				var iframe_height = list.offsetHeight - 3 + "px";
				dropdown_iframe.style.height = iframe_height;
				dropdown_iframe.style.display = "block";
				dropdown_iframe.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
			}
                        
			document.getElementById("dropPlus" + listNum).className = "dropPlusOver"; // change the pull down icon
			checkHeightNew(listNum); 
		}
	}
}

function closeDropDownNew()
{
	if (LastListNum != "") {
		var listId = "Lst" + LastListNum;
		var list = document.getElementById(listId);
		if (list) {
      		list.style.display = "none";
		  	list.parentNode.style.position = "";
		  	list.parentNode.style.zIndex = "";
            
            var dropdown_iframe = document.getElementById("dropdown_iframe");
			if (document.all && dropdown_iframe)
				dropdown_iframe.style.display = "none";
            
      		document.getElementById("dropPlus" + LastListNum).className = "dropPlus";
		}
    	LastListNum = ""; // set the menu ID to null 
	}
}









/* cache css bg images for IE6 */
if ( document.all )
{  
    try {
      document.execCommand("BackgroundImageCache", false, true);
    } catch(err) {}
}

// adList variables
var dartCalls = new Array();
var dartCounter = 0;
var dartSite = '';
var dartKeywords = '';

    dart = new Object();
    dart["sz"] = "";
    dart["site"] = "";
    dart["zone"] = "";
    dart["target"] = "";
    dart["url"] = "";
    dart["dcopt"] = "";

<!--// 
// BEGIN Standard popup window script BEGIN //
   window.name="opener";

	function popUpStylistBook(url)
	{
		window.open(url,'StylistBook','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=1000,height=730');
	}

   function popUpBigImage(url) {
	  var width=screen.width;
	  var height=screen.height;
      var detWindow="";
	  
	  if (width<900) {
      detWindow=window.open(url,'BIGimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=750,height=680,left=0,right=0');
	  } else {
	  detWindow=window.open(url,'BIGimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=750,height=680');
	  }
		  
   }

   function popUpBigImageWthNav(url) {
      var detWindow=""
      detWindow=window.open(url,'BIGimg', 'menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,width=734,height=470');
   }
   
   function popUpStylistSweeps(url) {
      var detWindow=""
      detWindow=window.open(url,'BIGimg', 'menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,width=750,height=620');
   }   

   function popUp7thOnSale(url) {
      var detWindow=""
      detWindow=window.open(url,'BIGimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=780,height=600');
   }
   
   function popUpVideoConsole(url) {
      var detWindow=""
      detWindow=window.open(url,'videoConsole','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=1050,height=723');
   }
   
   function popUpShowcaseVideo(url) {
      var detWindow=""
      detWindow=window.open(url,'showcaseVideo','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=575,height=425');
   }
   
   function popUpLevisClassic(url) {
      var detWindow=""
      detWindow=window.open(url,'videoConsole','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=732,height=635');
   }
   
     function popUpTrendAudio(url) {
	 
	  var detWindow=""
      detWindow=window.open(url,'trendAudio','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=731,height=675');
   }

   function popUpFashionShow(url) {
      var detWindow=""
      detWindow=window.open(url,'fashionShow','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=865,height=614');
   }
   
   function popUpBigImagePrintable(url) {
      var detWindow=""
      detWindow=window.open(url,'BIGimgPrint','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=240,height=360');
   }
   
   function popUpTallImage(url) {
	  var width=screen.width;
	  var height=screen.height;
      	  var detWindow="";

	  if (width<900) {
      detWindow=window.open(url,'TALLimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=768,height=550,left=0,right=0');
	  } else {
      detWindow=window.open(url,'TALLimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=768,height=614');
	  }
	  
   }
   
   function popUpTallImageDetails(url) {
   var detWindow=""
   detWindow=window.open(url,'TALLimgDetails','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,width=768,height=614, left=50,top=50');
   }

   function popUpBigImageSecondary(url) {
      var detWindow=""
      detWindow=window.open(url,'TALLDetailimg','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=no,resizable=no,width=420,height=620');
   }

   function goToURL(url) {
      if (url != "") { self.location=url; }
   }

// END Standard popup window script END //   


// BEGIN  winners popup window script BEGIN //
  window.name="winners";

   function popWinners(url) {
      var detWindow=""
      detWindow=window.open(url,'Winners','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,width=350,height=550');
   }
// END winners popup window script END //   

// Video one-off
    function popVivierVideo(url) {
      var detWindow=""
      detWindow=window.open(url,'Vivier','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,width=395,height=330');
   }
//
 
      function gotosite(site) {
                        if (site != "") {
                   self.location=site; } 
                   }
				   
	  function gotonewsite(site) {
	  	if (site != "") {
			newWindow = "";
			newWindow = window.open(site,'newWin');
		}
	  }
	
	/* master roll over code								 
	 Author : Daniel Nolan
	 http://www.bleedingego.co.uk/webdev.php
	 add the attribute class="imgover" to images that requires a mouseover 
     this image must be named exactly the same as the original image,      
	 but it needs _o on the end of the name in the same directory as the   
	 original. 															 
	*/

function initRollovers() {
	if (!document.getElementById) return
	
	var aPreLoad = new Array();
	var sTempSrc;
	var aImages = document.getElementsByTagName('img');
	
	for (var i = 0; i < aImages.length; i++) {		
		if (aImages[i].className == 'imgover') {
			var src = aImages[i].getAttribute('src');
			var ftype = src.substring(src.lastIndexOf('.'), src.length);
			var hsrc = src.replace(ftype, '_on'+ftype);

			aImages[i].setAttribute('hsrc', hsrc);
			
			aPreLoad[i] = new Image();
			aPreLoad[i].src = hsrc;
			
			aImages[i].onmouseover = function() {
				sTempSrc = this.getAttribute('src');
				this.setAttribute('src', this.getAttribute('hsrc'));
			}	
			
			aImages[i].onmouseout = function() {
				if (!sTempSrc) sTempSrc = this.getAttribute('src').replace('_on'+ftype, ftype);
				this.setAttribute('src', sTempSrc);
			}
		}
	}
}


          function go(url) {
			if (opener && !opener.closed) {
            	opener.location.href = url;
            	window.close();
			} else { 
				self.location.href = url;
			}
          }


/* Parses URL Pathname
	Author: Jamie L. Marin, Senior Web Developer
	Date: June !5, 2005
*/

/* Sets varibles for URI pathname and pathname length */
var browserURI = location.pathname;
var uriLength = browserURI.length;

/* Creates Array */
var directories = new Array();

/* Find out indexes of first, next, and last slashes */
var startSlash = browserURI.indexOf('/');
var nextSlash =  browserURI.indexOf('/', startSlash + 1);
var lastSlash = browserURI.lastIndexOf('/');
var slashCount = 0;

/* test for one deep section */ 
if (startSlash == lastSlash)
{
	directories[slashCount] = location.pathname.slice(startSlash + 1);
}


/* Loop to define sections from 1 to N */
while (startSlash != lastSlash || nextSlash != -1)
{
	directories[slashCount] = location.pathname.substring(startSlash + 1,nextSlash);	
	
	if (lastSlash + 1 != uriLength)
		directories[slashCount +1] = browserURI.slice(nextSlash + 1);
		
	startSlash = nextSlash;
	nextSlash =  browserURI.indexOf('/', startSlash + 1);		
	slashCount++;	
}

/* Set User Friendly Variables */
var firstDir = directories[0];
var lastDir = directories[directories.length-1];

bw = new checkBrowser();

function checkBrowser(){
	this.ver=navigator.appVersion;
	this.dom= (document.getElementById)? 1 : 0;
	this.ie5=((this.ver.indexOf("MSIE 5") >= 0) && this.dom)? 1 : 0;
	this.ie4=(document.all && !this.dom)? 1 : 0;
    this.ns6=(this.dom && parseInt(this.ver) >= 6)? 1 : 0;
	this.ns5=(this.dom && parseInt(this.ver) >= 5)? 1 : 0;
	this.ns4=(document.layers && !this.dom)? 1 : 0;
	this.bw=(this.ie5 || this.ie4 || this.ns4 || this.ns5);
	
	this.editBody = function(rootName, code) {
		if (this.dom) {
			document.getElementById(rootName).innerHTML = code;
		} else if (this.ie4) {
			document.all[rootName].innerHTML = code;
		} else if (this.ns4) {
			document.layers[rootName].document.open();
			document.layers[rootName].document.write(code);
			document.layers[rootName].document.close();
		} 
	}
	this.getRef = function(rootName) {
		if (this.dom) {
			return  document.getElementById(rootName)
		} else if (this.ie4) {
			return document.all[rootName]
		} else if (this.ns4) {
			return document.layers[rootName];
		} 
	}
	
}

function styleFlash_DoFSCommand(command, args) {
	var tileNum = parseInt(args), div, script;
	//alert(args.substr(args.indexOf("|") + 1));
	
	if (command == "updateAd") {
		bw.editBody("dartLayer" + tileNum, args.substr(args.indexOf("|") + 1));
		
		//alert(document.all["dartLayer" + tileNum].innerHTML);
	}
}

if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) {
  document.write('<SCRIPT LANGUAGE=VBScript\> \n');
  document.write('on error resume next \n');
  document.write('Sub styleFlash_FSCommand(ByVal command, ByVal args)\n');
  document.write(' call styleFlash_DoFSCommand(command, args)\n');
  document.write('end sub\n');
  document.write("</SCRIPT\> \n");
} 

function MM_openBrWindow(theURL,winName,features) { //v2.0
  window.open(theURL,winName,features);
}

/* for Lookbooks */
function openPrintPage(surl){	
	 window.open(surl,'','scrollbars=yes,menubar=no,height=800,width=700,resizable=yes,toolbar=no,location=no,status=no');
}

//Script to randomize constant spotlight promotions
function randImg(num){

var myImages = Array();
var titles = Array();
var blurbs = Array();
var result = Array();
var links = Array();

links[0] = "http://www.eccodomani.com/";
links[1] = "http://www.style.com/promo/vo5/";
links[2] = "http://www.iconoclaststv.com/";
links[3] = "http://www.fashionrocks06.com/";

myImages[0] = "/images/promo/promo_ecco.jpg";
myImages[1] = "/images/promo/promo_v05.jpg";
myImages[2] = "/images/promo/promo_fashionrocks.jpg";
myImages[3] = "/images/promo/promo_goose.jpg";

titles[0] = "Ecco Domani";
titles[1] = "VO5";
titles[2] = "Grey Goose";
titles[3] = "Fashion Rocks";

blurbs[0] = "Liquid Style in action&mdash;meet the 2006 Ecco Domani Fashion Foundation winners and see the future of fashion!";
blurbs[1] = "Win an iPod soundsystem! Vote for the next VO5 Red Hot Rising Star and you could be a winner. Take a listen, the choice is up to you!";
blurbs[2] = "Win a star&ndash;studded getaway to an ICONOCLASTS premiere event and see today&rsquo;s most intriguing and provocative creative leaders. Brought to you by Grey Goose Vodka";
blurbs[3] = "Your backstage pass to the star&mdash;studded night of style and sound&ndash;Get down with Fashion Rocks performers and rock out to today’s hottest new bands.";

result[0] = myImages[num];
result[1] = titles[num];
result[2] = blurbs[num];
result[3] = links[num];

return result;
}
	
//END to randomize constant spotlight promotions



/**** Contextual Back Link ****/
// Set Cookies
function SetCookie(cookieName,cookieValue,nDays) {
	var today = new Date();
	var expire = new Date();
	if (nDays==null || nDays==0) nDays=1;
	expire.setTime(today.getTime() + 3600000*24*nDays);
	document.cookie = cookieName+"="+escape(cookieValue)+ ";path=/"+ ";expires="+expire.toGMTString();
}

// Read Cookies
function ReadCookie(cookieName) {
	var theCookie=""+document.cookie;
	var ind=theCookie.indexOf(cookieName);
	if (ind==-1 || cookieName=="") return ""; 
	var ind1=theCookie.indexOf(';',ind);
	if (ind1==-1) ind1=theCookie.length; 
	return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
}

function deleteCookie(name) {
    document.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT" + "; path=/";
} 

// get URL params
function getURLParam(strHref){
  if ( strHref.indexOf("?") > -1 ){
    var strQueryString = strHref.substr(strHref.indexOf("?"));
  }
  return strQueryString;
}

var contextualBackUrlCookieName = 'contextualBackUrl';
var contextualBackTextCookieName = 'contextualBackText';

function storeContextualBackLink(text) {
	if (text) {
        var url = window.location.href;
        SetCookie(contextualBackUrlCookieName,url,1);
        SetCookie(contextualBackTextCookieName,text,1);
    }
}

function setupContextualBackLink(elementId){
    var contextualBackElement = document.getElementById(elementId);
    if (contextualBackElement) {
        var url = ReadCookie(contextualBackUrlCookieName);
        var text = ReadCookie(contextualBackTextCookieName);
        if (url && text) {
            contextualBackElement.innerHTML = '<a href="'+url+'">&#8249; Back to '+text+'</a>';
            contextualBackElement.style.display = 'block';
        }
    }
}


runOnLoad(DHTMLRollovers.windowOnLoad);
runOnLoad(initRollovers);



