// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

lib.rtdep('lib.colors', 'hterm.PreferenceManager');

// CSP means that we can't kick off the initialization from the html file,
// so we do it like this instead.
window.onload = function() {
  function setupPreferences() {
    var prefsEditor = new nassh.PreferencesEditor();

    // Useful for console debugging.
    window.term_ = prefsEditor;

    // Set up labels.
    document.getElementById('label_header').innerText =
        nassh.msg('PREFERENCES_HEADER');
    document.getElementById('label_profile').innerText =
        nassh.msg('TERMINAL_PROFILE_LABEL');

    // Set up reset button.
    document.getElementById('reset').onclick = function() {
        prefsEditor.resetAll();
      };

    // Set up profile selection field.
    var profile = document.getElementById('profile');
    profile.oninput = function() {
        nassh.PreferencesEditor.debounce(profile, function(input) {
            prefsEditor.notify(nassh.msg('LOADING_LABEL'), 500);
            if (input.value.length)
              prefsEditor.selectProfile(input.value);
          });
      };
    profile.value = nassh.msg('FIELD_TERMINAL_PROFILE_PLACEHOLDER');

    // Allow people to reset individual fields by pressing escape.
    document.onkeyup = function(e) {
        if (document.activeElement.name == 'settings' && e.keyCode == 27)
          prefsEditor.reset(document.activeElement);
      };
  }

  lib.init(setupPreferences);
};

/**
 * Class for editing hterm profiles.
 *
 * @param {string} opt_profileId Optional profile name to read settings from;
 *     defaults to the "default" profile.
 */
nassh.PreferencesEditor = function(opt_profileId) {
  this.selectProfile(opt_profileId || 'default');
};

/**
 * Debounce action on input element.
 *
 * This way people can type up a setting before seeing an update.
 * Useful with settings such as font names or sizes.
 *
 * @param {object} input An HTML input element to pass down to callback.
 * @param {function} callback Function to call after debouncing while passing
 *     it the input object.
 * @param {integer} opt_timeout Optional how long to debounce.
 */
nassh.PreferencesEditor.debounce = function(input, callback, opt_timeout) {
  clearTimeout(input.timeout);
  input.timeout = setTimeout(function() {
      callback(input);
      input.timeout = null;
    }, opt_timeout || 500);
};

/**
 * Select a profile for editing.
 *
 * This will load the settings and update the HTML display.
 *
 * @param {string} profileId The profile name to read settings from.
 */
nassh.PreferencesEditor.prototype.selectProfile = function(profileId) {
  var prefsEditor = this;
  var prefs = new hterm.PreferenceManager(profileId);
  this.prefs_ = prefs;
  prefs.readStorage(function() {
      prefs.notifyAll();
      prefsEditor.syncPage();
    });
};

/**
 * Save the HTML color state to the preferences.
 *
 * Since the HTML5 color picker does not support alpha, we have to split
 * the rgb and alpha information across two input objects.
 *
 * @param {string} key The HTML input.id to use to locate the color input
 *     object.  By appending ':alpha' to the key name, we can also locate
 *     the range input object.
 */
nassh.PreferencesEditor.prototype.colorSave = function(key) {
  var cinput = document.getElementById(key);
  var ainput = document.getElementById(key + ':alpha');
  var rgb = lib.colors.hexToRGB(cinput.value);
  this.prefs_.set(key, lib.colors.setAlpha(rgb, ainput.value / 100));
};

/**
 * Save the HTML state to the preferences.
 *
 * @param {object} input An HTML input element to update the corresponding
 *     preferences key.  Uses input.id to locate relevant preference.
 */
