/**
 * Navbar JavaScript class
 * @since 2009-11-01
 */
var Navbar = {

  // settings
  ghostOpacity    : 0,
  maxMoreFunRows  : 10,
  moreFunMinWidth : 133,
  moreFunMaxWidth : 199,

  // internal vars
  id              : '#navbar',
  idGhost         : '#navbar_ghost',
  idDropDown      : '#navbar_dropdown',
  idDropDownGhost : '#navbar_dropdown_ghost',
  idDropDownLoad  : '#navbar_dropdown_load',
  idSave          : '#navbar_save',
  idMoreFun       : '#navbar_morefun',
  idPlaceholder   : '#navbar_placeholder',

  jqObj              : null,
  jqGhostObj         : null,
  jqDropDownObj      : null,
  jqDropDownGhostObj : null,
  jqDropDownLoadObj  : null,
  jqSaveObj          : null,
  jqMoreFunObj       : null,
  jqPlaceholderObj   : null,
  jqOriginalObj      : null,

  dragTile            : null,
  dragTileId          : '',
  placeholderLocation : '',

  bodyMarginLeft : 0,
  originalZ      : null,
  isViewingMore  : false,
  isBeingEdited  : false,
  isLoggedIn     : false,
  isStatic       : false,

  mainNavOccupiedWidth : null,
  hiddenAds            : [ ],

  /**
   * Actions to take upon a new Navbar, usually document.ready
   */
  init : function( )
  {
    Navbar.originalZ = parseInt( Navbar.jq( ).css('z-index') );
    Navbar.jq( ).children( 'li' ).not( Navbar.idMoreFun )
      .bind( 'mouseenter', Navbar.tileMouseenter )
      .bind( 'mouseleave', Navbar.tileMouseleave );
    Navbar.moreFunBind( );
    Navbar.bindClickRecording( );
    Navbar.isStatic = Navbar.jq( ).hasClass( 'navbar_static' );
    Navbar.mainNavOccupiedWidth = null;
  },

  /**
   * Handles Navbar-related errors in a uniform way. This is necessary
   * in order to cancel Navbar actions in the correct way and return
   * to a normal state.
   *
   * @param object options for error handling
   *  error : error message to be displayed
   */
  errorHandler : function( errorObj )
  {
    var error = 'An unknown error has occurred. Please try again.';
    if ( errorObj && errorObj.error )
    {
      error = errorObj.error;
    }
    $.dragonAlert( error, { title : 'Navbar Error', okCallback : Navbar.reset } );
  },

  /**
   * Resets the Navbar to a default state. Useful when a user is canceling an edit,
   * or due to error.
   */
  reset : function( )
  {
    $.dragonCurtainRemove( );
    Navbar.jq( ).css( 'z-index', Navbar.originalZ );
    Navbar.isBeingEdited = false;
    Navbar.isViewingMore = false;
    Navbar.jqDropDown( ).remove( );
    Navbar.jqDropDownObj = null;
    Navbar.jqDropDownLoad( ).remove( );
    Navbar.jqDropDownLoadObj = null;
    Navbar.jqMoreFun( ).removeClass( 'morefun_on' );
    Navbar.moreFunBind( );
  },

  hideAds : function( )
  {
    Navbar.hiddenAds = $('embed, object, iframe').filter(':visible');
    Navbar.hiddenAds.each( function( ){
      var t = $(this);
      var p = t.parent( );
      t.parent( ).width( p.width( ) );
      t.parent( ).height( p.height( ) );
    }).hide( );
  },

  showAds : function( )
  {
    if ( Navbar.hiddenAds.length > 0 )
    {
      Navbar.hiddenAds.show( );
    }
  },

  /**
   * Get a standard IMAGE_URL.
   *
   * @return string IMAGE_URL
   */
  getImageURL : function( )
  {
    if ( MyYearbook.isLegacy( ) )
    {
      return IMAGE_URL + '/';
    }
    else
    {
      return IMAGE_URL;
    }
  },

  /**
   * Get a URL to use for Navbar jsonp requests.
   *
   * @return string url
   */
  getJSONURL : function ( )
  {
    if ( MyYearbook.currentServiceName == 'www' || MyYearbook.currentServiceName == 'home' )
    {
      return SITE_URL + 'apps/navbar/json/';
    }
    else if ( MyYearbook.currentServiceName == 'quiz' || MyYearbook.currentServiceName == 'pimp' )
    {
      return SITE_URL + '/apps/navbar/json/';
    }
    else
    {
      return '/navbar/json/';
    }
  },

  /**
   * Executes a Navbar jsonp request.
   *
   * @param string name of Navbar method to perform
   * @param object data to send in request
   */
  jsonP : function( method, data )
  {
    $.ajax({
      url : Navbar.getJSONURL( ) + method,
      type : 'get',
      dataType : 'jsonp',
      data : data,
      error : function( ){
        Navbar.errorHandler( );
      }
    });
  },

  jq : function( )
  {
    if ( !Navbar.jqObj || Navbar.jqObj.length < 1 )
    {
      Navbar.jqObj = $( Navbar.id );
    }
    return Navbar.jqObj;
  },

  jqGhost : function( )
  {
    if ( !Navbar.jqGhostObj || Navbar.jqGhostObj.length < 1 )
    {
      Navbar.jqGhostObj = $( Navbar.idGhost );
    }
    return Navbar.jqGhostObj;
  },

  jqDropDown : function( )
  {
    if ( !Navbar.jqDropDownObj || Navbar.jqDropDownObj.length < 1 )
    {
      Navbar.jqDropDownObj = $( Navbar.idDropDown );
    }
    return Navbar.jqDropDownObj;
  },

  jqDropDownGhost : function( )
  {
    if ( !Navbar.jqDropDownGhostObj || Navbar.jqDropDownGhostObj.length < 1 )
    {
      Navbar.jqDropDownGhostObj = $( Navbar.idDropDownGhost );
    }
    return Navbar.jqDropDownGhostObj;
  },

  jqDropDownLoad : function( )
  {
    if ( !Navbar.jqDropDownLoadObj || Navbar.jqDropDownLoadObj.length < 1 )
    {
      Navbar.jqDropDownLoadObj = $( Navbar.idDropDownLoad );
    }
    return Navbar.jqDropDownLoadObj;
  },

  jqMoreFun : function( )
  {
    if ( !Navbar.jqMoreFunObj || Navbar.jqMoreFunObj.length < 1 )
    {
      Navbar.jqMoreFunObj = $( Navbar.idMoreFun );
    }
    return Navbar.jqMoreFunObj;
  },

  jqSave : function( )
  {
    if ( !Navbar.jqSaveObj || Navbar.jqSaveObj.length < 1 )
    {
      Navbar.jqSaveObj = $( Navbar.idSave );
    }
    return Navbar.jqSaveObj;
  },

  jqPlaceholder : function( )
  {
    if ( !Navbar.jqPlaceholderObj || Navbar.jqPlaceholderObj.length < 1 )
    {
      Navbar.jqPlaceholderObj = $( Navbar.idPlaceholder );
    }
    return Navbar.jqPlaceholderObj;
  },

  jqOriginal : function( )
  {
    return Navbar.jqOriginalObj;
  },

  getSelectedTile : function( )
  {
    return Navbar.jq( ).attr( 'data-selected' ) || '';
  },

  /**
   * Changes display of a tile upon event 'mouseenter'.
   *
   * @param event
   */
  tileMouseenter : function( e )
  {
    var t = $(this);
    var id = t.attr('data-id');
    t.addClass( 'navbar_' + id + '_over' );

    if ( t.parents( Navbar.idDropDown ).length > 0 )
    {
      t.addClass( 'navbar_morefun_over' );
      t.find( 'span' ).addClass( 'navbar_' + id + '_over' );
    }
  },

  /**
   * Reverts display of a tile upon 'mouseleave',
   * that was modified with the event 'mouseenter'.
   *
   * @param event
   */
  tileMouseleave : function( e )
  {
    var t = $(this);
    var id = t.attr('data-id');
    t.removeClass( 'navbar_' + id + '_over' );

    if ( t.parents( Navbar.idDropDown ).length > 0 )
    {
      t.removeClass( 'navbar_morefun_over' );
      t.find( 'span' ).removeClass( 'navbar_' + id + '_over' );
    }
  },

  /**
   * Binds click action for the 'More Fun' tile.
   */
  moreFunBind : function( )
  {
    Navbar.jqMoreFun( )
      .unbind('click')
      .css({ cursor : 'pointer' });
    if ( !Navbar.jqDropDown( ).is( ':visible' ) )
    {
      Navbar.jqMoreFun( ).one( 'click', Navbar.moreFunClickOn );
    }
    else
    {
      Navbar.jqMoreFun( ).one( 'click', Navbar.moreFunClickOff );
    }
  },

  /**
   * Unbinds click action for the 'More Fun' tile.
   */
  moreFunUnbind : function( )
  {
    Navbar.jqMoreFun( ).unbind('click')
      .css({ cursor : 'default' });
  },

  /**
   *
   */
  moreFunClickOn : function( e )
  {
    e.stopPropagation( );
    Navbar.hideAds( );

    // to compensate for the extra border in the "on" state
    Navbar.jqMoreFun( ).addClass( 'morefun_on' );
    Navbar.jqMoreFun( ).width( Navbar.jqMoreFun( ).width( ) - 1 );
    if ( Navbar.jqDropDown( ).length > 0 )
    {
      if ( !Navbar.jqDropDown( ).data( 'bound' ) )
      {
        Navbar.dropDownPosition( );
        Navbar.dropDownBind( );
      }
      Navbar.dropDownShow( );
    }
    else
    {
      var imgPath = 'images/loading/99BBFF-E2EDFF-indicator.gif';
      if ( typeof( imageURL ) != 'undefined' )
      {
        // for hbl
        try
        {
          imgPath = imageURL( imgPath );
        }
        catch ( exc ) { }
      }
      else
      {
        imgPath = Navbar.getImageURL( ) + imgPath ;
      }
      $('<div id="navbar_dropdown_load"><img src="' + imgPath + '" /></div>')
        .appendTo( 'body' )
        .css({
          width : Navbar.jqMoreFun( ).width( ),
          top  : Navbar.dropDownTopCoord( ),
          right : Navbar.dropDownRightCoord( )
        });
      Navbar.jsonP( 'moreFun', { selected : Navbar.getSelectedTile( ) } );
    }
  },

  moreFunJSONHandler : function( data )
  {
    Navbar.jqDropDownLoad( ).remove( );
    Navbar.jqDropDownLoadObj = null;
    if ( data.success && data.markup && data.markup != '' )
    {
      $( data.markup ).hide( ).insertAfter( Navbar.id );

      Navbar.isLoggedIn = data.isLoggedIn;
      Navbar.dropDownPosition( );
      Navbar.dropDownBind( );
      Navbar.dropDownShow( );
    }
  },

  moreFunClickOff : function( e )
  {
    var t = $(this);

    if ( Navbar.isViewingMore )
    {
      Navbar.jqDropDown( ).find( 'div.view > div' ).trigger( 'click' );
    }

    Navbar.jqDropDown( ).slideUp( 'fast', function(){
      Navbar.jqMoreFun( )
        .removeClass( 'morefun_on' )
        .width( Navbar.jqMoreFun( ).width( ) + 1 );
      Navbar.moreFunBind( );
    });

    Navbar.showAds( );
  },

  dropDownTopCoord : function( )
  {
    var topCoord = Navbar.jqMoreFun( ).offset( ).top + Navbar.jqMoreFun( ).height( );
      topCoord++;
    return topCoord;
  },

  dropDownRightCoord : function( )
  {
    var rightCoord = 1;
    var ie6 = false;
    if ( $.browser.msie && $.browser.version == 6 )
    {
      ie6 = true;
    }

    if ( MyYearbook.isLegacy( ) && MyYearbook.currentServiceName != 'quiz' && MyYearbook.currentServiceName != 'pimp' )
    {
      rightCoord += parseInt( ( $(window).width( ) - $('#maincontainer').width( ) ) / 2 );
    }
    // some HAL themes
    else if ( $('html > body').hasClass( 'HAL' ) )
    {
      var contentWidth = $('#content').width( );
      var bodyWidth = $('html > body').width( );
      if ( ie6 )
      {
        bodyWidth -= 10;
      }

      if ( bodyWidth > contentWidth + 2 )
      {
        rightCoord += parseInt( ( bodyWidth - contentWidth ) / 2 );
        if ( ie6 )
        {
          rightCoord -= 5;
        }
      }
      else if ( ie6 )
      {
        rightCoord = 'auto';
      }
    }

    if ( $.browser.msie )
    {
      if ( $.browser.version == 8 && MyYearbook.isLegacy( ) && MyYearbook.currentServiceName != 'quiz' && MyYearbook.currentServiceName != 'pimp' )
      {
        rightCoord++;
      }
      else if ( $.browser.version == 7 && MyYearbook.isLegacy( ) && MyYearbook.currentServiceName != 'quiz' && MyYearbook.currentServiceName != 'pimp' )
      {
        rightCoord--;
      }
      else if ( ie6 && !MyYearbook.isLegacy( ) && rightCoord != 'auto' )
      {
        rightCoord += 10;
      }
    }
    else if ( $.browser.safari && MyYearbook.isLegacy( ) )
    {
      rightCoord -= 7;
    }

    return rightCoord;
  },

  dropDownPosition : function( )
  {
    Navbar.jqDropDown( ).css({
      top  : Navbar.dropDownTopCoord( ),
      right : Navbar.dropDownRightCoord( )
    });
  },

  dropDownBind : function( )
  {
    Navbar.jqDropDown( )
      .data( 'bound', true )
      .find( 'li' )
        .bind( 'mouseenter', Navbar.tileMouseenter )
        .bind( 'mouseleave', Navbar.tileMouseleave )
        .bind( 'click', function(e){ window.location = $(this).children( 'a' ).attr('href'); })
        .end( )
      .find('div.view > div')
        .unbind( 'click' )
        .toggle( Navbar.viewMoreClick, Navbar.viewLessClick )
        .get( 0 ).lastToggle = 2;

    if ( Navbar.isLoggedIn )
    {
      Navbar.isBeingEdited = false;
      Navbar.jqDropDown( )
        .find('div.edit > div')
        .unbind( 'click' )
        .toggle( Navbar.editStart, Navbar.editStop )
        .get( 0 ).lastToggle = 2;
      Navbar.jqSave( )
        .find( 'img.save' ).bind( 'click', Navbar.saveStart ).end( )
        .find( 'img.cancel' ).bind( 'click', Navbar.editCancel ).end( )
        .find( 'span.restore' ).bind( 'click', Navbar.restoreStart );
    }
    else
    {
      Navbar.jqDropDown( ).find('div.edit > div').bind( 'click', function(e){
        Navbar.errorHandler({ error : 'You must be logged in to edit your Navbar.' });
      });
    }

    Navbar.bindClickRecording( );
  },

  dropDownShow : function( )
  {
    $(document).trigger('click.search');
    $(document).trigger('click.profile');
    Navbar.jqDropDown( ).find( 'ul.main li' ).each(function(i){
      t = $(this);
      Navbar.dropDownFormat( t );
    });
    Navbar.tileAdjustments( );

    var width = Navbar.jqMoreFun( ).width( );
    Navbar.jqDropDown( ).find( 'ul' ).width( width );
    Navbar.jqDropDown( ).find( 'div.right' ).width( width + 2 );

    if ( !Navbar.isLoggedIn || Navbar.isStatic )
    {
      Navbar.jqDropDown( ).find( 'div.edit' ).hide( );
    }

    Navbar.dropDownPosition( );
    Navbar.jqDropDown( ).slideDown( 'fast', function( ){
      Navbar.moreFunBind( );
    });

    $(document).bind('click.NavbarMoreFun', function(e){
      if ( !Navbar.isBeingEdited )
      {
        if ( Navbar.jqDropDown( ).length > 0 )
        {
          var ddOffset = Navbar.jqDropDown( ).offset( );
          var ddWidth = Navbar.jqDropDown( ).width( );
          var ddHeight = Navbar.jqDropDown( ).height( );

          if ( e.pageX < ddOffset.left || e.pageX > ddOffset.left + ddWidth || e.pageY < ddOffset.top || e.pageY > ddOffset.top + ddHeight )
          {
            $(document).unbind( 'click.NavbarMoreFun' );
            Navbar.jqMoreFun( ).trigger( 'click' );
          }
        }
      }
    });
  },

  getMainNavOccupiedWidth : function( )
  {
    if ( Navbar.mainNavOccupiedWidth == null )
    {
      var totalWidth = 0;
      Navbar.jq( ).find( 'li[data-id]' ).each(function(i){
        // + 1 to account for one side's border.
        totalWidth += parseInt( $(this).css('width') ) + 1;
      });
      // + 2 to account for the #navbar border.
      totalWidth = totalWidth + 2;
      Navbar.mainNavOccupiedWidth = totalWidth;
    }
    
    return Navbar.mainNavOccupiedWidth;
  },

  clearMainNavOccupiedWidth : function( )
  {
    Navbar.mainNavOccupiedWidth = null;
  },

  getMainNavAvailableWidth : function( )
  {
    var availWidth = 952 - Navbar.getMainNavOccupiedWidth( );
    return availWidth;
  },

  moreFunAdjustment : function( )
  {
    // adjust More Fun size
    var mfWidth = Navbar.getMainNavAvailableWidth( );
    if ( mfWidth > Navbar.moreFunMaxWidth )
    {
      mfWidth = Navbar.moreFunMaxWidth;
    }
    else if ( mfWidth < Navbar.moreFunMinWidth )
    {
      mfWidth = Navbar.moreFunMinWidth;
    }

    if ( Navbar.jqMoreFun( ).hasClass( 'morefun_on' ) )
    {
      mfWidth = mfWidth - 1; // extra border on More Fun
    }
    Navbar.jqMoreFun( ).width( mfWidth );
    if ( Navbar.jqGhost( ).length > 0 )
    {
      Navbar.jqGhost( ).children( Navbar.idMoreFun ).width( mfWidth );
    }

    return mfWidth;
  },

  tileAdjustments : function( )
  {
    var availWidth = Navbar.getMainNavAvailableWidth( );

    // move tiles that won't fit in the main nav
    if ( availWidth < Navbar.moreFunMinWidth )
    {
      var tile = Navbar.jq( ).find('li:not(' + Navbar.idMoreFun + '):not(' + Navbar.idPlaceholder + '):not(.navbar_' + Navbar.dragTileId + '):last');
      var loc = Navbar.jqDropDown( ).find('ul.main');
      Navbar.moveTileToLocation( tile, loc, 'prepend' );

      // this function is going to run again after this tile is moved, so we can escape safely
      return;
    }

    var mfWidth = Navbar.moreFunAdjustment( );

    var allUl = Navbar.jqDropDown( ).find( 'ul' );

    if ( allUl.length < 2 )
    {
      Navbar.jqDropDown( ).find( 'div.view' ).hide( );
    }
    else if ( !Navbar.isBeingEdited )
    {
      Navbar.jqDropDown( ).find( 'div.view' ).show( );
    }

    var extra = Navbar.jqDropDown( ).find( 'div.extra' );
    var extraGhost = Navbar.jqDropDownGhost( ).find('div.extra');
    
    // ie fix
    if ( $.browser.msie )
    {
      extra.width( mfWidth + 2 );
      extraGhost.width( mfWidth + 2 );
    }

    allUl.each(function(i){
      var ul = $(this);
      var listNum = parseInt( ul.attr( 'data-list_num' ) );
      var ulLi = ul.find( 'li:not(' + Navbar.idPlaceholder + ')' );

      ul.width( mfWidth );
      Navbar.jqDropDownGhost( ).find('ul[data-list_num="' + listNum + '"]').width( mfWidth );

      if ( ulLi.length > Navbar.maxMoreFunRows )
      {
        var nextUl = allUl.eq( i + 1 );
        if ( nextUl.length < 1 )
        {
          var newListNum = listNum + 1;
          var ulWidth = ul.width( );
          nextUl = $('<ul />')
            .width( ulWidth )
            .attr( 'data-list_num', newListNum )
            .appendTo( extra );
          $('<ul />')
            .width( ulWidth )
            .attr( 'data-list_num', newListNum )
            .appendTo( extraGhost ).show( );
        }
        Navbar.moveTileToLocation( ulLi.filter( ':last' ), nextUl, 'prepend' );
        return true;
      }

      // if we have less than the max...
      if ( ulLi.length < Navbar.maxMoreFunRows )
      {
        // try to steal one from the next list
        var nextUlLi = allUl.eq( i + 1 ).find( 'li:not(' + Navbar.idPlaceholder + ')' );
        if ( nextUlLi.length > 0 )
        {
          Navbar.moveTileToLocation( nextUlLi.eq( 0 ), ul, 'append' );
          return true;
        }
      }

      if ( ulLi.length < 1 )
      {
        ul.hide( );
      }
      else
      {
        ul.show( );
      }
    });
  },

  dropDownShowAll : function( animate )
  {
    var right = Navbar.jqDropDown( ).find('div.right');
    var ul = right.find( 'ul:visible' );
    var width = ul.length * ul.filter( '.main' ).width( ) + 2;
    if ( ul.length > 1 )
    {
      width = width + 2;
    }
    if ( animate )
    {
      right.animate({ width:width });
    }
    else
    {
      right.width( width );
    }
    Navbar.jqDropDownGhost( ).find('div.right').width( width );
  },

  dropDownFormat : function( tile )
  {
    var span = tile.find( 'span' );
    if ( span.length < 1 )
    {
      tile.children( 'a').wrapInner( '<span />' );
      span = tile.find( 'span' );
    }
    span.addClass( tile.attr('class') ).attr( 'data-id', tile.attr( 'data-id' ) );
  },

  dropDownUnformat : function( tile )
  {
    tile.find( 'span' ).removeClass( tile.attr('class') ).attr( 'data-id', '' );
  },

  viewMoreClick : function( e )
  {
    e.stopPropagation( );
    var t = $(this);
    t.find('span').text( 'View Less' );
    t.find('div').addClass('less');
    Navbar.dropDownShowAll( true );
    Navbar.isViewingMore = true;
  },

  viewLessClick : function ( e )
  {
    e.stopPropagation( );
    var t = $(this);
    t.find('span').text( 'View More' );
    t.find('div').removeClass('less');

    var right = Navbar.jqDropDown( ).find('div.right');
    right.animate({ width : Navbar.jqMoreFun( ).width( ) + 2 }, 400 );

    Navbar.isViewingMore = false;
  },

  editStart : function( e )
  {
    e.stopPropagation( );
    $.dragonCurtain( );
    Navbar.isBeingEdited = true;
    Navbar.jq( ).addClass( 'navbar_custom' );

    Navbar.jqOriginalObj = $( Navbar.id + ', ' + Navbar.idDropDown ).clone( );
    Navbar.jqOriginalObj.data( 'isViewingMore', Navbar.isViewingMore );

    if ( $.browser.msie )
    {
      Navbar.jqDropDown( )
        .find('div.view').hide( ).end( )
        .find('div.edit').hide( );
    }
    else
    {
      Navbar.jqDropDown( )
        .find('div.view').slideUp( 'fast' ).end( )
        .find('div.edit').slideUp( 'fast' );
    }
    Navbar.moreFunUnbind( );

    if ( !Navbar.isViewingMore )
    {
      Navbar.jqDropDown( ).find('div.view > div').trigger( 'click' );
    }

    Navbar.jqSave( ).show( );

    var curtainZ = parseInt( $('#dragonCurtain').css( 'z-index' ) );
    Navbar.jq( ).css( 'z-index', curtainZ + 1 );
    Navbar.jqDropDown( ).css({ zIndex : curtainZ + 2 });

    Navbar.jq( ).find('li:not(' + Navbar.idMoreFun + ')').add( Navbar.jqDropDown( ).find('li') )
      .bind('mousedown', Navbar.tileStartDrag)
      .css( 'cursor', 'move' )
      .find( 'a' ).bind('click', function(e){ return false; })
        .css( 'cursor', 'move' );
  },

  editStop : function( e )
  {
    e.stopPropagation( );
    Navbar.isBeingEdited = false;
    Navbar.jqDropDown( ).find('div.view > div').trigger( 'click' );
    Navbar.jqSave( ).hide( );

    if ( $.browser.msie )
    {
      Navbar.jqDropDown( ).find('div.edit').show( );
      if ( Navbar.jqDropDown( ).find( 'ul' ).length > 1 )
      {
        Navbar.jqDropDown( ).find( 'div.view' ).show( );
      }
    }
    else
    {
      Navbar.jqDropDown( ).find('div.edit').slideDown( 'fast' );
      if ( Navbar.jqDropDown( ).find( 'ul' ).length > 1 )
      {
        Navbar.jqDropDown( ).find( 'div.view' ).slideDown( 'fast' );
      }
    }
    Navbar.moreFunBind( );
    $.dragonCurtainRemove( );
    Navbar.jq( ).css( 'z-index', Navbar.originalZ );

    Navbar.jq( ).find('li:not(' + Navbar.idMoreFun + ')').add( Navbar.jqDropDown( ).find( 'li' ) )
      .unbind('mousedown')
      .css( 'cursor', 'pointer' )
      .find( 'a' ).unbind('click')
        .css( 'cursor', 'pointer' );
  },

  editCancel : function( e )
  {
    e.stopPropagation( );
    $.dragonCurtainRemove( );
    Navbar.isBeingEdited = false;
    Navbar.jqOriginal( ).insertAfter( Navbar.jq( ).hide( ) );
    Navbar.jqDropDown( ).remove( );
    Navbar.jqDropDownObj = null;
    Navbar.jqSaveObj = null;
    Navbar.jq( ).remove( );
    Navbar.jqObj = null;
    Navbar.jqMoreFunObj = null;

    // if we created the original when the user was already 'viewing more'
    if ( Navbar.jqOriginal( ).data( 'isViewingMore' ) )
    {
      // fake a click to 'view less' for consistency
      Navbar.jqDropDown( ).find('div.view > div')
        .unbind( 'click' )
        .one( 'click', Navbar.viewLessClick )
        .trigger( 'click' );
    }
    Navbar.isViewingMore = false;

    Navbar.jqOriginalObj = null;
    Navbar.init( );
    Navbar.dropDownBind( );
    $.sayHey( 'Canceled!' );
  },

  saveStart : function( )
  {
    if ( !Navbar.isLoggedIn )
    {
      Navbar.errorHandler({ error : 'You must be logged in to edit your Navbar.' });
      return false;
    }

    if ( Navbar.isStatic )
    {
      Navbar.errorHandler({ error : 'Editing is temporarily disabled.' });
    }

    var saveData = { };
    Navbar.jq( ).children( 'li:not(' + Navbar.idMoreFun + ')' ).each(function(i){
      saveData['mainTiles[' + $(this).attr( 'data-id' ) + ']'] = i;
    });
    Navbar.jqDropDown( ).find('li').each(function(i){
      saveData['moreFunTiles[' + $(this).attr( 'data-id' ) + ']'] = i;
    });

    $.evalWithStatus(function( ){ Navbar.jsonP( 'save', saveData ); }, 'Saving...');
  },

  saveJSONHandler : function( data )
  {
    $.evalWithStatusComplete( false );
    Navbar.jqDropDown( ).find('div.edit > div').trigger( 'click' );
    if ( data.success )
    {
      Navbar.saveEnd( );
    }
    else
    {
      Navbar.errorHandler( data );
    }
  },

  saveEnd : function( e )
  {
    $.sayHey( 'Saved!' );
  },

  restoreStart : function( e )
  {
    $.dragonConfirm( 'Are you sure you want to restore to the default Navbar?', {
      confirmCallback : function( ){
        $.evalWithStatus(function( ){ Navbar.jsonP( 'restore' ); }, 'Restoring...');
      },
      curtain : false
    });
  },

  restoreJSONHandler : function( data )
  {
    $.evalWithStatusComplete( false );
    if ( data.success )
    {
      $( data.markup ).insertAfter( Navbar.jq( ).hide( ) );
      Navbar.isBeingEdited = false;
      Navbar.jq( ).remove( );
      Navbar.jqObj = null;
      Navbar.jqMoreFunObj = null;
      Navbar.jqDropDown( ).remove( );
      Navbar.jqDropDownObj = null;
      Navbar.jqSaveObj = null;
      Navbar.init( );
      $.sayHey( 'Restored!' );
    }
    else
    {
      var error = data.error ? data.error : 'There was an error trying to restore your Navbar. Please try again.' ;
      Navbar.errorHandler({ error : error });
    }
  },

  tileStartDrag : function( e )
  {
    $(document).bind('mousedown.Navbar', function(){ return false; });
    this.ondrag = function(){return false;};

    Navbar.bodyMarginLeft = $.getBodyMarginLeft( );

    var t = $(this);
    var tile = t.clone( );
    var tileClass = t.attr('class');
    var tileOffset = t.offset( );
    var id = t.attr('data-id');

    Navbar.createGhost( );
    Navbar.jqGhost( ).find( 'li > a' ).bind( 'mouseenter', Navbar.tileSort);
    Navbar.jqDropDownGhost( ).find( 'li a' ).bind('mouseenter', Navbar.tileSort);
    Navbar.jqGhost( ).bind( 'mouseenter', function(e){
      var trigger = $(this).find( 'li:last > a' );
      if ( trigger.length > 0 )
      {
        trigger.trigger( 'mouseenter' );
      }
      else
      {
        var tile = $( Navbar.id + ' li.navbar_' + Navbar.dragTileId + ', ' + Navbar.idDropDown + ' li.navbar_' + Navbar.dragTileId );
        var loc = Navbar.jq( );
        Navbar.moveTileToLocation( tile, loc, 'append' );
        Navbar.dropDownShowAll( );

        Navbar.jqPlaceholder( ).appendTo( loc );
        Navbar.jqPlaceholder( ).width( tile.width( ) - 4 );
        Navbar.jqPlaceholder( ).height( tile.height( ) - 3 );
      }
    });
    Navbar.jqDropDownGhost( ).find( 'div.right' ).bind( 'mouseenter', function(e){
      e.stopPropagation( );
      $(this).find( 'li:last' ).trigger( 'mouseenter' );
    });
    /*
    Navbar.jqMoreFun( ).bind( 'mouseenter', function(e){
      e.stopPropagation( );
      if ( Navbar.jqPlaceholder( ).parents( Navbar.idDropDownGhost ).length < 1 )
      {
        Navbar.jqDropDownGhost( ).find('li:first').trigger( 'mouseenter' );
      }
    });
    */

    var tW = t.width( );
    var tH = t.height( );
    Navbar.jqPlaceholderObj = $('<li id="navbar_placeholder" />').insertAfter( t );
    Navbar.jqPlaceholder( ).css({
      width : tW - 2,
      height : tH - 4
    });
    Navbar.placeholderLocation = 'left:' + id;
    t.hide( );

    Navbar.dragTile = $('<div class="navbar_tile" />').addClass( tileClass ).attr('data-id', id).append( tile.find( 'a' ) ).appendTo( 'body' );
    Navbar.dragTileId = id;

    Navbar.dragTile.xAdjust = ( Navbar.dragTile.width( ) / 2 );
    Navbar.dragTile.yAdjust = ( Navbar.dragTile.height( ) / 2 );

    Navbar.dragTile.css({
        left   : e.pageX - Navbar.bodyMarginLeft - Navbar.dragTile.xAdjust,
        top    : e.pageY - Navbar.dragTile.yAdjust,
        zIndex : parseInt( Navbar.jq( ).css( 'z-index' ) ) + 1
      });

    $(document).bind('mousemove.Navbar', Navbar.tileDrag)
      .bind('mouseup.Navbar', Navbar.tileStopDrag);
    $('html').css( 'cursor', 'move' );
  },

  tileDrag : function( e )
  {
    if ( Navbar.dragTile )
    {
      Navbar.dragTile.css({
        left : e.pageX - Navbar.bodyMarginLeft - Navbar.dragTile.xAdjust,
        top : e.pageY - Navbar.dragTile.yAdjust
      });
    }
  },

  tileStopDrag : function( e )
  {
    if ( Navbar.dragTile )
    {
      Navbar.removeGhost( );
      Navbar.jqPlaceholder( ).hide( );

      var id = Navbar.dragTile.attr('data-id');
      Navbar.dragTile.remove( );
      Navbar.dragTile = null;

      var tile = $('li.navbar_' + id).show( ).insertAfter( Navbar.jqPlaceholder( ) );
      tile.parents( Navbar.idDropDown ).length > 0 ? Navbar.dropDownFormat( tile ) : Navbar.dropDownUnformat( tile ) ;
      Navbar.jqPlaceholder( ).remove( );
      Navbar.jqPlaceholderObj = null;

      $(document).unbind('mousedown.Navbar');
      $(window).unbind('mousemove.Navbar mouseup.Navbar');
      $('html').css( 'cursor', '' );
    }
  },

  tileSort : function( e )
  {
    e.stopPropagation( );

    var t = $(this).parent( );
    var id = t.attr('data-id');
    var side = t.attr('data-side');

    if ( Navbar.dragTileId != id && Navbar.placeholderLocation != side + ':' + id )
    {
      // the tile below our dragTile should only exist in one of these places: main navbar or dropdown
      var loc;
      if ( t.parent( ).is( Navbar.idGhost ) )
      {
        loc = $('li.navbar_' + id, Navbar.id);
      }
      else
      {
        loc = $('li.navbar_' + id, Navbar.idDropDown);
      }

      var tile;
      if ( Navbar.jqPlaceholder( ).parent( ).is( Navbar.id ) )
      {
        tile = $('li.navbar_' + Navbar.dragTileId, Navbar.id);
      }
      else
      {
        tile = $('li.navbar_' + Navbar.dragTileId, Navbar.idDropDown);
      }

      Navbar.moveTileToLocation( tile, loc, side );

      side == 'after' ? Navbar.jqPlaceholder( ).insertAfter( tile ) : Navbar.jqPlaceholder( ).insertBefore( tile ) ;
      Navbar.jqPlaceholder( ).width( tile.width( ) - 2 );
      Navbar.jqPlaceholder( ).height( tile.height( ) - 4 );

      Navbar.placeholderLocation = side + ':' + id;
      Navbar.dropDownShowAll( );
    }
  },

  moveTileToLocation : function( tile, loc, method )
  {
    var tileId = tile.attr('data-id');
    var tileGhosts = Navbar.jqGhost( ).find('li[data-id=' + tileId + ']')
      .add( Navbar.idDropDownGhost + ' li[data-id=' + tileId + ']' );

    if ( loc.is( 'ul' ) )
    {
      var locGhost;
      if ( loc.parents( Navbar.idDropDown ).length > 0 )
      {
        locGhost = Navbar.jqDropDownGhost( ).find( ' ul[data-list_num=' + loc.attr('data-list_num') + ']' );
      }
      else
      {
        locGhost = Navbar.jqGhost( );
      }

      if ( method == 'append' )
      {
        tile.appendTo( loc );
        tileGhosts.filter('[data-side="before"]').appendTo( locGhost );
        tileGhosts.filter('[data-side="after"]').appendTo( locGhost );
      }
      else // if ( method == 'prepend' )
      {
        tile.prependTo( loc );
        tileGhosts.filter('[data-side="after"]').prependTo( locGhost );
        tileGhosts.filter('[data-side="before"]').prependTo( locGhost );
      }
    }
    else
    {
      var locId = loc.attr('data-id');
      var locGhosts = Navbar.jqGhost( ).find('li[data-id=' + locId + ']')
        .add( Navbar.idDropDownGhost + ' li[data-id=' + locId + ']' );

      if ( method == 'after' )
      {
        tile.insertAfter( loc );
        tileGhosts.filter('[data-side="after"]').insertAfter( locGhosts.filter('[data-side="after"]') );
        tileGhosts.filter('[data-side="before"]').insertAfter( locGhosts.filter('[data-side="after"]') );
      }
      else // if ( method == 'before' )
      {
        tile.insertBefore( loc );
        tileGhosts.filter('[data-side="before"]').insertBefore( locGhosts.filter('[data-side="before"]') );
        tileGhosts.filter('[data-side="after"]').insertBefore( locGhosts.filter('[data-side="before"]') );
      }
    }

    tile.parents( Navbar.idDropDown ).length > 0 ? Navbar.dropDownFormat( tile ) : Navbar.dropDownUnformat( tile ) ;
    tileGhosts.parents( Navbar.idDropDownGhost ).length > 0 ? Navbar.dropDownFormat( tileGhosts ) : Navbar.dropDownUnformat( tileGhosts ) ;
    tileGhosts.each(function(i){
      Navbar.sizeGhostTile( $(this) );
    });
    Navbar.clearMainNavOccupiedWidth( );
    Navbar.tileAdjustments( );
  },

  createGhost : function( e )
  {
    var offset = Navbar.jq( ).offset( );

    Navbar.jqGhostObj = Navbar.jq( ).clone( );
    Navbar.jqGhost( ).appendTo( 'body' )
      .attr('id', 'navbar_ghost')
      .css({
        left : offset.left - Navbar.bodyMarginLeft + 1,
        top : offset.top,
        opacity : Navbar.ghostOpacity,
        filter : 'alpha(opacity=' + ( Navbar.ghostOpacity * 100 ) + ')',
        zIndex : parseInt( Navbar.jq( ).css( 'z-index' ) ) + 2
      });
    
    Navbar.jqGhost( ).find( 'li' )
      .css( 'cursor', 'move' )
      .not( Navbar.idMoreFun ).each(function(i){
        var t = $(this);
        var tClone = t.clone( );
        Navbar.sizeGhostTile( t.attr( 'data-side', 'before' ) );
        Navbar.sizeGhostTile( tClone.attr( 'data-side', 'after' ).insertAfter( t ) );
      });

    var ddOffset = Navbar.jqDropDown( ).find( 'div.tiles' ).offset( );

    Navbar.jqDropDownGhostObj = Navbar.jqDropDown( ).clone( );
    Navbar.jqDropDownGhost( ).appendTo( 'body' )
      .attr('id', 'navbar_dropdown_ghost')
      .css({
        top : ddOffset.top,
        opacity : Navbar.ghostOpacity,
        filter : 'alpha(opacity=' + ( Navbar.ghostOpacity * 100 ) + ')',
        zIndex : parseInt( Navbar.jq( ).css( 'z-index' ) ) + 2
      })
      .find( 'div.view, div.edit, ' + Navbar.idSave ).remove( );
    
    Navbar.jqDropDownGhost( ).find( 'li' ).each(function(i){
      var t = $(this);
      var tClone = t.clone( );
      Navbar.sizeGhostTile( t.attr( 'data-side', 'before' ) );
      Navbar.sizeGhostTile( tClone.attr( 'data-side', 'after' ).insertAfter( t ) );
    });
  },

  removeGhost : function( e )
  {
    if ( Navbar.jqGhost( ).length > 0 )
    {
      Navbar.jqGhost( ).remove( );
      Navbar.jqGhostObj = null;
      Navbar.jqDropDownGhost( ).remove( );
      Navbar.jqDropDownGhostObj = null;
    }
  },

  sizeGhostTile : function( tile )
  {
    var side = tile.attr( 'data-side' );
    if ( tile.parent( Navbar.idGhost ).length > 0 )
    {
      /**
       * The size of the original tile's area is actually its width + 1
       * (because of the left/right border and negative margin-left).
       * So we need to end up with two tiles whose widths combine equal the original's
       * plus one.
       * For example:
       * If the tile is 99px, our two ghost tiles should be 50px each.
       * If the tile is 100px, our ghost tiles will be 50px and 51px.
       */
      var width = Navbar.jq( ).find( '[data-id="' + tile.attr('data-id') + '"]' ).width( );
      var w = width / 2;

      /**
       * If the width is odd, then half of it will be a decimal value,
       * so add another half to each (total of 1px added to this set).
       */
      if ( width % 2 != 0 )
      {
        w += .5;
      }
      // otherwise, just add 1px to the first tile.
      else if ( side == 'before' )
      {
        w++;
      }

      tile.width( w );
      tile.height( 24 );
    }
    else // if ( tile.parents( Navbar.idDropDownGhost ).length > 0 )
    {
      var h = 12;
      if ( side == 'before' )
      {
        h--;
      }
      tile.height( h );
      tile.css('width', '100%');
    }

    // makes it easier to see when debugging
    if ( Navbar.ghostOpacity > 0 )
    {
      if ( side == 'before' )
      {
        tile.find( 'a' ).css({
          textIndent : 0,
          backgroundColor : 'black',
          opacity : Navbar.ghostOpacity,
          filter : 'alpha(opacity=' + ( Navbar.ghostOpacity * 100 ) + ')',
          color : 'white'
        });
      }
      else
      {
        tile.find( 'a' )
          .css({
            textIndent : 0,
            backgroundColor : 'red',
            opacity : Navbar.ghostOpacity,
            filter : 'alpha(opacity=' + ( Navbar.ghostOpacity * 100 ) + ')',
            color : 'black'
          });
      }
    }
  },

  bindClickRecording : function( )
  {
    Navbar.jq( ).find('li')
      .add( Navbar.jqDropDown( ).find('li') )
      .add( $('li','#navLinks') )
      .add( $('#logo') )
      .add( $('li','#profileMenu') )
      .add( $('li','#siteSearchNav') )
      .add( $('li','#siteSearchMenu') )
      .add( $('#quickSearchBox') )
      .add( $('#reportIcon') )
      .unbind('click.ClickDetection')
      .bind('click.ClickDetection', function(e){
        // track clicks with a cookie
        document.cookie = 'navbar-click=' + $(this).attr( 'data-id' ) + ';max-age=60;path=/;domain=.' + IM_DOMAIN + ';';

        // process click as normal
        return true;
      });
  }
};


$(document).ready(function(){
  if ( window.location.search.indexOf( 'debug' ) == -1 )
  {
    return false;
  }
  var debugContent = $('<div style="text-align:left; padding:10px;"><input type="text" style="width:200px" /><br /><br /><strong>Result:</strong><div class="result"></div></div>');
  var debug = $('<div />').appendTo('body');
  debug.dragonDrop({
    curtain : false,
    type    : 'window',
    top     : 20,
    left    : 20 - $.getBodyMarginLeft( ),
    width   : 250,
    title   : 'Debug',
    content : debugContent
  });
  debug.find('input').bind('keyup',function(e){
    if ( e.keyCode == 13 )
    {
      var request = '>> ' + $(this).val( );
      var result;
      try
      {
        var evalResult = ( eval( $(this).val( ) ) );
        result = '<div>' + typeof( evalResult ) + ': ' + evalResult + '</div>';
      }
      catch(e)
      {
        result = '<div style="color:red">' + e.message + '</div>';
      }
      $(this).siblings('.result')
        .text( request )
        .append( result );
    }
  });
});
$(document).ready( Navbar.init );
