/**
 * * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Generated by Apache Flex Cross-Compiler from org/apache/flex/utils/Language.as
 * org.apache.flex.utils.Language
 *
 * @fileoverview
 *
 * @suppress {checkTypes|accessControls}
 */

goog.provide('org.apache.flex.utils.Language');
goog.require('org.apache.flex.utils.Language');



/**
 * @constructor
 */
org.apache.flex.utils.Language = function() {
};


/**
 * @private
 * @type {Array}
 */
org.apache.flex.utils.Language.sortNames;


/**
 * @private
 * @type {Array}
 */
org.apache.flex.utils.Language.sortNamesOne = [];


/**
 * @private
 * @type {number}
 */
org.apache.flex.utils.Language.muler;


/**
 * @private
 * @type {string}
 */
org.apache.flex.utils.Language.zeroStr = String.fromCharCode(0);


/**
 * as()
 *
 * @asparam leftOperand The lefthand operand of the
 * binary as operator in AS3.
 * @asparam rightOperand The righthand operand of the
 * binary operator in AS3.
 * @asparam coercion The cast is a coercion,
 * throw exception if it fails.
 * @asreturn Returns the lefthand operand if it is of the
 * type of the righthand operand, otherwise null.
 * @export
 * @param {Object} leftOperand
 * @param {Object} rightOperand
 * @param {*=} coercion
 * @return {Object}
 */
org.apache.flex.utils.Language.as = function(leftOperand, rightOperand, coercion) {
  coercion = typeof coercion !== 'undefined' ? coercion : null;
  var /** @type {Error} */ error, /** @type {boolean} */ itIs, /** @type {string} */ message;
  coercion = (coercion !== undefined) ? coercion : false;
  itIs = org.apache.flex.utils.Language.is(leftOperand, rightOperand);
  if (!itIs && coercion) {
    message = 'Type Coercion failed';
    if (TypeError) {
      error = new TypeError(message);
    } else {
      error = new Error(message);
    }
    throw error;
  }
  return itIs ? leftOperand : null;
};


/**
 * int()
 *
 * @asparam value The value to be cast.
 * @asreturn {number}
 * @export
 * @param {number} value
 * @return {number}
 */
org.apache.flex.utils.Language._int = function(value) {
  return value >> 0;
};


/**
 * int()
 *
 * @asparam value The value to be cast.
 * @asreturn {string}
 * @export
 * @param {*} value
 * @return {string}
 */
org.apache.flex.utils.Language.string = function(value) {
  return value == null ? null : value.toString();
};


/**
 * is()
 *
 * @asparam leftOperand The lefthand operand of the
 * binary as operator in AS3.
 * @asparam rightOperand The righthand operand of the
 * binary operator in AS3.
 * @asreturn {boolean}
 * @export
 * @param {Object} leftOperand
 * @param {Object} rightOperand
 * @return {boolean}
 */
org.apache.flex.utils.Language.is = function(leftOperand, rightOperand) {
  var /** @type {Object} */ superClass;
  if (leftOperand == null || rightOperand == null)
    return false;
  if (leftOperand instanceof rightOperand)
    return true;
  if (rightOperand === Object)
    return true;
  if (typeof(leftOperand) === 'string')
    return rightOperand === String;
  if (typeof(leftOperand) === 'number')
    return rightOperand === Number;
  if (typeof(leftOperand) === 'boolean')
    return rightOperand === Boolean;
  if (rightOperand === Array)
    return Array.isArray(leftOperand);
  if (leftOperand.FLEXJS_CLASS_INFO === undefined)
    return false;
  if (leftOperand.FLEXJS_CLASS_INFO.interfaces) {
    if (org.apache.flex.utils.Language.checkInterfaces(leftOperand, rightOperand)) {
      return true;
    }
  }
  superClass = leftOperand.constructor;
  superClass = superClass.superClass_;
  if (superClass) {
    while (superClass && superClass.FLEXJS_CLASS_INFO) {
      if (superClass.FLEXJS_CLASS_INFO.interfaces) {
        if (org.apache.flex.utils.Language.checkInterfaces(superClass, rightOperand)) {
          return true;
        }
      }
      superClass = superClass.constructor;
      superClass = superClass.superClass_;
    }
  }
  return false;
};


/**
 * Helper function for is()
 * @private
 * @param {*} leftOperand
 * @param {*} rightOperand
 * @return {boolean}
 */
org.apache.flex.utils.Language.checkInterfaces = function(leftOperand, rightOperand) {
  var /** @type {number} */ i, /** @type {Array} */ interfaces;
  interfaces = leftOperand.FLEXJS_CLASS_INFO.interfaces;
  for (i = interfaces.length - 1; i > -1; i--) {
    if (interfaces[i] === rightOperand) {
      return true;
    }
    if (interfaces[i].prototype.FLEXJS_CLASS_INFO.interfaces) {
      var /** @type {boolean} */ isit = org.apache.flex.utils.Language.checkInterfaces(interfaces[i].prototype, rightOperand);
      if (isit)
        return true;
    }
  }
  return false;
};