nassh.PreferencesEditor.prototype.save = function(input) {
  // Skip ones we don't yet handle.
  if (input.disabled)
    return;

  var keys = input.id.split(':');
  var key = keys[0];
  var prefs = this.prefs_;
  switch (input.type) {
    case 'checkbox':
      if (input.indeterminate) {
        prefs.set(key, null);
      } else {
        prefs.set(key, input.checked);
      }
      break;
    case 'number':
      prefs.set(key, Number(input.value));
      break;
    case 'range':
    case 'color':
      this.colorSave(key);
      break;
    case 'text':
    case 'textarea':
      var value = input.value;
      if (input.data == 'JSON') {
        try {
          value = JSON.parse(value);
        } catch (err) {
          this.notify(nassh.msg('JSON_PARSE_ERROR', key) + ': ' + err, 5000);
          value = prefs.get(key);
        }
      }
      prefs.set(key, value);
      break;
  }
};

/**
 * Sync the preferences state to the HTML color objects.
 *
 * @param {string} key The HTML input.id to use to locate the color input
 *     object.  By appending ':alpha' to the key name, we can also locate
 *     the range input object.
 * @param {object} pref The preference object to get the current state from.
 * @return {string} The rgba color information.
 */
nassh.PreferencesEditor.prototype.colorSync = function(key, pref) {
  var cinput = document.getElementById(key);
  var ainput = document.getElementById(key + ':alpha');

  var rgba = lib.colors.normalizeCSS(pref);

  cinput.value = lib.colors.rgbToHex(rgba);
  if (rgba) {
    ainput.value = lib.colors.crackRGB(rgba)[3] * 100;
  } else {
    ainput.value = ainput.max;
  }

  return rgba;
};

/**
 * Sync the preferences state to the HTML object.
 *
 * @param {Object} input An HTML input element to update the corresponding
 *     preferences key.  Uses input.id to locate relevant preference.
 */
nassh.PreferencesEditor.prototype.sync = function(input) {
  var keys = input.id.split(':');
  var key = keys[0];
  var pref = this.prefs_.get(key);

  if (input.type == 'color' || input.type == 'range') {
    var rgba = this.colorSync(key, pref);
  } else if (input.data == 'JSON') {
    input.value = JSON.stringify(pref);
  } else {
    input.value = pref;
  }
  switch (typeof pref) {
    case 'boolean':
      input.checked = pref;
      break;
  }

  // Now update the page to give more immediate feedback as to what
  // the preferences will look like in the terminal.
  var style = window.document.body.style;
  switch (key) {
    case 'background-color':
      style.backgroundColor = rgba;
      break;
    case 'background-image':
      style.backgroundImage = input.value;
      break;
    case 'background-size':
      style.backgroundSize = input.value;
      break;
    case 'background-position':
      style.backgroundPosition = input.value;
      break;
    case 'enable-bold':
      style.fontWeight = (input.checked && !input.indeterminate) ? 'bold' : '';
      break;
    case 'font-family':
      style.fontFamily = input.value;
      break;
    case 'font-size':
      style.fontSize = input.value + 'px';
      break;
    case 'font-smoothing':
      style.webkitFontSmoothing = input.value;
      break;
    case 'foreground-color':
      style.color = rgba;
      break;
    case 'scrollbar-visible':
      style.overflowY = input.checked ? 'scroll' : 'auto';
      break;
  }
};

/**
 * Update preferences from HTML input objects when the input changes.
 *
 * This is a helper that should be used in an event handler (e.g. onchange).
 * Should work with any input type.
 *
 * @param {Object} input An HTML input element to update from.
 */
nassh.PreferencesEditor.prototype.onInputChange = function(input) {
  this.save(input);
  this.sync(input);
};

/**
 * Update preferences from HTML checkbox input objects when the input changes.
 *
 * This is a helper that should be used in an event handler (e.g. onchange).
 * Used with checkboxes for tristate values (true/false/null).
 *
 * @param {Object} input An HTML checkbox input element to update from.
 */
nassh.PreferencesEditor.prototype.onInputChangeTristate = function(input) {
  switch (input.data % 3) {
    case 0: // unchecked -> indeterminate
       input.indeterminate = true;
       break;
    case 1: // indeterminate -> checked
       input.checked = true;
       break;
    case 2: // checked -> unchecked
       input.checked = false;
       break;
  }
  ++input.data;
  this.onInputChange(input);
};

