// Copyright (c) 2013 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.

cr.define('accessibility', function() {
  'use strict';

  // Note: keep these values in sync with the values in
  // content/common/accessibility_mode_enums.h
  const AccessibilityMode = {
    kNativeAPIs: 1 << 0,
    kWebContents: 1 << 1,
    kInlineTextBoxes: 1 << 2,
    kScreenReader: 1 << 3,
    kHTML: 1 << 4,

    get kAccessibilityModeWebContentsOnly() {
      return AccessibilityMode.kWebContents |
        AccessibilityMode.kInlineTextBoxes | AccessibilityMode.kScreenReader |
        AccessibilityMode.kHTML;
    },

    get kAccessibilityModeComplete() {
      return AccessibilityMode.kNativeAPIs | AccessibilityMode.kWebContents |
        AccessibilityMode.kInlineTextBoxes | AccessibilityMode.kScreenReader |
        AccessibilityMode.kHTML;
    }
  };

  function requestData() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'targets-data.json', false);
    xhr.send(null);
    if (xhr.status === 200) {
      console.log(xhr.responseText);
      return JSON.parse(xhr.responseText);
    }
    return [];
  }

  function toggleAccessibility(data, element, mode) {
    chrome.send('toggleAccessibility',
                [String(data.processId), String(data.routeId), mode]);
    document.location.reload();
  }

  function requestAccessibilityTree(data, element) {
    chrome.send('requestAccessibilityTree',
                [String(data.processId), String(data.routeId)]);
  }

  function initialize() {
    console.log('initialize');
    var data = requestData();

    bindCheckbox('native', data['native']);
    bindCheckbox('web', data['web']);
    bindCheckbox('text', data['text']);
    bindCheckbox('screenreader', data['screenreader']);
    bindCheckbox('html', data['html']);
    bindCheckbox('internal', data['internal']);

    $('pages').textContent = '';

    var list = data['list'];
    for (var i = 0; i < list.length; i++) {
      addToPagesList(list[i]);
    }
  }

  function bindCheckbox(name, value) {
    if (value == 'on')
      $(name).checked = true;
    if (value == 'disabled') {
      $(name).disabled = true;
      $(name).labels[0].classList.add('disabled');
    }
    $(name).addEventListener('change', function() {
      chrome.send('setGlobalFlag', [name, $(name).checked]);
      document.location.reload();
    });
  }

  function addToPagesList(data) {
    // TODO: iterate through data and pages rows instead
    var id = data['processId'] + '.' + data['routeId'];
    var row = document.createElement('div');
    row.className = 'row';
    row.id = id;
    formatRow(row, data);

    row.processId = data.processId;
    row.routeId = data.routeId;

    var list = $('pages');
    list.appendChild(row);
  }

  function formatRow(row, data) {
    if (!('url' in data)) {
      if ('error' in data) {
        row.appendChild(createErrorMessageElement(data, row));
        return;
      }
    }

    var siteInfo = document.createElement('div');
    var properties = ['favicon_url', 'name', 'url'];
    for (var j = 0; j < properties.length; j++)
      siteInfo.appendChild(formatValue(data, properties[j]));
    row.appendChild(siteInfo);

    row.appendChild(createModeElement(AccessibilityMode.kNativeAPIs, data))
    row.appendChild(createModeElement(AccessibilityMode.kWebContents, data))
    row.appendChild(createModeElement(AccessibilityMode.kInlineTextBoxes,
      data))
    row.appendChild(createModeElement(AccessibilityMode.kScreenReader, data))
    row.appendChild(createModeElement(AccessibilityMode.kHTML, data))

    row.appendChild(document.createTextNode(' | '));

    if ('tree' in data) {
      row.appendChild(createShowAccessibilityTreeElement(data, row, true));
      row.appendChild(createHideAccessibilityTreeElement(row.id));
      row.appendChild(createAccessibilityTreeElement(data));
    }
    else {
      row.appendChild(createShowAccessibilityTreeElement(data, row, false));
      if ('error' in data)
        row.appendChild(createErrorMessageElement(data, row));
    }
  }

  function formatValue(data, property) {
    var value = data[property];

    if (property == 'favicon_url') {
      var faviconElement = document.createElement('img');
      if (value)
        faviconElement.src = value;
      faviconElement.alt = "";
      return faviconElement;
    }

    var text = value ? String(value) : '';
    if (text.length > 100)
      text = text.substring(0, 100) + '\u2026';  // ellipsis

    var span = document.createElement('span');
    span.textContent = ' ' + text + ' ';
    span.className = property;
    return span;
  }

  function getNameForAccessibilityMode(mode) {
    switch (mode) {
      case AccessibilityMode.kNativeAPIs:
        return "native"
      case AccessibilityMode.kWebContents:
        return "web"
      case AccessibilityMode.kInlineTextBoxes:
        return "inline text"
      case AccessibilityMode.kScreenReader:
        return "screen reader"
      case AccessibilityMode.kHTML:
        return "html"
    }
    return "unknown"
  }

  function createModeElement(mode, data) {
    var currentMode = data['a11y_mode'];
    var link = document.createElement('a', 'action-link');
    link.setAttribute('role', 'button');

    var stateText = ((currentMode & mode) != 0) ? 'true' : 'false';
    link.textContent = getNameForAccessibilityMode(mode) + ": " + stateText;
    link.setAttribute('aria-pressed', stateText);
    link.addEventListener('click',
                          toggleAccessibility.bind(this, data, link, mode));
    return link;
  }

  function createShowAccessibilityTreeElement(data, row, opt_refresh) {
    var link = document.createElement('a', 'action-link');
    link.setAttribute('role', 'button');
    if (opt_refresh)
      link.textContent = 'refresh accessibility tree';
    else
      link.textContent = 'show accessibility tree';
    link.id = row.id + ':showTree';
    link.addEventListener('click',
                          requestAccessibilityTree.bind(this, data, link));
    return link;
  }

  function createHideAccessibilityTreeElement(id) {
    var link = document.createElement('a', 'action-link');
    link.setAttribute('role', 'button');
    link.textContent = 'hide accessibility tree';
    link.addEventListener('click',
                          function() {
        $(id + ':showTree').textContent = 'show accessibility tree';
        var existingTreeElements = $(id).getElementsByTagName('pre');
        for (var i = 0; i < existingTreeElements.length; i++)
          $(id).removeChild(existingTreeElements[i]);
        var row = $(id);
        while (row.lastChild != $(id + ':showTree'))
          row.removeChild(row.lastChild);
    });
    return link;
  }

  function createErrorMessageElement(data) {
    var errorMessageElement = document.createElement('div');
    var errorMessage = data.error;
    errorMessageElement.innerHTML = errorMessage + '&nbsp;';
    var closeLink = document.createElement('a');
    closeLink.href='#';
    closeLink.textContent = '[close]';
    closeLink.addEventListener('click', function() {
        var parentElement = errorMessageElement.parentElement;
        parentElement.removeChild(errorMessageElement);
        if (parentElement.childElementCount == 0)
          parentElement.parentElement.removeChild(parentElement);
    });
    errorMessageElement.appendChild(closeLink);
    return errorMessageElement;
  }

  function showTree(data) {
    var id = data.processId + '.' + data.routeId;
    var row = $(id);
    if (!row)
      return;

    row.textContent = '';
    formatRow(row, data);
  }

  function createAccessibilityTreeElement(data) {
    var treeElement = document.createElement('pre');
    var tree = data.tree;
    treeElement.textContent = tree;
    return treeElement;
  }

  return {
    initialize: initialize,
    showTree: showTree
  };
});

document.addEventListener('DOMContentLoaded', accessibility.initialize);
