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

function inspect(data) {
  chrome.send('inspect', [data]);
}

function terminate(data) {
  chrome.send('terminate', [data]);
}

function reload(data) {
  chrome.send('reload', [data]);
}

function open(browserId, url) {
  chrome.send('open', [browserId, url]);
}

function removeChildren(element_id) {
  var element = $(element_id);
  element.textContent = '';
}

function onload() {
  var tabContents = document.querySelectorAll('#content > div');
  for (var i = 0; i != tabContents.length; i++) {
    var tabContent = tabContents[i];
    var tabName = tabContent.querySelector('.content-header').textContent;

    var tabHeader = document.createElement('div');
    tabHeader.className = 'tab-header';
    var button = document.createElement('button');
    button.textContent = tabName;
    tabHeader.appendChild(button);
    tabHeader.addEventListener('click', selectTab.bind(null, tabContent.id));
    $('navigation').appendChild(tabHeader);
  }
  var selectedTabName = window.location.hash.slice(1) || 'devices';
  selectTab(selectedTabName + '-tab');
  initPortForwarding();
  chrome.send('init-ui');
}

function selectTab(id) {
  var tabContents = document.querySelectorAll('#content > div');
  var tabHeaders = $('navigation').querySelectorAll('.tab-header');
  for (var i = 0; i != tabContents.length; i++) {
    var tabContent = tabContents[i];
    var tabHeader = tabHeaders[i];
    if (tabContent.id == id) {
      tabContent.classList.add('selected');
      tabHeader.classList.add('selected');
    } else {
      tabContent.classList.remove('selected');
      tabHeader.classList.remove('selected');
    }
  }
}

function populateLists(data) {
  removeChildren('pages');
  removeChildren('extensions');
  removeChildren('apps');
  removeChildren('others');

  for (var i = 0; i < data.length; i++) {
    if (data[i].type === 'page')
      addToPagesList(data[i]);
    else if (data[i].type === 'extension')
      addToExtensionsList(data[i]);
    else if (data[i].type === 'app')
      addToAppsList(data[i]);
    else
      addToOthersList(data[i]);
  }
}

function populateWorkersList(data) {
  removeChildren('workers');

  for (var i = 0; i < data.length; i++)
    addToWorkersList(data[i]);
}

function populateDeviceLists(devices) {
  if (!devices)
    return;

  function alreadyDisplayed(element, data) {
    var json = JSON.stringify(data);
    if (element.cachedJSON == json)
      return true;
    element.cachedJSON = json;
    return false;
  }

  var deviceList = $('devices');
  if (alreadyDisplayed(deviceList, devices))
    return;

  function removeObsolete(validIds, section) {
    if (validIds.indexOf(section.id) < 0)
      section.remove();
  }

  var newDeviceIds = devices.map(function(d) { return d.adbGlobalId });
  Array.prototype.forEach.call(
      deviceList.querySelectorAll('.device'),
      removeObsolete.bind(null, newDeviceIds));

  for (var d = 0; d < devices.length; d++) {
    var device = devices[d];

    var browserList;
    var deviceSection = $(device.adbGlobalId);
    if (deviceSection) {
      browserList = deviceSection.querySelector('.browsers');
    } else {
      deviceSection = document.createElement('div');
      deviceSection.id = device.adbGlobalId;
      deviceSection.className = 'device list';
      deviceList.appendChild(deviceSection);

      var deviceHeader = document.createElement('div');
      deviceHeader.className = 'section';
      deviceHeader.textContent = device.adbModel;
      deviceSection.appendChild(deviceHeader);

      browserList = document.createElement('div');
      browserList.className = 'browsers';
      deviceSection.appendChild(browserList);
    }

    if (alreadyDisplayed(deviceSection, device))
      continue;

    var newBrowserIds =
        device.browsers.map(function(b) { return b.adbGlobalId });
    Array.prototype.forEach.call(
        browserList.querySelectorAll('.browser'),
        removeObsolete.bind(null, newBrowserIds));

    for (var b = 0; b < device.browsers.length; b++) {
      var browser = device.browsers[b];

      var pageList;
      var browserSection = $(browser.adbGlobalId);
      if (browserSection) {
        pageList = browserSection.querySelector('.pages');
        pageList.textContent = '';
      } else {
        browserSection = document.createElement('div');
        browserSection.id = browser.adbGlobalId;
        browserSection.className = 'browser';
        browserList.appendChild(browserSection);

        var browserHeader = document.createElement('div');
        browserHeader.className = 'small-section';
        browserHeader.textContent = browser.adbBrowserName;
        browserSection.appendChild(browserHeader);

        var newPage = document.createElement('div');
        newPage.className = 'open';

        var newPageUrl = document.createElement('input');
        newPageUrl.type = 'text';
        newPageUrl.placeholder = 'Open tab with url';
        newPage.appendChild(newPageUrl);

        var openHandler = function(browserId, input) {
          open(browserId, input.value || 'about:blank');
          input.value = '';
        }.bind(null, browser.adbGlobalId, newPageUrl);
        newPageUrl.addEventListener('keyup', function(handler, event) {
          if (event.keyIdentifier == 'Enter' && event.target.value)
            handler();
        }.bind(null, openHandler), true);

        var newPageButton = document.createElement('button');
        newPageButton.textContent = 'Open';
        newPage.appendChild(newPageButton);
        newPageButton.addEventListener('click', openHandler, true);

        browserSection.appendChild(newPage);

        pageList = document.createElement('div');
        pageList.className = 'list pages';
        browserSection.appendChild(pageList);
      }

      if (alreadyDisplayed(browserSection, browser))
        continue;

      for (var p = 0; p < browser.pages.length; p++) {
        var page = browser.pages[p];
        var row = addTargetToList(
            page, pageList, ['faviconUrl', 'name', 'url']);
        row.appendChild(createActionLink(
            'reload', reload.bind(null, page), page.attached));
        row.appendChild(createActionLink(
            'close', terminate.bind(null, page), page.attached));
      }
    }
  }
}

