
/**
 * Encapsulate all Javascript used by the navbar - expose only the navbar class.
 * This is to avoid function and library conflicts when the navbar is embedded.
 * 
 * This technique is described in http://ajaxcookbook.org/javascript-api-namespaces/
 */
function defineNavbar() {

    /* PROTOTYPE EXTRACT */
	
	/* NAVBAR CLASS */
	
       /* to avoid library clashes with other frameworks (for example MooTools).
 * 
 * Some functions have been modified to avoid extending shared
 * classes (like Element). If prototype extends these classes
 * you run the risk of problems as other frameworks do the same.
 * 
 * This approach sucks for these reasons (among others):
 *   - if you want to upgrade Protoype you will need to go through these functions one by one and merge in changes
 *   - if you want to use Prototype functions not included here you will need to hack them in
 *   - we have modified Prototype so we can no longer be totally confident everything works
 *     - we should ideally cover all of these functions with JSUnit tests or at least ensure the functional tests cover every condition
 * 
 * Be on the lookout for a framework that doesn't extend shared classes.
 * Such a framework could be used a lot more easily and cleanly.
 */
var navA = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

function nav_bind() {
	var args = navA(arguments), __method = args.shift(), object = args.shift();
	return function() {
		return __method.apply(object, args.concat(navA(arguments)));
	}
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

/* this has been based on http://daniel.lorch.cc/docs/ajax_simple/ rather than Prototype */
function update(elementId, url) {
	var http = false;
	
	if(navigator.appName == "Microsoft Internet Explorer") {
	  http = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
	  http = new XMLHttpRequest();
	}
	
	http.open("GET", url);
	http.onreadystatechange = function() {
	  if(http.readyState == 4) {
	    navbar_helper(elementId).innerHTML = http.responseText;
	  }
	}
	http.send(null);
}

function getElementsByClassName(parentElement, className) {
	var children = (nabar_helper(parentElement) || document.body).getElementsByTagName('*');
	var elements = [], child;
	for (var i = 0, length = children.length; i < length; i++) {
	  child = children[i];
	  if (hasClass(child, className))
	    elements.push(child);
	}
	return elements;
}

function hasClass(element, searchClass) {
	var classNames = classNamesOf(element);
	for(var i = 0; i < classNames.length; i++) {
		if (classNames[i] == searchClass) return true;
	}
	
	return false;
}

function dimensionsOf(element) {
	element = navbar_helper(element);
    var display = styleOf(element, 'display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
}

function styleOf(element, style) {
	element = navbar_helper(element);
    var value = element.style[style];
    if (!value) {
      if (document.defaultView && document.defaultView.getComputedStyle) {
        var css = document.defaultView.getComputedStyle(element, null);
        value = css ? css[style] : null;
      } else if (element.currentStyle) {
        value = element.currentStyle[style];
      }
    }

    if((value == 'auto') && ['width','height'].include(style) && (styleOf(element, 'display') != 'none'))
      value = element['offset'+style.capitalize()] + 'px';

    return value == 'auto' ? null : value;
}

function setStyleOf(elem, style) {
	
	jq14("#"+elem).css('width', style);
	
    return elem;
}

function navbar_helper(element) {
	if (typeof element == 'string')
	element = document.getElementById(element);
	return element;
}

function observe(elementId, eventType, observer, useCapture) {
	var observed = navbar_helper(elementId);
	if(observed==null)
		return;
	if (observed.addEventListener) {
      observed.addEventListener(eventType, observer, useCapture);
    } else if (observed.attachEvent) {
      observed.attachEvent('on' + eventType, observer);
    }
}
var NAVBAR_CONTAINER = "navBar_content";
var MENU_CONTENT = "navbar_TopNav";
var RIGHT_SECTION = "navbar_rightSection";
/*
 * This width needs to be set to around 5px bigger
 * than the actual width of the right section.
 * Otherwise, the bigpond arrow tends to drop down
 * in IE 6.
 */
var MINIMUM_RIGHT_SECTION_WIDTH = 290

/* HELPER METHODS */

function setWidthOf(element, widthInPixels) {
    setStyleOf(element, widthInPixels);
}

function widthOf(elem) {
  return jq14("#"+elem).width();
}

function observeResizeWith(handler) {
	observe(window, 'resize', handler, false);
}

function show(element) {
	setStyleOf(element, {display: 'block'});
}

// Cache cell widths so we only ever need to calculate them once. The calculate method - getSiteCellWidths() - leaves
// a side effect (alters the width of the LEFT_SECTION) that triggers a resize event recursion in IE8.
var siteCellWidths = null;	

var NavBar = Class.create();
NavBar.prototype = {
	
	initialize: function() {
	},
	
	observeElements: function() {
        observeResizeWith(nav_bind(this.resizeNavbar, this));
	},
	
	resizeNavbar: function() {
        /* 
         * first show the Navbar container
         * we hide it to begin with because it appears weird before resizing
         */
        //show(NAVBAR_CONTAINER);
        
        var navbarWidth = widthOf(NAVBAR_CONTAINER);
		
		var navBarParent = jq14('#navBar').parent();
		
		var windowWidth = navBarParent.innerWidth();
		
        /*
         * Read the navbar width again - Safari thinks
         * the navbar size has shrunk by 15px since the first read.
         * This only happens on browser load - resize is fine.
         * Is it the resize for reading site cell widths causing
         * this problem?
         */
    
		if((windowWidth - widthOf(MENU_CONTENT))<290) {
			setWidthOf(RIGHT_SECTION, 290);
		} else
			setWidthOf(RIGHT_SECTION, windowWidth - widthOf(MENU_CONTENT));
		
		setWidthOf(NAVBAR_CONTAINER, widthOf(MENU_CONTENT)+widthOf(RIGHT_SECTION));
		// TODO provide the proper site cell width and ioffset
		//setIndexes(0, 70);
	},
    
    clearSearchField: function() {
        navbar_helper("navbar_searchField").value = '';
    },
    
    fireEventsOnLoad: function() {
        //observe(window, 'load', nav_bind(this.resizeNavbar, this), false);
        //observe(window, 'load', nav_bind(this.observeElements, this), false);
        //observe(window, 'resize', nav_bind(this.resizeNavbar, this), false);
        //observe(window, 'resize', nav_bind(this.observeElements, this), false);
//        observe(window, 'resize', bind(this.setIndexes, this), false);
    }
};
	

	var navbar = new NavBar();
    return navbar;
}
