// 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;
      });

  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;
  currentFile = currentFile.replaceAll('%2f', '/').replaceAll('/go.dev/', '/');

  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('/doc/codewalk/?fileprint=/'+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() {
  /* The new go.dev footer is too big; hide it since we are trying to keep the whole page on the screen. */
  jQuery('.Footer').hide();

  /* The -30 here work around some margin that seems to be introduced by the browsers. */
  var windowHeight = jQuery(window).height() - 30
  var areaHeight = windowHeight - this.codeArea.offset().top
  var footerHeight = jQuery('.Site-footer').outerHeight(true)
  this.commentArea.height(areaHeight - footerHeight - this.context.find('#comment-options').outerHeight(true))
  var codeHeight = areaHeight - footerHeight - 30
  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();
});
