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

<include src="keyboard_overlay_data.js"/>
<include src="keyboard_overlay_accessibility_helper.js"/>

var BASE_KEYBOARD = {
  top: 0,
  left: 0,
  width: 1237,
  height: 514
};

var BASE_INSTRUCTIONS = {
  top: 194,
  left: 370,
  width: 498,
  height: 142
};

var MODIFIER_TO_CLASS = {
  'SHIFT': 'modifier-shift',
  'CTRL': 'modifier-ctrl',
  'ALT': 'modifier-alt',
  'SEARCH': 'modifier-search'
};

var IDENTIFIER_TO_CLASS = {
  '2A': 'is-shift',
  '1D': 'is-ctrl',
  '38': 'is-alt',
  'E0 5B': 'is-search'
};

var LABEL_TO_IDENTIFIER = {
  'search': 'E0 5B',
  'ctrl': '1D',
  'alt': '38',
  'caps lock': '3A',
  'esc': '01',
  'disabled': 'DISABLED'
};

var KEYCODE_TO_LABEL = {
  8: 'backspace',
  9: 'tab',
  13: 'enter',
  27: 'esc',
  32: 'space',
  33: 'pageup',
  34: 'pagedown',
  35: 'end',
  36: 'home',
  37: 'left',
  38: 'up',
  39: 'right',
  40: 'down',
  46: 'delete',
  91: 'search',
  92: 'search',
  96: '0',
  97: '1',
  98: '2',
  99: '3',
  100: '4',
  101: '5',
  102: '6',
  103: '7',
  104: '8',
  105: '9',
  106: '*',
  107: '+',
  109: '-',
  110: '.',
  111: '/',
  112: 'back',
  113: 'forward',
  114: 'reload',
  115: 'full screen',
  116: 'switch window',
  117: 'bright down',
  118: 'bright up',
  119: 'mute',
  120: 'vol. down',
  121: 'vol. up',
  186: ';',
  187: '+',
  188: ',',
  189: '-',
  190: '.',
  191: '/',
  192: '`',
  219: '[',
  220: '\\',
  221: ']',
  222: '\'',
};

var keyboardOverlayId = 'en_US';
var identifierMap = {};

/**
 * Returns the layout name.
 * @return {string} layout name.
 */
function getLayoutName() {
  return getKeyboardGlyphData().layoutName;
}

/**
 * Returns layout data.
 * @return {Array} Keyboard layout data.
 */
function getLayout() {
  return keyboardOverlayData['layouts'][getLayoutName()];
}

// Cache the shortcut data after it is constructed.
var shortcutDataCache;

/**
 * Returns shortcut data.
 * @return {Object} Keyboard shortcut data.
 */
function getShortcutData() {
  if (shortcutDataCache)
    return shortcutDataCache;

  shortcutDataCache = keyboardOverlayData['shortcut'];

  if (!isDisplayUIScalingEnabled()) {
    // Zoom screen in
    delete shortcutDataCache['+<>CTRL<>SHIFT'];
    // Zoom screen out
    delete shortcutDataCache['-<>CTRL<>SHIFT'];
    // Reset screen zoom
    delete shortcutDataCache['0<>CTRL<>SHIFT'];
  }

  return shortcutDataCache;
}

/**
 * Returns the keyboard overlay ID.
 * @return {string} Keyboard overlay ID.
 */
function getKeyboardOverlayId() {
  return keyboardOverlayId;
}

/**
 * Returns keyboard glyph data.
 * @return {Object} Keyboard glyph data.
 */
function getKeyboardGlyphData() {
  return keyboardOverlayData['keyboardGlyph'][getKeyboardOverlayId()];
}

/**
 * Converts a single hex number to a character.
 * @param {string} hex Hexadecimal string.
 * @return {string} Unicode values of hexadecimal string.
 */
function hex2char(hex) {
  if (!hex) {
    return '';
  }
  var result = '';
  var n = parseInt(hex, 16);
  if (n <= 0xFFFF) {
    result += String.fromCharCode(n);
  } else if (n <= 0x10FFFF) {
    n -= 0x10000;
    result += (String.fromCharCode(0xD800 | (n >> 10)) +
               String.fromCharCode(0xDC00 | (n & 0x3FF)));
  } else {
    console.error('hex2Char error: Code point out of range :' + hex);
  }
  return result;
}

var searchIsPressed = false;

