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

// DO NOT EDIT
// Auto-generated dart:html library.

/**
 * HTML elements and other resources for web-based applications that need to
 * interact with the browser and the DOM (Document Object Model).
 *
 * This library includes DOM element types, CSS styling, local storage,
 * media, speech, events, and more.
 * To get started,
 * check out the [Element] class, the base class for many of the HTML
 * DOM types.
 *
 * ## Other resources
 *
 * * If you've never written a web app before, try our
 * tutorials&mdash;[A Game of Darts](http://dartlang.org/docs/tutorials).
 *
 * * To see some web-based Dart apps in action and to play with the code,
 * download
 * [Dart Editor](http://www.dartlang.org/#get-started)
 * and run its built-in examples.
 *
 * * For even more examples, see
 * [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
 * on Github.
 */
library dart.dom.html;

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:indexed_db' show indexed_dbBlinkMap;
import 'dart:indexed_db' show indexed_dbBlinkFunctionMap;
import 'dart:isolate';
import 'dart:js' as js;
import "dart:convert";
import 'dart:math';
// TODO(vsm): Remove this when we can do the proper checking in
// native code for custom elements.
import 'dart:mirrors';
import 'dart:nativewrappers';
import 'dart:typed_data';
import 'dart:web_gl' as gl;
import 'dart:web_gl' show web_glBlinkMap;
import 'dart:web_gl' show web_glBlinkFunctionMap;
import 'dart:web_sql';
// Not actually used, but imported since dart:html can generate these objects.
import 'dart:svg' as svg;
import 'dart:svg' show svgBlinkMap;
import 'dart:svg' show svgBlinkFunctionMap;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show web_audioBlinkMap;
import 'dart:web_audio' show web_audioBlinkFunctionMap;
import 'dart:_blink' as _blink;

export 'dart:math' show Rectangle, Point;

$!GENERATED_DART_FILES

// Issue 14721, order important for WrappedEvent.
part '$AUXILIARY_DIR/AttributeMap.dart';
part '$AUXILIARY_DIR/CanvasImageSource.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
part '$AUXILIARY_DIR/dartium_CssClassSet.dart';
part '$AUXILIARY_DIR/CssRectangle.dart';
part '$AUXILIARY_DIR/Dimension.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/EventStreamProvider.dart';
part '$AUXILIARY_DIR/Html5NodeValidator.dart';
part '$AUXILIARY_DIR/ImmutableListMixin.dart';
part '$AUXILIARY_DIR/KeyCode.dart';
part '$AUXILIARY_DIR/KeyLocation.dart';
part '$AUXILIARY_DIR/KeyName.dart';
part '$AUXILIARY_DIR/KeyboardEventStream.dart';
part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
part '$AUXILIARY_DIR/ReadyState.dart';
part '$AUXILIARY_DIR/Validators.dart';
part '$AUXILIARY_DIR/WrappedList.dart';
part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
part '$AUXILIARY_DIR/_ListIterators.dart';
part '$AUXILIARY_DIR/dartium_CustomElementSupport.dart';
part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
part '$AUXILIARY_DIR/dartium_Platform.dart';
part '$AUXILIARY_DIR/dartium_WrappedEvent.dart';
part '$AUXILIARY_DIR/shared_html.dart';

part '$AUXILIARY_DIR/native_DOMImplementation.dart';

Window _window;

/**
 * Top-level container for a web page, which is usually a browser tab or window.
 *
 * Each web page loaded in the browser has its own [Window], which is a
 * container for the web page.
 *
 * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
 * [Window] object, which is accessible only to that `<iframe>`.
 *
 * See also:
 *
 *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
 */
Window get window {
  if (_window != null) {
    return _window;
  }
$if DARTIUM
$if JSINTEROP
  _window = wrap_jso(js.context['window']);
$else
  _window = _Utils.window();
$endif
$endif
  return _window;
}

HtmlDocument _document;

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document {
  if (_document != null) {
    return _document;
  }
  _document = window.document;
  return _document;
}

/**
 * Spawn a DOM isolate using the given URI in the same window.
 * This isolate is not concurrent.  It runs on the browser thread
 * with full access to the DOM.
 * Note: this API is still evolving and may move to dart:isolate.
 */
@Experimental()
Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
  // TODO(17738): Plumb arguments and return value through.
  return _Utils.spawnDomUri(uri.toString());
}
// FIXME: Can we make this private?
final htmlBlinkMap = {
  '_HistoryCrossFrame': () => _HistoryCrossFrame,
  '_LocationCrossFrame': () => _LocationCrossFrame,
  '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
  // FIXME: Move these to better locations.
  'DateTime': () => DateTime,
  'JsObject': () => js.JsObjectImpl,
  'JsFunction': () => js.JsFunctionImpl,
  'JsArray': () => js.JsArrayImpl,
$!TYPE_MAP
};

