(function() {
  Neaux.Namespace( 'Neaux.Util', 'Neaux.Api');
  var CONTACT_SUCCESS_MSG = 'Your request was submitted successfully.<br/>We will contact you shortly.<br/><br/> \
                             Click in this area to continue';

  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.
    //
    MenuNodes: 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')
          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();
    },
    //
    // Given an array of list nodes, generate a document fragment to be used as breadcrumbs.
    //
    MakeBreadcrumbs: function( aMenuNodes, aBreadcrumbID) { 
      if ( typeof aMenuNodes == 'string') aMenuNodes = Neaux.Util.MenuNodes(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);
      }
      var theBC = $ID(aBreadcrumbID);
      theBC.replaceChild( theFrag, theBC.firstChild);
    },
    
    Overlay: function( aOptions) {
      this.Create( aOptions);
    }
  });

  Neaux.Util.Overlay.prototype = {
    overlay: null,
    container: null,
    Create: function( aOptions) {
      this.overlay = document.createElement('div');
      Neaux.Merge( this.overlay.style, { position: 'absolute', top: '0px', left: '0px', zIndex: 10000, display: 'none' });
      if ( aOptions || aOptions.cssOverlay) this.overlay.className = aOptions.cssOverlay;
      document.body.appendChild(this.overlay);

      this.container = document.createElement('div');
      Neaux.Merge( this.container.style, { position: 'absolute', zIndex: 10001, visibility: 'hidden' });
      if ( aOptions || aOptions.cssContainer) this.container.className = aOptions.cssContainer;
      document.body.appendChild(this.container);

    },
    Load: function( aObj) {
      var scr = Neaux.Html.Viewport(), ov = this.overlay, ct = this.container;
      Neaux.Merge( ov.style, {
        width: '100%',
        height: (Neaux.isJSIE ? document.body.offsetHeight : scr.pageHeight) + 'px',
        display: 'block'
      });

      if ( ct.firstChild)
        ct.replaceChild(aObj, ct.firstChild);
      else
        ct.appendChild(aObj);

      Neaux.Merge( ct.style, { 
          top: Math.ceil((scr.height - ct.offsetHeight)/2) + scr.y + 'px',
          left: Math.ceil((scr.width - ct.offsetWidth)/2) + 'px',
          width: ct.offsetWidth + 'px', 
          height: ct.offsetHeight + 'px',
          visibility: 'visible' 
      });
    },
    Unload: function() {
      this.container.removeChild(this.container.firstChild);
      this.container.style.visibility = 'hidden';
      this.overlay.style.display = 'none';
      this.container.onclick = '';
      // Temporary Fix
      document.body.removeChild(this.container);
      document.body.removeChild(this.overlay);
    },
    toString: function() { return '[Neaux.Util.Overlay]' }
  }


  var $AFLD = Neaux.Api.Altos ? Neaux.Api.Altos.FIELDS : null,
      $APRM = Neaux.Api.Altos ? Neaux.Api.Altos.PARAMS : null,
      $Fn   = Neaux.Function,
      dummy = null;
  BLOUNT_ALTOS_ACCOUNT = '52847396';
  Blount = {
    overlay: null,
    form: null,
    altos: {
      obj: null,
      current: -1,
      opts: [ 
        { city: 'westport', stat: 'median', img: null, desc: 'Westport Homes - Median Price' },
        { city: 'weston', stat: 'median', img: null, desc: 'Weston Homes - Median Price' },
        { city: 'fairfield', stat: 'mean_dom', img: null, desc: 'Fairfield Homes - Days on Market' },
        { city: 'wilton', stat: 'inventory', img: null, desc: 'Wilton Homes - Inventory' },
        { city: 'darien', stat: 'median', img: null, desc: 'Darien Homes - Median Price' },
        { city: 'new canaan', stat: 'inventory', img: null, desc: 'New Canaan Homes - Inventory' },
        { city: 'easton', stat: 'mean_dom', img: null, desc: 'Easton Homes - Days on Market' },
        { city: 'greenwich', stat: 'median', img: null, desc: 'Greenwich Homes - Median Price' }
      ]
    },
    AdjustColumnHeight: function() {
      var left = $ID('content_left'), right = $ID('content_right');
      if ( !left || !right) return;
      var rightHeight = right.offsetHeight + 20;  // Fudge Factor
      // Special case, if Cathy's picks are on the page and there is extra space to overlap, then do it.
      // Need some CSS tweaking to make this happen
      //if ( $ID('sbr_cathys_picks_area')) { rightHeight -= RIGHT_OVERLAP; $ID('footer').style.clear = 'left'; }
      if ( left.offsetHeight < rightHeight)
        left.style.height = rightHeight + 'px';
      var theHeight = (left.offsetHeight > rightHeight ? left.offsetHeight : rightHeight);
      $ID('content').style.height = theHeight + 'px';
    },

    // ALTOS stuff for sidebar charts
    NextAltosChart: function() {
      var opt = Blount.altos.opts, altos = Blount.altos.obj;
      if ( ++Blount.altos.current == opt.length) Blount.altos.current = 0;
      var i = Blount.altos.current;
      var elt = $ID(Blount.chartID+'_caption');
      if ( elt) elt.innerHTML = opt[i].desc;
      if ( !opt[i].img) {
        altos.SetField( $AFLD.FLD_CITY, opt[i].city);
        altos.SetField( $AFLD.FLD_STATISTIC, opt[i].stat);
        opt[i].img = altos.Image();
      }
      var div = $ID(Blount.chartID+'_image');
      if ( div.childNodes.length)
        div.replaceChild(opt[i].img, div.firstChild);
      else
        div.appendChild(opt[i].img);
      $Fn.Delay(Blount.NextAltosChart,5000);
    },
/*
    InitAltosSidebar: function() { 
      // The ID is used exclusively for rotation of Altos Charts in the Sidebar.
      if ($ID('sbr_market_data_area')) {
        Blount.altos.obj = new Neaux.Api.AltosChart(BLOUNT_ALTOS_ACCOUNT);
        var altos = Blount.altos.obj;
        altos.SetField( $AFLD.FLD_STATE, 'CT');
        altos.SetField( $AFLD.FLD_ZIP, 'a');
        altos.Save();
        Blount.altos.obj.SetField( $AFLD.FLD_CHART_SIZE, $APRM.SZ_SMALL );
        Blount.NextAltosChart();
      }
    },
*/
    InitAltosChartWidget: function( aID, aSize) { 
      if ($ID(aID)) {
        Blount.chartID = aID;   // todo: would prefer a local-er scope
        Blount.altos.obj = new Neaux.Api.AltosChart(BLOUNT_ALTOS_ACCOUNT);
        var altos = Blount.altos.obj;
        altos.SetField( $AFLD.FLD_STATE, 'CT');
        altos.SetField( $AFLD.FLD_ZIP, 'a');
        altos.Save();
        Blount.altos.obj.SetField( $AFLD.FLD_CHART_SIZE, aSize );
        Blount.NextAltosChart();
      }
    },
    PreloadImages: function() {
      (function() {
        var dummy = new Array(arguments.length);
        for ( var i=0; i < arguments.length; i++) {
          dummy[i] = new Image();
          dummy[i].src = 'images/'+arguments[i];
        }
      })('ask_cathy.png');
    },
    SetBreadcrumbs: function( aBcContainer, aMenu) {
      if ( !$ID(aBcContainer)) return;
      // Clear Sample Breadcrumbs
      $ID(aBcContainer).innerHTML = '&nbsp;';
      Neaux.Util.MakeBreadcrumbs( aMenu, aBcContainer);
    },
    InitIconBar: function() {
      if ( $ID('ftr_icon_bar'))
        $ON('icon_suggest,icon_stats,icon_contact,icon_share','click',Blount.HandleIconBar);
      if ( $ID('page_title_bar'))
        $ON('page_title_bar','click',Blount.HandleIconBar);
    },
    HandleIconBar: function( aEvt) {
      switch( aEvt.CurrentTarget().id) {
        case 'icon_suggest':
          Blount.DoPopupForm('suggestion_box_form.php');
          break;        
        case 'icon_contact':
          Blount.DoPopupForm('contact_cathy_form.php');
          break;        
        case 'icon_share':
          break; 
        case 'page_title_bar':
          if ( aEvt.Target().tagName.toLowerCase() == 'span')
            Blount.DoPopupForm('ask_cathy_form.php');
          break;
      }
    },
    DoPopupForm: function( aUrl) {
      Blount.overlay = new Neaux.Util.Overlay( { cssOverlay: 'overlay', cssContainer: 'overlay_container' } );
      //if ( !Blount.overlay) Blount.overlay = new Neaux.Util.Overlay( { cssOverlay: 'overlay', cssContainer: 'overlay_container' } );
      Blount.form = new Blount.PopupForm( aUrl, { overlay: Blount.overlay } );
      Blount.form.onclose = function() { Blount.overlay.Unload() };
      Blount.form.SetListeners( { submit: 'btnSubmit', close: 'form_title_bar_close' });
    },
    Start: function() {
      Blount.AdjustColumnHeight();
      //Blount.InitAltosSidebar();
      Blount.InitAltosChartWidget('sbr_market_data', $APRM.SZ_SMALL);
      Blount.InitAltosChartWidget('home_market_data', $APRM.SZ_BLOG);
      Blount.PreloadImages();
      Blount.SetBreadcrumbs( 'breadcrumbs_bar', 'nav_bar');
      Blount.InitIconBar();
    },
    PopupForm: function( aUrl, aOptions) {    // Constructor
      if ( aOptions) Neaux.Merge( this, aOptions);
      this.Load(aUrl);
      if ( this.overlay) this.overlay.Load( this.form);
    },
    toString: function() { return '[Blount]' }
  }

  Blount.PopupForm.prototype = {
    form: null,
    conn: null,
    submit: null,
    overlay: null,

    onsuccess: $EFN,
    onerror: $EFN,
    onclose: $EFN,

    Form: function() { return this.form },
    Load: function( aUrl) {
      var xhr = new XMLHttpRequest;
      xhr.open( 'get', aUrl, false);
      xhr.send( null);
      if ( xhr.status != 200) throw new Error( 'XMLHttpRequest Error # ' + xhr.status);
      this.form = Neaux.Html.CreateHtml(xhr.responseText);
    },
    SetListeners: function( aOptions) {
      if ( aOptions) {
        if ( aOptions.submit) {
          this.submit = $ID(aOptions.submit);
          this.submit.onclick = $Fn.Bind(this.DoSubmit, this);
        }
        if ( aOptions.close) $ID(aOptions.close).onclick = $Fn.Bind(this.onclose, this);
      }
    },
    DoSubmit: function() {
      this.submit.disabled = true;
      if ( !this.conn) {
        this.conn = new Neaux.Http.Connection();
        this.conn.oncomplete = $Fn.Bind(this.HandleServerResponse, this);
      }
      this.conn.Request( { form: this.form } );
    },
    HandleServerResponse: function( aResp) {
      var theResponse = aResp.Text();
      var theStatus = Neaux.Array.IndexOf(theResponse, 'ERROR:');
      var theStatusText = CONTACT_SUCCESS_MSG;
      var theMsgArea = $ID('notification_area');
      var factor = 0;
      if ( theStatus >= 0) {
        theStatus += 'ERROR:'.length;
        theStatusText = '<u>Please make the following corrections:</u><br/><br/>' + theResponse.substr(theStatus);
        factor = 20;
      }
      else {
        theMsgArea = document.createElement('div');
        this.form.display = 'none';
        //this.form.reset();
        this.form = theMsgArea;
        this.form.style.padding = '40px 0';
        this.overlay.Load( theMsgArea);
        //$Fn.Delay( function() { this.overlay.onclick = this.overlay.Unload; }, 3000, this);
        this.overlay.container.onclick = $Fn.Bind(this.overlay.Unload, this.overlay);
      }
      this.submit.disabled = false;
      theMsgArea.innerHTML = theStatusText;
      theMsgArea.style.color = theStatus < 0 ? '#333333' : '#ff0000';
      theMsgArea.style.textAlign = 'center';
      theMsgArea.style.display = 'block';
      this.overlay.container.style.height = this.form.offsetHeight + factor + 'px';
    },
    toString: function() { return '[Blount.PopupForm]' }
  }

  Neaux.OnLoad(Blount.Start);
})();
