// Copyright (c) 2011, 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 EventTest;
import "package:expect/expect.dart";
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
import 'dart:html';

// TODO(nweiz): Make this private to testEvents when Frog supports closures with
// optional arguments.
eventTest(String name, Event eventFn(), void validate(Event),
    [String type = 'foo']) {
  test(name, () {
    final el = new Element.tag('div');
    var fired = false;
    el.on[type].add((ev) {
      fired = true;
      validate(ev);
    });
    el.on[type].dispatch(eventFn());
    expect(fired, isTrue, reason: 'Expected event to be dispatched.');
  });
}

main() {
  useHtmlConfiguration();

  // Issue 1005.
  // eventTest('AnimationEvent', () => new AnimationEvent('foo', 'color', 0.5),
  //     (ev) {
  //   expect(ev.animationName, 'color');
  //   expect(ev.elapsedTime, 0.5);
  // });

  // Issue 1005.
  // eventTest('BeforeLoadEvent',
  //    () => new BeforeLoadEvent('foo', 'http://example.url'),
  //    (ev) { expect(ev.url, 'http://example.url'); });

  // Issue 1005.
  // eventTest('CloseEvent',
  //     () => new CloseEvent('foo', 5, 'reason', wasClean: true),
  //     (ev) {
  //   expect(ev.code, 5);
  //   expect(ev.reason, 'reason');
  //   expect(ev.wasClean, isTrue);
  // });

  eventTest('CompositionEvent',
      () => new CompositionEvent('compositionstart', window, 'data'),
      (ev) { expect(ev.data, 'data'); },
      type: 'compositionstart');

  // initCustomEvent is not yet implemented
  // eventTest('CustomEvent',
  //     () => new CustomEvent('foo', false, false, 'detail'),
  //     (ev) { expect(ev.detail, 'detail'); });

  // DeviceMotionEvent has no properties to itself, so just test that it doesn't
  // error out on creation and can be dispatched.
  eventTest('DeviceMotionEvent', () => new DeviceMotionEvent('foo'), (ev) {});

  // initDeviceOrientationEvent is not yet implemented
  // eventTest('DeviceOrientationEvent',
  //     () => new DeviceOrientationEvent('foo', 0.1, 0.2, 0.3),
  //     (ev) {
  //   expect(ev.alpha, 0.1);
  //   expect(ev.beta, 0.2);
  //   expect(ev.gamma, 0.3);
  // });

  // Issue 1005.
  // eventTest('ErrorEvent',
  //     () => new ErrorEvent('foo', 'message', 'filename', 10),
  //     (ev) {
  //   expect('message', ev.message);
  //   expect('filename', ev.filename);
  //   expect(ev.lineno, 10);
  // });

  eventTest('Event',
      () => new Event('foo', canBubble: false, cancelable: false),
      (ev) {
    expect(ev.type, equals('foo'));
    expect(ev.bubbles, isFalse);
    expect(ev.cancelable, isFalse);
  });

  eventTest('HashChangeEvent',
      () => new HashChangeEvent('foo', 'http://old.url', 'http://new.url'),
      (ev) {
    expect(ev.oldUrl, equals('http//old.url'));
    expect(ev.newUrl, equals('http://new.url'));
  });

  eventTest('KeyboardEvent',
      () => new KeyboardEvent('foo', window, 'key', 10, ctrlKey: true,
          altKey: true, shiftKey: true, metaKey: true, altGraphKey: true),
      (ev) {
    expect.equals(ev.keyIdentifier, equals('key'));
    expect.equals(ev.keyLocation, equals(10));
    expect(ev.ctrlKey, isTrue);
    expect(ev.altKey, isTrue);
    expect(ev.shiftKey, isTrue);
    expect(ev.metaKey, isTrue);
    expect(ev.altGraphKey, isTrue);
  });

  eventTest('MouseEvent',
      // canBubble and cancelable are currently required to avoid dartc
      // complaining about the types of the named arguments.
      () => new MouseEvent('foo', window, 1, 2, 3, 4, 5, 6, canBubble: true,
          cancelable: true, ctrlKey: true, altKey: true, shiftKey: true,
          metaKey: true, relatedTarget: new Element.tag('div')),
      (ev) {
    expect(ev.detail, 1);
    expect(ev.screen.x, 2);
    expect(ev.screen.y, 3);
    expect(ev.client.x, 4);
    expect(ev.client.y, 5);
    expect(ev.offset.x, 4);  // Same as clientX.
    expect(ev.offset.y, 5);  // Same as clientY.
    expect(ev.button, 6);
    expect(ev.ctrlKey, isTrue);
    expect(ev.altKey, isTrue);
    expect(ev.shiftKey, isTrue);
    expect(ev.metaKey, isTrue);
    expect(ev.relatedTarget.tagName, 'DIV');
  });

  eventTest('MutationEvent',
      () => new MutationEvent('foo', new Element.tag('div'), 'red', 'blue',
          'color', MutationEvent.MODIFICATION),
      (ev) {
    expect(ev.relatedNode.tagName, 'DIV');
    expect.equals(ev.prevValue, 'red');
    expect.equals(ev.newValue, 'blue');
    expect.equals(ev.attrName, 'color');
    expect.equals(ev.attrChange, equals(MutationEvent.MODIFICATION));
  });

  test('DOMMutationEvent', () {
    var div = new DivElement();
    div.on['DOMSubtreeModified'].add(expectAsync((DOMMutationEvent e) {}));
    div.append(new SpanElement());
  });

  // Issue 1005.
  // eventTest('OverflowEvent',
  //     () => new OverflowEvent(OverflowEvent.BOTH, true, true),
  //     (ev) {
  //   expect(ev.orient, OverflowEvent.BOTH);
  //   expect(ev.horizontalOverflow, isTrue);
  //   expect(ev.verticalOverflow, isTrue);
  // }, type: 'overflowchanged');

  // Issue 1005.
  // eventTest('PageTransitionEvent',
  //     () => new PageTransitionEvent('foo', persisted: true),
  //     (ev) { expect(ev.persisted, isTrue); });

  // initPopStateEvent is not yet implemented
  // eventTest('PopStateEvent', () => new PopStateEvent('foo', 'state'),
  //     (ev) { expect(ev.state, 'state'); }

  // Issue 1005.
  // eventTest('ProgressEvent',
  //     // canBubble and cancelable are currently required to avoid dartc
  //     // complaining about the types of the named arguments.
  //     () => new ProgressEvent('foo', 5, canBubble: true, cancelable: true,
  //         lengthComputable: true, total: 10),
  //     (ev) {
  //   expect(ev.loaded, 5);
  //   expect(ev.lengthComputable, isTrue);
  //   expect(ev.total, 10);
  // });

  eventTest('StorageEvent',
      () => new StorageEvent('foo', 'key', 'http://example.url',
          window.localStorage, canBubble: true, cancelable: true,
          oldValue: 'old', newValue: 'new'),
      (ev) {
    expect(ev.key, 'key');
    expect(ev.url, 'http://example.url');
    // Equality isn't preserved for storageArea
    expect.isNotNull(ev.storageArea);
    expect(ev.oldValue, 'old');
    expect(ev.newValue, 'new');
  });

  eventTest('TextEvent', () => new TextEvent('foo', window, 'data'),
      (ev) { expect(ev.data, 'data'); });

  // Issue 1005.
  // eventTest('TransitionEvent', () => new TransitionEvent('foo', 'color', 0.5),
  //     (ev) {
  //   expect(ev.propertyName, 'color');
  //   expect(ev.elapsedTime, 0.5);
  // });

  eventTest('UIEvent', () => new UIEvent('foo', window, 12),
      (ev) {
    expect(window, ev.view, window);
    expect(12, ev.detail, 12);
  });

  eventTest('WheelEvent',
      () => new WheelEvent(1, 2, window, 3, 4, 5, 6, ctrlKey: true,
          altKey: true, shiftKey: true, metaKey: true),
      (ev) {
    // wheelDelta* properties are multiplied by 120 for some reason
    expect(ev.wheelDeltaX, 120);
    expect(ev.wheelDeltaY, 240);
    expect(ev.screen.x, 3);
    expect(ev.screen.y, 4);
    expect(ev.client.x, 5);
    expect(ev.client.y, 6);
    expect(ev.ctrlKey, isTrue);
    expect(ev.altKey, isTrue);
    expect(ev.shiftKey, isTrue);
    expect(ev.metaKey, isTrue);
  }, type: 'mousewheel');
}
