// 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.key == 'Enter' || e.button != 2) {
        let kind;
        const 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.
      const base = this.window.location.href.split('#')[0];
      urls = urls.map(function(url) {
        return url[0] == '#' ? base + url : url;
      });

      const 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,
  };
});
