<!--
// Copyright 2014 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.
-->
<import src="sky-binder.sky" as="binder" />
<import src="element-registry.sky" as="registry" />
<script>
function parseAttributeSpec(registration, definition) {
  var spec = definition.getAttribute('attributes');

  if (!spec)
    return;

  var attributeTokens = spec.split(',');

  for (var i = 0; i < attributeTokens.length; ++i) {
    var parts = attributeTokens[i].split(':');

    if (parts.length != 2) {
      console.error('Invalid attribute spec "' + spec + '", attributes must' +
          ' be {name}:{type}, where type is one of  boolean, number or' +
          ' string.');
      continue;
    }

    var name = parts[0].trim();
    var type = parts[1].trim();

    registration.defineAttribute(name, type);
  }
}

function parseEventHandlers(registration, definition) {
  var eventHandlers = [];
  var attributes = definition.getAttributes();

  for (var i = 0; i < attributes.length; i++) {
    var attr = attributes[i];
    var name = attr.name;
    var value = attr.value;

    if (name.startsWith('on-')) {
      registration.eventHandlers.set(name.substring(3), value);
    }
  }
}

class SkyElement extends HTMLElement {

  static register() {
    var definition = document.currentScript.parentNode;

    if (definition.localName !== 'sky-element') {
      throw new Error('register() calls must be inside a <sky-element>.');
    }

    var tagName = definition.getAttribute('name');
    if (!tagName) {
      throw new Error('<sky-element> must have a name.');
    }

    var registration = registry.registerElement(tagName);

    parseAttributeSpec(registration, definition);
    parseEventHandlers(registration, definition);

    registration.template = definition.querySelector('template');

    registration.synthesizeAttributes(this.prototype);

    return document.registerElement(tagName, {
      prototype: this.prototype,
    });
  }

  created() {
    // override
  }

  attached() {
    // override
  }

  detached() {
    // override
  }

  attributeChanged(attrName, oldValue, newValue) {
    // override
  }

  shadowRootReady() {
    // override
  }

  createdCallback() {
    this.isAttached = false;
    this.propertyBindings = null;
    this.dirtyPropertyBindings = null;
    this.created();

    Object.preventExtensions(this);

    // Invoke attributeChanged callback when element is first created too.
    var attributes = this.getAttributes();
    for (var i = 0; i < attributes.length; ++i) {
      var attribute = attributes[i];
      this.attributeChangedCallback(attribute.name, null, attribute.value);
    }

    var registration = registry.getRegistration(this.localName);
    registration.addInstanceEventListeners(this);
  }

  attachedCallback() {
    if (!this.shadowRoot) {
      var registration = registry.getRegistration(this.localName);
      if (registration.template) {
        var shadow = this.ensureShadowRoot();
        var instance = binder.createInstance(registration.template, this);
        shadow.appendChild(instance.fragment);
        this.shadowRootReady();
      }
    }
    this.attached();
    this.isAttached = true;
  }

  detachedCallback() {
    this.detached();
    this.isAttached = false;
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (registry.isExpandableAttribute(name))
      return;
    this.attributeChanged(name, oldValue, newValue);
    var registration = registry.getRegistration(this.localName);
    var converter = registration.attributes.get(name);
    if (converter) {
      this.notifyPropertyChanged(name, converter(oldValue),
          converter(newValue));
    }
  }

  notifyPropertyChanged(name, oldValue, newValue) {
    if (oldValue == newValue)
      return;
    var notifier = Object.getNotifier(this);
    notifier.notify({
      type: 'update',
      name: name,
      oldValue: oldValue,
    });
    var handler = this[name + 'Changed'];
    if (typeof handler == 'function')
      handler.call(this, oldValue, newValue);
    this.schedulePropertyBindingUpdate(name);
  }

  addPropertyBinding(name, binding) {
    if (!this.propertyBindings)
      this.propertyBindings = new Map();
    this.propertyBindings.set(name, binding);
  }

  getPropertyBinding(name) {
    if (!this.propertyBindings)
      return null;
    return this.propertyBindings.get(name);
  }

  schedulePropertyBindingUpdate(name) {
    if (!this.dirtyPropertyBindings) {
      this.dirtyPropertyBindings = new Set();
      Promise.resolve().then(this.updatePropertyBindings.bind(this));
    }
    this.dirtyPropertyBindings.add(name);
  }

  updatePropertyBindings() {
    for (var name of this.dirtyPropertyBindings) {
      var binding = this.getPropertyBinding(name);
      if (binding) {
        binding.setValue(this[name]);
        binding.discardChanges();
      }
    }
    this.dirtyPropertyBindings = null;
  }
};

module.exports = SkyElement;
</script>