/**
 * Returns a list of modifiers from the key event.
 * @param {Event} e The key event.
 * @return {Array} List of modifiers based on key event.
 */
function getModifiers(e) {
  if (!e)
    return [];

  var isKeyDown = (e.type == 'keydown');
  var keyCodeToModifier = {
    16: 'SHIFT',
    17: 'CTRL',
    18: 'ALT',
    91: 'SEARCH',
  };
  var modifierWithKeyCode = keyCodeToModifier[e.keyCode];
  var isPressed = {
      'SHIFT': e.shiftKey,
      'CTRL': e.ctrlKey,
      'ALT': e.altKey,
      'SEARCH': searchIsPressed
  };
  if (modifierWithKeyCode)
    isPressed[modifierWithKeyCode] = isKeyDown;

  searchIsPressed = isPressed['SEARCH'];

  // make the result array
  return ['SHIFT', 'CTRL', 'ALT', 'SEARCH'].filter(
      function(modifier) {
        return isPressed[modifier];
      }).sort();
}

/**
 * Returns an ID of the key.
 * @param {string} identifier Key identifier.
 * @param {number} i Key number.
 * @return {string} Key ID.
 */
function keyId(identifier, i) {
  return identifier + '-key-' + i;
}

/**
 * Returns an ID of the text on the key.
 * @param {string} identifier Key identifier.
 * @param {number} i Key number.
 * @return {string} Key text ID.
 */
function keyTextId(identifier, i) {
  return identifier + '-key-text-' + i;
}

/**
 * Returns an ID of the shortcut text.
 * @param {string} identifier Key identifier.
 * @param {number} i Key number.
 * @return {string} Key shortcut text ID.
 */
function shortcutTextId(identifier, i) {
  return identifier + '-shortcut-text-' + i;
}

/**
 * Returns true if |list| contains |e|.
 * @param {Array} list Container list.
 * @param {string} e Element string.
 * @return {boolean} Returns true if the list contains the element.
 */
function contains(list, e) {
  return list.indexOf(e) != -1;
}

/**
 * Returns a list of the class names corresponding to the identifier and
 * modifiers.
 * @param {string} identifier Key identifier.
 * @param {Array} modifiers List of key modifiers.
 * @return {Array} List of class names corresponding to specified params.
 */
function getKeyClasses(identifier, modifiers) {
  var classes = ['keyboard-overlay-key'];
  for (var i = 0; i < modifiers.length; ++i) {
    classes.push(MODIFIER_TO_CLASS[modifiers[i]]);
  }

  if ((identifier == '2A' && contains(modifiers, 'SHIFT')) ||
      (identifier == '1D' && contains(modifiers, 'CTRL')) ||
      (identifier == '38' && contains(modifiers, 'ALT')) ||
      (identifier == 'E0 5B' && contains(modifiers, 'SEARCH'))) {
    classes.push('pressed');
    classes.push(IDENTIFIER_TO_CLASS[identifier]);
  }
  return classes;
}

/**
 * Returns true if a character is a ASCII character.
 * @param {string} c A character to be checked.
 * @return {boolean} True if the character is an ASCII character.
 */
function isAscii(c) {
  var charCode = c.charCodeAt(0);
  return 0x00 <= charCode && charCode <= 0x7F;
}

/**
 * Returns a remapped identiifer based on the preference.
 * @param {string} identifier Key identifier.
 * @return {string} Remapped identifier.
 */
function remapIdentifier(identifier) {
  return identifierMap[identifier] || identifier;
}

/**
 * Returns a label of the key.
 * @param {string} keyData Key glyph data.
 * @param {Array} modifiers Key Modifier list.
 * @return {string} Label of the key.
 */
function getKeyLabel(keyData, modifiers) {
  if (!keyData) {
    return '';
  }
  if (keyData.label) {
    return keyData.label;
  }
  var keyLabel = '';
  for (var j = 1; j <= 9; j++) {
    var pos = keyData['p' + j];
    if (!pos) {
      continue;
    }
    keyLabel = hex2char(pos);
    if (!keyLabel) {
      continue;
     }
    if (isAscii(keyLabel) &&
        getShortcutData()[getAction(keyLabel, modifiers)]) {
      break;
    }
  }
  return keyLabel;
}

