// Copyright (c) 2012, 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.

/**
 * Custom HTML tags, data binding, and templates for building
 * structured, encapsulated, client-side web apps.
 *
 * Polymer.dart, the next evolution of Web UI,
 * is an in-progress Dart port of the
 * [Polymer project](http://www.polymer-project.org/).
 * Polymer.dart compiles to JavaScript and runs across the modern web.
 *
 * To use polymer.dart in your application,
 * first add a
 * [dependency](http://pub.dartlang.org/doc/dependencies.html)
 * to the app's pubspec.yaml file.
 * Instead of using the open-ended `any` version specifier,
 * we recommend using a range of version numbers, as in this example:
 *
 *     dependencies:
 *       polymer: '>=0.7.1 <0.8'
 *
 * Then import the library into your application:
 *
 *     import 'package:polymer/polymer.dart';
 *
 * ## Other resources
 *
 * * [Polymer.dart homepage](http://www.dartlang.org/polymer-dart/):
 * Example code, project status, and
 * information about how to get started using Polymer.dart in your apps.
 *
 * * [polymer.dart package](http://pub.dartlang.org/packages/polymer):
 * More details, such as the current major release number.
 *
 * * [Upgrading to Polymer.dart](http://www.dartlang.org/polymer-dart/upgrading-to-polymer-from-web-ui.html):
 * Tips for converting your apps from Web UI to Polymer.dart.
 */
library polymer;

import 'dart:async';
import 'dart:mirrors';

import 'package:mdv/mdv.dart' as mdv;
import 'package:observe/src/microtask.dart';
import 'package:path/path.dart' as path;
import 'polymer_element.dart' show registerPolymerElement;

export 'package:custom_element/custom_element.dart';
export 'package:observe/observe.dart';
export 'package:observe/html.dart';
export 'package:observe/src/microtask.dart';

export 'polymer_element.dart';


/** Annotation used to automatically register polymer elements. */
class CustomTag {
  final String tagName;
  const CustomTag(this.tagName);
}

/**
 * Metadata used to label static or top-level methods that are called
 * automatically when loading the library of a custom element.
 */
const initMethod = const _InitMethodAnnotation();

/**
 * Initializes a polymer application as follows:
 *   * set up up polling for observable changes
 *   *  initialize MDV
 *   *  for each library in [libraries], register custom elements labeled with
 *      [CustomTag] and invoke the initialization method on it.
 *
 * The initialization on each library is either a method named `main` or
 * a top-level function and annotated with [initMethod].
 *
 * The urls in [libraries] can be absolute or relative to [srcUrl].
 */
void initPolymer(List<String> libraries, [String srcUrl]) {
  wrapMicrotask(() {
    // DOM events don't yet go through microtasks, so we catch those here.
    new Timer.periodic(new Duration(milliseconds: 125),
        (_) => performMicrotaskCheckpoint());

    // TODO(jmesserly): mdv should use initMdv instead of mdv.initialize.
    mdv.initialize();
    for (var lib in libraries) {
      _loadLibrary(lib, srcUrl);
    }
  })();
}

/** All libraries in the current isolate. */
final _libs = currentMirrorSystem().libraries;

/**
 * Reads the library at [uriString] (which can be an absolute URI or a relative
 * URI from [srcUrl]), and:
 *
 *   * If present, invokes `main`.
 *
 *   * If present, invokes any top-level and static functions marked
 *     with the [initMethod] annotation (in the order they appear).
 *
 *   * Registers any [PolymerElement] that is marked with the [CustomTag]
 *     annotation.
 */
void _loadLibrary(String uriString, [String srcUrl]) {
  var uri = Uri.parse(uriString);
  if (uri.scheme == '' && srcUrl != null) {
    uri = Uri.parse(path.normalize(path.join(path.dirname(srcUrl), uriString)));
  }
  var lib = _libs[uri];
  if (lib == null) {
    print('warning: $uri library not found');
    return;
  }

  // Invoke `main`, if present.
  if (lib.functions[const Symbol('main')] != null) {
    lib.invoke(const Symbol('main'), const []);
  }

  // Search top-level functions marked with @initMethod
  for (var f in lib.functions.values) {
    _maybeInvoke(lib, f);
  }

  for (var c in lib.classes.values) {
    // Search for @CustomTag on classes
    for (var m in c.metadata) {
      var meta = m.reflectee;
      if (meta is CustomTag) {
        registerPolymerElement(meta.tagName,
            () => c.newInstance(const Symbol(''), const []).reflectee);
      }
    }

    // TODO(sigmund): check also static methods marked with @initMethod.
    // This is blocked on two bugs:
    //  - dartbug.com/12133 (static methods are incorrectly listed as top-level
    //    in dart2js, so they end up being called twice)
    //  - dartbug.com/12134 (sometimes "method.metadata" throws an exception,
    //    we could wrap and hide those exceptions, but it's not ideal).
  }
}

void _maybeInvoke(ObjectMirror obj, MethodMirror method) {
  var annotationFound = false;
  for (var meta in method.metadata) {
    if (identical(meta.reflectee, initMethod)) {
      annotationFound = true;
      break;
    }
  }
  if (!annotationFound) return;
  if (!method.isStatic) {
    print("warning: methods marked with @initMethod should be static,"
        " ${method.simpleName} is not.");
    return;
  }
  if (!method.parameters.where((p) => !p.isOptional).isEmpty) {
    print("warning: methods marked with @initMethod should take no "
        "arguments, ${method.simpleName} expects some.");
    return;
  }
  obj.invoke(method.simpleName, const []);
}

class _InitMethodAnnotation {
  const _InitMethodAnnotation();
}
