// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of html;

class _ModelTreeObserver {
  static bool _initialized = false;

  /**
   * Start an observer watching the document for tree changes to automatically
   * propagate model changes.
   *
   * Currently this does not support propagation through Shadow DOMs.
   */
  static void initialize() {
    if (!_initialized) {
      _initialized = true;

      if (MutationObserver.supported) {
        var observer = new MutationObserver(_processTreeChange);
        observer.observe(document, childList: true, subtree: true);
      } else {
        document.on['DOMNodeInserted'].listen(_handleNodeInserted);
        document.on['DOMNodeRemoved'].listen(_handleNodeRemoved);
      }
    }
  }

  static void _processTreeChange(List<MutationRecord> mutations,
      MutationObserver observer) {
    for (var record in mutations) {
      for (var node in record.addedNodes) {
        // When nodes enter the document we need to make sure that all of the
        // models are properly propagated through the entire sub-tree.
        propagateModel(node, _calculatedModel(node), true);
      }
      for (var node in record.removedNodes) {
        propagateModel(node, _calculatedModel(node), false);
      }
    }
  }

  static void _handleNodeInserted(MutationEvent e) {
    var node = e.target;
    window.setImmediate(() {
      propagateModel(node, _calculatedModel(node), true);
    });
  }

  static void _handleNodeRemoved(MutationEvent e) {
    var node = e.target;
    window.setImmediate(() {
      propagateModel(node, _calculatedModel(node), false);
    });
  }

  /**
   * Figures out what the model should be for a node, avoiding any cached
   * model values.
   */
  static _calculatedModel(node) {
    if (node._hasLocalModel == true) {
      return node._model;
    } else if (node.parentNode != null) {
      return node.parentNode._model;
    }
    return null;
  }

  /**
   * Pushes model changes down through the tree.
   *
   * Set fullTree to true if the state of the tree is unknown and model changes
   * should be propagated through the entire tree.
   */
  static void propagateModel(Node node, model, bool fullTree) {
    // Calling into user code with the != call could generate exceptions.
    // Catch and report them a global exceptions.
    try {
      if (node._hasLocalModel != true && node._model != model &&
          node._modelChangedStream != null) {
        node._model = model;
        node._modelChangedStream.add(node);
      }
    } on AsyncError catch (e) {
      e.throwDelayed();
    } catch (e, s) {
      new AsyncError(e, s).throwDelayed();
    }
    for (var child = node.$dom_firstChild; child != null;
        child = child.nextNode) {
      if (child._hasLocalModel != true) {
        propagateModel(child, model, fullTree);
      } else if (fullTree) {
        propagateModel(child, child._model, true);
      }
    }
  }
}
