/**

* @namespace jvm Holds core methods and classes used by jVectorMap.
*/

var jvm = {

/**
 * Inherits child's prototype from the parent's one.
 * @param {Function} child
 * @param {Function} parent
 */
inherits: function(child, parent) {
  function temp() {}
  temp.prototype = parent.prototype;
  child.prototype = new temp();
  child.prototype.constructor = child;
  child.parentClass = parent;
},

/**
 * Mixes in methods from the source constructor to the target one.
 * @param {Function} target
 * @param {Function} source
 */
mixin: function(target, source){
  var prop;

  for (prop in source.prototype) {
    if (source.prototype.hasOwnProperty(prop)) {
      target.prototype[prop] = source.prototype[prop];
    }
  }
},

min: function(values){
  var min = Number.MAX_VALUE,
      i;

  if (values instanceof Array) {
    for (i = 0; i < values.length; i++) {
      if (values[i] < min) {
        min = values[i];
      }
    }
  } else {
    for (i in values) {
      if (values[i] < min) {
        min = values[i];
      }
    }
  }
  return min;
},

max: function(values){
  var max = Number.MIN_VALUE,
      i;

  if (values instanceof Array) {
    for (i = 0; i < values.length; i++) {
      if (values[i] > max) {
        max = values[i];
      }
    }
  } else {
    for (i in values) {
      if (values[i] > max) {
        max = values[i];
      }
    }
  }
  return max;
},

keys: function(object){
  var keys = [],
      key;

  for (key in object) {
    keys.push(key);
  }
  return keys;
},

values: function(object){
  var values = [],
      key,
      i;

  for (i = 0; i < arguments.length; i++) {
    object = arguments[i];
    for (key in object) {
      values.push(object[key]);
    }
  }
  return values;
},

whenImageLoaded: function(url){
  var deferred = new jvm.$.Deferred(),
      img = jvm.$('<img/>');

  img.error(function(){
    deferred.reject();
  }).load(function(){
    deferred.resolve(img);
  });
  img.attr('src', url);

  return deferred;
},

isImageUrl: function(s){
  return /\.\w{3,4}$/.test(s);
}

};

jvm.$ = jQuery;

/**

* indexOf polyfill for IE < 9
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
*/

if (!Array.prototype.indexOf) {

Array.prototype.indexOf = function (searchElement, fromIndex) {

  var k;

  // 1. Let O be the result of calling ToObject passing
  //    the this value as the argument.
  if (this == null) {
    throw new TypeError('"this" is null or not defined');
  }

  var O = Object(this);

  // 2. Let lenValue be the result of calling the Get
  //    internal method of O with the argument "length".
  // 3. Let len be ToUint32(lenValue).
  var len = O.length >>> 0;

  // 4. If len is 0, return -1.
  if (len === 0) {
    return -1;
  }

  // 5. If argument fromIndex was passed let n be
  //    ToInteger(fromIndex); else let n be 0.
  var n = +fromIndex || 0;

  if (Math.abs(n) === Infinity) {
    n = 0;
  }

  // 6. If n >= len, return -1.
  if (n >= len) {
    return -1;
  }

  // 7. If n >= 0, then Let k be n.
  // 8. Else, n<0, Let k be len - abs(n).
  //    If k is less than 0, then let k be 0.
  k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

  // 9. Repeat, while k < len
  while (k < len) {
    // a. Let Pk be ToString(k).
    //   This is implicit for LHS operands of the in operator
    // b. Let kPresent be the result of calling the
    //    HasProperty internal method of O with argument Pk.
    //   This step can be combined with c
    // c. If kPresent is true, then
    //    i.  Let elementK be the result of calling the Get
    //        internal method of O with the argument ToString(k).
    //   ii.  Let same be the result of applying the
    //        Strict Equality Comparison Algorithm to
    //        searchElement and elementK.
    //  iii.  If same is true, return k.
    if (k in O && O[k] === searchElement) {
      return k;
    }
    k++;
  }
  return -1;
};

}