<!DOCTYPE html>
<!--
Copyright (c) 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.
-->
<link rel="import" href="/base/events.html">
<script>
'use strict';

tr.exportTo('tr.b', function() {
  /**
   * Fires a property change event on the target.
   * @param {EventTarget} target The target to dispatch the event on.
   * @param {string} propertyName The name of the property that changed.
   * @param {*} newValue The new value for the property.
   * @param {*} oldValue The old value for the property.
   */
  function dispatchPropertyChange(target, propertyName, newValue, oldValue,
                                  opt_bubbles, opt_cancelable) {
    var e = new tr.b.Event(propertyName + 'Change',
                           opt_bubbles, opt_cancelable);
    e.propertyName = propertyName;
    e.newValue = newValue;
    e.oldValue = oldValue;

    var error;
    e.throwError = function(err) {  // workaround CR 239648
      error = err;
    };

    target.dispatchEvent(e);
    if (error)
      throw error;
  }

  function setPropertyAndDispatchChange(obj, propertyName, newValue) {
    var privateName = propertyName + '_';
    var oldValue = obj[propertyName];
    obj[privateName] = newValue;
    if (oldValue !== newValue)
      tr.b.dispatchPropertyChange(obj, propertyName,
          newValue, oldValue, true, false);
  }

  /**
   * Converts a camelCase javascript property name to a hyphenated-lower-case
   * attribute name.
   * @param {string} jsName The javascript camelCase property name.
   * @return {string} The equivalent hyphenated-lower-case attribute name.
   */
  function getAttributeName(jsName) {
    return jsName.replace(/([A-Z])/g, '-$1').toLowerCase();
  }

  /* Creates a private name unlikely to collide with object properties names
   * @param {string} name The defineProperty name
   * @return {string} an obfuscated name
   */
  function getPrivateName(name) {
    return name + '_tr_';
  }

  /**
   * The kind of property to define in {@code defineProperty}.
   * @enum {number}
   * @const
   */
  var PropertyKind = {
    /**
     * Plain old JS property where the backing data is stored as a 'private'
     * field on the object.
     */
    JS: 'js',

    /**
     * The property backing data is stored as an attribute on an element.
     */
    ATTR: 'attr',

    /**
     * The property backing data is stored as an attribute on an element. If the
     * element has the attribute then the value is true.
     */
    BOOL_ATTR: 'boolAttr'
  };

  /**
   * Helper function for defineProperty that returns the getter to use for the
   * property.
   * @param {string} name The name of the property.
   * @param {tr.b.PropertyKind} kind The kind of the property.
   * @return {function():*} The getter for the property.
   */
  function getGetter(name, kind) {
    switch (kind) {
      case PropertyKind.JS:
        var privateName = getPrivateName(name);
        return function() {
          return this[privateName];
        };
      case PropertyKind.ATTR:
        var attributeName = getAttributeName(name);
        return function() {
          return this.getAttribute(attributeName);
        };
      case PropertyKind.BOOL_ATTR:
        var attributeName = getAttributeName(name);
        return function() {
          return this.hasAttribute(attributeName);
        };
    }
  }

  /**
   * Helper function for defineProperty that returns the setter of the right
   * kind.
   * @param {string} name The name of the property we are defining the setter
   *     for.
   * @param {tr.b.PropertyKind} kind The kind of property we are getting the
   *     setter for.
   * @param {function(*):void=} opt_setHook A function to run after the property
   *     is set, but before the propertyChange event is fired.
   * @param {boolean=} opt_bubbles Whether the event bubbles or not.
   * @param {boolean=} opt_cancelable Whether the default action of the event
   *     can be prevented.
   * @return {function(*):void} The function to use as a setter.
   */
  function getSetter(name, kind, opt_setHook, opt_bubbles, opt_cancelable) {
    switch (kind) {
      case PropertyKind.JS:
        var privateName = getPrivateName(name);
        return function(value) {
          var oldValue = this[privateName];
          if (value !== oldValue) {
            this[privateName] = value;
            if (opt_setHook)
              opt_setHook.call(this, value, oldValue);
            dispatchPropertyChange(this, name, value, oldValue,
                opt_bubbles, opt_cancelable);
          }
        };

      case PropertyKind.ATTR:
        var attributeName = getAttributeName(name);
        return function(value) {
          var oldValue = this.getAttribute(attributeName);
          if (value !== oldValue) {
            if (value == undefined)
              this.removeAttribute(attributeName);
            else
              this.setAttribute(attributeName, value);
            if (opt_setHook)
              opt_setHook.call(this, value, oldValue);
            dispatchPropertyChange(this, name, value, oldValue,
                opt_bubbles, opt_cancelable);
          }
        };

      case PropertyKind.BOOL_ATTR:
        var attributeName = getAttributeName(name);
        return function(value) {
          var oldValue = (this.getAttribute(attributeName) === name);
          if (value !== oldValue) {
            if (value)
              this.setAttribute(attributeName, name);
            else
              this.removeAttribute(attributeName);
            if (opt_setHook)
              opt_setHook.call(this, value, oldValue);
            dispatchPropertyChange(this, name, value, oldValue,
                opt_bubbles, opt_cancelable);
          }
        };
    }
  }

  /**
   * Defines a property on an object. When the setter changes the value a
   * property change event with the type {@code name + 'Change'} is fired.
   * @param {!Object} obj The object to define the property for.
   * @param {string} name The name of the property.
   * @param {tr.b.PropertyKind=} opt_kind What kind of underlying storage to
   * use.
   * @param {function(*):void=} opt_setHook A function to run after the
   *     property is set, but before the propertyChange event is fired.
   * @param {boolean=} opt_bubbles Whether the event bubbles or not.
   * @param {boolean=} opt_cancelable Whether the default action of the event
   *     can be prevented.
   */
  function defineProperty(obj, name, opt_kind, opt_setHook,
                          opt_bubbles, opt_cancelable) {
    console.error("Don't use tr.b.defineProperty");
    if (typeof obj == 'function')
      obj = obj.prototype;

    var kind = opt_kind || PropertyKind.JS;

    if (!obj.__lookupGetter__(name))
      obj.__defineGetter__(name, getGetter(name, kind));

    if (!obj.__lookupSetter__(name))
      obj.__defineSetter__(name, getSetter(name, kind, opt_setHook,
          opt_bubbles, opt_cancelable));
  }

  return {
    PropertyKind: PropertyKind,
    defineProperty: defineProperty,
    dispatchPropertyChange: dispatchPropertyChange,
    setPropertyAndDispatchChange: setPropertyAndDispatchChange
  };
});
</script>
