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

// TODO(jmesserly): more commentary here.
/**
 * This library provides access to Model-Driven-Views APIs on HTML elements.
 * More information can be found at: <https://github.com/Polymer/mdv>.
 */
library mdv;

import 'dart:async';
import 'dart:collection';
import 'dart:html';
import 'package:observe/observe.dart';

// TODO(jmesserly): get this from somewhere else. See http://dartbug.com/4161.
import 'package:serialization/src/serialization_helpers.dart' show IdentityMap;

import 'src/list_diff.dart' show calculateSplices, ListChangeDelta;

part 'src/element.dart';
part 'src/input_bindings.dart';
part 'src/input_element.dart';
part 'src/node.dart';
part 'src/select_element.dart';
part 'src/template.dart';
part 'src/template_iterator.dart';
part 'src/text.dart';
part 'src/text_area_element.dart';

/** Initialize the Model-Driven Views polyfill. */
void initialize() {
  TemplateElement.mdvPackage = _mdv;
}


typedef DocumentFragmentCreated(DocumentFragment fragment);

// TODO(jmesserly): ideally this would be a stream, but they don't allow
// reentrancy.
Set<DocumentFragmentCreated> _instanceCreated;

/**
 * *Warning*: This is an implementation helper for Model-Driven Views and
 * should not be used in your code.
 *
 * This event is fired whenever a template is instantiated via
 * [Element.createInstance].
 */
// TODO(rafaelw): This is a hack, and is neccesary for the polyfill
// because custom elements are not upgraded during clone()
// TODO(jmesserly): polymer removed this in:
// https://github.com/Polymer/platform/commit/344ffeaae475babb529403f6608588a0fc73f4e7
Set<DocumentFragmentCreated> get instanceCreated {
  if (_instanceCreated == null) {
    _instanceCreated = new Set<DocumentFragmentCreated>();
  }
  return _instanceCreated;
}


// TODO(jmesserly): investigate if expandos give us enough performance.

// The expando for storing our MDV wrappers.
//
// In general, we need state associated with the nodes. Rather than having a
// bunch of individual expandos, we keep one per node.
//
// Aside from the potentially helping performance, it also keeps things simpler
// if we decide to integrate MDV into the DOM later, and means less code needs
// to worry about expandos.
final Expando _mdvExpando = new Expando('mdv');

_mdv(node) {
  var wrapper = _mdvExpando[node];
  if (wrapper != null) return wrapper;

  if (node is InputElement) {
    wrapper = new _InputElementExtension(node);
  } else if (node is SelectElement) {
    wrapper = new _SelectElementExtension(node);
  } else if (node is TextAreaElement) {
    wrapper = new _TextAreaElementExtension(node);
  } else if (node is Element) {
    if (node.isTemplate) {
      wrapper = new _TemplateExtension(node);
    } else {
      wrapper = new _ElementExtension(node);
    }
  } else if (node is Text) {
    wrapper = new _TextExtension(node);
  } else if (node is Node) {
    wrapper = new _NodeExtension(node);
  } else {
    // TODO(jmesserly): this happens for things like CompoundBinding.
    wrapper = node;
  }

  _mdvExpando[node] = wrapper;
  return wrapper;
}
