YAHOO.namespace('YAHOO.EU.widget.DTKNav');
YAHOO.EU.widget.DTKNav.DropDown = function(oConfig) { 
 this.oConfig = oConfig;
 this.dropper = '';
 this.dropLink = '';
 this.navBar = '';
 this.dropHeight = 0;
 
 this.iLeft = 0;
 this.iParLeft = 0;
 
 this.isActive = false;
 this.isMouse = false;
 
 this.create = function() {
 // Grab the nav bar that will be the parent to our dropper.
 var oNavBar = YAHOO.util.Dom.getElementsByClassName(this.oConfig.sClassNavParent, 'ul', this.oConfig.sNavContainerId);
 if (oNavBar.length < 1) {
 // What do you mean, there's no nav bar???!?
 return false;
 }
 // Just the one, Mrs Wembley.
 this.navBar = oNavBar[0];
 
 // Obtain a list of items for our dropper.
 var oDropItem = YAHOO.util.Dom.getElementsByClassName(this.oConfig.sClassNavDrop, 'li', this.navBar);
 if (oDropItem.length < 1) {
 // Bugger off cos there's no items.
 return false;
 }
 
 // Create some elephants as prep.
 var oDropWrap = document.createElement('div');
 var oDropDiv = document.createElement('div');
 var oDropTriggerTab = document.createElement('li');
 var oDropTriggerLink = document.createElement('a');
 var oDropTriggerSpan = document.createElement('span');
 var oDropUl = []; // An array for our uls
 var iListCol;
 for (var i=0, iListCol=Math.ceil(oDropItem.length / this.oConfig.iColMax);i<iListCol;i+=1) {
 oDropUl[i] = document.createElement('ul');
 }
 
 // Add a touch of class
 YAHOO.util.Dom.addClass(oDropTriggerTab, 'dtk-dropper');
 YAHOO.util.Dom.addClass(oDropWrap, 'navmore');
 YAHOO.util.Dom.addClass(oDropDiv, 'flyout');
 
 // Obtain the parent.
 var parent = oDropItem[0].parentNode;
 var current = false;
 
 // Loop through our list of items, clone them,
 // add/take-away their class and stick 'em in our dropper.
 for (var i=0,j=0;i<oDropItem.length;i+=1) {
 var crumbFlag = false;
 if (YAHOO.util.Dom.hasClass(oDropItem[i], "selected") || YAHOO.util.Dom.hasClass(oDropItem[i], "current")) {
 YAHOO.util.Dom.removeClass(oDropItem[i], "selected");
 if (YAHOO.util.Dom.hasClass(parent, "main")) {
 YAHOO.util.Dom.removeClass(oDropItem[i], this.oConfig.sClassNavDrop);
 YAHOO.util.Dom.addClass(oDropItem[i], "crumb");
 crumbFlag = true;
 var current = oDropItem[i];
 } else if (YAHOO.util.Dom.hasClass(parent, "sub")) {
 YAHOO.util.Dom.addClass(oDropTriggerTab, "selected");
 }
 }
 if (!crumbFlag) {
 var clne = oDropItem[i].cloneNode(true); // Clone
 if ((i % this.oConfig.iColMax)===0) {
 // If it's the first item add a class of "first-child".
 YAHOO.util.Dom.addClass(clne, 'first-child');
 }
 if (navigator.userAgent.toLowerCase().match(/safari/)) {
 var oAEl = clne.getElementsByTagName('a');
 for (var k=0;k<oAEl.length;k+=1) {
 YAHOO.util.Dom.addClass(oAEl[k], 'safari');
 }
 }
 // Remove the class used to identify the item
 // as dropper-fodder.
 YAHOO.util.Dom.removeClass(clne, this.oConfig.sClassNavDrop);
 // Move the item to the list elephant we created earlier.
 oDropUl[Math.floor(i/this.oConfig.iColMax)].appendChild(clne);
 parent.removeChild(oDropItem[i]);
 }
 }
 
 // Loop through our completed ul's, make 'em fit
 // and shove 'em up yer dropper div.
 for (var i=0;i<oDropUl.length;i+=1) {
 YAHOO.util.Dom.setStyle(oDropUl[i], 'width', (100 / iListCol)+'%');
 oDropDiv.appendChild(oDropUl[i]);
 }
 
 // If we're a general links object is defined in the
 // config object then we're going to want to create
 // those links.
 if (this.oConfig.oGeneralLinks) {
 // Create elephants
 var oGenLinksDiv = document.createElement('div');
 var oH = document.createElement('h2');
 var oHText = document.createTextNode(this.oConfig.oGeneralLinks.sTitle);
 
 var oLinks = this.oConfig.oGeneralLinks.oLinks;
 
 // Get a count of how many links in our oLinks object.
 var oLinksCount = 0;
 for (i in oLinks) {
 oLinksCount++;
 }
 
 // Create an array of uls for our general links
 var oGenLinkUl = [];
 var iGenListCol = Math.ceil(oLinksCount / this.oConfig.oGeneralLinks.iColMax);
 for (var i=0;i<iGenListCol;i+=1) {
 oGenLinkUl[i] = document.createElement('ul');
 }
 
 j = 0;
 for (var i in oLinks) {
 var tmpLi = document.createElement('li');
 var tmpA = document.createElement('a');
 var tmpSpan = document.createElement('span');
 var tmpTxt = document.createTextNode(i);
 tmpA.setAttribute('href', oLinks[i]);
 var x = Math.floor(j/this.oConfig.oGeneralLinks.iColMax);
 j += 1;
 YAHOO.util.Dom.setStyle(oGenLinkUl[x], 'width', (100 / iGenListCol)+'%');
 tmpSpan.appendChild(tmpTxt);
 tmpA.appendChild(tmpSpan);
 tmpLi.appendChild(tmpA);
 oGenLinkUl[x].appendChild(tmpLi);
 }
 
 // Add a touch of class
 YAHOO.util.Dom.addClass(oGenLinksDiv, 'general');
 
 oH.appendChild(oHText);
 oGenLinksDiv.appendChild(oH);
 for (i=0;i<oGenLinkUl.length;i+=1) {
 oGenLinksDiv.appendChild(oGenLinkUl[i]);
 }
 oDropDiv.appendChild(oGenLinksDiv);
 }
 
 // Create the trigger tab for our dropper and stick it
 // in the afore-mentioned nav bar. We keep the link as it
 // will aid in keyboard navigation - but we make it an
 // internal reference to a generated id (which we'll apply
 // to the dropper).
 var oDropTriggerText = document.createTextNode(this.oConfig.oTextNavItem.label);
 oDropTriggerSpan.appendChild(oDropTriggerText);
 oDropTriggerLink.setAttribute('href', this.oConfig.oTextNavItem.location);
 oDropTriggerLink.appendChild(oDropTriggerSpan);
 oDropTriggerTab.appendChild(oDropTriggerLink);
 oDropWrap.appendChild(oDropDiv);
 oDropTriggerTab.appendChild(oDropWrap);
 // Check to see if we have any rogue tabs - if we do,
 // we'll insert before them rather than after. This prevents
 // funkyness in the tab order.
 var oFirstRogue = YAHOO.util.Dom.getElementsByClassName(this.oConfig.sClassNavRogue, 'li', this.navBar)[0];
 if (oFirstRogue) {
 this.navBar.insertBefore(oDropTriggerTab, oFirstRogue);
 if (current) {
 this.navBar.insertBefore(current, oFirstRogue);
 }
 } else {
 this.navBar.appendChild(oDropTriggerTab);
 if (current) {
 this.navBar.appendChild(current);
 }
 }
 // Set up the widths of the containers. Works out how wide the
 // dropper should be by multiplying the css width by the number
 // of columns.
 var sDropDivWidth = YAHOO.util.Dom.getStyle(oDropDiv, 'width');
 // console.log(sDropDivWidth);
 var iWidth = parseInt(sDropDivWidth,10);
 // console.log(iWidth);
 var sWidth = (iWidth * iListCol)+'px';
 var sWrapWidth = (iWidth * iListCol)+4+'px';
 // console.log(iWidth);
 YAHOO.util.Dom.setStyle(oDropDiv, 'width', sWidth);
 YAHOO.util.Dom.setStyle(oDropWrap, 'width', sWrapWidth);
 
 if (YAHOO.util.Event.isIE) {
 // Iframe shim
 var oDropIframe = document.createElement('iframe');
 oDropWrap.appendChild(oDropIframe);
 YAHOO.util.Dom.setStyle(oDropIframe, 'position', 'absolute');
 YAHOO.util.Dom.setStyle(oDropDiv, 'position', 'relative');
 YAHOO.util.Dom.setStyle(oDropDiv, 'z-index', '500');
 YAHOO.util.Dom.setStyle(oDropIframe, 'z-index', '499');
 YAHOO.util.Dom.setX(oDropIframe, YAHOO.util.Dom.getX(oDropDiv));
 YAHOO.util.Dom.setY(oDropIframe, YAHOO.util.Dom.getY(oDropDiv));
 YAHOO.util.Dom.setStyle(oDropIframe, 'width', oDropDiv.offsetWidth+'px');
 YAHOO.util.Dom.setStyle(oDropIframe, 'height', oDropDiv.offsetHeight+'px');
 //YAHOO.util.Dom.setStyle(oDropIframe, 'background', '#f0f');
 }
 
 // Set up the height as an object wide variable
 this.dropHeight = oDropDiv.offsetHeight;
 
 // Hide the dropper using height
 this.iLeft = YAHOO.util.Dom.getX(oDropWrap);
 this.iParLeft = YAHOO.util.Dom.getX(this.oConfig.sNavContainerId);
 YAHOO.util.Dom.setStyle(oDropWrap, 'overflow', 'hidden');
 YAHOO.util.Dom.setStyle(oDropWrap, 'height', '0');
 YAHOO.util.Dom.setStyle(oDropWrap, 'display', 'none');
 
 // Assign the important elements as object vars.
 this.dropper = oDropWrap;
 this.dropLink = oDropTriggerLink;
 
 // Add event listeners
 YAHOO.util.Event.on(this.dropLink, 'mousedown', this.toggleDropper, this, true);
 YAHOO.util.Event.on(document, 'click', this.onDOMEvent, this, true);
 
 // Safari sucks
 if (navigator.userAgent.toLowerCase().indexOf('safari') !== -1) {
 var oBodyEl = document.getElementsByTagName('body')[0];
 YAHOO.util.Dom.removeClass(oBodyEl, 'notsafari');
 // This doesn't seem to work. Commented in case.
 // YAHOO.util.Event.on(oDropDiv, 'mouseover', function(){YAHOO.util.Dom.setStyle(oDropDiv, 'cursor', 'pointer');}, this, true);
 // YAHOO.util.Event.on(oDropDiv, 'mouseout', function(){YAHOO.util.Dom.setStyle(oDropDiv, 'cursor', '');}, this, true);
 }
 };
 
 this.getCurrentXPos = function() {
 if (document.body && document.body.scrollLeft) {
 return document.body.scrollLeft;
 }
 if (document.documentElement && document.documentElement.scrollLeft) {
 return document.documentElement.scrollLeft;
 }
 if (window.pageXOffset) {
 return window.pageXOffset;
 }
 return 0;
 };
 
 // Drop down display handler - are we showing
 // or hiding?
 this.toggleDropper = function(e) {
 // If we've got here, the mouse has been used.
 // We note this for use in our DOM event handler.
 this.isMouse = true;
 
 // Is the drop-down already active?
 if (this.isActive) {
 this.hideDropper(e);
 } else {
 this.showDropper(e);
 }
 
 YAHOO.util.Event.stopEvent(e);
 };
 
 this.showDropper = function(e) {
 YAHOO.util.Dom.setStyle(this.dropper, 'display', 'block');
 
 var iRightWhitespace = 20;
 var iCParLeft = YAHOO.util.Dom.getX(this.oConfig.sNavContainerId);
 var iOrigLeft = (this.iLeft - this.iParLeft) + iCParLeft;
 var iScreenWidth = YAHOO.util.Dom.getViewportWidth();
 var iScreenOffset = this.getCurrentXPos();
 var iDropperWidth = this.dropper.offsetWidth;
 
 var test1 = iScreenOffset + iScreenWidth;
 var test2 = iOrigLeft + iDropperWidth + iRightWhitespace;
 
 if (test1 < test2) {
 var iX = (iScreenOffset + iScreenWidth) - (iDropperWidth + iRightWhitespace);
 } else {
 var iX = iOrigLeft;
 }
 
 YAHOO.util.Dom.setX(this.dropper, iX);
 
 if (navigator.userAgent.toLowerCase().indexOf('gecko') === -1) {
 var attributes = {
 height: { to: this.dropHeight }
 };
 var anim = new YAHOO.util.Anim(this.dropper, attributes, 0.3, YAHOO.util.Easing.backOut);
 anim.animate();
 } else {
 YAHOO.util.Dom.setStyle(this.dropper, 'height', this.dropHeight+'px');
 }
 
 this.isActive = true;
 };
 
 this.hideDropper = function(e) {
 if (navigator.userAgent.toLowerCase().indexOf('gecko') === -1) {
 var attributes = {
 height: { to: 0 }
 };
 var anim = new YAHOO.util.Anim(this.dropper, attributes, 0.3, YAHOO.util.Easing.backOut);
 anim.animate();
 
 // The onComplete subscriber loses the object's "this" reference; so
 // let's set up our object var as a function scoped var.
 var thisLoser = this.dropper;
 anim.onComplete.subscribe(function(){YAHOO.util.Dom.setStyle(thisLoser, 'display', 'none');});
 } else {
 YAHOO.util.Dom.setStyle(this.dropper, 'height', '0');
 YAHOO.util.Dom.setStyle(this.dropper, 'display', 'none');
 }
 
 this.isActive = false;
 
 YAHOO.util.Event.stopEvent(e);
 };
 
 this.onDOMEvent = function(e) {
 var targetElement = YAHOO.util.Event.getTarget(e);
 
 if (this.isActive) {
 var bFlyout = false;
 while (targetElement && targetElement.nodeName.toUpperCase() !== 'BODY') {
 if (targetElement === this.dropper || targetElement === this.dropLink) {
 bFlyout = true;
 break;
 }
 targetElement = targetElement.parentNode;
 }
 
 if (!bFlyout) {
 // The click event has occured outside the dropper
 // so let's hide that puppy.
 this.hideDropper(e);
 }
 }
 
 if (this.isMouse) {
 YAHOO.util.Event.stopEvent(e);
 }
 
 this.isMouse = false;
 };
 
 return true; // A constructor should ALWAYS return true.
};