function addToPagesList(data) {
  addTargetToList(data, $('pages'), ['faviconUrl', 'name', 'url']);
}

function addToExtensionsList(data) {
  addTargetToList(data, $('extensions'), ['name', 'url']);
}

function addToAppsList(data) {
  addTargetToList(data, $('apps'), ['name', 'url']);
}

function addToWorkersList(data) {
  var row = addTargetToList(data, $('workers'), ['name', 'url', 'pid']);
  row.appendChild(createActionLink(
      'terminate', terminate.bind(null, data), data.attached));
}

function addToOthersList(data) {
  addTargetToList(data, $('others'), ['url']);
}

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

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

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

  if (property == 'pid')
    text = 'Pid:' + text;

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

function addTargetToList(data, list, properties) {
  var row = document.createElement('div');
  row.className = 'row';
  for (var j = 0; j < properties.length; j++)
    row.appendChild(formatValue(data, properties[j]));

  row.appendChild(createActionLink('inspect', inspect.bind(null, data)));

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

  list.appendChild(row);
  return row;
}

function createActionLink(text, handler, opt_disabled) {
  var link = document.createElement('a');
  if (opt_disabled)
    link.classList.add('disabled');
  else
    link.classList.remove('disabled');

  link.setAttribute('href', '#');
  link.textContent = text;
  link.addEventListener('click', handler, true);
  return link;
}


function initPortForwarding() {
  $('port-forwarding-enable').addEventListener('change', enablePortForwarding);

  $('port-forwarding-config-open').addEventListener(
      'click', openPortForwardingConfig);
  $('port-forwarding-config-close').addEventListener(
      'click', closePortForwardingConfig);
  $('port-forwarding-config-done').addEventListener(
      'click', commitPortForwardingConfig);
}

function enablePortForwarding(event) {
  chrome.send('set-port-forwarding-enabled', [event.target.checked]);
}

function handleKey(event) {
  switch (event.keyCode) {
    case 13:  // Enter
      if (event.target.nodeName == 'INPUT') {
        var line = event.target.parentNode;
        if (!line.classList.contains('fresh') ||
            line.classList.contains('empty'))
          commitPortForwardingConfig();
        else
          commitFreshLineIfValid(true /* select new line */);
      } else {
        commitPortForwardingConfig();
      }
      break;

    case 27:
      closePortForwardingConfig();
      break;
  }
}

function openPortForwardingConfig() {
  loadPortForwardingConfig(window.portForwardingConfig);

  $('port-forwarding-overlay').classList.add('open');
  document.addEventListener('keyup', handleKey);

  var freshPort = document.querySelector('.fresh .port');
  if (freshPort)
    freshPort.focus();
  else
    $('port-forwarding-config-done').focus();
}

function closePortForwardingConfig() {
  $('port-forwarding-overlay').classList.remove('open');
  document.removeEventListener('keyup', handleKey);
}

function loadPortForwardingConfig(config) {
  var list = $('port-forwarding-config-list');
  list.textContent = '';
  for (var port in config)
    list.appendChild(createConfigLine(port, config[port]));
  list.appendChild(createEmptyConfigLine());
}

