// 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';
    }

    var format = keyboardGlyphData.keys[layout[i][0]].format;
    if (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);
