// 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 mdv;

/** Extensions to [Element]s that behave as templates. */
class _TemplateExtension extends _ElementExtension {
  var _model;
  BindingDelegate _bindingDelegate;
  _TemplateIterator _templateIterator;
  bool _scheduled = false;

  _TemplateExtension(Element node) : super(node);

  Element get node => super.node;

  NodeBinding createBinding(String name, model, String path) {
    switch (name) {
      case 'bind':
      case 'repeat':
      case 'if':
        if (_templateIterator == null) {
          _templateIterator = new _TemplateIterator(node);
        }
        // TODO(jmesserly): why do we do this here and nowhere else?
        if (path == null) path = '';
        return new _TemplateBinding(node, name, model, path);
      default:
        return super.createBinding(name, model, path);
    }
  }

  /**
   * Creates an instance of the template.
   */
  DocumentFragment createInstance(model, BindingDelegate delegate) {
    var template = node.ref;
    if (template == null) template = node;

    var instance = _createDeepCloneAndDecorateTemplates(
        template.ref.content, delegate);

    if (_instanceCreated != null) {
      for (var callback in _instanceCreated) callback(instance);
    }

    _addBindings(instance, model, delegate);
    _addTemplateInstanceRecord(instance, model);
    return instance;
  }

  /**
   * The data model which is inherited through the tree.
   */
  get model => _model;

  void set model(value) {
    _model = value;
    _ensureSetModelScheduled();
  }

  /**
   * The binding delegate which is inherited through the tree. It can be used
   * to configure custom syntax for `{{bindings}}` inside this template.
   */
  BindingDelegate get bindingDelegate => _bindingDelegate;

  void set bindingDelegate(BindingDelegate value) {
    _bindingDelegate = value;
    _ensureSetModelScheduled();
  }

  _ensureSetModelScheduled() {
    if (_scheduled) return;
    _scheduled = true;
    runAsync(_setModel);
  }

  void _setModel() {
    _scheduled = false;
    _addBindings(node, _model, _bindingDelegate);
  }
}

class _TemplateBinding extends NodeBinding {
  // TODO(jmesserly): MDV uses TemplateIterator as the node, see:
  // https://github.com/Polymer/mdv/issues/127
  _TemplateBinding(node, name, model, path)
      : super(node, name, model, path) {
    _mdv(node)._templateIterator.inputs.bind(property, model, path);
  }

  // These are no-ops because we don't use the underlying PathObserver.
  void _observePath() {}
  void boundValueChanged(newValue) {}

  void close() {
    if (closed) return;
    var templateIterator = _mdv(node)._templateIterator;
    if (templateIterator != null) templateIterator.inputs.unbind(property);
    super.close();
  }
}