/**
 * Returns a normalized string used for a key of shortcutData.
 *
 * Examples:
 *   keyCode: 'd', modifiers: ['CTRL', 'SHIFT'] => 'd<>CTRL<>SHIFT'
 *   keyCode: 'alt', modifiers: ['ALT', 'SHIFT'] => 'ALT<>SHIFT'
 *
 * @param {string} keyCode Key code.
 * @param {Array} modifiers Key Modifier list.
 * @return {string} Normalized key shortcut data string.
 */
function getAction(keyCode, modifiers) {
  /** @const */ var separatorStr = '<>';
  if (keyCode.toUpperCase() in MODIFIER_TO_CLASS) {
    keyCode = keyCode.toUpperCase();
    if (keyCode in modifiers) {
      return modifiers.join(separatorStr);
    } else {
      var action = [keyCode].concat(modifiers);
      action.sort();
      return action.join(separatorStr);
    }
  }
  return [keyCode].concat(modifiers).join(separatorStr);
}

/**
 * Returns a text which displayed on a key.
 * @param {string} keyData Key glyph data.
 * @return {string} Key text value.
 */
function getKeyTextValue(keyData) {
  if (keyData.label) {
    // Do not show text on the space key.
    if (keyData.label == 'space') {
      return '';
    }
    return keyData.label;
  }

  var chars = [];
  for (var j = 1; j <= 9; ++j) {
    var pos = keyData['p' + j];
    if (pos && pos.length > 0) {
      chars.push(hex2char(pos));
    }
  }
  return chars.join(' ');
}

/**
 * Updates the whole keyboard.
 * @param {Array} modifiers Key Modifier list.
 */
function update(modifiers) {
  var instructions = $('instructions');
  if (modifiers.length == 0) {
    instructions.style.visibility = 'visible';
  } else {
    instructions.style.visibility = 'hidden';
  }

  var keyboardGlyphData = getKeyboardGlyphData();
  var shortcutData = getShortcutData();
  var layout = getLayout();
  for (var i = 0; i < layout.length; ++i) {
    var identifier = remapIdentifier(layout[i][0]);
    var keyData = keyboardGlyphData.keys[identifier];
    var classes = getKeyClasses(identifier, modifiers, keyData);
    var keyLabel = getKeyLabel(keyData, modifiers);
    var shortcutId = shortcutData[getAction(keyLabel, modifiers)];
    if (modifiers.length == 1 && modifiers[0] == 'SHIFT' &&
        identifier == '2A') {
      // Currently there is no way to identify whether the left shift or the
      // right shift is preesed from the key event, so I assume the left shift
      // key is pressed here and do not show keyboard shortcut description for
      // 'Shift - Shift' (Toggle caps lock) on the left shift key, the
      // identifier of which is '2A'.
      // TODO(mazda): Remove this workaround (http://crosbug.com/18047)
      shortcutId = null;
    }
    if (shortcutId) {
      classes.push('is-shortcut');
    }

    var key = $(keyId(identifier, i));
    key.className = classes.join(' ');

    if (!keyData) {
      continue;
    }

    var keyText = $(keyTextId(identifier, i));
    var keyTextValue = getKeyTextValue(keyData);
    if (keyTextValue) {
       keyText.style.visibility = 'visible';
    } else {
       keyText.style.visibility = 'hidden';
    }
    keyText.textContent = keyTextValue;

    var shortcutText = $(shortcutTextId(identifier, i));
    if (shortcutId) {
      shortcutText.style.visibility = 'visible';
      shortcutText.textContent = loadTimeData.getString(shortcutId);
    } else {
      shortcutText.style.visibility = 'hidden';
    }

    if (keyData.format) {
      var format = keyData.format;
      if (format == 'left' || format == 'right') {
        shortcutText.style.textAlign = format;
        keyText.style.textAlign = format;
      }
    }
  }
}

/**
 * A callback function for onkeydown and onkeyup events.
 * @param {Event} e Key event.
 */
function handleKeyEvent(e) {
  if (!getKeyboardOverlayId()) {
    return;
  }
  var modifiers = getModifiers(e);
  update(modifiers);
  KeyboardOverlayAccessibilityHelper.maybeSpeakAllShortcuts(modifiers);
  e.preventDefault();
}

/**
 * Initializes the layout of the keys.
 */
