/**
 * Filename    : Array.js
 * Author      : Robert Cerny
 * Created     : 2006-07-26
 * Last Change : 2006-11-26
 *
 * Description:
 *   Some useful methods for the Array prototype.
 *
 * History:
 *   2006-07-26 Created.
 *
 * License:
 */

CERNY.js.Array = {};

CERNY.require("CERNY.js.Array");

/**
 * Map an array onto another array based on func.
 *
 * func - the function that should be applied to all elements of this
 *        array
 * return - an array of the results of the applications of func to the
 *          items of this array
 */
Array.prototype.map = function(func) {
    var result = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
        result[i] = func(this[i]);
    }
    return result;
};

/**
 * Append array to this array.
 *
 * array - the array to append
 */
Array.prototype.append = function(array) {
    for (var i = 0; i < a.length; i += 1) {
        this.push(array[i]);
    }
};

if (!Array.prototype.push) {
    Array.prototype.push = function() {
        for (var i = 0; i < arguments.length; i++) {
            this[this.length] = arguments[i];
        }
        return this.length;
    };
}

/**
 * Filter this array through predicate.
 *
 * predicate - the predicate to apply to all items of array
 * return - a new array containing all items that return true on application of predicate
 */
Array.prototype.filter = function(predicate) {
    var result = [];
    for (var i = 0; i < this.length; i += 1) {
        if (predicate(this[i])){
            result.push(this[i]);
        }
    }
    return result;
};

/**
 * Copy this array.
 *
 * return - a copy of this array
 */
Array.prototype.copy = function() {
    return this.filter(function() {return true; });
};

/**
 * Figure out the index of x in array based on cmpFunc.
 *
 * x - the item to look for in this array
 * cmpFunc - the function to use to decide on identity
 * return - the index of the position of x in this array or -1, if x
 *          is not in this array.
 */
Array.prototype.indexOf = function(x, cmpFunc) {
    if (!isFunction(cmpFunc)) {
        cmpFunc = function (a, b) { return a == b; };
    }
    for (var i = 0; i < this.length; i++) {
        if (cmpFunc(this[i], x)) return i;
    }
    return -1;
};

/**
 * Figure out whether x is contained in this array.
 *
 * x - the item to look for in this array
 * cmpFunc - the function to use to decide on identity
 * return - true if x is in this array, false otherwise
 */
Array.prototype.contains = function(x, cmpFunc) {
    var i = this.indexOf(o, cmpFunc);
    if (i >= 0 ) {
        return true;
    }
    return false;
}

/**
 * Remove item from this array.
 *
 * item - the item to remove
 * cmpFunc - the function to use to decide on identity
 */
Array.prototype.remove = function(item, cmpFunc) {
    var i = this.indexOf(item, cmpFunc);
    if (i >= 0 ) {
        this.splice(i,1);
    }
};

/**
 * Replace an item in an array.
 *
 * replaced - the item to be replaced
 * replacing - the item to take the position of the replaced
 * cmpFunc - the function to use to decide on identity
 */
Array.prototype.replace = function(replaced, replacing, cmpFunc) {
    var i = this.indexOf(replaced, cmpFunc);
    if (i < 0) {
        this.push(replacing);
    } else {
        this.splice(i, 1, replacing);
    }
};

/**
 * Figure out whether array is a sub array of this array based on
 * cmpFunc.
 *
 * array - the array that is checked whether it's a sub array
 * cmpFunc - the function to use to decide on identity
 * return - true, if there is no item in array that is not in this
 *          array, false otherwise
 */
Array.prototype.isSubArray = function(array, cmpFunc) {
    for (var i = 0; i < this.length; i++) {
        if (array.indexOf(this[i], cmpFunc) < 0) {
            return false;
        }
    }
    return true;
};