// TODO(leafp): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
Type _getType(String key) {
  var result;

  // TODO(vsm): Add Cross Frame and JS types here as well.

  // Check the html library.
  result = _getHtmlType(key);
  if (result != null) {
    return result;
  }

  // Check the web gl library.
  result = _getWebGlType(key);
  if (result != null) {
    return result;
  }

  // Check the indexed db library.
  result = _getIndexDbType(key);
  if (result != null) {
    return result;
  }

  // Check the web audio library.
  result = _getWebAudioType(key);
  if (result != null) {
    return result;
  }

  // Check the web sql library.
  result = _getWebSqlType(key);
  if (result != null) {
    return result;
  }

  // Check the svg library.
  result = _getSvgType(key);
  if (result != null) {
    return result;
  }

  return null;
}

Type _getHtmlType(String key) {
  if (htmlBlinkMap.containsKey(key)) {
    return htmlBlinkMap[key]();
  }
  return null;
}

Type _getWebGlType(String key) {
  if (web_glBlinkMap.containsKey(key)) {
    return web_glBlinkMap[key]();
  }
  return null;
}

Type _getIndexDbType(String key) {
  if (indexed_dbBlinkMap.containsKey(key)) {
    return indexed_dbBlinkMap[key]();
  }
  return null;
}

Type _getWebAudioType(String key) {
  if (web_audioBlinkMap.containsKey(key)) {
    return web_audioBlinkMap[key]();
  }
  return null;
}

Type _getWebSqlType(String key) {
  if (web_sqlBlinkMap.containsKey(key)) {
    return web_sqlBlinkMap[key]();
  }
  return null;
}

Type _getSvgType(String key) {
  if (svgBlinkMap.containsKey(key)) {
    return svgBlinkMap[key]();
  }
  return null;
}

$if JSINTEROP
// FIXME: Can we make this private?
final htmlBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};

// TODO(terry): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
getHtmlCreateFunction(String key) {
  var result;

  // TODO(vsm): Add Cross Frame and JS types here as well.

  // Check the html library.
  result = _getHtmlFunction(key);
  if (result != null) {
    return result;
  }

  // Check the web gl library.
  result = _getWebGlFunction(key);
  if (result != null) {
    return result;
  }

  // Check the indexed db library.
  result = _getIndexDbFunction(key);
  if (result != null) {
    return result;
  }

  // Check the web audio library.
  result = _getWebAudioFunction(key);
  if (result != null) {
    return result;
  }

  // Check the web sql library.
  result = _getWebSqlFunction(key);
  if (result != null) {
    return result;
  }

  // Check the svg library.
  result = _getSvgFunction(key);
  if (result != null) {
    return result;
  }

  return null;
}

