/*global jQuery */

var BB = {    //Blindbox
    DOT                : ' .',
    ICONOPEN_SRC       : '../images/bbExpand.jpg',
    ICONCLOSE_SRC      : '../images/bbCollapse.jpg',
    
    BLINDBOX_CLASS     : 'blindbox',
    CONTROL_CLASS      : 'bbcontrol',
    CONTROL_SEL        : ' .bbcontrol',
    CONTENT_CLASS      : 'bbcontent',
    CONTENT_SEL        : ' .bbcontent',
    CONTROLICON_CLASS  : 'bbicon',
    CONTROL_OPEN_CLASS : 'bbshowing',
    
    OPEN_TITLE_TXT     : 'Click to hide',
    CLOSED_TITLE_TXT   : 'Click to show more',
    
    CLOSE_SPEED        : 250,
    OPEN_SPEED         : 1075,
    
    makeIcon : function(imgPath) {
        var icon = document.createElement('img');
        icon.className = BB.CONTROLICON_CLASS;
        icon.src = imgPath;
        icon.alt = '';
        return icon;
    },

    addIcon : function(controlElem) {
        var whichPath = '';
        var icon = null;
        
        if(jQuery(controlElem).hasClass(BB.CONTROL_OPEN_CLASS)) {
            whichPath = BB.ICONCLOSE_SRC;
        }
        else {
            whichPath = BB.ICONOPEN_SRC;
        }
        icon = BB.makeIcon(whichPath);
        //controlElem.appendChild(icon);
        controlElem.insertBefore(icon,controlElem.firstChild);
        controlElem.bbIcon = icon;
    },
    
    // jQuery.fn function
    //    function must be called AFTER an element with a class attribute value of "bbcontrol" has had
    //        its class attribute value updated to reflect a click event!!
    toggleIcon : function() {
        //keyword this refers to a wrapped set
        jQuery(this).each( 
            function() {
                //keyword this refers to each element in a wrapped set
                if(jQuery(this).hasClass(BB.CONTROL_OPEN_CLASS)) {
                    this.title = BB.OPEN_TITLE_TXT;
                    this.bbIcon.src = BB.ICONCLOSE_SRC;
                }
                else {
                    this.title = BB.CLOSED_TITLE_TXT;
                    this.bbIcon.src = BB.ICONOPEN_SRC;
                }                
            }
        );
    },
    
    controlbbClickHandler : function(evtObj) {
        var containingBlindBox = null;
        var iconClick = (jQuery(evtObj.target).hasClass(BB.CONTROLICON_CLASS))?true:false;
        
        function findBBParent(controlElem) {
            var parent = controlElem.parentNode;
            while(!jQuery(parent).hasClass(BB.BLINDBOX_CLASS) && parent.nodeName.toLowerCase() !== 'html') {
                parent = parent.parentNode;    
            }
            if(parent.nodeName.toLowerCase() === 'html') {
                parent = null;
            }
            return parent;
        } //end findBBParent        
        
        containingBlindBox = findBBParent(this);
        if(iconClick){
            if(jQuery(this).hasClass(BB.CONTROL_OPEN_CLASS)) {
                //close this blind box and all nested blind boxes 
                jQuery(BB.CONTROL_SEL, containingBlindBox).each(
                    function(){
                        jQuery(this).removeClass(BB.CONTROL_OPEN_CLASS).toggleIcon();
                    }
                );
                jQuery(BB.CONTENT_SEL, containingBlindBox).slideUp(BB.CLOSE_SPEED);
            }
            else {
                //open up just this level of blind box content
                jQuery(this).siblings().filter(BB.CONTENT_SEL).slideDown(BB.OPEN_SPEED);
                jQuery(this).addClass(BB.CONTROL_OPEN_CLASS).toggleIcon();
            }
        } //end if iconClick
    }, //end controlbbClickHandler
    
    
    init :  function() {        
        jQuery(BB.CONTROL_SEL).click(BB.controlbbClickHandler).each(
            function(){
                BB.addIcon(this);
            }
        );
    }    
}; //end BB


