function msNavigation() {
    this.navAreas    = [];
    this.navigations = [];
}

msNavigation.prototype.addEvent = function (obj,evt,fn) {
  if (document.addEventListener) {
    this.addEvent = function (obj,evt,fn) {
      obj.addEventListener(evt,fn,false);
    }
  }
  else if (document.attachEvent) {
    this.addEvent = function (obj,evt,fn) {
      obj.attachEvent('on'+evt,fn);
    }
  }
  this.addEvent(obj,evt,fn);
}
msNavigation.prototype.handleEvent = function (e, state, effect) {
    var target = null;
    if (!e)
        var e = window.event;
    if (e.target)
        target = e.target;
    else if (e.srcElement)
        target = e.srcElement;
    if (target.nodeType == 3) // defeat Safari bug
        target = entry.parentNode;

    if (effect == 'imgshift')
        this.imgshift(target, state);
    else if (effect == 'expandUl')
        this.expandUl(target);
    else if (effect == 'expandDiv')
        this.expandDiv(target);
}
msNavigation.prototype.imgshift = function (target, state) {
    if (target.tagName != 'IMG' || target.style.display == 'none' || !target.complete)
        return;

    var height = target.height / 4; // 4 states in one file

    var base_offset = 0;
    if(hasClass(target, 'active'))
        base_offset = -3;

    // over event - show second image
    if (state == 1 || state == 3) {
        target.style.marginTop = -1 * height + 'px';
    }
    // out event - show first image
    else if (state == 0){
        target.style.marginTop = base_offset * height + 'px';
    }
    // down event - show third image
    else if (state == 2){
        target.style.marginTop = -2 * height + 'px';
    }
    // off event - show first image
    else {
        target.style.marginTop = base_offset * height + 'px';
    }
}
msNavigation.prototype.expandUl = function (target) {
    if (!(target.tagName == 'A' || target.tagName == 'SPAN') || target.style.display == 'none')
        return;

    var branch = target.tagName == 'A' ? target : target.parentNode; // A tag not SPAN tag
    var ul = this.nextObject(branch);
    if (ul != null)
        branch = ul;
    else
        branch = branch.parentNode.parentNode; // ul


    // up event
    if (branch != null) {
        // find my top parent
        var openList = [];
        while (branch && branch.tagName == 'UL'){
            openList[openList.length] = branch;
            branch = branch.parentNode.parentNode; // ul li ul
        }
        // close all branches
        this.closeTree(openList[openList.length-1]);
        // open the selected branch and all its parents
        for (var i in openList){
            var obj = openList[i];
            obj.style.display = '';
            this.replaceClass(this.prevObject(obj), 'closed', 'open');
        }
    }
}
msNavigation.prototype.expandDiv = function (target) {
    if (!(target.tagName == 'A'    ||
          target.tagName == 'DIV') ||
          target.style.display == 'none' ||
          (target.tagName == 'A' &&
           target.href &&
           target.href.length > 1))
        return;

    // A tag not DIV tag
    var branch = target.tagName == 'A' ? target : target.parentNode;
        branch = branch.tagName == 'A' ? branch : branch.parentNode;
    var ul = this.nextObject(branch);
    if (ul != null)
        branch = ul;
    else
        branch = branch.parentNode.parentNode; // DIV

    var closeClass = 'close';
    var openClass  = 'open';
    if (this.hasClass(branch.parentNode, 'open')){
        closeClass = '';
        openClass  = '';
    }

    // up event
    if (branch != null && branch.tagName == 'DIV') {
        var siblings = branch.parentNode.parentNode.childNodes;
        for ( var i = 0; i < siblings.length; i++ ) {
            var obj = siblings[i];
            if (obj.tagName == 'DIV'){
                this.replaceClass(obj, 'close', openClass);
                this.replaceClass(obj, 'open',  closeClass);
                this.limitChildHeight(obj);
            }
        }
        this.replaceClass(branch.parentNode, 'close', openClass);
    }
    this.limitChildHeight(target);
}
msNavigation.prototype.getElementsByClassName = function ( strClassName, obj, list ) {
    if (obj == null)
        return;

    if ( this.hasClass(obj, strClassName) )
        list[list.length] = obj;

    for ( var i = 0; i < obj.childNodes.length; i++ )
        this.getElementsByClassName( strClassName, obj.childNodes[i], list );
}
msNavigation.prototype.hasClass = function (obj, strClassName){
    if (obj == null || obj.className == null)
        return 0;

    var found = obj.className.indexOf(strClassName) != -1 ? 1 : 0;
    return found;
}
msNavigation.prototype.replaceClass = function (obj, oldClass, newClass){
    if (obj == null || obj.className == null)
        return 0;

    if (this.hasClass(obj, oldClass)){
        obj.className = obj.className.replace(RegExp("\\s*" + oldClass + "\\s*"),'');
    }
    if (!this.hasClass(obj, newClass))
        if (obj.className)
            obj.className = obj.className + ' ' + newClass;
        else
            obj.className = newClass;
}
msNavigation.prototype.enhance = function (navobj, effect){
    if (effect == 'imgshift'){
        this.addEvent(navobj, 'mouseup',   function (e) { msNav.handleEvent(e, 3, 'imgshift'); });
        this.addEvent(navobj, 'mousedown', function (e) { msNav.handleEvent(e, 2, 'imgshift'); });
        this.addEvent(navobj, 'mouseover', function (e) { msNav.handleEvent(e, 1, 'imgshift'); });
        this.addEvent(navobj, 'mouseout',  function (e) { msNav.handleEvent(e, 0, 'imgshift'); });

        // if IE remove alt tags from navigation images and show the previous sibling span if image load failed
        if (navigator.appName == 'Microsoft Internet Explorer'){
            this.removeAltAttributeForIE(navobj);
        }
    }
    else if (effect == 'expandUl'){
        this.addEvent(navobj, 'mouseup',   function (e) { msNav.handleEvent(e, 0, 'expandUl'); });
    }
    else if (effect == 'expandDiv'){
        this.addEvent(navobj, 'mouseup',   function (e) { msNav.handleEvent(e, 0, 'expandDiv'); });
    }

    // Enhance active items on page load
    var list = [];
    this.getElementsByClassName( 'active', navobj, list );
    for ( var i = 0; i < list.length; i++ ) {
        var obj = list[i];
        if (effect == 'imgshift')
            this.imgshift(obj, 0);
        else if (effect == 'expand')
            this.expand(obj);
        else if (effect == 'expandDiv')
            this.expandDiv(obj);
    }
}
msNavigation.prototype.nextObject = function (obj) {
    do obj = obj.nextSibling;
    while (obj && obj.nodeType != 1);
    return obj;
}
msNavigation.prototype.prevObject = function (obj) {
    do obj = obj.previousSibling;
    while (obj && obj.nodeType != 1);
    return obj;
}
msNavigation.prototype.closeTree = function (obj) {
    if (obj){
        for ( var i = 0; i < obj.childNodes.length; i++ ) {
            if (obj.tagName == 'UL' || obj.tagName == 'LI'){
                this.closeTree( obj.childNodes[i] );
            }
        }
        if (obj.tagName == 'UL'){
            obj.style.display = 'none';
            this.replaceClass(this.prevObject(obj), 'open', 'closed');
        }
    }
}
msNavigation.prototype.removeAltAttributeForIE = function (obj) {
    if (obj){
        // only remove alt attribute value for completed images
        if (obj.tagName == 'IMG'){
            if (obj.complete){
                obj.alt = '';
            }
            else {
                this.prevObject(obj).style.display = 'inline';
                obj.style.display = 'none';
            }
        }
        else {
            for ( var i = 0; i < obj.childNodes.length; i++ ) {
                this.removeAltAttributeForIE( obj.childNodes[i] );
            }
        }
    }
}
msNavigation.prototype.addNavArea = function (areaId, effect) {
    if (this.navAreas[areaId] == null)
        this.navAreas[areaId] = [];
    if (this.navAreas[areaId]['effect'] == null)
        this.navAreas[areaId]['effect'] = [];
    this.navAreas[areaId]['effect'].push(effect);
}
msNavigation.prototype.initNav = function () {
    // register event listeners
    msNav.addEvent(window, 'load', function () {
        debugDiv = document.getElementById('content-body');

        // nav image replacement on mouse event
        for( var areaId in msNav.navAreas ) {
            var navobj = msNav.navAreas[areaId];
            navobj['object'] = document.getElementById(areaId);
            // enhance experience
            if (navobj != null && navobj['object'] != null) {
                for( var i in navobj['effect']){
                    msNav.enhance(navobj['object'], navobj['effect'][i]);
                }
            }
        }
    });
}
msNavigation.prototype.limitChildHeight = function (obj) {
    var kids = [];
    this.getElementsByClassName( 'collapsible', obj.parentNode.parentNode, kids );
    for ( var k = 0; k < kids.length; k++ ) {
        var child = kids[k];
        var maxHeight = child.offsetHeight - 10;
        var totalHeight = 0;
        var childNodes = child.childNodes;
        var childCount = childNodes.length;
        for ( var i = 0; i < childCount; i++ ){
            var node = childNodes[i];
            if (node.tagName == 'DIV'){
                node.style.display = '';
                totalHeight = totalHeight + node.offsetHeight;
                if (node.id == 'twtr-widget-1') {
                    childNodes = [];
                    this.getElementsByClassName( 'twtr-tweet', node, childNodes );
                    childCount = childNodes.length;
                    totalHeight = 0;
                    i = 0;
                }
                else if ( totalHeight > maxHeight) {
                    node.style.display="none";
                }
            }
        }
    }
}

var msNav = new msNavigation();
msNav.addNavArea('blog-archive', 'expandUl' );
msNav.addNavArea('home-news',    'expandDiv');
msNav.initNav();


