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

library polymer.polymer_element;

import 'dart:async';
import 'dart:html';
import 'dart:mirrors';
import 'dart:js' as js;

import 'package:custom_element/custom_element.dart';
import 'package:mdv/mdv.dart' show NodeBinding;
import 'package:observe/observe.dart';
import 'package:observe/src/microtask.dart';
import 'package:polymer_expressions/polymer_expressions.dart';

import 'src/utils.dart' show toCamelCase, toHyphenedName;

/**
 * Registers a [PolymerElement]. This is similar to [registerCustomElement]
 * but it is designed to work with the `<element>` element and adds additional
 * features.
 */
void registerPolymerElement(String localName, PolymerElement create()) {
  registerCustomElement(localName, () => create().._initialize(localName));
}

/**
 * *Warning*: many features of this class are not fully implemented.
 *
 * The base class for Polymer elements. It provides convience features on top
 * of the custom elements web standard.
 *
 * Currently it supports publishing attributes via:
 *
 *     <element name="..." attributes="foo, bar, baz">
 *
 * Any attribute published this way can be used in a data binding expression,
 * and it should contain a corresponding DOM field.
 *
 * *Warning*: due to dart2js mirror limititations, the mapping from HTML
 * attribute to element property is a conversion from `dash-separated-words`
 * to camelCase, rather than searching for a property with the same name.
 */
// TODO(jmesserly): fix the dash-separated-words issue. Polymer uses lowercase.
class PolymerElement extends CustomElement with _EventsMixin {
  // This is a partial port of:
  // https://github.com/Polymer/polymer/blob/stable/src/attrs.js
  // https://github.com/Polymer/polymer/blob/stable/src/bindProperties.js
  // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
  // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
  // TODO(jmesserly): we still need to port more of the functionality

  /// The one syntax to rule them all.
  static BindingDelegate _polymerSyntax = new PolymerExpressions();
  // TODO(sigmund): delete. The next line is only added to avoid warnings from
  // the analyzer (see http://dartbug.com/11672)
  Element get host => super.host;

  bool get applyAuthorStyles => false;
  bool get resetStyleInheritance => false;

  /**
   * The declaration of this polymer-element, used to extract template contents
   * and other information.
   */
  static Map<String, Element> _declarations = {};
  static Element getDeclaration(String localName) {
    if (localName == null) return null;
    var element = _declarations[localName];
    if (element == null) {
      element = document.query('polymer-element[name="$localName"]');
      _declarations[localName] = element;
    }
    return element;
  }

  Map<String, PathObserver> _publishedAttrs;
  Map<String, StreamSubscription> _bindings;
  final List<String> _localNames = [];

  void _initialize(String localName) {
    if (localName == null) return;

    var declaration = getDeclaration(localName);
    if (declaration == null) return;

    var extendee = declaration.attributes['extends'];
    if (extendee != null) {
      // Skip normal tags, only initialize parent custom elements.
      if (extendee.contains('-')) _initialize(extendee);
    }

    _parseHostEvents(declaration);
    _parseLocalEvents(declaration);
    _publishAttributes(declaration);

    var templateContent = declaration.query('template').content;
    _shimStyling(templateContent, localName);

    _localNames.add(localName);
  }

  void _publishAttributes(elementElement) {
    _bindings = {};
    _publishedAttrs = {};

    var attrs = elementElement.attributes['attributes'];
    if (attrs != null) {
      // attributes='a b c' or attributes='a,b,c'
      for (var name in attrs.split(attrs.contains(',') ? ',' : ' ')) {
        name = name.trim();

        // TODO(jmesserly): PathObserver is overkill here; it helps avoid
        // "new Symbol" and other mirrors-related warnings.
        _publishedAttrs[name] = new PathObserver(this, toCamelCase(name));
      }
    }
  }

  void created() {
    // TODO(jmesserly): this breaks until we get some kind of type conversion.
    // _publishedAttrs.forEach((name, propObserver) {
    // var value = attributes[name];
    //   if (value != null) propObserver.value = value;
    // });
    _initShadowRoot();
    _addHostListeners();
  }

