// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/**
 * A class to hold information about the Codewalk Viewer.
 * @param {jQuery} context The top element in whose context the viewer should
 *     operate.  It will not touch any elements above this one.
 * @constructor
 */
 var CodewalkViewer = function(context) {
  this.context = context;

  /**
   * The div that contains all of the comments and their controls.
   */
  this.commentColumn = this.context.find('#comment-column');

  /**
   * The div that contains the comments proper.
   */
  this.commentArea = this.context.find('#comment-area');

  /**
   * The div that wraps the iframe with the code, as well as the drop down menu
   * listing the different files.
   * @type {jQuery}
   */
  this.codeColumn = this.context.find('#code-column');

  /**
   * The div that contains the code but excludes the options strip.
   * @type {jQuery}
   */
  this.codeArea = this.context.find('#code-area');

  /**
   * The iframe that holds the code (from Sourcerer).
   * @type {jQuery}
   */
  this.codeDisplay = this.context.find('#code-display');

  /**
   * The overlaid div used as a grab handle for sizing the code/comment panes.
   * @type {jQuery}
   */
  this.sizer = this.context.find('#sizer');

  /**
   * The full-screen overlay that ensures we don't lose track of the mouse
   * while dragging.
   * @type {jQuery}
   */
  this.overlay = this.context.find('#overlay');

  /**
   * The hidden input field that we use to hold the focus so that we can detect
   * shortcut keypresses.
   * @type {jQuery}
   */
  this.shortcutInput = this.context.find('#shortcut-input');

  /**
   * The last comment that was selected.
   * @type {jQuery}
   */
  this.lastSelected = null;
};

/**
 * Minimum width of the comments or code pane, in pixels.
 * @type {number}
 */
CodewalkViewer.MIN_PANE_WIDTH = 200;

/**
 * Navigate the code iframe to the given url and update the code popout link.
 * @param {string} url The target URL.
 * @param {Object} opt_window Window dependency injection for testing only.
 */
CodewalkViewer.prototype.navigateToCode = function(url, opt_window) {
  if (!opt_window) opt_window = window;
  // Each iframe is represented by two distinct objects in the DOM:  an iframe
  // object and a window object.  These do not expose the same capabilities.
  // Here we need to get the window representation to get the location member,
  // so we access it directly through window[] since jQuery returns the iframe
  // representation.
  // We replace location rather than set so as not to create a history for code
  // navigation.
  opt_window['code-display'].location.replace(url);
  var k = url.indexOf('&');
  if (k != -1) url = url.slice(0, k);
  k = url.indexOf('fileprint=');
  if (k != -1) url = url.slice(k+10, url.length);
  this.context.find('#code-popout-link').attr('href', url);
};

/**
 * Selects the first comment from the list and forces a refresh of the code
 * view.
 */
CodewalkViewer.prototype.selectFirstComment = function() {
  // TODO(rsc): handle case where there are no comments
  var firstSourcererLink = this.context.find('.comment:first');
  this.changeSelectedComment(firstSourcererLink);
};

/**
 * Sets the target on all links nested inside comments to be _blank.
 */
CodewalkViewer.prototype.targetCommentLinksAtBlank = function() {
  this.context.find('.comment a[href], #description a[href]').each(function() {
    if (!this.target) this.target = '_blank';
  });
};

/**
 * Installs event handlers for all the events we care about.
 */
CodewalkViewer.prototype.installEventHandlers = function() {
  var self = this;

  this.context.find('.comment')
      .click(function(event) {
        if (jQuery(event.target).is('a[href]')) return true;
        self.changeSelectedComment(jQuery(this));
        return false;
      });

  this.context.find('#code-selector')
      .change(function() {self.navigateToCode(jQuery(this).val());});

  this.context.find('#description-table .quote-feet.setting')
      .click(function() {self.toggleDescription(jQuery(this)); return false;});

  this.sizer
      .mousedown(function(ev) {self.startSizerDrag(ev); return false;});
  this.overlay
      .mouseup(function(ev) {self.endSizerDrag(ev); return false;})
      .mousemove(function(ev) {self.handleSizerDrag(ev); return false;});

  this.context.find('#prev-comment')
      .click(function() {
          self.changeSelectedComment(self.lastSelected.prev()); return false;
      });

  this.context.find('#next-comment')
      .click(function() {
          self.changeSelectedComment(self.lastSelected.next()); return false;
      });

  // Workaround for Firefox 2 and 3, which steal focus from the main document
  // whenever the iframe content is (re)loaded.  The input field is not shown,
  // but is a way for us to bring focus back to a place where we can detect
  // keypresses.
  this.context.find('#code-display')
      .load(function(ev) {self.shortcutInput.focus();});

  jQuery(document).keypress(function(ev) {
    switch(ev.which) {
      case 110:  // 'n'
          self.changeSelectedComment(self.lastSelected.next());
          return false;
      case 112:  // 'p'
          self.changeSelectedComment(self.lastSelected.prev());
          return false;
      default:  // ignore
    }
  });

  window.onresize = function() {self.updateHeight();};
};

/**
 * Starts dragging the pane sizer.
 * @param {Object} ev The mousedown event that started us dragging.
 */
CodewalkViewer.prototype.startSizerDrag = function(ev) {
  this.initialCodeWidth = this.codeColumn.width();
  this.initialCommentsWidth = this.commentColumn.width();
  this.initialMouseX = ev.pageX;
  this.overlay.show();
};

