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

part of $LIBRARYNAME;

typedef void RemoveFrameRequestMapping(int id);

/**
 * The task object representing animation-frame requests.
 *
 * For historical reasons, [Window.requestAnimationFrame] returns an integer
 * to users. However, zone tasks must be unique objects, and an integer can
 * therefore not be used as task object. The [Window] class thus keeps a mapping
 * from the integer ID to the corresponding task object. All zone related
 * operations work on this task object, whereas users of
 * [Window.requestAnimationFrame] only see the integer ID.
 *
 * Since this mapping takes up space, it must be removed when the
 * animation-frame task has triggered. The default implementation does this
 * automatically, but intercepting implementations of `requestAnimationFrame`
 * must make sure to call the [AnimationFrameTask.removeMapping]
 * function that is provided in the task specification.
 *
 * *Experimental*. This class may disappear without notice.
 */
abstract class AnimationFrameTask {
  /** The ID that is returned to users. */
  int get id;

  /** The zone in which the task will run. */
  Zone get zone;

  /**
   * Cancels the animation-frame request.
   *
   * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
   * forwards the request to this function.
   *
   * Zones that intercept animation-frame requests implement this method so
   * that they can react to cancelation requests.
   */
  void cancel(Window window);

  /**
   * Maps animation-frame request IDs to their task objects.
   */
  static final Map<int, _AnimationFrameTask> _tasks = {};

  /**
   * Removes the mapping from [id] to [AnimationFrameTask].
   *
   * This function must be invoked by user-implemented animation-frame
   * tasks, before running [callback].
   *
   * See [AnimationFrameTask].
   */
  static void removeMapping(int id) {
    _tasks.remove(id);
  }
}

class _AnimationFrameTask implements AnimationFrameTask {
  final int id;
  final Zone zone;
  final FrameRequestCallback _callback;

  _AnimationFrameTask(this.id, this.zone, this._callback);

  void cancel(Window window) {
    window._cancelAnimationFrame(this.id);
  }
}

/**
 * The task specification for an animation-frame request.
 *
 * *Experimental*. This class may disappear without notice.
 */
class AnimationFrameRequestSpecification implements TaskSpecification {
  /**
   * The window on which [Window.requestAnimationFrame] was invoked.
   */
  final Window window;

  /**
   * The callback that is executed when the animation-frame is ready.
   *
   * Note that the callback hasn't been registered in any zone when the `create`
   * function (passed to [Zone.createTask]) is invoked.
   */
  final FrameRequestCallback callback;

  AnimationFrameRequestSpecification(this.window, this.callback);

  String get name => "dart.html.request-animation-frame";
  bool get isOneShot => true;
}

@DocsEditable()
$if DART2JS
$(ANNOTATIONS)@Native("Window,DOMWindow")
$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
$else
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
$endif

  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame(completer.complete);
    return completer.future;
  }

$if DART2JS
  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web
   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) =>
      JS('Window|Null', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
   *   from MDN.
   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
   *   from WebPlatform.org.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  set _location(value) {
    JS('void', '#.location = #', this, value);
  }

$endif

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  @DomName('Window.requestAnimationFrame')
  int requestAnimationFrame(FrameRequestCallback callback) {
$if DART2JS
    _ensureRequestAnimationFrame();
$endif
    if (identical(Zone.current, Zone.ROOT)) {
      return _requestAnimationFrame(callback);
    }
    var spec = new AnimationFrameRequestSpecification(this, callback);
    var task = Zone.current.createTask/*<AnimationFrameTask>*/(
        _createAnimationFrameTask, spec);
    AnimationFrameTask._tasks[task.id] = task;
    return task.id;
  }

  static _AnimationFrameTask _createAnimationFrameTask(
      AnimationFrameRequestSpecification spec, Zone zone) {
    var task;
    var id = spec.window._requestAnimationFrame((num time) {
      AnimationFrameTask.removeMapping(task.id);
      zone.runTask(_runAnimationFrame, task, time);
    });
    var callback = zone.registerUnaryCallback(spec.callback);
    task = new _AnimationFrameTask(id, zone, callback);
    return task;
  }

  static void _runAnimationFrame(_AnimationFrameTask task, num time) {
    task._callback(time);
  }

  /**
   * Cancels an animation frame request.
   *
   * ## Other resources
   *
   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
   *   from MDN.
   */
  @DomName('Window.cancelAnimationFrame')
  void cancelAnimationFrame(int id) {
    _ensureRequestAnimationFrame();
    var task = AnimationFrameTask._tasks.remove(id);
    if (task == null) {
      // Assume that the animation frame request wasn't intercepted by a zone.
      _cancelAnimationFrame(id);
      return;
    }
    task.cancel(this);
  }

$if DART2JS
  @JSName('requestAnimationFrame')
  int _requestAnimationFrame(FrameRequestCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool',
           '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
      return;

    JS('void',
       r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
       this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  @Experimental()
  IdbFactory get indexedDB =>
      JS('IdbFactory|Null',  // If not supported, returns null.
         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
         this, this, this);

  /// The debugging console for this window.
  @DomName('Window.console')
  Console get console => Console._safeConsole;
$endif

  /**
   * Access a sandboxed file system of the specified `size`. If `persistent` is
   * true, the application will request permission from the user to create
   * lasting storage. This storage cannot be freed without the user's
   * permission. Returns a [Future] whose value stores a reference to the
   * sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent? 1 : 0, size);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  static bool get supportsPointConversions => DomPoint.supported;
$!MEMBERS

  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
   *   from MDN.
   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
   *   from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

$if DART2JS
  @DomName('Window.pageXOffset')
  @DocsEditable()
  int get pageXOffset => JS('num', '#.pageXOffset', this).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => JS('num', '#.pageYOffset', this).round();

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => JS('bool', '("scrollX" in #)', this) ?
      JS('num', '#.scrollX', this).round() :
      document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => JS('bool', '("scrollY" in #)', this) ?
      JS('num', '#.scrollY', this).round() :
      document.documentElement.scrollTop;
$else
  @DomName('Window.pageXOffset')
  @DocsEditable()
  int get pageXOffset => _blink.BlinkWindow.instance.pageXOffset_Getter_(this).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(this).round();

  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(this).round();

  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(this).round();
$endif
}

$if DART2JS
class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base): super(base);

  String get returnValue => _returnValue;

  set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}
$endif

class _BeforeUnloadEventStreamProvider implements
    EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
$if DART2JS
    // Specify the generic type for EventStream only in dart2js to avoid
    // checked mode errors in dartium.
    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
    var controller = new StreamController<BeforeUnloadEvent>(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
    });

    return controller.stream;
$else
    var stream = new _EventStream(e, _eventType, useCapture);
    return stream;
$endif
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e, {bool useCapture: false}) {
$if DART2JS
    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
    // avoid checked mode errors in dartium.
    return new _ElementEventStreamImpl<BeforeUnloadEvent>(e, _eventType, useCapture);
$else
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
$endif
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
      {bool useCapture: false}) {
$if DART2JS
    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
    // avoid checked mode errors in dartium.
    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, useCapture);
$else
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
$endif
  }
}