/**
 * Implementation of "classDef is Class"
 * @export
 * @param {*} classDef
 * @return {boolean}
 */
org.apache.flex.utils.Language.prototype.isClass = function(classDef) {
  return typeof(classDef) === 'function' && classDef.prototype && classDef.prototype.constructor === classDef;
};


/**
 * Implementation of "classDef as Class"
 * @export
 * @param {*} classDef
 * @return {Object}
 */
org.apache.flex.utils.Language.prototype.asClass = function(classDef) {
  return this.isClass(classDef) ? classDef : null;
};


/**
 * postdecrement handles foo--
 *
 * @asparam obj The object with the getter/setter.
 * @asparam prop The name of a property.
 * @asreturn {number}
 * @export
 * @param {Object} obj
 * @param {string} prop
 * @return {number}
 */
org.apache.flex.utils.Language.postdecrement = function(obj, prop) {
  var /** @type {number} */ value = Number(obj[prop]);
  obj[prop] = value - 1;
  return value;
};


/**
 * postincrement handles foo++
 *
 * @asparam obj The object with the getter/setter.
 * @asparam prop The name of a property.
 * @asreturn {number}
 * @export
 * @param {Object} obj
 * @param {string} prop
 * @return {number}
 */
org.apache.flex.utils.Language.postincrement = function(obj, prop) {
  var /** @type {number} */ value = Number(obj[prop]);
  obj[prop] = value + 1;
  return value;
};


/**
 * predecrement handles --foo
 *
 * @asparam obj The object with the getter/setter.
 * @asparam prop The name of a property.
 * @asreturn {number}
 * @export
 * @param {Object} obj
 * @param {string} prop
 * @return {number}
 */
org.apache.flex.utils.Language.predecrement = function(obj, prop) {
  var /** @type {number} */ value = obj[prop] - 1;
  obj[prop] = value;
  return value;
};


/**
 * preincrement handles ++foo
 *
 * @asparam obj The object with the getter/setter.
 * @asparam prop The name of a property.
 * @asreturn {number}
 * @export
 * @param {Object} obj
 * @param {string} prop
 * @return {number}
 */
org.apache.flex.utils.Language.preincrement = function(obj, prop) {
  var /** @type {number} */ value = Number(obj[prop] + 1);
  obj[prop] = value;
  return value;
};


/**
 * superGetter calls the getter on the given class' superclass.
 *
 * @asparam clazz The class.
 * @asparam pthis The this pointer.
 * @asparam prop The name of the getter.
 * @asreturn {Object}
 * @export
 * @param {Object} clazz
 * @param {Object} pthis
 * @param {string} prop
 * @return {Object}
 */
org.apache.flex.utils.Language.superGetter = function(clazz, pthis, prop) {
  var /** @type {Object} */ superClass = clazz.superClass_;
  var /** @type {Object} */ superdesc = Object.getOwnPropertyDescriptor(superClass, prop);
  while (superdesc == null) {
    superClass = superClass.constructor;
    superClass = superClass.superClass_;
    superdesc = Object.getOwnPropertyDescriptor(superClass, prop);
  }
  return superdesc.get.call(pthis);
};


/**
 * superSetter calls the setter on the given class' superclass.
 *
 * @asparam clazz The class.
 * @asparam pthis The this pointer.
 * @asparam prop The name of the getter.
 * @asparam value The value.
 * @export
 * @param {Object} clazz
 * @param {Object} pthis
 * @param {string} prop
 * @param {Object} value
 */
org.apache.flex.utils.Language.superSetter = function(clazz, pthis, prop, value) {
  var /** @type {Object} */ superClass = clazz.superClass_;
  var /** @type {Object} */ superdesc = Object.getOwnPropertyDescriptor(superClass, prop);
  while (superdesc == null) {
    superClass = superClass.constructor;
    superClass = superClass.superClass_;
    superdesc = Object.getOwnPropertyDescriptor(superClass, prop);
  }
  superdesc.set.apply(pthis, [value]);
};


/**
 * @export
 * @param {...} rest
 */
org.apache.flex.utils.Language.trace = function(rest) {
  rest = Array.prototype.slice.call(arguments, 0);
  var /** @type {*} */ theConsole;
  theConsole = goog.global.console;
  if (theConsole === undefined) {
    if (typeof(window) !== "undefined") {
      theConsole = window.console;
    } else if (typeof(console) !== "undefined") {
      theConsole = console;
    }
  }
  try {
    if (theConsole && theConsole.log) {
      theConsole.log.apply(theConsole, rest);
    }
  } catch (e) {
  }
};


/**
 * uint()
 *
 * @asparam value The value to be cast.
 * @asreturn {number}
 * @export
 * @param {number} value
 * @return {number}
 */
org.apache.flex.utils.Language.uint = function(value) {
  return value >>> 0;
};


