(function() {
  Neaux.setNamespace( 'Neaux.Util');

  var CACHED_IMAGES = ['header_tab_1_hover.png','header_tab_2_hover.png','header_tab_3_hover.png','light_blue_cross.png'];

  Neaux.Easing = {
    linear: function( aTime, aBegin, aDelta, aTotal) { 
      return ( aDelta * aTime/aTotal + aBegin );
    },
    sinusoidal: function( aTime, aBegin, aDelta, aTotal) { 
		  return aBegin + ((-Math.cos((aTime/aTotal)*Math.PI)/2) + 0.5) * aDelta;
    }
  }

  Neaux.merge( Neaux.Util, {
    // Given an ID of an element at the top of a UL-based menu, return an array of the menu's LI
    // elements.  (Note: CHANGED indicates a change due to accordian menu's departure from a typical list-based menu)
    //
    getMenuNodes: function( aMenu) {     // CHANGED
      var menu = $ID(aMenu);          // CHANGED
      if ( !menu) return;             // CHANGED
      // Get all of the anchors in the menu hierarchy, iterate through them until 
      // the href attribute matches the page name
      var anchors = menu.getElementsByTagName('a');
      for ( var i = 0; i < anchors.length; ++i)
        if ( window.location.href == anchors[i].href) break;

      // For a page not in the menu, return null
      if ( i == anchors.length) return null;

      var theNodes = [];
      // Now we go walk back up the tree and get the node hierarchy and save it for later (e.g., for breadcrumbs)
      var ptr = anchors[i];
      while( ptr && ptr != menu) {              // CHANGED
        var tag = ptr.nodeName.toLowerCase();   // CHANGED
        if ( tag == 'ul') {                     // CHANGED
          while( (ptr = ptr.previousSibling) && (ptr.nodeType != Node.ELEMENT_NODE)); // CHANGED
          tag = ptr.nodeName.toLowerCase();     // CHANGED
        }                                       // CHANGED
        if ( tag == 'li' || tag == 'div')       // CHANGED
          theNodes.push(ptr);
        ptr = ptr.parentNode;
      }
      var home = menu.getElementsByTagName('div')[0];   // CHANGED
      if ( home != theNodes[theNodes.length-1])
        theNodes.push(home);

      // Return 'em in top-down order
      return theNodes.reverse();
    },
    //
    // Given an array of list nodes, generate a document fragment to be used as breadcrumbs.
    //
    makeBreadcrumbs: function( aMenuNodes, aBreadcrumbID) { 
      var theBC = $ID(aBreadcrumbID);
      if ( !theBC) return;
      if ( typeof aMenuNodes == 'string') aMenuNodes = Neaux.Util.getMenuNodes(aMenuNodes);
      if ( !aMenuNodes) return;
      var theClone, theNode, theFrag = document.createDocumentFragment();
      for ( var i in aMenuNodes) {
        theNode = aMenuNodes[i].getElementsByTagName('a');
        if ( i > 0) theFrag.appendChild(document.createTextNode(' > '));
        theClone = theNode[0].cloneNode(true);
        theClone.style.cssText = '';
        theFrag.appendChild(theClone);
      }
      theBC.replaceChild( theFrag, theBC.firstChild);
    },

    // Optimize image loads - preload initially hidden images on home page
    cacheImages: function( aImgList) {
      for ( var i in aImgList) {
        var img = new Image();
        img.src = 'images/'+aImgList[i];
      }  
    }

  });

  var ACCORDIAN_DURATION = 250; // milliseconds
  var ACCORDIAN_RATE = 40;      // Frames per second
  var Continuum = {
    menuNodes: null,
    accRef: 0,
    easing: Neaux.Easing.sinusoidal,
    initAccordian: function( aNav) {
      var nav = $ID(aNav);
      var ul = nav.getElementsByTagName('ul');
      var accNodes = [];
      for ( var i=0; i < ul.length; i++) {
        var elm = ul[i]
        while( (elm = elm.previousSibling) && elm.nodeType != Node.ELEMENT_NODE);
        var foo =  {
          container: ul[i],
          closed: true
        }
        elm.__NW__ = foo;
        var img = new Image();
        img.src = 'images/acc_closed.png';
        elm.insertBefore( img, elm.firstChild);
        accNodes.push(elm);
        if ( Cm.menuNodes && elm == Cm.menuNodes[1]) Cm.doAccordian( elm);
        var li = nav.getElementsByTagName('li');
        $ON(li,'mouseover,mouseout',Cm.subMenuHandler);
      }
      var div = nav.getElementsByTagName('div');
      $ON(div,'mouseover,mouseout,click',Cm.menuHandler)
    },
    doAccordian: function(aElm) {
      // Does anything need to be closed?
      var div = $ID('nav').getElementsByTagName('div');
      for ( var i=0; i < div.length; i++) {
        if ( (div[i] != aElm) && div[i].__NW__ && !div[i].__NW__.closed) {
          Cm.accRef++;
          Cm.doSlide(div[i]);
        }
      }
      // Can we open this thang?
      if ( aElm.__NW__) {
        Cm.accRef++;
        Cm.doSlide(aElm);
      }
    },
    accordianHandler: function( aElm) {
      if ( aElm.__NW__.closed) {
        aElm.__NW__.container.style.display = 'block';
        aElm.__NW__.closed = false;
        aElm.firstChild.src = 'images/acc_opened.png';
      }
      else {
        aElm.__NW__.container.style.display = 'none';
        aElm.__NW__.closed = true;
        aElm.firstChild.src = 'images/acc_closed.png';
      }
      --Cm.accRef;
    },
    doSlide: function( aElm) {
      var ul = aElm.__NW__.container;
      var isClosed = aElm.__NW__.closed;
      var total = Math.ceil(ACCORDIAN_RATE * ACCORDIAN_DURATION / 1000);
      var interval = 1000 / ACCORDIAN_RATE;
      var start = isClosed ? 0 : 1;
      var count = 0;
//alert('Start: '+start+'\nTotal: '+total+'\nInterval: '+interval);
      var height = isClosed ? (function() { 
        Neaux.merge( ul.style, { position: 'absolute', visibility: 'hidden', display: 'block', overflow: 'hidden', height: '' });
        var oh = ul.offsetHeight;
        Neaux.merge( ul.style, { position: '', height: '0px', visibility: 'visible' });
        return oh;
      })() : ul.offsetHeight;
      function renderContainer() {
        var pct = Cm.easing(++count,start,(isClosed ? 1 : -1), total);
        if ( pct > 1) pct = 1;
        else if ( pct < 0) pct = 0;
        ul.style.height = (height * pct) + 'px';
        var done = (count >= total);
        if ( done)
          Cm.accordianHandler( aElm);
        else
          setTimeout( renderContainer, interval);
      };
      renderContainer();
    },
    menuHandler: function( aEvt) {
      if ( Cm.accRef) return;
      var elm = aEvt.getCurrentTarget();
      switch( aEvt.getType()) {
        case 'click':
          if ( aEvt.getTarget().tagName == 'IMG')
            Cm.doAccordian( elm, aEvt.getTarget()); 
          break;
        case 'mouseover':
          elm.className = 'hover';
          break;
        case 'mouseout':
          if ( !Cm.menuNodes)
            elm.className = '';
          else
            elm.className = ((elm == Cm.menuNodes[0] && Cm.menuNodes.length == 1 )|| elm == Cm.menuNodes[1]) ? 'active' : '';
          break;
      }
    },
    subMenuHandler: function( aEvt) {
      if ( Cm.accRef) return;
      var elm = aEvt.getCurrentTarget();
      switch( aEvt.getType()) {
        case 'mouseover':
          elm.className = (Cm.menuNodes && elm == Cm.menuNodes[2]) ? 'hover active' : 'hover';;
          break;
        case 'mouseout':
          elm.className = (Cm.menuNodes && elm == Cm.menuNodes[2]) ? 'active' : '';;
          break;
      }
    },
    initMenu: function() {
      var nav = $ID('nav'), bc;
      if ( !nav) return;
      var nodes = Neaux.Util.getMenuNodes(nav);
      if ( bc = $ID('breadcrumbs')) { 
        bc.innerHTML = '&nbsp;';
        Neaux.Util.makeBreadcrumbs( nodes, bc);
      }
      if ( nodes) {
        if ( nodes.length > 2) nodes[2].className = 'active';
        var topNode = nodes.length > 1 ? 1 : 0;
        nodes[topNode].className = 'active';
      }
      Cm.menuNodes = nodes;
      Cm.initAccordian(nav);
    },
    initListeners: function() {
      if ( $ID('lnkSchedule')) {
        Cm.resetForm();
        $ON( 'lnkSchedule', 'click', function( aEvt) {
          Cm.showOverlay();
          aEvt.preventDefault();
        });
        $ON( 'overlay_close', 'click', function( aEvt) { 
          $ID('form_container').style.cssText = '';
          $ID('overlay').style.display = 'none';
          aEvt.preventDefault();
        });
        $ON( 'frmConsultation', 'submit', function( aEvt) {
          var $Http = Neaux.Http;
          $ID('btnSubmit').disabled = true;
          if ( Cm.validateForm())
            $Http.request( 'assets/continuum.php', 'post', Cm.handleServerResponse, aEvt.getTarget());
          aEvt.preventDefault();
        });
        $ON('txtServices','focus', function( aEvt) {
          var tgt = aEvt.getTarget();
          if ( tgt.value == tgt.defaultValue) { 
            tgt.value = '';
            tgt.style.cssText = '';
          }
        });
      }
    },
    resetForm: function() {
      $ID('frmConsultation').reset();
      $ID('btnSubmit').disabled = false;
    },
    showOverlay: function() {
      var ovl = $ID('overlay'), cnt = $ID('form_container'), scr = Neaux.Dom.getViewport();
      Neaux.merge( ovl.style, { 
        width: '100%',
        height: (Neaux.isMSIE ? document.body.offsetHeight : scr.pageHeight) + 'px',
        display: 'block'
      });
      Neaux.merge( cnt.style, { 
          top: Math.ceil((scr.height - cnt.offsetHeight)/2) + scr.y + 'px',
          left: Math.ceil((scr.width - cnt.offsetWidth)/2) + 'px',
          width: cnt.offsetWidth + 'px', 
          height: cnt.offsetHeight + 'px',
          visibility: 'visible'
      });
    },
    validateForm: function() {
      var theFrm = $ID('frmConsultation');
      var frmValid = true;
      for( var i=0; i < theFrm.elements.length; i++) {
        var theElt = theFrm.elements[i];
        if ( theElt.name) {
          var isValid = theElt.value && (theElt.value != theElt.defaultValue);
          Cm.setValidField( theElt, isValid);
          if ( !isValid) frmValid = false;
        }
      }
      var msg = $ID('msgRequired');
      msg.innerHTML = frmValid ? '<span>*</span>All fields are required' : 'PLEASE FILL IN FIELDS MARKED IN ORANGE.';
      if ( !frmValid) {
        $ID('btnSubmit').disabled = false;
        msg.style.color = '#f7941e';
      }
      else
        msg.style.cssText = '';
      return frmValid;
    },
    setValidField: function( aElt, aIsValid) {
      if ( typeof aIsValid == 'undefined') aIsValid = true;
      aElt.style.color = aIsValid ? '#000' : '#fff';
      aElt.style.backgroundColor = aIsValid ? '#fff' : '#f7941e';
    },
    handleServerResponse: function(aEvt) { 
      if ( !aEvt.isDone()) return;
      if ( aEvt.isOK()) {
        var ret = aEvt.getText();
//alert(ret);
        if ( ret == 'ACK')
          Cm.closeForm( true);
        else if ( ret != 'NAK') {
          var frm = $ID('frmConsultation');
          var o = Neaux.decodeJson(ret);
          for ( var i=0; i < o.count; ++i) {
            var name = o[i].field;
            Cm.setValidField( frm.elements[name], false);
          }
          var msg = $ID('msgRequired');
          msg.innerHTML = 'FIELDS MARKED IN ORANGE ARE INVALID.';
          $ID('btnSubmit').disabled = false;
          msg.style.color = '#f7941e';
        }
        else {
          alert('The system is currently not available or connectivity cannot be established');
          Cm.closeForm();
        }
      }
    },
    closeForm: function(aSuccess) {
      $ID('frmConsultation').style.display = 'none';
      $ID('form_container').style.cssText = '';
      if ( aSuccess) $ID('winConsultationSuccess').style.display = 'block';
      Cm.showOverlay();
    },
    start: function() { 
      Cm.initMenu();
      Neaux.Util.cacheImages(CACHED_IMAGES);
      Cm.initListeners();
/*
      var tgt = $ID('top_box');
      if ( tgt) $ON( tgt, 'mouseover,mouseout', function( aEvt) {
        if ( aEvt.getType() == 'mouseover')
          tgt.className = 'hover';
        else if ( aEvt.getTarget() == aEvt.getCurrentTarget())
          tgt.className = '';
      });
*/
    },
    toString: function() { return '[Continuum]'; }
  }
  Cm = Continuum;

  Neaux.onload( Cm.start);
})();