  /**
   * Creates the document fragment to use for each instance of the custom
   * element, given the `<template>` node. By default this is equivalent to:
   *
   *     template.createInstance(this, polymerSyntax);
   *
   * Where polymerSyntax is a singleton `PolymerExpressions` instance from the
   * [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
   * package.
   *
   * You can override this method to change the instantiation behavior of the
   * template, for example to use a different data-binding syntax.
   */
  DocumentFragment instanceTemplate(Element template) =>
      template.createInstance(this, _polymerSyntax);

  void _initShadowRoot() {
    for (var localName in _localNames) {
      var declaration = getDeclaration(localName);
      var root = createShadowRoot(localName);
      _addInstanceListeners(root, localName);

      root.applyAuthorStyles = applyAuthorStyles;
      root.resetStyleInheritance = resetStyleInheritance;

      var templateNode = declaration.query('template');
      if (templateNode == null) return;

      // Create the contents of the element's ShadowRoot, and add them.
      root.nodes.add(instanceTemplate(templateNode));
    }
  }

  NodeBinding createBinding(String name, model, String path) {
    var propObserver = _publishedAttrs[name];
    if (propObserver != null) {
      return new _PolymerBinding(this, name, model, path, propObserver);
    }
    return super.createBinding(name, model, path);
  }

  /**
   * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
   */
  void _shimStyling(DocumentFragment template, String localName) {
    if (js.context == null) return;

    var platform = js.context['Platform'];
    if (platform == null) return;

    var style = template.query('style');
    if (style == null) return;

    var shadowCss = platform['ShadowCSS'];
    if (shadowCss == null) return;

    // TODO(terry): Remove calls to shimShadowDOMStyling2 and replace with
    //              shimShadowDOMStyling when we support unwrapping dart:html
    //              Element to a JS DOM node.
    var shimShadowDOMStyling2 = shadowCss['shimShadowDOMStyling2'];
    if (shimShadowDOMStyling2 == null) return;

    var scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
        [style.text, localName]);

    // TODO(terry): Remove when shimShadowDOMStyling is called we don't need to
    //              replace original CSS with scoped CSS shimShadowDOMStyling
    //              does that.
    style.text = scopedCSS;
  }
}

class _PolymerBinding extends NodeBinding {
  final PathObserver _publishedAttr;

  _PolymerBinding(node, property, model, path, PathObserver this._publishedAttr)
      : super(node, property, model, path);

  void boundValueChanged(newValue) {
    _publishedAttr.value = newValue;
  }
}

/**
 * Polymer features to handle the syntactic sugar on-* to declare to
 * automatically map event handlers to instance methods of the [PolymerElement].
 * This mixin is a port of:
 * https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
 * https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
 */
abstract class _EventsMixin {
  // TODO(sigmund): implement the Dart equivalent of 'inheritDelegates'
  // Notes about differences in the implementation below:
  //  - _templateDelegates: polymer stores the template delegates directly on
  //    the template node (see in parseLocalEvents: 't.delegates = {}'). Here we
  //    simply use a separate map, where keys are the name of the
  //    custom-element.
  //  - _listenLocal we return true/false and propagate that up, JS
  //    implementation does't forward the return value.
  //  - we don't keep the side-table (weak hash map) of unhandled events (see
  //    handleIfNotHandled)
  //  - we don't use event.type to dispatch events, instead we save the event
  //    name with the event listeners. We do so to avoid translating back and
  //    forth between Dom and Dart event names.

  // ---------------------------------------------------------------------------
  // The following section was ported from:
  // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
  // ---------------------------------------------------------------------------

  /** Maps event names and their associated method in the element class. */
  final Map<String, String> _delegates = {};

  /** Expected events per element node. */
  // TODO(sigmund): investigate whether we need more than 1 set of local events
  // per element (why does the js implementation stores 1 per template node?)
  final Map<String, Set<String>> _templateDelegates =
      new Map<String, Set<String>>();

  /** [host] is needed by this mixin, but not defined here. */
  Element get host;