function initLayout() {
  // Add data for the caps lock key
  var keys = getKeyboardGlyphData().keys;
  if (!('3A' in keys)) {
    keys['3A'] = {label: 'caps lock', format: 'left'};
  }
  // Add data for the special key representing a disabled key
  keys['DISABLED'] = {label: 'disabled', format: 'left'};

  var layout = getLayout();
  var keyboard = document.body;
  var minX = window.innerWidth;
  var maxX = 0;
  var minY = window.innerHeight;
  var maxY = 0;
  var multiplier = 1.38 * window.innerWidth / BASE_KEYBOARD.width;
  var keyMargin = 7;
  var offsetX = 10;
  var offsetY = 7;
  for (var i = 0; i < layout.length; i++) {
    var array = layout[i];
    var identifier = remapIdentifier(array[0]);
    var x = Math.round((array[1] + offsetX) * multiplier);
    var y = Math.round((array[2] + offsetY) * multiplier);
    var w = Math.round((array[3] - keyMargin) * multiplier);
    var h = Math.round((array[4] - keyMargin) * multiplier);

    var key = document.createElement('div');
    key.id = keyId(identifier, i);
    key.className = 'keyboard-overlay-key';
    key.style.left = x + 'px';
    key.style.top = y + 'px';
    key.style.width = w + 'px';
    key.style.height = h + 'px';

    var keyText = document.createElement('div');
    keyText.id = keyTextId(identifier, i);
    keyText.className = 'keyboard-overlay-key-text';
    keyText.style.visibility = 'hidden';
    key.appendChild(keyText);

    var shortcutText = document.createElement('div');
    shortcutText.id = shortcutTextId(identifier, i);
    shortcutText.className = 'keyboard-overlay-shortcut-text';
    shortcutText.style.visilibity = 'hidden';
    key.appendChild(shortcutText);
    keyboard.appendChild(key);

    minX = Math.min(minX, x);
    maxX = Math.max(maxX, x + w);
    minY = Math.min(minY, y);
    maxY = Math.max(maxY, y + h);
  }

  var width = maxX - minX + 1;
  var height = maxY - minY + 1;
  keyboard.style.width = (width + 2 * (minX + 1)) + 'px';
  keyboard.style.height = (height + 2 * (minY + 1)) + 'px';

  var instructions = document.createElement('div');
  instructions.id = 'instructions';
  instructions.className = 'keyboard-overlay-instructions';
  instructions.style.left = ((BASE_INSTRUCTIONS.left - BASE_KEYBOARD.left) *
                             width / BASE_KEYBOARD.width + minX) + 'px';
  instructions.style.top = ((BASE_INSTRUCTIONS.top - BASE_KEYBOARD.top) *
                            height / BASE_KEYBOARD.height + minY) + 'px';
  instructions.style.width = (width * BASE_INSTRUCTIONS.width /
                              BASE_KEYBOARD.width) + 'px';
  instructions.style.height = (height * BASE_INSTRUCTIONS.height /
                               BASE_KEYBOARD.height) + 'px';

  var instructionsText = document.createElement('div');
  instructionsText.id = 'instructions-text';
  instructionsText.className = 'keyboard-overlay-instructions-text';
  instructionsText.innerHTML =
      loadTimeData.getString('keyboardOverlayInstructions');
  instructions.appendChild(instructionsText);
  var instructionsHideText = document.createElement('div');
  instructionsHideText.id = 'instructions-hide-text';
  instructionsHideText.className = 'keyboard-overlay-instructions-hide-text';
  instructionsHideText.innerHTML =
      loadTimeData.getString('keyboardOverlayInstructionsHide');
  instructions.appendChild(instructionsHideText);
  var learnMoreLinkText = document.createElement('div');
  learnMoreLinkText.id = 'learn-more-text';
  learnMoreLinkText.className = 'keyboard-overlay-learn-more-text';
  learnMoreLinkText.addEventListener('click', learnMoreClicked);
  var learnMoreLinkAnchor = document.createElement('a');
  learnMoreLinkAnchor.href =
      loadTimeData.getString('keyboardOverlayLearnMoreURL');
  learnMoreLinkAnchor.textContent =
      loadTimeData.getString('keyboardOverlayLearnMore');
  learnMoreLinkText.appendChild(learnMoreLinkAnchor);
  instructions.appendChild(learnMoreLinkText);
  keyboard.appendChild(instructions);
}

/**
 * Returns true if the device has a diamond key.
 * @return {boolean} Returns true if the device has a diamond key.
 */
function hasDiamondKey() {
  return loadTimeData.getBoolean('keyboardOverlayHasChromeOSDiamondKey');
}

