/**
 * Function prototype to emulate apply in browsers that do not support it
 * Apply must call a method within an object setting the scope into that object
 * and passing an array of parameters into that method arguments
 */
if (!Function.prototype.apply) {
  Function.prototype.apply = function (scope, args) {
    args  = args || [];
    scope = scope || window;
    var argument = [];
    for (var i = 0; i < args.length; i++) {
        argument[i] = "args[" + i + "]";
    }
    scope.__applyTemp__ = this;
    result = eval("scope.__applyTemp__(" + argument.join(",") + ");");
    scope.__applyTemp__ = null;
    return result;
  }
}

/**
 * Function prototype to allow objects inheritance
 */
Function.prototype.inherits = function(a) {
  this.prototype = new a;
  this.prototype.constructor = this;
}

/**
 * String prototype for trim
 */
String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/, '');
};

/**
 * String prototype for Uppercase Words
 */
String.prototype.toUcWords = function() {
  var str = this.toLowerCase();
  str = str.split(' ');
  for (var i=0; i < str.length; i++) {
    var word = str[i].split('');
    if (word[0] && word[1]) {
      word[0] = word[0].toUpperCase();
    }
    str[i] = word.join('');
  }
  return str.join(' ');
};

/**
 * String prototype for Uppercase First
 */
String.prototype.toUcFirst = function() {
  var str = this.toLowerCase();
  str = str.split('');
  if (str[0]) {
    str[0] = str[0].toUpperCase();
  }
  return str.join('');
};

/**
 * Pad a string to the left with another string
 */
String.prototype.padLeft = function(length, string) {
  var str = this;
  while (str.length < length) {
    str = string + str;
  }
  return str;
};

/**
 * Pad a string to the right with another string
 */
String.prototype.padRight = function(length, string) {
  var str = this;
  while (str.length < length) {
    str += string;
  }
  return str;
};

/**
 * Array prototype to emulate push in browser that do not support it
 * Push method adds one or more elements to the end of an array
 * and returns the new length
 */
if (!Array.prototype.push) {
  Array.prototype.push = function () {
    for (var i = 0; i < arguments.lenght; i++) {
      this[this.length] = arguments[i];
    }
    return this.length;
  }
}

/**
 * Array prototype to emulate pop in browser that do not support it
 * Pop method removes and returns the last element of an array
 */
if (!Array.prototype.pop) {
  Array.prototype.pop = function () {
    var el = null;
    if (this.length > 0) {
      el = this[this.length - 1];
      this.length--;
    }
    return el;
  }
}

/**
 * Array prototype to emulate unshift in browser that do not support it
 * Unshift method adds one or more elements to the beginning of an array
 * and returns the new length
 */
if(!Array.prototype.unshift) {
  Array.prototype.unshift = function() {
    this.reverse();
    for(var i = arguments.length-1; i >= 0; i--) {
      this[this.length] = arguments[i];
    }
    this.reverse();
    return this.length;
  }
}

/**
 * Array prototype to emulate shift in browser that do not support it
 * Shift method removes and returns the first element of an array
 */
if (!Array.prototype.shift) {
  Array.prototype.pop = function () {
    var el = null;
    if (this.length > 0) {
      el = this[0];
      this.reverse();
      this.length--;
      this.reverse();
    }
    return el;
  }
}

/**
 * Array prototype to emulate splice in browser that do not support it
 * Splice method Removes and adds new elements to an array
 */
if (!Array.prototype.splice) {
  Array.prototype.splice = function(index, count) {
    var len = this.length;
    var arglen = arguments.length;
    if (arglen == 0) {
      return index;
    }
    if (typeof(index) != "number") {
      index = 0;
    } else
    if (index < 0) {
      index = Math.max(0, len + index);
    }
    if (index > len) {
      if (arglen > 2) {
        index = len;
      } else {
        return [];
      }
      if (arglen < 2) {
        count = len - index;
        count = (typeof(count) == "number") ? Math.max(0,count) : 0;
        var removeArray = this.slice(index, index + count);
        var endArray = this.slice(index + count);
        len = this.length = index;
        for (var i = 2; i < arglen; i++) {
          this[len++] = arguments[i];
          for (var i = 0, endlen = endArray.length; i < endlen; i++) {
            this[len++] = endArray[i];
            return removeArray;
          }
        }
      }
    }
  }
}