  /** Attribute prefix used for declarative event handlers. */
  static const _eventPrefix = 'on-';

  /** Whether an attribute declares an event. */
  static bool _isEvent(String attr) => attr.startsWith(_eventPrefix);

  /** Extracts events from the element tag attributes. */
  void _parseHostEvents(elementElement) {
    for (var attr in elementElement.attributes.keys.where(_isEvent)) {
      _delegates[toCamelCase(attr)] = elementElement.attributes[attr];
    }
  }

  /** Extracts events under the element's <template>. */
  void _parseLocalEvents(elementElement) {
    var name = elementElement.attributes["name"];
    if (name == null) return;
    var events = null;
    for (var template in elementElement.queryAll('template')) {
      var content = template.content;
      if (content != null) {
        for (var child in content.children) {
          events = _accumulateEvents(child, events);
        }
      }
    }
    if (events != null) {
      _templateDelegates[name] = events;
    }
  }

  /** Returns all events names listened by [element] and it's children. */
  static Set<String> _accumulateEvents(Element element, [Set<String> events]) {
    events = events == null ? new Set<String>() : events;

    // from: accumulateAttributeEvents, accumulateEvent
    events.addAll(element.attributes.keys.where(_isEvent).map(toCamelCase));

    // from: accumulateChildEvents
    for (var child in element.children) {
      _accumulateEvents(child, events);
    }

    // from: accumulateTemplatedEvents
    if (element.isTemplate) {
      var content = element.content;
      if (content != null) {
        for (var child in content.children) {
          _accumulateEvents(child, events);
        }
      }
    }
    return events;
  }

  // ---------------------------------------------------------------------------
  // The following section was ported from:
  // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
  // ---------------------------------------------------------------------------

  /** Attaches event listeners on the [host] element. */
  void _addHostListeners() {
    for (var eventName in _delegates.keys) {
      _addNodeListener(host, eventName,
          (e) => _hostEventListener(eventName, e));
    }
  }

  void _addNodeListener(node, String onEvent, Function listener) {
    // If [node] is an element (typically when listening for host events) we
    // use directly the '.onFoo' event stream of the element instance.
    if (node is Element) {
      reflect(node).getField(new Symbol(onEvent)).reflectee.listen(listener);
      return;
    }

    // When [node] is not an element, most commonly when [node] is the
    // shadow-root of the polymer-element, we find the appropriate static event
    // stream providers and attach it to [node].
    var eventProvider = _eventStreamProviders[onEvent];
    if (eventProvider != null) {
      eventProvider.forTarget(node).listen(listener);
      return;
    }

    // When no provider is available, mainly because of custom-events, we use
    // the underlying event listeners from the DOM.
    var eventName = onEvent.substring(2).toLowerCase(); // onOneTwo => onetwo
    // Most events names in Dart match those in JS in lowercase except for some
    // few events listed in this map. We expect these cases to be handled above,
    // but just in case we include them as a safety net here.
    var jsNameFixes = const {
      'animationend': 'webkitAnimationEnd',
      'animationiteration': 'webkitAnimationIteration',
      'animationstart': 'webkitAnimationStart',
      'doubleclick': 'dblclick',
      'fullscreenchange': 'webkitfullscreenchange',
      'fullscreenerror': 'webkitfullscreenerror',
      'keyadded': 'webkitkeyadded',
      'keyerror': 'webkitkeyerror',
      'keymessage': 'webkitkeymessage',
      'needkey': 'webkitneedkey',
      'speechchange': 'webkitSpeechChange',
    };
    var fixedName = jsNameFixes[eventName];
    node.on[fixedName != null ? fixedName : eventName].listen(listener);
  }

  void _addInstanceListeners(ShadowRoot root, String elementName) {
    var events = _templateDelegates[elementName];
    if (events == null) return;
    for (var eventName in events) {
      _addNodeListener(root, eventName,
          (e) => _instanceEventListener(eventName, e));
    }
  }