/**
 * Update the preferences page to reflect current preference object.
 *
 * Will basically rewrite the displayed HTML code on the fly.
 */
nassh.PreferencesEditor.prototype.syncPage = function() {
  var prefsEditor = this;

  var tbl = document.getElementById('settings');

  // Clear out existing settings table.
  while (tbl.hasChildNodes()) {
    tbl.removeChild(tbl.firstChild);
  }

  // Create the table of settings.
  var typeMap = {
    'boolean': 'checkbox',
    'number': 'number',
    'object': 'text',
    'string': 'text',
  };
  for (var key in this.prefs_.prefRecords_) {
    var input = document.createElement('input');
    var pref = this.prefs_.get(key);

    var onchangeCursorReset = function() {
        nassh.PreferencesEditor.debounce(this, function(input) {
            // Chrome has a bug where it resets cursor position on us when
            // we debounce the input.  So manually save & restore cursor.
            var i = input.selectionStart;
            prefsEditor.onInputChange(input);
            if (document.activeElement === input)
              input.setSelectionRange(i, i);
          });
      };
    var onchange = function() {
        nassh.PreferencesEditor.debounce(this, function(input) {
            prefsEditor.onInputChange(input);
          });
      };
    var oninput = null;

    var keyParts = key.split('-')
    if (key == 'enable-bold' ||
        key == 'mouse-paste-button') {
      input.indeterminate = true;
      input.type = 'checkbox';
      input.data = 1;
      onchange = function() {
          prefsEditor.onInputChangeTristate(this);
        };
    } else if (keyParts[keyParts.length - 1] == 'color') {
      input.type = 'color';
    } else {
      var type = typeof pref;
      switch (type) {
        case 'object':
          // We'll use JSON to go between object/user text.
          input = document.createElement('textarea');
          input.data = 'JSON';
          onchange = onchangeCursorReset;
          break;
        case 'string':
          // Save simple strings immediately.
          oninput = onchangeCursorReset;
          onchange = null;
          break;
      }
      input.type = typeMap[type];
    }

    input.name = 'settings';
    input.id = key;
    input.onchange = onchange;
    input.oninput = oninput;

    var row = tbl.insertRow(-1);
    row.insertCell(0).innerText = key;
    var cell = row.insertCell(1);
    cell.appendChild(input);

    if (input.type == 'color') {
      // Since the HTML5 color picker does not support alpha,
      // we have to create a dedicated slider for it.
      var ainput = document.createElement('input');
      ainput.type = 'range';
      ainput.id = key + ':alpha';
      ainput.min = '0';
      ainput.max = '100';
      ainput.name = 'settings';
      ainput.onchange = onchange;
      ainput.oninput = oninput;
      cell.appendChild(ainput);
    }

    this.sync(input);
  }
};

/**
 * Reset all preferences to their default state and update the HTML objects.
 */
nassh.PreferencesEditor.prototype.resetAll = function() {
  var settings = document.getElementsByName('settings');

  this.prefs_.resetAll();
  for (var i = 0; i < settings.length; ++i)
    this.sync(settings[i]);
  this.notify(nassh.msg('PREFERENCES_RESET'));
};

/**
 * Reset specified preference to its default state.
 *
 * @param {object} input An HTML input element to reset.
 */
nassh.PreferencesEditor.prototype.reset = function(input) {
  var keys = input.id.split(':');
  var key = keys[0];
  this.prefs_.reset(key);
  this.sync(input);
};

/**
 * Display a message to the user.
 *
 * @param {string} msg The string to show to the user.
 * @param {integer} opt_timeout Optional how long to show the message.
 */
nassh.PreferencesEditor.prototype.notify = function(msg, opt_timeout) {
  // Update status to let user know options were updated.
  clearTimeout(this.notifyTimeout_);
  var status = document.getElementById('label_status');
  status.innerText = msg;
  this.notifyTimeout_ = setTimeout(function() {
      status.innerHTML = '&nbsp;';
    }, opt_timeout || 1000);
};
