
/**
 * Array functions
 */

//
// Add one or more arrays, and return the new array. No array is modified.
// Arguments:
//    a - The array that has to be joined with this array
//
if ( typeof Array.prototype.concat === 'undefined' ) {
	Array.prototype.concat = function(a) {
		for(var i = 0, b = this.copy(); i < a.length; i++) {
			b[b.length] = a[i];
		}
		return b;
	};
}

//
// Copy all elements to a new array, by reference if possible, or by value.
//
if ( typeof Array.prototype.copy === 'undefined' ) {
	Array.prototype.copy = function() {
		var a = [], i = this.length;
		while(i--) {
			a[i] = (typeof this[i].copy !== 'undefined') ? this[i].copy() : this[i];
		}
		return a;
	};
}

//
// Remove and return the last element of an array.
//
if ( typeof Array.prototype.pop === 'undefined' ) {
	Array.prototype.pop = function() {
		var b = this[this.length-1];
		this.length--;
		return b;
	};
}

//
// Add one or more elements to the end of an array, return the new length.
//
if ( typeof Array.prototype.push === 'undefined' ) {
	Array.prototype.push == function() {
		for(var i = 0, b = this.length, a = arguments, l = a.length; i < l; i++) {
			this[b + i] = a[i];
		}
		return this.length;
	};
}

//
// Remove and return the first element.
//
if ( typeof Array.prototype.shift === 'undefined' ) {
	Array.prototype.shift = function() {
		for(var i = 0, b = this[0], l = this.length - 1; i < l; i++) {
			this[i] = this[i + 1];
		}
		this.length--;
		return b;
	};
}

//
// Copy and return several elements. The original array is not modified.
//
if ( typeof Array.prototype.slice === 'undefined' ) {
	Array.prototype.slice = function(a, c) {
		var i, l = this.length, r = [];
		if( !c ) { c = l; }
		if( c < 0 ) { c = l + c; }
		if( a < 0 ) { a = l - a; }
		if( c < a ) { i = a; a = c; c = i; }
		for( i = 0; i < c - a; i++ ) { r[i] = this[a + i]; }
		return r;
	};
}

//
// Remove or replace several elements and return any deleted elements.
//
if ( typeof Array.prototype.splice === 'undefined' ) {
	Array.prototype.splice = function(a, c) {
		var i = 0, e = arguments, d = this.copy(), f = a, l = this.length;
		if( !c ) { c = l - a; }
		for( i; i < e.length - 2; i++ ) { this[a + i] = e[i + 2]; }
		for( a; a < l - c; a++ ) { this[a + e.length - 2] = d[a - c]; }
		this.length -= c - e.length + 2;
		return d.slice(f, f + c);
	};
}

//
// Add an element to the beginning of an array, return the new length.
//
if ( typeof Array.prototype.unshift === 'undefined' ) {
	Array.prototype.unshift = function() {
		this.reverse();
		var a = arguments, i = a.length;
		while(i--) { this.push(a[i]); }
		this.reverse();
		return this.length;
	};
}

//
// Return index of the first element that matches value.
// Arguments:
//    v - value
//    b - search from this element forward
//    s - search strict
Array.prototype.indexOf = function( v, b, s ) {
	for( var i = +b || 0, l = this.length; i < l; i++ ) {
		if( this[i]===v || s && this[i]==v ) { return i; }
	}
	return -1;
};

//
// Return index of the last element that matches value.
// Arguments:
//    v - value
//    b - search from this element backward
//    s - search strict
Array.prototype.lastIndexOf = function( v, b, s ) {
	b = +b || 0;
	var i = this.length;
	while(i-->b) {
		if( this[i]===v || s && this[i]==v ) { return i; }
	}
	return -1;
};

//
// Return an array where duplicate elements have been removed.
//
Array.prototype.unique = function( b ) {
	var a = [], i, l = this.length;
	for( i=0; i<l; i++ ) {
		if( a.indexOf( this[i], 0, b ) < 0 ) { a.push( this[i] ); }
	}
	return a;
};
