(function($) {
  var closeTimer = null;
  var openTimer = null;

  $(document).ready(function() {
    $('.hoverbox-trigger').mouseover(function() {
      var trigger = $(this);
      
      // Is this a hoverbox for a user hovercard? 
      // If so, then fetch on demand
      if (trigger.closest('a').attr('data-user-id') &&
          $(document).data('hoverboxes-fetched') == undefined) {
        $(document).data('hoverboxes-fetched', false);
        fetchHoverboxes(function() {
          setTimeout(function() {
            showHoverbox(trigger);
          }, 50)
        });
      } else {
        openTimer = setTimeout(function() {
          showHoverbox(trigger);
        }, 250)
      }
      
    }).mouseout(function() {
      clearTimeout(openTimer);
    });
    
    // if user leaves hoverbox, call to close
    $('#lightbox.hoverbox').live('mouseout', function() {
      closeHoverbox();
    }); 
    // if user leaves trigger, call to close
    $('.hoverbox-trigger').mouseout(function() {
      closeHoverbox();
    });   
    // if user interacts with hoverbox, cancel call to close
    $('#lightbox.hoverbox').live('mouseover', function() {
      clearTimeout(closeTimer);
    });
  });
  
  var fetchHoverboxes = function(callback) {
    var userIds = $.unique($.map($('a.hoverbox-trigger'), function(node) {return $(node).attr('data-user-id')})).join('|');

    $.get('/shared/hoverboxes', {ids: userIds}, function(data) {
      $(document).data('hoverboxes-fetched', true);
      $(document.body).append(data);
      callback();
    })
  }
  var closeHoverbox = function() {
    closeTimer = setTimeout(function() {
      $("#lightbox.hoverbox").remove();
    }, 100);
  };
  
  var showHoverbox = function(trigger) {
    var hoverboxFlipBot = false;
    var userID = $(trigger).closest('a').attr('data-user-id');
    
    // need to test if it's a linked image because anchors reported offset is incorrect
    if ( trigger.children(".avatar").length ) {
      var triggerPos = trigger.children(".avatar").offset();
    } else {
      var triggerPos = trigger.offset();
    }
    
    if ( $("#lightbox.hoverbox").length == 0 ) {
      var hoverBoxHTML = '<table id="lightbox" class="hoverbox"><tr><td class="tl"></td><td class="tc"></td><td class="tr"></td></tr><tr><td class="ml"></td><td class="mm"><div class="content">';
      hoverBoxHTML += '</div></td><td class="mr"></td></tr><tr><td class="bl"></td><td class="bc"></td><td class="br"></td></tr></table>'
      $("body").append(hoverBoxHTML);
    } else {
      clearTimeout(closeTimer);
    }

    // If we're fetching for a user hovercard...
    if (userID) {
      var hoverBoxContent = $(".hoverbox-data[data-user-id=" + userID + "]").html();
    } else {
      var hoverBoxContent = trigger.next(".hoverbox-data").html();
    }
    
    $("#lightbox.hoverbox .content").html(hoverBoxContent).append('<div class="hoverbox-arrow"></div>');

    var hoverBox = $("#lightbox.hoverbox");
    var hoverBoxWidth = hoverBox.width();
    var hoverBoxHeight = hoverBox.height();
    var triggerHeight = trigger.height();
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();
    var windowScrollTop = $(window).scrollTop();
    var triggerWidth = trigger.width();
    var followButton = $("#lightbox.hoverbox .content .follow");
    
    // Hook up the follow button, if it exists.
    if (followButton.length > 0) {
      var userID = followButton.attr('data-user-id');
      
      followButton.click(function() {
        if (followButton.data('following') === true) {
          window.location = '/account/recommended/following';
        } else {
          followButton.html('<img src="/images/molt/fpo/indicator.gif">');
          $.get('/account/toggle_follow', {id: userID}, function() {
            followButton.data('following', true);
            followButton.html("Following");
          });
        }
      });
      
      $.get('/account/is_following', {id: userID}, function(res) {
        if (res == '1') {
          followButton.data('following', true);
          followButton.html("Following");
        } else {
          followButton.data('following', false);
          followButton.html('<span class="ico-small ico-follow-small"></span>Follow');
        }
      });
    }

    // hoverbox default location is left/above the trigger
    
    showBottom = false;
    showLeft = false;
    
    var finalPosTop = triggerPos.top - hoverBoxHeight - 5;
    var finalPosLeft = triggerPos.left - 42 + (triggerWidth/2);
    
    if ( windowScrollTop > triggerPos.top - hoverBoxHeight ) { // show below
      showBottom = true ;
      var finalPosTop = triggerPos.top + triggerHeight + 5;
    }
    if ( triggerPos.left + hoverBoxWidth > windowWidth  ) { // show to the right
      showLeft = true ;
      var finalPosLeft = triggerPos.left - hoverBoxWidth + 41 + (triggerWidth/2) ;
    }

    if ( showBottom == true && showLeft == false ) { // hoverbox oriented to left/below of trigger
      $("#lightbox.hoverbox .hoverbox-arrow").addClass("top-left");
    } else if ( showBottom == false && showLeft == true ) { // hoverbox oriented to right/above of trigger
      $("#lightbox.hoverbox .hoverbox-arrow").addClass("bot-right");
    } else if ( showBottom == true && showLeft == true ) { // hoverbox oriented to right/below of trigger
      $("#lightbox.hoverbox .hoverbox-arrow").addClass("top-right");
    } else {
      $("#lightbox.hoverbox .hoverbox-arrow").addClass("bot-left");
    }

    hoverBox.css({ top:finalPosTop, left:finalPosLeft }).hide().fadeIn("fast")
  };
})(jQuery);