var FauxTarget = {      //False Target set <a> target attribute value to "_blank"
    BLINDBOXOPENER : 'bbopener',
    NEW_WINDOW     : 'external',
    NEWWIND_CLASS  : 'newWindIcon',
    ICON_SRC       : '/images/newWindow.png',

    makeIcon : function() {
        var icon = document.createElement('img');
        icon.alt = 'Opens in new window or tab';
        icon.title = icon.alt;
        icon.className = FauxTarget.NEWWIND_CLASS;
        icon.src = FauxTarget.ICON_SRC;
        return icon;
    },
    
    //Function adds new window icon and a target attribute value of _blank to each <a>
    //    that has a rel attribute value set to "external".
    //
    //    input
    //        elem : When called from script context this is expected to be a DOM element.
    //               When called from an event listener context this will be the Event object
    //               BE CAREFUL!
    //    output
    //        All the collected <a> elements (those with a rel attribute value of "external") will
    //        have a new window icon appended and the target attribute value set to "_blank".
    //        
    windowOpener :    function(elem) {
        var i = 0;
        var oneAnchor = null;
        var anchors = null;
        
        if(!elem || !elem.nodeName) {
            elem = document;  //elem is either a DOM element or an Event object
        }
        if(elem.getElementsByTagName){
            anchors = elem.getElementsByTagName('a');
            for(i = 0; i < anchors.length; i += 1) {
                oneAnchor = anchors[i];
                if(oneAnchor.rel === FauxTarget.NEW_WINDOW.toLowerCase()) {
                    oneAnchor.target = '_blank';
                    oneAnchor.appendChild(FauxTarget.makeIcon());
                }
            }        
        }
    } //end windowOpener()
}; //end object FauxTarget




//   Object handles roll-over images for the right sidebar
//
//   File naming convention: OrganizationAbreviation_off.filetype,
//                            OrganizationAbreviation_over.filetype
var Roll = {
  DOM_ROOT :  'sideBar',
    
	// jQuery Event handler functions.
	//	 input e => jQuery normalize Event object
	//   output => changes the target <img> src attribute value
	mouseOverHandler : function(e) {
		e.target.src = e.target.overSrc;	
	},
	
	mouseOutHandler : function(e) {
		e.target.src = e.target.offSrc;
	},
	
	// Recursive function moves through the DOM tree with a root at element.
	//	input => element: the DOM node that is the root for the traversal.
	//  output => finds all <a> with <img> children elements and binds
	//		mouseover, and mouseout event handlers to the <img> elements.		
    traverse : function(element) {
        var child = null;
        var children = element.childNodes;
        var cacheImg = null;
        var i = 0;
        for (; i < children.length; i += 1) {
            child = children[i];
            if(child.nodeType === 1){
                if ( (child.nodeName.toLowerCase() === 'img') && 
                     (child.parentNode.nodeName.toLowerCase() === 'a') ){
                    child.className = 'normal';
                    jQuery(child).mouseover(Roll.mouseOverHandler);
                    jQuery(child).mouseout(Roll.mouseOutHandler);
                    child.offSrc = child.src;
                    cacheImg = new Image(); 
                    cacheImg.src = child.src.replace('_off','_over');
                    child.overSrc = cacheImg.src;
                    //alert('child.overSrc is: ' +child.overSrc);
                } //end if child is an img element inside an a element     
                else {
                    this.traverse(child);
                }
            }//end if child is an xhtml element    
        }//end for
    }, //end traverse()
  
    init   : function() {
        var sidebar = document.getElementById(Roll.DOM_ROOT);
        if(sidebar) {
            Roll.traverse(sidebar);
        }
    }
}; //end Object Roll


