// 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.

/**
 * Takes the |pluginsData| input argument which represents data about the
 * currently installed/running plugins and populates the html jstemplate with
 * that data.
 * @param {Object} pluginsData Detailed info about installed plugins. Same
 *     expected format as returnPluginsData().
 */
function renderTemplate(pluginsData) {
  // This is the javascript code that processes the template:
  var input = new JsEvalContext(pluginsData);
  var output = $('pluginTemplate');
  jstProcess(input, output);
}

// Keeps track of whether details have been made visible (expanded) or not.
var tmiModeExpanded = false;

/**
 * @param {boolean} showDetails
 */
function loadShowDetailsFromPrefs(showDetails) {
  tmiModeExpanded = showDetails;
  // TODO(dpapad): Use setAttribute()/removeAttribute() with 'hidden' instead of
  // style.display.
  $('collapse').style.display = showDetails ? 'inline' : 'none';
  $('expand').style.display = showDetails ? 'none' : 'inline';
  document.body.className = showDetails ? 'show-in-tmi-mode' : 'hide-tmi-mode';
}

/**
 * Called by the web_ui_ to re-populate the page with data representing the
 * current state of installed plugins.
 * @param {Object} pluginsData Detailed info about installed plugins. The
 *     template expects each plugin's format to match the following structure to
 *     correctly populate the page:
 *   {
 *     plugins: [
 *       {
 *         name: 'Group Name',
 *         description: 'description',
 *         version: 'version',
 *         update_url: 'http://update/',
 *         critical: true,
 *         enabled_mode: 'enabledByUser',
 *         id: 'plugin-name',
 *         always_allowed: false,
 *         plugin_files: [
 *           {
 *             path: '/foo/bar/baz/MyPlugin.plugin',
 *             name: 'MyPlugin',
 *             version: '1.2,3'
 *             description: 'My plugin',
 *             type: 'BROWSER PLUGIN',
 *             mime_types: [
 *               {
 *                 description: 'Foo Media',
 *                 file_extensions: ['pdf'],
 *                 mime_type: 'application/x-my-foo'
 *               },
 *               {
 *                 description: 'Bar Stuff',
 *                 file_extensions: ['bar', 'baz'],
 *                 mime_type: 'application/my-bar'
 *               }
 *             ],
 *             enabled_mode: 'enabledByUser',
 *           },
 *           {
 *             path: '/tmp/MyFirst.plugin',
 *             name: 'MyFirstPlugin',
 *             version: '3.14r15926',
 *             description: 'My first plugin',
 *             type: 'BROWSER PLUGIN',
 *             mime_types: [
 *               {
 *                 description: 'New Guy Media',
 *                 file_extensions: ['mfp'],
 *                 mime_type: 'application/x-my-first'
 *               },
 *             ],
 *             enabled_mode: 'disabledByUser',
 *           },
 *         ],
 *       },
 *     ],
 *   }
 */
function returnPluginsData(pluginsData) {
  var bodyContainer = $('body-container');
  var body = document.body;

  // Set all page content to be visible so we can measure heights.
  bodyContainer.style.visibility = 'hidden';
  body.className = '';
  var slidables = document.getElementsByClassName('show-in-tmi-mode');
  for (var i = 0; i < slidables.length; i++)
    slidables[i].style.height = 'auto';

  renderTemplate(pluginsData);

  // Add handlers to dynamically created HTML elements.
  var links = document.getElementsByClassName('disable-plugin-link');
  for (var i = 0; i < links.length; i++) {
    links[i].onclick = function() {
      handleEnablePlugin(this, false, false);
      return false;
    };
  }
  links = document.getElementsByClassName('enable-plugin-link');
  for (var i = 0; i < links.length; i++) {
    links[i].onclick = function() {
      handleEnablePlugin(this, true, false);
      return false;
    };
  }
  links = document.getElementsByClassName('disable-group-link');
  for (var i = 0; i < links.length; i++) {
    links[i].onclick = function() {
      handleEnablePlugin(this, false, true);
      return false;
    };
  }
  links = document.getElementsByClassName('enable-group-link');
  for (var i = 0; i < links.length; i++) {
    links[i].onclick = function() {
      handleEnablePlugin(this, true, true);
      return false;
    };
  }
  var checkboxes = document.getElementsByClassName('always-allow');
  for (var i = 0; i < checkboxes.length; i++) {
    checkboxes[i].onclick = function() {
      handleSetPluginAlwaysAllowed(this);
    };
  }

  if (cr.isChromeOS) {
    // Disable some controls for Guest in ChromeOS.
    uiAccountTweaks.UIAccountTweaks.applyGuestSessionVisibility(document);
    // Disable some controls for Public session in ChromeOS.
    uiAccountTweaks.UIAccountTweaks.applyPublicSessionVisibility(document);
  }

  // Make sure the left column (with "Description:", "Location:", etc.) is the
  // same size for all plugins.
  var labels = document.getElementsByClassName('plugin-details-label');
  var maxLabelWidth = 0;
  for (var i = 0; i < labels.length; i++)
    labels[i].style.width = 'auto';
  for (var i = 0; i < labels.length; i++)
    maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth);
  for (var i = 0; i < labels.length; i++)
    labels[i].style.width = maxLabelWidth + 'px';

  // Explicitly set the height for each element that wants to be "slid" in and
  // out when the tmiModeExpanded is toggled.
  var slidables = document.getElementsByClassName('show-in-tmi-mode');
  for (var i = 0; i < slidables.length; i++)
    slidables[i].style.height = slidables[i].offsetHeight + 'px';

  // Reset visibility of page based on the current tmi mode.
  $('collapse').style.display =
     tmiModeExpanded ? 'inline' : 'none';
  $('expand').style.display =
     tmiModeExpanded ? 'none' : 'inline';
  bodyContainer.style.visibility = 'visible';
  body.className = tmiModeExpanded ?
     'show-tmi-mode-initial' : 'hide-tmi-mode-initial';
}