  void _hostEventListener(String eventName, Event event) {
    var method = _delegates[eventName];
    if (event.bubbles && method != null) {
      _dispatchMethod(this, method, event, host);
    }
  }

  void _dispatchMethod(Object receiver, String methodName, Event event,
      Node target) {
    var detail = event is CustomEvent ? (event as CustomEvent).detail : null;
    var args = [event, detail, target];

    var method = new Symbol(methodName);
    // TODO(sigmund): consider making event listeners list all arguments
    // explicitly. Unless VM mirrors are optimized first, this reflectClass call
    // will be expensive once custom elements extend directly from Element (see
    // dartbug.com/11108).
    var methodDecl = reflectClass(receiver.runtimeType).methods[method];
    if (methodDecl != null) {
      // This will either truncate the argument list or extend it with extra
      // null arguments, so it will match the signature.
      // TODO(sigmund): consider accepting optional arguments when we can tell
      // them appart from named arguments (see http://dartbug.com/11334)
      args.length = methodDecl.parameters.where((p) => !p.isOptional).length;
    }
    reflect(receiver).invoke(method, args);
    performMicrotaskCheckpoint();
  }

  bool _instanceEventListener(String eventName, Event event) {
    if (event.bubbles) {
      if (event.path == null || !ShadowRoot.supported) {
        return _listenLocalNoEventPath(eventName, event);
      } else {
        return _listenLocal(eventName, event);
      }
    }
    return false;
  }

  bool _listenLocal(String eventName, Event event) {
    var controller = null;
    for (var target in event.path) {
      // if we hit host, stop
      if (target == host) return true;

      // find a controller for the target, unless we already found `host`
      // as a controller
      controller = (controller == host) ? controller : _findController(target);

      // if we have a controller, dispatch the event, and stop if the handler
      // returns true
      if (controller != null
          && handleEvent(controller, eventName, event, target)) {
        return true;
      }
    }
    return false;
  }

  // TODO(sorvell): remove when ShadowDOM polyfill supports event path.
  // Note that _findController will not return the expected controller when the
  // event target is a distributed node.  This is because we cannot traverse
  // from a composed node to a node in shadowRoot.
  // This will be addressed via an event path api
  // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066
  bool _listenLocalNoEventPath(String eventName, Event event) {
    var target = event.target;
    var controller = null;
    while (target != null && target != host) {
      controller = (controller == host) ? controller : _findController(target);
      if (controller != null
          && handleEvent(controller, eventName, event, target)) {
        return true;
      }
      target = target.parent;
    }
    return false;
  }

  // TODO(sigmund): investigate if this implementation is correct. Polymer looks
  // up the shadow-root that contains [node] and uses a weak-hashmap to find the
  // host associated with that root. This implementation assumes that the
  // [node] is under [host]'s shadow-root.
  Element _findController(Node node) => host.xtag;

  bool handleEvent(
      Element controller, String eventName, Event event, Element element) {
    // Note: local events are listened only in the shadow root. This dynamic
    // lookup is used to distinguish determine whether the target actually has a
    // listener, and if so, to determine lazily what's the target method.
    var methodName = element.attributes[toHyphenedName(eventName)];
    if (methodName != null) {
      _dispatchMethod(controller, methodName, event, element);
    }
    return event.bubbles;
  }
}


