// 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 _js_helper;

String typeNameInChrome(obj) {
  String name = JS('String', "#.constructor.name", obj);
  return typeNameInWebKitCommon(name);
}

String typeNameInSafari(obj) {
  String name = JS('String', '#', constructorNameFallback(obj));
  // Safari is very similar to Chrome.
  return typeNameInWebKitCommon(name);
}

String typeNameInWebKitCommon(tag) {
  String name = JS('String', '#', tag);
  if (name == 'CanvasPixelArray') return 'Uint8ClampedArray';
  if (name == 'AudioChannelMerger') return 'ChannelMergerNode';
  if (name == 'AudioChannelSplitter') return 'ChannelSplitterNode';
  if (name == 'AudioGainNode') return 'GainNode';
  if (name == 'AudioPannerNode') return 'PannerNode';
  if (name == 'JavaScriptAudioNode') return 'ScriptProcessorNode';
  if (name == 'Oscillator') return 'OscillatorNode';
  if (name == 'RealtimeAnalyserNode') return 'AnalyserNode';
  if (name == 'IDBVersionChangeRequest') return 'IDBOpenDBRequest';
  return name;
}

String typeNameInOpera(obj) {
  String name = JS('String', '#', constructorNameFallback(obj));
  return name;
}

String typeNameInFirefox(obj) {
  String name = JS('String', '#', constructorNameFallback(obj));
  if (name == 'BeforeUnloadEvent') return 'Event';
  if (name == 'CSS2Properties') return 'CSSStyleDeclaration';
  if (name == 'DataTransfer') return 'Clipboard';
  if (name == 'DragEvent') return 'MouseEvent';
  if (name == 'GeoGeolocation') return 'Geolocation';
  if (name == 'WorkerMessageEvent') return 'MessageEvent';
  if (name == 'XMLDocument') return 'Document';
  return name;
}

String typeNameInIE(obj) {
  String name = JS('String', '#', constructorNameFallback(obj));
  if (name == 'Document') {
    // IE calls both HTML and XML documents 'Document', so we check for the
    // xmlVersion property, which is the empty string on HTML documents.
    if (JS('bool', '!!#.xmlVersion', obj)) return 'Document';
    return 'HTMLDocument';
  }
  if (name == 'BeforeUnloadEvent') return 'Event';
  if (name == 'CanvasPixelArray') return 'Uint8ClampedArray';
  if (name == 'DataTransfer') return 'Clipboard';
  if (name == 'DragEvent') return 'MouseEvent';
  if (name == 'HTMLDDElement') return 'HTMLElement';
  if (name == 'HTMLDTElement') return 'HTMLElement';
  if (name == 'HTMLTableDataCellElement') return 'HTMLTableCellElement';
  if (name == 'HTMLTableHeaderCellElement') return 'HTMLTableCellElement';
  if (name == 'HTMLPhraseElement') return 'HTMLElement';
  if (name == 'MSStyleCSSProperties') return 'CSSStyleDeclaration';
  if (name == 'Position') return 'Geoposition';

  // Patches for types which report themselves as Objects.
  if (name == 'Object') {
    if (JS('bool', 'window.DataView && (# instanceof window.DataView)', obj)) {
      return 'DataView';
    }
  }
  return name;
}

String constructorNameFallback(object) {
  if (object == null) return 'Null';
  var constructor = JS('var', "#.constructor", object);
  if (identical(JS('String', "typeof(#)", constructor), 'function')) {
    var name = JS('var', r'#.builtin$cls', constructor);
    if (name != null) return name;
    // The constructor isn't null or undefined at this point. Try
    // to grab hold of its name.
    name = JS('var', '#.name', constructor);
    // If the name is a non-empty string, we use that as the type
    // name of this object. On Firefox, we often get 'Object' as
    // the constructor name even for more specialized objects so
    // we have to fall through to the toString() based implementation
    // below in that case.
    if (name is String
        && !identical(name, '')
        && !identical(name, 'Object')
        && !identical(name, 'Function.prototype')) {  // Can happen in Opera.
      return name;
    }
  }
  String string = JS('String', 'Object.prototype.toString.call(#)', object);
  return JS('String', '#.substring(8, # - 1)', string, string.length);
}

/**
 * If a lookup on an object [object] that has [tag] fails, this function is
 * called to provide an alternate tag.  This allows us to fail gracefully if we
 * can make a good guess, for example, when browsers add novel kinds of
 * HTMLElement that we have never heard of.
 */
String alternateTag(object, String tag) {
  // Does it smell like some kind of HTML element?
  if (JS('bool', r'!!/^HTML[A-Z].*Element$/.test(#)', tag)) {
    // Check that it is not a simple JavaScript object.
    String string = JS('String', 'Object.prototype.toString.call(#)', object);
    if (string == '[object Object]') return null;
    return 'HTMLElement';
  }
  return null;
}

// TODO(ngeoffray): stop using this method once our optimizers can
// change str1.contains(str2) into str1.indexOf(str2) != -1.
bool contains(String userAgent, String name) {
  return JS('int', '#.indexOf(#)', userAgent, name) != -1;
}

int arrayLength(List array) {
  return JS('int', '#.length', array);
}

arrayGet(List array, int index) {
  return JS('var', '#[#]', array, index);
}

void arraySet(List array, int index, var value) {
  JS('var', '#[#] = #', array, index, value);
}

propertyGet(var object, String property) {
  return JS('var', '#[#]', object, property);
}

bool callHasOwnProperty(var function, var object, String property) {
  return JS('bool', '#.call(#, #)', function, object, property);
}

void propertySet(var object, String property, var value) {
  JS('var', '#[#] = #', object, property, value);
}

