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

var chrome = chrome || {};

/**
 * Organizes all signin event listeners and asynchronous requests.
 * This object has no public constructor.
 * @type {Object}
 */
chrome.signin = chrome.signin || {};

(function() {

// TODO(vishwath): This function is identical to the one in sync_internals.js
// Merge both if possible.
// Accepts a DOM node and sets its highlighted attribute oldVal != newVal
function highlightIfChanged(node, oldVal, newVal) {
  var oldStr = oldVal.toString();
  var newStr = newVal.toString();
  if (oldStr != '' && oldStr != newStr) {
    // Note the addListener function does not end up creating duplicate
    // listeners.  There can be only one listener per event at a time.
    // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
    node.addEventListener('webkitAnimationEnd',
                          function() { this.removeAttribute('highlighted'); },
                          false);
    node.setAttribute('highlighted');
  }
}

// Wraps highlightIfChanged for multiple conditions.
function highlightIfAnyChanged(node, oldToNewValList) {
  for (var i = 0; i < oldToNewValList.length; i++)
    highlightIfChanged(node, oldToNewValList[i][0], oldToNewValList[i][1]);
}

function setClassFromValue(value) {
  if (value == 0)
    return 'zero';
  if (value == 'Successful')
    return 'ok';

  return '';
}

// Allow signin_index.html to access the functions above using the
// corresponding chrome.signin.<method> calls.
chrome.signin['highlightIfChanged'] = highlightIfChanged;
chrome.signin['highlightIfAnyChanged'] = highlightIfAnyChanged;
chrome.signin['setClassFromValue'] = setClassFromValue;

// Simplified Event class, borrowed (ok, stolen) from chrome_sync.js
function Event() {
  this.listeners_ = [];
}

// Add a new listener to the list.
Event.prototype.addListener = function(listener) {
  this.listeners_.push(listener);
};

// Remove a listener from the list.
Event.prototype.removeListener = function(listener) {
  var i = this.findListener_(listener);
  if (i == -1) {
    return;
  }
  this.listeners_.splice(i, 1);
};

// Check if the listener has already been registered so we can prevent
// duplicate registrations.
Event.prototype.hasListener = function(listener) {
  return this.findListener_(listener) > -1;
};

// Are there any listeners registered yet?
Event.prototype.hasListeners = function() {
  return this.listeners_.length > 0;
};

// Returns the index of the given listener, or -1 if not found.
Event.prototype.findListener_ = function(listener) {
  for (var i = 0; i < this.listeners_.length; i++) {
    if (this.listeners_[i] == listener) {
      return i;
    }
  }
  return -1;
};

// Fires the event.  Called by the actual event callback.  Any
// exceptions thrown by a listener are caught and logged.
Event.prototype.fire = function() {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < this.listeners_.length; i++) {
    try {
      this.listeners_[i].apply(null, args);
    } catch (e) {
      if (e instanceof Error) {
        // Non-standard, but useful.
        console.error(e.stack);
      } else {
        console.error(e);
      }
    }
  }
};

// These are the events that will be registered.
chrome.signin.events = {
  'signin_manager': [
    'onSigninInfoChanged'
 ]
};

for (var eventType in chrome.signin.events) {
  var events = chrome.signin.events[eventType];
  for (var i = 0; i < events.length; ++i) {
    var event = events[i];
    chrome.signin[event] = new Event();
  }
}

// Creates functions that call into SigninInternalsUI.
function makeSigninFunction(name) {
  var callbacks = [];

  // Calls the function, assuming the last argument is a callback to be
  // called with the return value.
  var fn = function() {
    var args = Array.prototype.slice.call(arguments);
    callbacks.push(args.pop());
    chrome.send(name, args);
  };

  // Handle a reply, assuming that messages are processed in FIFO order.
  // Called by SigninInternalsUI::HandleJsReply().
  fn.handleReply = function() {
    var args = Array.prototype.slice.call(arguments);
    // Remove the callback before we call it since the callback may
    // throw.
    var callback = callbacks.shift();
    callback.apply(null, args);
  };

  return fn;
}

// The list of js functions that call into SigninInternalsUI
var signinFunctions = [
  // Signin Summary Info
  'getSigninInfo'
];

for (var i = 0; i < signinFunctions.length; ++i) {
  var signinFunction = signinFunctions[i];
  chrome.signin[signinFunction] = makeSigninFunction(signinFunction);
}

chrome.signin.internalsInfo = {};

// Replace the displayed values with the latest fetched ones.
function refreshSigninInfo(signinInfo) {
  chrome.signin.internalsInfo = signinInfo;
  var internalsInfoDiv = $('signin-info');
  jstProcess(new JsEvalContext(signinInfo), internalsInfoDiv);
  var tokenInfoDiv = $('token-info');
  jstProcess(new JsEvalContext(signinInfo), tokenInfoDiv);
}

// On load, do an initial refresh and register refreshSigninInfo to be invoked
// whenever we get new signin information from SigninInternalsUI.
function onLoad() {
  chrome.signin.getSigninInfo(refreshSigninInfo);

  chrome.signin.onSigninInfoChanged.addListener(function(info) {
    refreshSigninInfo(info);
  });
}

document.addEventListener('DOMContentLoaded', onLoad, false);
})();