/** Event stream providers per event name. */
// TODO(sigmund): after dartbug.com/11108 is fixed, consider eliminating this
// table and using reflection instead.
const Map<String, EventStreamProvider> _eventStreamProviders = const {
  'onMouseWheel': Element.mouseWheelEvent,
  'onTransitionEnd': Element.transitionEndEvent,
  'onAbort': Element.abortEvent,
  'onBeforeCopy': Element.beforeCopyEvent,
  'onBeforeCut': Element.beforeCutEvent,
  'onBeforePaste': Element.beforePasteEvent,
  'onBlur': Element.blurEvent,
  'onChange': Element.changeEvent,
  'onClick': Element.clickEvent,
  'onContextMenu': Element.contextMenuEvent,
  'onCopy': Element.copyEvent,
  'onCut': Element.cutEvent,
  'onDoubleClick': Element.doubleClickEvent,
  'onDrag': Element.dragEvent,
  'onDragEnd': Element.dragEndEvent,
  'onDragEnter': Element.dragEnterEvent,
  'onDragLeave': Element.dragLeaveEvent,
  'onDragOver': Element.dragOverEvent,
  'onDragStart': Element.dragStartEvent,
  'onDrop': Element.dropEvent,
  'onError': Element.errorEvent,
  'onFocus': Element.focusEvent,
  'onInput': Element.inputEvent,
  'onInvalid': Element.invalidEvent,
  'onKeyDown': Element.keyDownEvent,
  'onKeyPress': Element.keyPressEvent,
  'onKeyUp': Element.keyUpEvent,
  'onLoad': Element.loadEvent,
  'onMouseDown': Element.mouseDownEvent,
  'onMouseMove': Element.mouseMoveEvent,
  'onMouseOut': Element.mouseOutEvent,
  'onMouseOver': Element.mouseOverEvent,
  'onMouseUp': Element.mouseUpEvent,
  'onPaste': Element.pasteEvent,
  'onReset': Element.resetEvent,
  'onScroll': Element.scrollEvent,
  'onSearch': Element.searchEvent,
  'onSelect': Element.selectEvent,
  'onSelectStart': Element.selectStartEvent,
  'onSubmit': Element.submitEvent,
  'onTouchCancel': Element.touchCancelEvent,
  'onTouchEnd': Element.touchEndEvent,
  'onTouchEnter': Element.touchEnterEvent,
  'onTouchLeave': Element.touchLeaveEvent,
  'onTouchMove': Element.touchMoveEvent,
  'onTouchStart': Element.touchStartEvent,
  'onFullscreenChange': Element.fullscreenChangeEvent,
  'onFullscreenError': Element.fullscreenErrorEvent,
  'onAutocomplete': FormElement.autocompleteEvent,
  'onAutocompleteError': FormElement.autocompleteErrorEvent,
  'onSpeechChange': InputElement.speechChangeEvent,
  'onCanPlay': MediaElement.canPlayEvent,
  'onCanPlayThrough': MediaElement.canPlayThroughEvent,
  'onDurationChange': MediaElement.durationChangeEvent,
  'onEmptied': MediaElement.emptiedEvent,
  'onEnded': MediaElement.endedEvent,
  'onLoadStart': MediaElement.loadStartEvent,
  'onLoadedData': MediaElement.loadedDataEvent,
  'onLoadedMetadata': MediaElement.loadedMetadataEvent,
  'onPause': MediaElement.pauseEvent,
  'onPlay': MediaElement.playEvent,
  'onPlaying': MediaElement.playingEvent,
  'onProgress': MediaElement.progressEvent,
  'onRateChange': MediaElement.rateChangeEvent,
  'onSeeked': MediaElement.seekedEvent,
  'onSeeking': MediaElement.seekingEvent,
  'onShow': MediaElement.showEvent,
  'onStalled': MediaElement.stalledEvent,
  'onSuspend': MediaElement.suspendEvent,
  'onTimeUpdate': MediaElement.timeUpdateEvent,
  'onVolumeChange': MediaElement.volumeChangeEvent,
  'onWaiting': MediaElement.waitingEvent,
  'onKeyAdded': MediaElement.keyAddedEvent,
  'onKeyError': MediaElement.keyErrorEvent,
  'onKeyMessage': MediaElement.keyMessageEvent,
  'onNeedKey': MediaElement.needKeyEvent,
  'onWebGlContextLost': CanvasElement.webGlContextLostEvent,
  'onWebGlContextRestored': CanvasElement.webGlContextRestoredEvent,
  'onPointerLockChange': Document.pointerLockChangeEvent,
  'onPointerLockError': Document.pointerLockErrorEvent,
  'onReadyStateChange': Document.readyStateChangeEvent,
  'onSelectionChange': Document.selectionChangeEvent,
  'onSecurityPolicyViolation': Document.securityPolicyViolationEvent,
};
