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

/**
 * @fileoverview This file provides a class that can be used to open URLs based
 * on user interactions. It ensures a consistent behavior when it comes to
 * holding down Ctrl and Shift while clicking or activating the a link.
 *
 * This depends on the {@code chrome.windows} and {@code chrome.tabs}
 * extensions API.
 */

/**
 * The kind of link open we want to perform.
 * @enum {number}
 */
cr.LinkKind = {
  FOREGROUND_TAB: 0,
  BACKGROUND_TAB: 1,
  WINDOW: 2,
  SELF: 3,
  INCOGNITO: 4
};

cr.define('cr', function() {
  /**
   * This class is used to handle opening of links based on user actions. The
   * following actions are currently implemented:
   *
   * * Press Ctrl and click a link. Or click a link with your middle mouse
   *   button (or mousewheel). Or press Enter while holding Ctrl.
   *     Opens the link in a new tab in the background .
   * * Press Ctrl+Shift and click a link. Or press Shift and click a link with
   *   your middle mouse button (or mousewheel). Or press Enter while holding
   *   Ctrl+Shift.
   *     Opens the link in a new tab and switches to the newly opened tab.
   * * Press Shift and click a link. Or press Enter while holding Shift.
   *     Opens the link in a new window.
   *
   * On Mac, uses Command instead of Ctrl.
   * For keyboard support you need to use keydown.
   *
   * @param {!LoadTimeData} localStrings The local strings object which is used
   *     to localize the warning prompt in case the user tries to open a lot of
   *     links.
   * @constructor
   */
  function LinkController(localStrings) {
    this.localStrings_ = localStrings;
  }

  LinkController.prototype = {
    /**
     * The number of links that can be opened before showing a warning confirm
     * message.
     */
    warningLimit: 15,

    /**
     * The DOM window that we want to open links into in case we are opening
     * links in the same window.
     * @type {!Window}
     */
    window: window,

    /**
     * This method is used for showing the warning confirm message when the
     * user is trying to open a lot of links.
     * @param {number} count The number of URLs to open.
     * @return {string} The message to show the user.
     */
    getWarningMessage: function(count) {
      return this.localStrings_.getStringF('should_open_all', String(count));
    },

    /**
     * Open an URL from a mouse or keyboard event.
     * @param {string} url The URL to open.
     * @param {!Event} e The event triggering the opening of the URL.
     */
    openUrlFromEvent: function(url, e) {
      // We only support keydown Enter and non right click events.
      if (e.type == 'keydown' && e.keyIdentifier == 'Enter' ||
          e.button != 2) {
        var kind;
        var ctrl = cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey;

        if (e.button == 1 || ctrl) // middle, ctrl or keyboard
          kind = e.shiftKey ? cr.LinkKind.FOREGROUND_TAB :
              cr.LinkKind.BACKGROUND_TAB;
        else // left or keyboard
          kind = e.shiftKey ? cr.LinkKind.WINDOW : cr.LinkKind.SELF;

        this.openUrls([url], kind);
      }
    },


    /**
     * Opens a URL in a new tab, window or incognito window.
     * @param {string} url The URL to open.
     * @param {cr.LinkKind} kind The kind of open we want to do.
     */
    openUrl: function(url, kind) {
      this.openUrls([url], kind);
    },

    /**
     * Opens URLs in new tab, window or incognito mode.
     * @param {!Array.<string>} urls The URLs to open.
     * @param {cr.LinkKind} kind The kind of open we want to do.
     */
    openUrls: function(urls, kind) {
      if (urls.length < 1)
        return;

      if (urls.length > this.warningLimit) {
        if (!this.window.confirm(this.getWarningMessage(urls.length)))
          return;
      }

      // Fix '#124' URLs since opening those in a new window does not work. We
      // prepend the base URL when we encounter those.
      var base = this.window.location.href.split('#')[0];
      urls = urls.map(function(url) {
        return url[0] == '#' ? base + url : url;
      });

      var incognito = kind == cr.LinkKind.INCOGNITO;
      if (kind == cr.LinkKind.WINDOW || incognito) {
        chrome.windows.create({
          url: urls,
          incognito: incognito
        });
      } else if (kind == cr.LinkKind.FOREGROUND_TAB ||
                 kind == cr.LinkKind.BACKGROUND_TAB) {
        urls.forEach(function(url, i) {
          chrome.tabs.create({
            url: url,
            selected: kind == cr.LinkKind.FOREGROUND_TAB && !i
          });
        });
      } else {
        this.window.location.href = urls[0];
      }
    }
  };

  // Export
  return {
    LinkController: LinkController,
  };
});