/* *********************************************************************************
 *
 *	Object used to modify the "validation" link located in the page footer.
 *		NU_PATH -> this property contains the full path and the beginning of the
 *			query string for passing the rendered page file to the validator site.
 *
 *     output -> the href attribute of the validator link is reset with the
 *			correct query string parameter.
 *
 * Object also used to create links for CSS3 validation for each <link> stylesheet.
 *     output -> <a> with correct path names and query strings linking to a CSS3
 *					validator for each style sheet linked to the DOM with a
 *					<link> element.
 *
 * ********************************************************************************* */			
var VL = {     //Validation Link
    VALIDATION_ID : '#validator',
	NU_PATH       : 'http://html5.validator.nu?doc=',
	CSS_ID        : '#cssValidator',
	CSS_PATH      : 'http://jigsaw.w3.org/css-validator/validator?profile=css3&amp;warning=no&amp;uri=',
	
	TOGGLE_ID     : '#cssToggle',
	
	//IE fix
	// Function determines if the parameter is a complete URI -- with protocal, host, and path.
	//	input -> uri is a string representing some uri or url.
	//  output -> the input has a protocol/host appended if the uri is only partial (some forms of
	//  of IE).
	fixHref : function(uri) {
		var protoHost = window.location.protocol + '//' + window.location.host;
		var fixUri = uri;
		if(uri.indexOf(protoHost) < 0){
			fixUri = protoHost + uri;	
		}
		return fixUri;
	},

	makeCSSLinks : function() {
		var hrefs = null;
		
		function toggleCSS() {
			var txt1 = 'disable';
			var txt2 = 'enable';
			function clickHandler(e){
				var i = 0;
				var ss = null;
				if(e.target.innerHTML.search(txt1) >= 0) {
					e.target.innerHTML = e.target.innerHTML.replace(txt1,txt2);	
				}
				else {
					e.target.innerHTML = e.target.innerHTML.replace(txt2,txt1);	
				}
				for(;i < document.styleSheets.length; i += 1){
					ss = document.styleSheets[i];
					ss.disabled = !ss.disabled;
				}
			}
			jQuery(VL.TOGGLE_ID).click(clickHandler);
		} //end toggleCSS		
		function getStyleSheets() {
			var list = [];
			var href = null;
			var i = 0;
			if(document.styleSheets.length) {
				for(;i < document.styleSheets.length; i += 1) {
					if(document.styleSheets[i].href) {
						list.push(VL.fixHref(document.styleSheets[i].href));
					}
				}
			}
			return list;
		}
		function makeAnchors(urls) {
			var anchors =[];
			var i = 0;
			var anch = null;
			//
			if(urls.length){
				for(;i < urls.length; i += 1) {
					anch = document.createElement('a');
					anch.href = VL.CSS_PATH + urls[i];
					anch.rel = FauxTarget.NEW_WINDOW;
					anch.innerHTML = 'CSS' + '#' + (i + 1);
					anchors.push(anch);
				}
			}
			return anchors;
		}
		
		function insertAnchors(anchorList) {
			var elem = jQuery(VL.CSS_ID)[0];
			var i = 0;
			if(elem && anchorList.length) {
				for(;i < anchorList.length; i += 1) {
					elem.appendChild(anchorList[i]);	
				}
			}
		}
		
		hrefs = getStyleSheets();
		if(hrefs.length > 0) {
			insertAnchors(makeAnchors(hrefs));	
		}
		toggleCSS();
	},
	
	setValidation : function (){
		jQuery(VL.VALIDATION_ID).click( function(e) {
			e.target.href = VL.NU_PATH + window.location;
			return true;
		});
	}
}; //end VL

jQuery(document).ready( function() {
	VL.setValidation();
	VL.makeCSSLinks();
    Roll.init();
    FauxTarget.windowOpener();
    (jQuery).fn.toggleIcon = BB.toggleIcon;
    BB.init();
});