/**
 * caches closures and returns the one closure
 *
 * @asparam fn The method on the instance.
 * @asparam object The instance.
 * @asparam boundMethodName The name to use to cache the closure.
 * @asreturn The closure.
 * @export
 * @param {Function} fn
 * @param {Object} object
 * @param {string} boundMethodName
 * @return {Function}
 */
org.apache.flex.utils.Language.closure = function(fn, object, boundMethodName) {
  if (object.hasOwnProperty(boundMethodName)) {
    return object[boundMethodName];
  }
  var /** @type {Function} */ boundMethod = goog.bind(fn, object);
  Object.defineProperty(object, boundMethodName, {value:boundMethod});
  return boundMethod;
};


/**
 * @asparam	arr
 * @asparam	names
 * @asparam	opt
 * @export
 * @param {Array} arr
 * @param {Object} names
 * @param {Object=} opt
 */
org.apache.flex.utils.Language.sortOn = function(arr, names, opt) {
  opt = typeof opt !== 'undefined' ? opt : 0;
  if (org.apache.flex.utils.Language.is(names, Array)) {
    org.apache.flex.utils.Language.sortNames = org.apache.flex.utils.Language.as(names, Array);
  } else {
    org.apache.flex.utils.Language.sortNamesOne[0] = names;
    org.apache.flex.utils.Language.sortNames = org.apache.flex.utils.Language.sortNamesOne;
  }
  if (org.apache.flex.utils.Language.is(opt, Array)) {
    var /** @type {number} */ opt2 = 0;
    var foreachiter0_target = opt;
    for (var foreachiter0 in foreachiter0_target) 
    {
    var o = foreachiter0_target[foreachiter0];
    {
      opt2 = opt2 | o;
    }}
    
  } else {
    opt2 = org.apache.flex.utils.Language.as(opt, Number);
  }
  org.apache.flex.utils.Language.muler = (2 & opt2) > 0 ? -1 : 1;
  if (opt2 & 16) {
    arr.sort(org.apache.flex.utils.Language.compareNumber);
  } else if (opt2 & 1) {
    arr.sort(org.apache.flex.utils.Language.compareStringCaseinsensitive);
  } else {
    arr.sort(org.apache.flex.utils.Language.compareString);
  }
};


/**
 * @private
 * @param {Object} a
 * @param {Object} b
 * @return {number}
 */
org.apache.flex.utils.Language.compareStringCaseinsensitive = function(a, b) {
  var foreachiter1_target = org.apache.flex.utils.Language.sortNames;
  for (var foreachiter1 in foreachiter1_target) 
  {
  var n = foreachiter1_target[foreachiter1];
  {
    var /** @type {number} */ v = Number((a[n] || org.apache.flex.utils.Language.zeroStr).toString().toLowerCase().localeCompare((b[n] || org.apache.flex.utils.Language.zeroStr).toString().toLowerCase()));
    if (v != 0) {
      return v * org.apache.flex.utils.Language.muler;
    }
  }}
  
  return 0;
};


/**
 * @private
 * @param {Object} a
 * @param {Object} b
 * @return {number}
 */
org.apache.flex.utils.Language.compareString = function(a, b) {
  var foreachiter2_target = org.apache.flex.utils.Language.sortNames;
  for (var foreachiter2 in foreachiter2_target) 
  {
  var n = foreachiter2_target[foreachiter2];
  {
    var /** @type {number} */ v = Number((a[n] || org.apache.flex.utils.Language.zeroStr).toString().localeCompare((b[n] || org.apache.flex.utils.Language.zeroStr).toString()));
    if (v != 0) {
      return v * org.apache.flex.utils.Language.muler;
    }
  }}
  
  return 0;
};


/**
 * @private
 * @param {Object} a
 * @param {Object} b
 * @return {number}
 */
org.apache.flex.utils.Language.compareNumber = function(a, b) {
  var foreachiter3_target = org.apache.flex.utils.Language.sortNames;
  for (var foreachiter3 in foreachiter3_target) 
  {
  var n = foreachiter3_target[foreachiter3];
  {
    if (a[n] > b[n]) {
      return org.apache.flex.utils.Language.muler;
    } else if (a[n] < b[n]) {
      return -org.apache.flex.utils.Language.muler;
    }
  }}
  
  return 0;
};


/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org.apache.flex.utils.Language.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'Language', qName: 'org.apache.flex.utils.Language'}] };


/**
 * Prevent renaming of class. Needed for reflection.
 */
goog.exportSymbol('org.apache.flex.utils.Language', org.apache.flex.utils.Language);



/**
 * Reflection
 *
 * @return {Object.<string, Function>}
 */
org.apache.flex.utils.Language.prototype.FLEXJS_REFLECTION_INFO = function () {
  return {
    variables: function () {
      return {
      };
    },
    accessors: function () {
      return {
      };
    },
    methods: function () {
      return {
        'isClass': { type: 'Boolean', declaredBy: 'org.apache.flex.utils.Language'},
        'asClass': { type: 'Class', declaredBy: 'org.apache.flex.utils.Language'}
      };
    }
  };
};