(function() {
  var ACCORDION_DELAY = 375;
  var ACCORDION_HEIGHT = 194;
  var ACCORDION_DURATION = 500;
  var ACCORDION_RATE = 20;
  var ROTATOR_DELAY = 3000;     // 3 seconds
  var ROTATOR_DURATION = 2000;  // 2 seconds
  //Neaux.Transition.__debug = true;

  MMA = { 
    rotator: null,
    accordion: null,
    contact: null,
    getMenuNodes: function( aMenuID) { 
      var menu = $ID(aMenuID);
      // 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.id != aMenuID) {
        if ( ptr.nodeName.toLowerCase() == 'li') {
          var a = ptr.getElementsByTagName('a');
          if ( a.length) {
            ptr.className = 'active';
            a[0].className = 'active';
          }
          theNodes.push(ptr);
        }
        ptr = ptr.parentNode;
      }

      var home = menu.getElementsByTagName('li')[0];
      if ( home != theNodes[theNodes.length-1])
        theNodes.push(home);

      // Return 'em in top-down order
      return theNodes.reverse();
    },


    startMenuHelper: function() {
      var mainnav = MMA.getMenuNodes('nav');
      if ( !mainnav || mainnav.length < 2) return;

//foo = ''; for ( var i=0; i < mainnav.length; i++) foo += mainnav[i].innerHTML + '\n'; alert(foo);
      var subnav = $ID('mod_subnav');
      if ( !subnav) return;     // Sidebar module is not deployed... nothing to do

      // Get the first unordered list tag from the menu (The current menu bar selection)
      var mainUL = mainnav[1].getElementsByTagName('ul');
      // Get the Anchor from the menu bar...
      var mainLink = mainnav[1].getElementsByTagName('a')[0];

      var oldUl = subnav.getElementsByTagName('ul');
      var newUL = document.createElement('ul')
      var li = document.createElement('li');
      var bar = newUL.appendChild(li);
      //alert(bar);
      subnav.replaceChild(newUL,oldUl[0]);
      li.innerHTML = '<a href="' + mainLink.href + '">' + mainLink.innerHTML + '</a>';

      // If there is a dropdown, make a copy of active part of the menu bar tree
      // Append this to the 
      if ( mainUL.length) {  // Has 1 or more levels
        var newUL = mainUL[0].cloneNode(true);
        li.appendChild(newUL);
      }
      //alert(subnav.innerHTML);
    },

    initContactForm: function() {
  	  if ( !$ID( 'frmContact')) return;
      MMA.contact = new Neaux.Form( { 
        element: 'frmContact',
        method: 'post',
        action: '/assets/mma.php',
        onsubmit: function( aEvt) {
          var frm = aEvt.getSource().getElement();
          var invFields = {};
          emailRegex = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i;
          for ( var i=0; i<frm.length; i++) {
            //alert( 'Name: '+frm[i].name+'\nValue: '+frm[i].value+'\nDefault: '+frm[i].defaultValue);
            //if ( !frm[i].name || frm[i].name == 'newsletter') continue;   // Skip
            if ( frm[i].value == frm[i].defaultValue) {
              invFields[frm[i].name] = true;  // Required
              frm[i].title = frm[i].name + ': Field is Required';
            }
            else if ( frm[i].name == 'email' && !emailRegex.test(frm[i].value)) {
              invFields[frm[i].name] = true;  // Invalid email address 
              frm[i].title = frm[i].name + ': Invalid email address';
            }
          }
          if ( MMA.renderInvalidFields(frm, invFields))
            aEvt.cancel();
        },
        oncomplete: function( aEvt) {
          //alert(aEvt.getText());
		      $ID('thank_you').style.display = 'block';
					var google_conversion_id = 1011971597;
					var google_conversion_language = "en";
					var google_conversion_format = "3";
					var google_conversion_color = "ffffff";
					var google_conversion_label = "oAdOCMP4sAIQjezF4gM";
					var google_conversion_value = 0;
					_gaq.push(['_trackPageview', '/thank-you.html']);
		      return false;
        }
	    });
    },
    renderInvalidFields: function( aFrm, aInvList) {
      var errorsFound = false;
      for ( var i=0; i<aFrm.length; i++) {
        if ( aFrm[i].name) {
          if ( aInvList[aFrm[i].name]) {
            //alert( aFrm[i].name + aFrm[i].value);
            errorsFound = true;
            aFrm[i].className = 'invalid';
          }
          else {
            aFrm[i].className = '';
            aFrm[i].title = '';
          }
        }
      }
      if ( errorsFound)
        $ID('frmContactError').style.visibility = 'visible';
      return errorsFound;
    },

    initHomeRotator: function() {
      if ( !$ID('home_banner')) return;   // Not on home page
      MMA.rotator = new MMA.Rotator();
    },

    initHomeAccordion: function() {
      if ( !$ID('home_expertise')) return;   // Not on home page
      MMA.accordion = new MMA.Accordion();
    },

    initHomeThoughtLeadership: function() {
      if ( !$ID('home_thought')) return;    // Not on home page
      var btns = $ID('leadership_pubs').getElementsByTagName('li');
      var secs = Neaux.Dom.getElementsByClassName('news_section','leadership_news');
      var current = 0;
      for ( var i=0; i < btns.length; ++i) btns[i].__NW__ = i;
      $ON( btns, 'click', function( aEvt) {
        var value = aEvt.getCurrentTarget().__NW__;
        aEvt.preventDefault();
        if ( value == current) return;
        secs[current].style.display = 'none';
        btns[current].className = "";
        secs[value].style.display = 'block';
        btns[value].className = "selected";
        current = value;
      });
    },

    run: function() {
      //MMA.startMenuHelper();  // PLACED IN PAGE BODY
      MMA.initContactForm();
      MMA.initHomeAccordion();
      MMA.initHomeRotator();
      MMA.initHomeThoughtLeadership();
    },
    toString: function() { return '[Marketing Management Analytics object]'; }
  }


  MMA.Rotator = Neaux.Class( {
    m_selection: null,          // Currently selected item (numeric)
    m_items: null,              // Numeric array containing selection information (object)
    m_selectors: null,          // Assoc array of selector numbers (indexed by selector text)
    m_fadeIn: null,             // Transition object executing fade-in
    m_fadeOut: null,            // Transition object executing fade-out
    m_isTransEnabled: true,     // True if selections fade in/out
    m_isRotatorEnabled: true,   // True if automatic rotation of images are enabled.
    m_count: 0,                 // Number of outstanding transitions-in-progress
    m_timer: null,              // Between transitions timer

    __construct: function() { 
      // The selectors are LI elements that contain a keyword corresponding to the image.
      var theSelectors = $ID('banner_selector').getElementsByTagName('li');

      this.m_selection = 0;
      // Initialize the working data properties
      this.m_items = []; this.m_selectors = {};
      for ( var i=0; i < theSelectors.length; i++) {
        theSelectors.className = (i == this.m_selection) ? 'active' : ""; // Class = active is the current selector and is rendered as such
        var theText = theSelectors[i].innerHTML.toLowerCase();
        var theContainer = $ID('home_'+theText);
        if ( !theContainer) throw new Error('Rotator - No image section for home_' + theText + ' was found');
        theContainer.style.zIndex = (i == this.m_selection) ? 10 : 1; // Current selector is z-indexed at 10
        theContainer.style.display = 'block';
        this.m_items[i] = { text: theText, selector: theSelectors[i], container: theContainer };
        this.m_selectors[theText] = i;
      }

      // Create the Transition objects to fade in and fade out (for crossfade).
      var theProps = { property: 'opacity', from: 0, to: 1, duration: ROTATOR_DURATION, onfinish: [this,this.handleTransition] };
      this.m_fadeIn = new Neaux.Transition( theProps);
      theProps.direction = Neaux.Transition.OUT,
      this.m_fadeOut = new Neaux.Transition( theProps);

      //this.m_isTransEnabled = false;    // TO TEMPORARILY DISABLE TRANSITIONS FOR TESTING
      $ON( theSelectors, 'mouseover', [this,this.handleSelection]);
      if ( this.m_isRotatorEnabled) this.doTransition();
    },

    doTransition: function( aNew) {
      var _this = this;
      var sel = (typeof aNew !== 'undefined') ? aNew : (function() {
        if ( !_this.m_isRotatorEnabled) return this.m_selection;
        var next = _this.m_selection + 1;
        return (next < _this.m_items.length) ? next : 0;
      })();
      if ( sel == this.m_selection) return;

      // initialize the opacity and stack the new item on top
      Neaux.Html.setStyle( this.m_items[sel].container, { opacity: 0, zIndex: 20 });

      var cur = this.m_selection;
      this.m_fadeIn.applyParams( { target: this.m_items[sel].container } );
      this.m_fadeOut.applyParams( { target: this.m_items[cur].container } );

      // Start the fade
      this.m_count = 2;
      this.m_candidate = sel;
      this.m_fadeIn.start();
      this.m_fadeOut.start();   // FOR XFADE
    },

    // This is called when user mouses over a selector
    handleSelection: function( aEvt) {
      this.m_isRotatorEnabled = false;
      if ( this.m_count) return;
      var tgt = aEvt.getTarget();
      if ( tgt.tagName != 'LI') return;
      var theText = tgt.innerHTML.toLowerCase();
      var sel = this.m_selectors[theText];
      var cur = this.m_selection;
      if ( sel == cur) return; // Nothing to do
//alert('cur: '+cur+'\nsel: '+sel);
      if ( !this.m_isTransEnabled) {
        this.m_items[cur].container.style.zIndex = 1;
        this.m_items[cur].selector.className = "";
        this.m_items[sel].container.style.zIndex = 10;
        this.m_items[sel].selector.className = 'selected';
        this.m_selection = sel;
      }
      else
        this.doTransition(sel);
    },

    // This is called after each transition completes
    handleTransition: function() {
      if ( --this.m_count) return;
      var cur = this.m_selection;
      var sel = this.m_candidate;

      this.m_items[cur].container.style.zIndex = 1;
      this.m_items[cur].selector.className = "";
      this.m_items[sel].container.style.zIndex = 10;
      this.m_items[sel].selector.className = "selected";
      this.m_selection = sel;
      if ( this.m_isRotatorEnabled) { 
        this.m_timer = Neaux.Function.delay( function() {
          this.m_timer = null;
          this,this.doTransition();
        }, ROTATOR_DELAY, this);
      }
    },

    toString: function() { return '[class MMA.Rotator]'; }
  });

  // TODO: MAKE CONTAINING <DIV>'S <P>'S FOR CONTENT MANAGEMENT
  MMA.Accordion = Neaux.Class( {
    m_selection: null,  // Currently selected section (numeric)
    m_bars: null,       // Title bars that activate accordion (numeric array)
    m_content: null,    // Content area section for each accordion (numeric array)
    m_in: null,         // Transition object executing fade-in
    m_out: null,        // Transition object executing fade-out
    m_timer: null,      // Mouseover delay timer handle
    m_candidate: null,  // The section which will become current (numeric)
    m_count: 0,         // Number of outstanding transitions-in-progress

    __construct: function() {
      this.m_bars = Neaux.Dom.getElementsByClassName('accordion_bar', 'expertise_content');
      this.m_content = Neaux.Dom.getElementsByClassName('accordion_content', 'expertise_content');

      // Set up 2 transition objects - in to grow, out to shrink
      var theProps = { property: 'height', from: 0, to: ACCORDION_HEIGHT, units: 'px', 
        rate: 20, duration: ACCORDION_DURATION, onfinish: [this,this.handleTransition] 
      };
      this.m_in = new Neaux.Transition( theProps);
      theProps.direction = Neaux.Transition.OUT;
      this.m_out = new Neaux.Transition( theProps);

      // Mouseing over a bar triggers accordioning, but if they don't stay in the bar area for
      // a small period of time, we don't do it, so mouse out cancels a triggered accordion
      $ON( this.m_bars, 'click', function(aEvt) { aEvt.stopEvents(); });  // Disable clicks
      $ON( this.m_bars, 'mouseover', [this, this.triggerAccordion]);
      $ON( this.m_bars, 'mouseout', [this, this.cancelAccordion]);

      this.m_selection = 0;   // Start with 0 selected (assume it is styled that way)
    },

    // Called if the user clicks on an accordion bar
    triggerAccordion: function( aEvt) {
      if ( this.m_count) return;  // Bail out if we are already accordioning
      if ( this.m_timer) { alert('MOUSEOVER CALLED WHEN TIMER ACTIVE'); return; }   // This shouldn't happen
      var tgt = aEvt.getCurrentTarget();  // Need current target (element that issued the listen call
      if ( tgt.tagName != 'DIV') return;  // It should be a div tag
      
      var n = this.m_selection, cur = this.m_bars[n];
      if (tgt == cur) return;  // Already selected, outta here

      for ( var i=0; i < this.m_bars.length; i++) // i will be the number of the candidate bar
        if ( tgt == this.m_bars[i]) break;
      if (i == this.m_bars.length) alert('TARGET OUT OF BOUNDS');   // This shouldn't happen
      this.m_candidate = i;

      // Set the timer that will trigger the accordion if not cancelled
      this.m_timer = Neaux.Function.delay([this,this.timerHandler], ACCORDION_DELAY);
    },

    // Called if the user mouses out of an accordion bar
    cancelAccordion: function( aEvt) {
      if ( this.m_timer) {  // Irrelevent if the accordion trigger delay timer is not in-process
        window.clearTimeout(this.m_timer);
        this.m_timer = null;
      }
    },

    // If this timer is called, we're good to go with the accordioning
    timerHandler: function() {
      this.m_timer = null;
      this.m_count = 2;

      var newContent = this.m_content[this.m_candidate];
      newContent.style.height = '0px';
      newContent.className = 'accordion_content active';
      this.m_bars[this.m_candidate].className = 'accordion_bar active';
      // Since the "see more" link is bottom anchored absolutely position, there's some weirdness
      // when the container changes size - it slides down... so let's make make it disappear and
      // restore it when the transition has completed.
      var seemore = Neaux.Dom.getElementsByClassName('see_more', newContent);
      seemore[0].style.display = 'none';

      this.m_out.applyParams( { target: this.m_content[this.m_selection] } );
      this.m_out.start();
      this.m_in.applyParams( { target: newContent } );    
      this.m_in.start();
    },

    // Called as each transition has completed
    handleTransition: function() {
      --this.m_count;
      if ( this.m_count == 0) {
        var o = this.m_selection;
        var n = this.m_candidate;
        this.m_bars[o].className = 'accordion_bar';
        this.m_content[o].className = 'accordion_content';
        //this.m_bars[n].className = 'accordion_bar active';
        //this.m_content[n].className = 'accordion_content active';
        var seemore = Neaux.Dom.getElementsByClassName('see_more', this.m_content[n]);
        seemore[0].style.display = 'inline';
        this.m_selection = this.m_candidate;
      }
    },

    toString: function() { return '[class MMA.Accordion]'; }
  });

  Neaux.onload( MMA.run);
})();
