// 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 - unless you are editing documentation as per:
// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
// Auto-generated dart:svg library.

/**
 * A client-side key-value store with support for indexes.
 *
 * Many browsers support IndexedDB&mdash;a web standard for
 * an indexed database.
 * By storing data on the client in an IndexedDB,
 * a web app gets some advantages, such as faster performance and persistence.
 * To find out which browsers support IndexedDB,
 * refer to [Can I Use?](http://caniuse.com/#feat=indexeddb)
 *
 * In IndexedDB, each record is identified by a unique index or key,
 * making data retrieval speedy.
 * You can store structured data,
 * such as images, arrays, and maps using IndexedDB.
 * The standard does not specify size limits for individual data items
 * or for the database itself, but browsers may impose storage limits.
 *
 * ## Using indexed_db
 *
 * The classes in this library provide an interface
 * to the browser's IndexedDB, if it has one.
 * To use this library in your code:
 *
 *     import 'dart:indexed_db';
 *
 * A web app can determine if the browser supports
 * IndexedDB with [IdbFactory.supported]:
 *
 *     if (IdbFactory.supported)
 *       // Use indexeddb.
 *     else
 *       // Find an alternative.
 *
 * Access to the browser's IndexedDB is provided by the app's top-level
 * [Window] object, which your code can refer to with `window.indexedDB`.
 * So, for example,
 * here's how to use window.indexedDB to open a database:
 *
 *     Future open() {
 *       return window.indexedDB.open('myIndexedDB',
 *           version: 1,
 *           onUpgradeNeeded: _initializeDatabase)
 *         .then(_loadFromDB);
 *     }
 *     void _initializeDatabase(VersionChangeEvent e) {
 *       ...
 *     }
 *     Future _loadFromDB(Database db) {
 *       ...
 *     }
 *
 *
 * All data in an IndexedDB is stored within an [ObjectStore].
 * To manipulate the database use [Transaction]s.
 *
 * ## Other resources
 *
 * Other options for client-side data storage include:
 *
 * * [Window.localStorage]&mdash;a
 * basic mechanism that stores data as a [Map],
 * and where both the keys and the values are strings.
 *
 * * [dart:web_sql]&mdash;a database that can be queried with SQL.
 * 
 * For a tutorial about using the indexed_db library with Dart,
 * check out
 * [Use IndexedDB](http://www.dartlang.org/docs/tutorials/indexeddb/).
 *
 * MDN provides [API
 * documentation](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API).
 *
 * {@category Web}
 */
library dart.dom.indexed_db;

import 'dart:async';
import 'dart:html';
import 'dart:html_common';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:_js_helper' show Creates, Returns, JSName, Native;
import 'dart:_foreign_helper' show JS;
import 'dart:_interceptors' show Interceptor, JSExtendableArray;

import 'dart:_js_helper' show convertDartClosureToJS;

$!GENERATED_DART_FILES

class _KeyRangeFactoryProvider {

  static KeyRange createKeyRange_only(/*Key*/ value) =>
      _only(_class(), _translateKey(value));

  static KeyRange createKeyRange_lowerBound(
      /*Key*/ bound, [bool open = false]) =>
      _lowerBound(_class(), _translateKey(bound), open);

  static KeyRange createKeyRange_upperBound(
      /*Key*/ bound, [bool open = false]) =>
      _upperBound(_class(), _translateKey(bound), open);

  static KeyRange createKeyRange_bound(/*Key*/ lower, /*Key*/ upper,
      [bool lowerOpen = false, bool upperOpen = false]) =>
      _bound(_class(), _translateKey(lower), _translateKey(upper),
             lowerOpen, upperOpen);

  static var _cachedClass;

  static _class() {
    if (_cachedClass != null) return _cachedClass;
    return _cachedClass = _uncachedClass();
  }

  static _uncachedClass() =>
    JS('var',
       '''window.webkitIDBKeyRange || window.mozIDBKeyRange ||
          window.msIDBKeyRange || window.IDBKeyRange''');

  static _translateKey(idbkey) => idbkey;  // TODO: fixme.

  static KeyRange _only(cls, value) =>
       JS('KeyRange', '#.only(#)', cls, value);

  static KeyRange _lowerBound(cls, bound, open) =>
       JS('KeyRange', '#.lowerBound(#, #)', cls, bound, open);

  static KeyRange _upperBound(cls, bound, open) =>
       JS('KeyRange', '#.upperBound(#, #)', cls, bound, open);

  static KeyRange _bound(cls, lower, upper, lowerOpen, upperOpen) =>
       JS('KeyRange', '#.bound(#, #, #, #)',
          cls, lower, upper, lowerOpen, upperOpen);
}

// Conversions for IDBKey.
//
// Per http://www.w3.org/TR/IndexedDB/#key-construct
//
// "A value is said to be a valid key if it is one of the following types: Array
// JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float
// [WEBIDL]. However Arrays are only valid keys if every item in the array is
// defined and is a valid key (i.e. sparse arrays can not be valid keys) and if
// the Array doesn't directly or indirectly contain itself. Any non-numeric
// properties are ignored, and thus does not affect whether the Array is a valid
// key. Additionally, if the value is of type float, it is only a valid key if
// it is not NaN, and if the value is of type Date it is only a valid key if its
// [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN."

// What is required is to ensure that an Lists in the key are actually
// JavaScript arrays, and any Dates are JavaScript Dates.


/**
 * Converts a native IDBKey into a Dart object.
 *
 * May return the original input.  May mutate the original input (but will be
 * idempotent if mutation occurs).  It is assumed that this conversion happens
 * on native IDBKeys on all paths that return IDBKeys from native DOM calls.
 *
 * If necessary, JavaScript Dates are converted into Dart Dates.
 */
_convertNativeToDart_IDBKey(nativeKey) {
  containsDate(object) {
    if (isJavaScriptDate(object)) return true;
    if (object is List) {
      for (int i = 0; i < object.length; i++) {
        if (containsDate(object[i])) return true;
      }
    }
    return false;  // number, string.
  }
  if (containsDate(nativeKey)) {
    throw new UnimplementedError('Key containing DateTime');
  }
  // TODO: Cache conversion somewhere?
  return nativeKey;
}

/**
 * Converts a Dart object into a valid IDBKey.
 *
 * May return the original input.  Does not mutate input.
 *
 * If necessary, [dartKey] may be copied to ensure all lists are converted into
 * JavaScript Arrays and Dart Dates into JavaScript Dates.
 */
_convertDartToNative_IDBKey(dartKey) {
  // TODO: Implement.
  return dartKey;
}



/// May modify original.  If so, action is idempotent.
_convertNativeToDart_IDBAny(object) {
  return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
}

// TODO(sra): Add DateTime.
const String _idbKey = 'JSExtendableArray|=Object|num|String';
const _annotation_Creates_IDBKey = const Creates(_idbKey);
const _annotation_Returns_IDBKey = const Returns(_idbKey);