Function _getHtmlFunction(String key) {
  if (htmlBlinkFunctionMap.containsKey(key)) {
    return htmlBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebGlFunction(String key) {
  if (web_glBlinkFunctionMap.containsKey(key)) {
    return web_glBlinkFunctionMap[key]();
  }
  return null;
}

Function _getIndexDbFunction(String key) {
  if (indexed_dbBlinkFunctionMap.containsKey(key)) {
    return indexed_dbBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebAudioFunction(String key) {
  if (web_audioBlinkFunctionMap.containsKey(key)) {
    return web_audioBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebSqlFunction(String key) {
  if (web_sqlBlinkFunctionMap.containsKey(key)) {
    return web_sqlBlinkFunctionMap[key]();
  }
  return null;
}

Function _getSvgFunction(String key) {
  if (svgBlinkFunctionMap.containsKey(key)) {
    return svgBlinkFunctionMap[key]();
  }
  return null;
}


/******************************************************************************
 **********                                                          **********
 **********                    JS Interop Support                    **********
 **********                                                          **********
 ******************************************************************************/

Rectangle make_dart_rectangle(r) =>
    r == null ? null : new Rectangle(r['left'], r['top'], r['width'], r['height']);

// Need a default constructor for constructing classes with mixins that are
// also extending NativeFieldWrapperClass2.  Defining JsoNativeFieldWrapper
// extending NativeFieldWrapperClass2 creates a default constructor.
class JsoNativeFieldWrapper extends NativeFieldWrapperClass2 {}

// Flag to disable JS interop asserts.  Setting to false will speed up the
// wrap_jso calls.
bool __interop_checks = true;

/** Expando for JsObject, used by every Dart class associated with a Javascript
 *  class (e.g., DOM, WebAudio, etc.).
 */

/**
 * Return the JsObject associated with a Dart class [dartClass_instance].
 */
unwrap_jso(dartClass_instance) {
  try {
    if (dartClass_instance != null)
      return dartClass_instance is NativeFieldWrapperClass2 ?
          dartClass_instance.blink_jsObject : dartClass_instance;
    else
      return null;
  } catch(NoSuchMethodException) {
    // No blink_jsObject then return the dartClass_instance is probably an
    // array that was already converted to a Dart class e.g., Uint8ClampedList.
    return dartClass_instance;
  }
}

/**
 * Create Dart class that maps to the JS Type, add the JsObject as an expando
 * on the Dart class and return the created Dart class.
 */
wrap_jso(jsObject) {
  try {
    if (jsObject is! js.JsObject) {
      // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
      return jsObject;
    }
    // Try the most general type conversions on it.
    // TODO(alanknight): We may be able to do better. This maintains identity,
    // which is useful, but expensive. And if we nest something that only
    // this conversion handles, how does that work? e.g. a list of maps of elements.
    var converted = convertNativeToDart_SerializedScriptValue(jsObject);
    if (!identical(converted, jsObject)) {
      return converted;
    }
    var constructor = jsObject['constructor'];
    if (__interop_checks) {
      debug_or_assert("constructor != null", constructor != null);
    }
    var jsTypeName = constructor['name'];
    if (__interop_checks) {
      debug_or_assert("constructor != null && jsTypeName.length > 0", constructor != null && jsTypeName.length > 0);
    }

    var dartClass_instance;
    if (jsObject.hasProperty('dart_class')) {
      // Got a dart_class (it's a custom element) use it it's already set up.
      dartClass_instance = jsObject['dart_class'];
    } else {
      var func = getHtmlCreateFunction(jsTypeName);
      if (func != null) {
        dartClass_instance = func();
        dartClass_instance.blink_jsObject = jsObject;
      }
    }
    return dartClass_instance;
  } catch(e, stacktrace){
    if (__interop_checks) {
      if (e is DebugAssertException)
        window.console.log("${e.message}\n ${stacktrace}");
      else
        window.console.log("${stacktrace}");
    }
  }

  return null;
}

/**
 * Create Dart class that maps to the JS Type that is the JS type being
 * extended using JS interop createCallback (we need the base type of the
 * custom element) not the Dart created constructor.
 */
wrap_jso_custom_element(jsObject) {
  try {
    if (jsObject is! js.JsObject) {
      // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
      return jsObject;
    }

    // Find out what object we're extending.
    var objectName = jsObject.toString();
    // Expect to see something like '[object HTMLElement]'.
    if (!objectName.startsWith('[object ')) {
      return jsObject;
    }

    var extendsClass = objectName.substring(8, objectName.length - 1);
    var func = getHtmlCreateFunction(extendsClass);
    if (__interop_checks)
      debug_or_assert("func != null name = ${extendsClass}", func != null);
    var dartClass_instance = func();
    dartClass_instance.blink_jsObject = jsObject;
    return dartClass_instance;
  } catch(e, stacktrace){
    if (__interop_checks) {
      if (e is DebugAssertException)
        window.console.log("${e.message}\n ${stacktrace}");
      else
        window.console.log("${stacktrace}");
    }

    // Problem?
    return null;
  }
}

class DebugAssertException implements Exception {
  String message;
  DebugAssertException(this.message);
}

debug_or_assert(message, expression) {
  if (!expression) {
    throw new DebugAssertException("$message");
  }
}

// TODO(terry): Manage JS interop JsFunctions for each listener used for add/
//              removeEventListener.  These JsFunctions will leak look at
//              fixing with weak-refs in C++.  The key are the hashcodes of the
//              user's this (this is needed for futures) and listener function.
Map<int, Map<int, js.JsFunction>> _knownListeners = {};

js.JsFunction wrap_event_listener(theObject, Function listener) {
  var thisHashCode = theObject.hashCode;
  var listenerHashCode = identityHashCode(listener);

  _knownListeners.putIfAbsent(thisHashCode, () => new Map<int, js.JsFunction>());
  _knownListeners[thisHashCode].putIfAbsent(listenerHashCode, () =>
    new js.JsFunction.withThis((theObject, event) => listener(wrap_jso(event))));

  return _knownListeners[thisHashCode][listenerHashCode];
}

Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
  var result = new Map();
  var keys = js.context['Object'].callMethod('keys', [jsObject]);
  for (var key in keys) {
    result[key] = wrap_jso(jsObject[key]);
  }
  return result;
}

// Converts a flat Dart map into a JavaScript object with properties this is
// is the Dartium only version it uses dart:js.
// TODO(alanknight): This could probably be unified with the dart2js conversions
// code in html_common and be more general.
convertDartToNative_Dictionary(Map dict) {
  if (dict == null) return null;
  var jsObject = new js.JsObject(js.context['Object']);
  dict.forEach((String key, value) {
    if (value is List) {
      var jsArray = new js.JsArray();
      value.forEach((elem) {
        jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
      });
      jsObject[key] = jsArray;
    } else {
      jsObject[key] = value;
    }
  });
  return jsObject;
}

// Converts a Dart list into a JsArray. For the Dartium version only.
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);

// Conversion function place holder (currently not used in dart2js or dartium).
List convertDartToNative_StringArray(List<String> input) => input;

$else
class JsoNativeFieldWrapper extends NativeFieldWrapperClass2 {}

unwrap_jso(dartClass_instance) => dartClass_instance;
wrap_jso(jsObject) => jsObject;
make_dart_rectangle(r) => r;
convertDartToNative_Dictionary(Map dict) => dict;
List convertDartToNative_StringArray(List<String> input) => input;
convertDartToNative_List(List input) => input;

$endif
