// 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
 * A class for moving clipboard items between the plugin and the OS.
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/**
 * @constructor
 */
remoting.Clipboard = function() {
};

/**
 * @private
 * @enum {string}
 */
remoting.Clipboard.prototype.ItemTypes = {
  TEXT_TYPE: 'text/plain',
  TEXT_UTF8_TYPE: 'text/plain; charset=UTF-8'
};

/**
 * @private
 * @type {string}
 */
remoting.Clipboard.prototype.previousContent = "";

/**
 * @private
 * @type {boolean}
 */
remoting.Clipboard.prototype.itemFromHostTextPending = false;

/**
 * @private
 * @type {boolean}
 */
remoting.Clipboard.prototype.blockOneClipboardSend_ = false;

/**
 * Notifies this object that a session has started.
 *
 * @return {void} Nothing.
 */
remoting.Clipboard.prototype.startSession = function() {
  // Clear the store of items sent and received. Those items now relate to a
  // previous session.
  this.previousContent = "";
  this.itemFromHostTextPending = false;

  // Do a paste operation, but make sure the resulting clipboard data isn't sent
  // to the host. This stops the host seeing items that were placed on the
  // clipboard before the session began. The user may not have intended such
  // items to be sent to the host.
  this.blockOneClipboardSend_ = true;
  this.initiateToHost();
};

/**
 * Accepts a clipboard from the OS, and sends any changed clipboard items to
 * the host.
 *
 * Currently only text items are supported.
 *
 * @param {remoting.ClipboardData} clipboardData
 * @return {void} Nothing.
 */
remoting.Clipboard.prototype.toHost = function(clipboardData) {
  if (!clipboardData || !clipboardData.types || !clipboardData.getData) {
    console.log('Got invalid clipboardData.');
    return;
  }
  if (!remoting.clientSession) {
    return;
  }
  for (var i = 0; i < clipboardData.types.length; i++) {
    var type = clipboardData.types[i];
    var item = clipboardData.getData(type);
    if (!item) {
      item = "";
    }
    console.log('Got clipboard from OS, type: ' + type +
                ' length: ' + item.length + ' new: ' +
                (item != this.previousContent) + ' blocking-send: ' +
                this.blockOneClipboardSend_);
    // The browser presents text clipboard items as 'text/plain'.
    if (type == this.ItemTypes.TEXT_TYPE) {
      // Don't send the same item more than once. Otherwise the item may be
      // sent to and fro indefinitely.
      if (item != this.previousContent) {
        if (!this.blockOneClipboardSend_) {
          // The plugin's JSON reader emits UTF-8.
          console.log('Sending clipboard to host.');
          remoting.clientSession.sendClipboardItem(
              this.ItemTypes.TEXT_UTF8_TYPE, item);
        }
        this.previousContent = item;
      }
    }
  }
  this.blockOneClipboardSend_ = false;
};

/**
 * Accepts a clipboard item from the host, and stores it so that toOs() will
 * subsequently send it to the OS clipboard.
 *
 * @param {string} mimeType The MIME type of the clipboard item.
 * @param {string} item The clipboard item.
 * @return {void} Nothing.
 */
remoting.Clipboard.prototype.fromHost = function(mimeType, item) {
  // The plugin's JSON layer will correctly convert only UTF-8 data sent from
  // the host.
  console.log('Got clipboard from host, type: ' + mimeType +
              ' length: ' + item.length + ' new: ' +
              (item != this.previousContent));
  if (mimeType != this.ItemTypes.TEXT_UTF8_TYPE) {
    return;
  }
  if (item == this.previousContent) {
    return;
  }
  this.previousContent = item;
  this.itemFromHostTextPending = true;
  this.initiateToOs();
};

/**
 * Moves any pending clipboard items to a ClipboardData object.
 *
 * @param {remoting.ClipboardData} clipboardData
 * @return {boolean} Whether any clipboard items were moved to the ClipboardData
 *     object.
 */
remoting.Clipboard.prototype.toOs = function(clipboardData) {
  if (!this.itemFromHostTextPending) {
    console.log('Got unexpected clipboard copy event.');
    return false;
  }
  // The JSON layer between the plugin and this webapp converts UTF-8 to the
  // JS string encoding. The browser will convert JS strings to the correct
  // encoding, per OS and locale conventions, provided the data type is
  // 'text/plain'.
  console.log('Setting OS clipboard, length: ' + this.previousContent.length);
  clipboardData.setData(this.ItemTypes.TEXT_TYPE, this.previousContent);
  this.itemFromHostTextPending = false;
  return true;
};

/**
 * Initiates the process of sending any fresh items on the OS clipboard, to the
 * host.
 *
 * This method makes the browser fire a paste event, which provides access to
 * the OS clipboard. That event will be caught by a handler in the document,
 * which will call toHost().
 */
remoting.Clipboard.prototype.initiateToHost = function() {
  // It would be cleaner to send a paste command to the plugin element,
  // but that's not supported.
  //console.log('Initiating clipboard paste.');
  document.execCommand("paste");
};

/**
 * Initiates the process of sending any items freshly received from the host,
 * to the OS clipboard.
 *
 * This method makes the browser fire a copy event, which provides access to
 * the OS clipboard. That event will be caught by a handler in the document,
 * which will call toOs().
 */
remoting.Clipboard.prototype.initiateToOs = function() {
  // It would be cleaner to send a paste command to the plugin element,
  // but that's not supported.
  console.log('Initiating clipboard copy.');
  document.execCommand("copy");
};

/** @type {remoting.Clipboard} */
remoting.clipboard = null;