/**
 * Handles dragging the pane sizer.
 * @param {Object} ev The mousemove event updating dragging position.
 */
CodewalkViewer.prototype.handleSizerDrag = function(ev) {
  var delta = ev.pageX - this.initialMouseX;
  if (this.codeColumn.is('.right')) delta = -delta;
  var proposedCodeWidth = this.initialCodeWidth + delta;
  var proposedCommentWidth = this.initialCommentsWidth - delta;
  var mw = CodewalkViewer.MIN_PANE_WIDTH;
  if (proposedCodeWidth < mw) delta = mw - this.initialCodeWidth;
  if (proposedCommentWidth < mw) delta = this.initialCommentsWidth - mw;
  proposedCodeWidth = this.initialCodeWidth + delta;
  proposedCommentWidth = this.initialCommentsWidth - delta;
  // If window is too small, don't even try to resize.
  if (proposedCodeWidth < mw || proposedCommentWidth < mw) return;
  this.codeColumn.width(proposedCodeWidth);
  this.commentColumn.width(proposedCommentWidth);
  this.options.codeWidth = parseInt(
      this.codeColumn.width() /
      (this.codeColumn.width() + this.commentColumn.width()) * 100);
  this.context.find('#code-column-width').text(this.options.codeWidth + '%');
};

/**
 * Ends dragging the pane sizer.
 * @param {Object} ev The mouseup event that caused us to stop dragging.
 */
CodewalkViewer.prototype.endSizerDrag = function(ev) {
  this.overlay.hide();
  this.updateHeight();
};

/**
 * Toggles the Codewalk description between being shown and hidden.
 * @param {jQuery} target The target that was clicked to trigger this function.
 */
CodewalkViewer.prototype.toggleDescription = function(target) {
  var description = this.context.find('#description');
  description.toggle();
  target.find('span').text(description.is(':hidden') ? 'show' : 'hide');
  this.updateHeight();
};

/**
 * Changes the side of the window on which the code is shown and saves the
 * setting in a cookie.
 * @param {string?} codeSide The side on which the code should be, either
 *     'left' or 'right'.
 */
CodewalkViewer.prototype.changeCodeSide = function(codeSide) {
  var commentSide = codeSide == 'left' ? 'right' : 'left';
  this.context.find('#set-code-' + codeSide).addClass('selected');
  this.context.find('#set-code-' + commentSide).removeClass('selected');
  // Remove previous side class and add new one.
  this.codeColumn.addClass(codeSide).removeClass(commentSide);
  this.commentColumn.addClass(commentSide).removeClass(codeSide);
  this.sizer.css(codeSide, 'auto').css(commentSide, 0);
  this.options.codeSide = codeSide;
};

/**
 * Adds selected class to newly selected comment, removes selected style from
 * previously selected comment, changes drop down options so that the correct
 * file is selected, and updates the code popout link.
 * @param {jQuery} target The target that was clicked to trigger this function.
 */
CodewalkViewer.prototype.changeSelectedComment = function(target) {
  var currentFile = target.find('.comment-link').attr('href');
  if (!currentFile) return;

  if (!(this.lastSelected && this.lastSelected.get(0) === target.get(0))) {
    if (this.lastSelected) this.lastSelected.removeClass('selected');
    target.addClass('selected');
    this.lastSelected = target;
    var targetTop = target.position().top;
    var parentTop = target.parent().position().top;
    if (targetTop + target.height() > parentTop + target.parent().height() ||
        targetTop < parentTop) {
      var delta = targetTop - parentTop;
      target.parent().animate(
          {'scrollTop': target.parent().scrollTop() + delta},
          Math.max(delta / 2, 200), 'swing');
    }
    var fname = currentFile.match(/(?:select=|fileprint=)\/[^&]+/)[0];
    fname = fname.slice(fname.indexOf('=')+2, fname.length);
    this.context.find('#code-selector').val(fname);
    this.context.find('#prev-comment').toggleClass(
        'disabled', !target.prev().length);
    this.context.find('#next-comment').toggleClass(
        'disabled', !target.next().length);
  }

  // Force original file even if user hasn't changed comments since they may
  // have navigated away from it within the iframe without us knowing.
  this.navigateToCode(currentFile);
};

/**
 * Updates the viewer by changing the height of the comments and code so that
 * they fit within the height of the window.  The function is typically called
 * after the user changes the window size.
 */
CodewalkViewer.prototype.updateHeight = function() {
  var windowHeight = jQuery(window).height() - 5  // GOK
  var areaHeight = windowHeight - this.codeArea.offset().top
  var footerHeight = this.context.find('#footer').outerHeight(true)
  this.commentArea.height(areaHeight - footerHeight - this.context.find('#comment-options').outerHeight(true))
  var codeHeight = areaHeight - footerHeight - 15  // GOK
  this.codeArea.height(codeHeight)
  this.codeDisplay.height(codeHeight - this.codeDisplay.offset().top + this.codeArea.offset().top);
  this.sizer.height(codeHeight);
};

window.initFuncs.push(function() {
  var viewer = new CodewalkViewer(jQuery('#codewalk-main'));
  viewer.selectFirstComment();
  viewer.targetCommentLinksAtBlank();
  viewer.installEventHandlers();
  viewer.updateHeight();
});