function commitPortForwardingConfig() {
  if (document.querySelector(
      '.port-forwarding-pair:not(.fresh) input.invalid'))
    return;

  if (document.querySelector(
      '.port-forwarding-pair.fresh:not(.empty) input.invalid'))
    return;

  closePortForwardingConfig();
  commitFreshLineIfValid();
  var lines = document.querySelectorAll('.port-forwarding-pair');
  var config = {};
  for (var i = 0; i != lines.length; i++) {
    var line = lines[i];
    var portInput = line.querySelector('.port:not(.invalid)');
    var locationInput = line.querySelector('.location:not(.invalid)');
    if (portInput && locationInput)
      config[portInput.value] = locationInput.value;
  }
  chrome.send('set-port-forwarding-config', [config]);
}

function updatePortForwardingEnabled(enabled) {
  var checkbox = $('port-forwarding-enable');
  checkbox.checked = !!enabled;
  checkbox.disabled = false;
}

function updatePortForwardingConfig(config) {
  window.portForwardingConfig = config;
  $('port-forwarding-config-open').disabled = !config;
}

function createConfigLine(port, location) {
  var line = document.createElement('div');
  line.className = 'port-forwarding-pair';

  var portInput = createConfigField(port, 'port', 'Port', validatePort);
  line.appendChild(portInput);

  var locationInput = createConfigField(
      location, 'location', 'IP address and port', validateLocation);
  line.appendChild(locationInput);
  locationInput.addEventListener('keydown', function(e) {
    if (e.keyIdentifier == 'U+0009' &&  // Tab
        !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey &&
        line.classList.contains('fresh') &&
        !line.classList.contains('empty')) {
      // Tabbing forward on the fresh line, try create a new empty one.
      commitFreshLineIfValid(true);
      e.preventDefault();
    }
  });

  var lineDelete = document.createElement('div');
  lineDelete.className = 'close-button';
  lineDelete.addEventListener('click', function() {
    var newSelection = line.nextElementSibling;
    line.parentNode.removeChild(line);
    selectLine(newSelection);
  });
  line.appendChild(lineDelete);

  line.addEventListener('click', selectLine.bind(null, line));
  line.addEventListener('focus', selectLine.bind(null, line));

  checkEmptyLine(line);

  return line;
}

function validatePort(input) {
  var match = input.value.match(/^(\d+)$/);
  if (!match)
    return false;
  var port = parseInt(match[1]);
  if (port < 5000 || 10000 < port)
    return false;

  var inputs = document.querySelectorAll('input.port:not(.invalid)');
  for (var i = 0; i != inputs.length; ++i) {
    if (inputs[i] == input)
      break;
    if (parseInt(inputs[i].value) == port)
      return false;
  }
  return true;
}

function validateLocation(input) {
  var match = input.value.match(/^([a-zA-Z0-9\.]+):(\d+)$/);
  if (!match)
    return false;
  var port = parseInt(match[2]);
  return port <= 10000;
}

function createEmptyConfigLine() {
  var line = createConfigLine('', '');
  line.classList.add('fresh');
  return line;
}

function createConfigField(value, className, hint, validate) {
  var input = document.createElement('input');
  input.className = className;
  input.type = 'text';
  input.placeholder = hint;
  input.value = value;

  function checkInput() {
    if (validate(input))
      input.classList.remove('invalid');
    else
      input.classList.add('invalid');
    if (input.parentNode)
      checkEmptyLine(input.parentNode);
  }
  checkInput();

  input.addEventListener('keyup', checkInput);
  input.addEventListener('focus', function() {
    selectLine(input.parentNode);
  });

  return input;
}

function checkEmptyLine(line) {
  var inputs = line.querySelectorAll('input');
  var empty = true;
  for (var i = 0; i != inputs.length; i++) {
    if (inputs[i].value != '')
      empty = false;
  }
  if (empty)
    line.classList.add('empty');
  else
    line.classList.remove('empty');
}

function selectLine(line) {
  if (line.classList.contains('selected'))
    return;
  unselectLine();
  line.classList.add('selected');
}

function unselectLine() {
  var line = document.querySelector('.port-forwarding-pair.selected');
  if (!line)
    return;
  line.classList.remove('selected');
  commitFreshLineIfValid();
}

function commitFreshLineIfValid(opt_selectNew) {
  var line = document.querySelector('.port-forwarding-pair.fresh');
  if (line.querySelector('.invalid'))
    return;
  line.classList.remove('fresh');
  var freshLine = createEmptyConfigLine();
  line.parentNode.appendChild(freshLine);
  if (opt_selectNew)
    freshLine.querySelector('.port').focus();
}

document.addEventListener('DOMContentLoaded', onload);