getPropertyFromPrototype(var object, String name) {
  return JS('var', 'Object.getPrototypeOf(#)[#]', object, name);
}

newJsObject() {
  return JS('var', '{}');
}

/**
 * Returns the function to use to get the type name of an object.
 */
Function getFunctionForTypeNameOf() {
  // If we're not in the browser, we're almost certainly running on v8.
  if (!identical(JS('String', 'typeof(navigator)'), 'object')) return typeNameInChrome;

  String userAgent = JS('String', "navigator.userAgent");
  // TODO(antonm): remove a reference to DumpRenderTree.
  if (contains(userAgent, 'Chrome') || contains(userAgent, 'DumpRenderTree')) {
    return typeNameInChrome;
  } else if (contains(userAgent, 'Firefox')) {
    return typeNameInFirefox;
  } else if (contains(userAgent, 'MSIE')) {
    return typeNameInIE;
  } else if (contains(userAgent, 'Opera')) {
    return typeNameInOpera;
  } else if (contains(userAgent, 'AppleWebKit')) {
    // Chrome matches 'AppleWebKit' too, but we test for Chrome first, so this
    // is not a problem.
    // Note: Just testing for "Safari" doesn't work when the page is embedded
    // in a UIWebView on iOS 6.
    return typeNameInSafari;
  } else {
    return constructorNameFallback;
  }
}


/**
 * Cached value for the function to use to get the type name of an
 * object.
 */
Function _getTypeNameOf;

/**
 * Returns the type name of [obj].
 */
String getTypeNameOf(var obj) {
  if (_getTypeNameOf == null) _getTypeNameOf = getFunctionForTypeNameOf();
  return _getTypeNameOf(obj);
}

String toStringForNativeObject(var obj) {
  String name = JS('String', '#', getTypeNameOf(obj));
  return 'Instance of $name';
}

int hashCodeForNativeObject(object) => Primitives.objectHashCode(object);

/**
 * Sets a JavaScript property on an object.
 */
void defineProperty(var obj, String property, var value) {
  JS('void',
      'Object.defineProperty(#, #, '
          '{value: #, enumerable: false, writable: true, configurable: true})',
      obj,
      property,
      value);
}


// Is [obj] an instance of a Dart-defined class?
bool isDartObject(obj) {
  // Some of the extra parens here are necessary.
  return JS('bool', '((#) instanceof (#))', obj, JS_DART_OBJECT_CONSTRUCTOR());
}

/// A JavaScript object mapping tags to interceptors.
var interceptorsByTag;

/// A JavaScript object mapping tags to `true` or `false`.
var leafTags;

/**
 * Associates tags with an interceptor.  Called from generated code.  The tags
 * are all 'leaf' tags representing classes that have no subclasses with
 * different behaviour.
 *
 * [tags] is a string of `|`-separated tags.
 */
void defineNativeMethods(String tags, interceptorClass) {
  defineNativeMethodsCommon(tags, interceptorClass, true);
}

/**
 * Associates tags with an interceptor.  Called from generated code.  The tags
 * are all non-'leaf' tags, representing classes that have a subclass with
 * different behaviour.
 */
void defineNativeMethodsNonleaf(String tags, interceptorClass) {
  defineNativeMethodsCommon(tags, interceptorClass, false);
}

void defineNativeMethodsCommon(String tags, var interceptorClass, bool isLeaf) {
  var methods = JS('', '#.prototype', interceptorClass);
  if (interceptorsByTag == null) interceptorsByTag = JS('=Object', '{}');
  if (leafTags == null) leafTags = JS('=Object', '{}');

  var tagsList = JS('=List', '#.split("|")', tags);
  for (int i = 0; i < tagsList.length; i++) {
    var tag = tagsList[i];
    JS('void', '#[#] = #', interceptorsByTag, tag, methods);
    JS('void', '#[#] = #', leafTags, tag, isLeaf);
  }
}

void defineNativeMethodsFinish() {
  // TODO(sra): Investigate placing a dispatch record on Object.prototype that
  // returns an interceptor for JavaScript objects.  This avoids needing a test
  // in every interceptor, and prioritizes the performance of known native
  // classes over unknown.
}

lookupInterceptor(var hasOwnPropertyFunction, String tag) {
  var map = interceptorsByTag;
  if (map == null) return null;
  return callHasOwnProperty(hasOwnPropertyFunction, map, tag)
      ? propertyGet(map, tag)
      : null;
}

lookupDispatchRecord(obj) {
  var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
  var interceptor = null;
  assert(!isDartObject(obj));
  String tag = getTypeNameOf(obj);

  interceptor = lookupInterceptor(hasOwnPropertyFunction, tag);
  if (interceptor == null) {
    String secondTag = alternateTag(obj, tag);
    if (secondTag != null) {
      interceptor = lookupInterceptor(hasOwnPropertyFunction, secondTag);
    }
  }
  if (interceptor == null) {
    // This object is not known to Dart.  There could be several
    // reasons for that, including (but not limited to):
    // * A bug in native code (hopefully this is caught during development).
    // * An unknown DOM object encountered.
    // * JavaScript code running in an unexpected context.  For
    //   example, on node.js.
    return null;
  }
  var isLeaf =
      (leafTags != null) && JS('bool', '(#[#]) === true', leafTags, tag);
  if (isLeaf) {
    var fieldName = JS_IS_INDEXABLE_FIELD_NAME();
    bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName);
    return makeDispatchRecord(interceptor, false, null, indexability);
  } else {
    var proto = JS('', 'Object.getPrototypeOf(#)', obj);
    return makeDispatchRecord(interceptor, proto, null, null);
  }
}