/**
 * Handles a 'enable' or 'disable' button getting clicked.
 * @param {HTMLElement} node The HTML element for the plugin being changed.
 * @param {boolean} enable Whether to enable or disable the plugin.
 * @param {boolean} isGroup True if we're enabling/disabling a plugin group,
 *     rather than a single plugin.
 */
function handleEnablePlugin(node, enable, isGroup) {
  whenBrowserProxyReady.then(function(browserProxy) {
    if (isGroup)
      browserProxy.setPluginGroupEnabled(node.path, enable);
    else
      browserProxy.setPluginEnabled(node.path, enable);
  });
}

/*
 * Toggles visibility of details.
 */
function toggleTmiMode() {
  tmiModeExpanded = !tmiModeExpanded;

  $('collapse').style.display =
      tmiModeExpanded ? 'inline' : 'none';
  $('expand').style.display =
      tmiModeExpanded ? 'none' : 'inline';

  document.body.className =
      tmiModeExpanded ? 'show-tmi-mode' : 'hide-tmi-mode';

  whenBrowserProxyReady.then(function(browserProxy) {
    browserProxy.saveShowDetailsToPrefs(tmiModeExpanded);
  });
}

function handleSetPluginAlwaysAllowed(el) {
  whenBrowserProxyReady.then(function(browserProxy) {
    browserProxy.setPluginAlwaysAllowed(el.identifier, el.checked);
  });
}

/**
 * @param {Object} plugin An object containing the information about a plugin.
 *     See returnPluginsData() for the format of this object.
 * @return {boolean} Whether the plugin's version should be displayed.
 */
function shouldDisplayPluginVersion(plugin) {
  return !!plugin.version && plugin.version != '0';
}

/**
 * @param {Object} plugin An object containing the information about a plugin.
 *     See returnPluginsData() for the format of this object.
 * @return {boolean} Whether the plugin's description should be displayed.
 */
function shouldDisplayPluginDescription(plugin) {
  // Only display the description if it's not blank and if it's not just the
  // name, version, or combination thereof.
  return plugin.description &&
         plugin.description != plugin.name &&
         plugin.description != plugin.version &&
         plugin.description != 'Version ' + plugin.version &&
         plugin.description != plugin.name + ' ' + plugin.version;
}

/**
 * @param {Object} plugin An object containing the information about a plugin.
 *     See returnPluginsData() for the format of this object.
 * @return {boolean} Whether the plugin is enabled.
 */
function isPluginEnabled(plugin) {
  return plugin.enabled_mode == 'enabledByUser' ||
         plugin.enabled_mode == 'enabledByPolicy';
}

// Unfortunately, we don't have notifications for plugin (list) status changes
// (yet), so in the meanwhile just update regularly.
setInterval(function() {
  whenBrowserProxyReady.then(function(browserProxy) {
    return browserProxy.getPluginsData();
  }).then(returnPluginsData);
}, 30000);

// Add handlers to static HTML elements.
$('collapse').onclick = toggleTmiMode;
$('expand').onclick = toggleTmiMode;
$('details-link').onclick = toggleTmiMode;

// NOTE: Need to keep a reference to the stub here such that it is not garbage
// collected, which causes the pipe to close and future calls from C++ to JS to
// get dropped.
var pluginsPageStub = null;

/**
 * A promise to use for getting a reference to the proxy object allowing
 * communication with the browser side.
 * @type {!Promise}
 */
var whenBrowserProxyReady = new Promise(function(resolve, reject) {
  define([
    'mojo/public/js/bindings',
    'mojo/public/js/core',
    'mojo/public/js/connection',
    'chrome/browser/ui/webui/plugins/plugins.mojom',
    'content/public/renderer/frame_service_registry',
  ], function(bindings, core, connection, pluginsMojom, serviceProvider) {
    var browserProxy = connection.bindHandleToProxy(
        serviceProvider.connectToService(
            pluginsMojom.PluginsHandlerMojo.name),
        pluginsMojom.PluginsHandlerMojo);

    // Perform necessary setup for the C++ side to make calls to JS at will.

    // Connect pipe handle to JS code.
    var pipe = core.createMessagePipe();
    pluginsPageStub = connection.bindHandleToStub(
        pipe.handle0, pluginsMojom.PluginsPageMojo);

    bindings.StubBindings(pluginsPageStub).delegate = {
      __proto__: pluginsMojom.PluginsPageMojo.stubClass.prototype,
      onPluginsUpdated: function(plugins) {
        returnPluginsData({plugins: plugins});
      },
    };

    // Send pipe handle to C++.
    browserProxy.setClientPage(pipe.handle1);

    resolve(browserProxy);
  });
});

/**
 * @type {!Promise} A promise firing when DOMContentLoaded event is received.
 */
var whenDomContentLoaded = new Promise(function(resolve, reject) {
  document.addEventListener('DOMContentLoaded', resolve);
});

Promise.all([
  whenDomContentLoaded,
  whenBrowserProxyReady
]).then(function(results) {
  var browserProxy = results[1];
  browserProxy.getShowDetails().then(function(response) {
    // Set the |tmiModeExpanded| first otherwise the UI flickers when
    // returnPlignsData executes.
    loadShowDetailsFromPrefs(response.show_details);
    return browserProxy.getPluginsData();
  }).then(returnPluginsData);
});