/**
 * Returns true if display scaling feature is enabled.
 * @return {boolean} True if display scaling feature is enabled.
 */
function isDisplayUIScalingEnabled() {
  return loadTimeData.getBoolean('keyboardOverlayIsDisplayUIScalingEnabled');
}

/**
 * Initializes the layout and the key labels for the keyboard that has a diamond
 * key.
 */
function initDiamondKey() {
  var newLayoutData = {
    '1D': [65.0, 287.0, 60.0, 60.0],  // left Ctrl
    '38': [185.0, 287.0, 60.0, 60.0],  // left Alt
    'E0 5B': [125.0, 287.0, 60.0, 60.0],  // search
    '3A': [5.0, 167.0, 105.0, 60.0],  // caps lock
    '5B': [803.0, 6.0, 72.0, 35.0],  // lock key
    '5D': [5.0, 287.0, 60.0, 60.0]  // diamond key
  };

  var layout = getLayout();
  var powerKeyIndex = -1;
  var powerKeyId = '00';
  for (var i = 0; i < layout.length; i++) {
    var keyId = layout[i][0];
    if (keyId in newLayoutData) {
      layout[i] = [keyId].concat(newLayoutData[keyId]);
      delete newLayoutData[keyId];
    }
    if (keyId == powerKeyId)
      powerKeyIndex = i;
  }
  for (var keyId in newLayoutData)
    layout.push([keyId].concat(newLayoutData[keyId]));

  // Remove the power key.
  if (powerKeyIndex != -1)
    layout.splice(powerKeyIndex, 1);

  var keyData = getKeyboardGlyphData()['keys'];
  var newKeyData = {
    '3A': {'label': 'caps lock', 'format': 'left'},
    '5B': {'label': 'lock'},
    '5D': {'label': 'diamond', 'format': 'left'}
  };
  for (var keyId in newKeyData)
    keyData[keyId] = newKeyData[keyId];
}

/**
 * A callback function for the onload event of the body element.
 */
function init() {
  document.addEventListener('keydown', handleKeyEvent);
  document.addEventListener('keyup', handleKeyEvent);
  chrome.send('getLabelMap');
}

/**
 * Initializes the global map for remapping identifiers of modifier keys based
 * on the preference.
 * Called after sending the 'getLabelMap' message.
 * @param {Object} remap Identifier map.
 */
function initIdentifierMap(remap) {
  for (var key in remap) {
    var val = remap[key];
    if ((key in LABEL_TO_IDENTIFIER) &&
        (val in LABEL_TO_IDENTIFIER)) {
      identifierMap[LABEL_TO_IDENTIFIER[key]] =
          LABEL_TO_IDENTIFIER[val];
    } else {
      console.error('Invalid label map element: ' + key + ', ' + val);
    }
  }
  chrome.send('getInputMethodId');
}

/**
 * Initializes the global keyboad overlay ID and the layout of keys.
 * Called after sending the 'getInputMethodId' message.
 * @param {inputMethodId} inputMethodId Input Method Identifier.
 */
function initKeyboardOverlayId(inputMethodId) {
  // Libcros returns an empty string when it cannot find the keyboard overlay ID
  // corresponding to the current input method.
  // In such a case, fallback to the default ID (en_US).
  var inputMethodIdToOverlayId =
      keyboardOverlayData['inputMethodIdToOverlayId'];
  if (inputMethodId) {
    keyboardOverlayId = inputMethodIdToOverlayId[inputMethodId];
  }
  if (!keyboardOverlayId) {
    console.error('No keyboard overlay ID for ' + inputMethodId);
    keyboardOverlayId = 'en_US';
  }
  while (document.body.firstChild) {
    document.body.removeChild(document.body.firstChild);
  }
  // We show Japanese layout as-is because the user has chosen the layout
  // that is quite diffrent from the physical layout that has a diamond key.
  if (hasDiamondKey() && getLayoutName() != 'J')
    initDiamondKey();
  initLayout();
  update([]);
  window.webkitRequestAnimationFrame(function() {
    chrome.send('didPaint');
  });
}

/**
 * Handles click events of the learn more link.
 * @param {Event} e Mouse click event.
 */
function learnMoreClicked(e) {
  chrome.send('openLearnMorePage');
  chrome.send('DialogClose');
  e.preventDefault();
}

document.addEventListener('DOMContentLoaded', init);
