function AList() {
    this.values = new Array();
    this.keys = new Array();
    
    this.currentIndex = 0;
}

AList.createEx = function (obj, addFunction) {
    var defaultAddFunction = false;
    
    if (1 < arguments.length) {
        defaultAddFunction = (arguments[1] == true) ? true : false;
    }
    
    var result = new AList();
    
    var k = null;
    var v = null;
    
    for (k in obj) {
        v = obj[k];
        
        if ((typeof v == 'function')
                && (defaultAddFunction == false)) {
            continue;
        }
        
        if (typeof v == 'object') {
            v = AList.createEx(v, defaultAddFunction);
            
        }
        
        result.set(k, v);
    }
    
    return result;
}


AList.create = function (obj) {
    var defaultAddFunction = false;
    var rec = false;
    
	if (2 < arguments.length) {
		rec = (arguments[2] == true) ? true : false;
	}
	
	if (1 < arguments.length) {
        defaultAddFunction = (arguments[1] == true) ? true : false;
    }
    
    var result = new AList();
    
    var k = null;
    var v = null;
    
    for (k in obj) {
        v = obj[k];
        
        if ((typeof v == 'function')
                && (defaultAddFunction == false)) {
            continue;
        }
        
        if ((typeof v == 'object')
				&& (rec == true)) {
            v = AList.createEx(v, defaultAddFunction);
            
        }
		
        result.set(k, v);
    }
    
    return result;
}

AList.prototype.reverse = function(sl) {
    var result = new AList();
    result.values = this.values.reverse();
    result.keys = this.keys.reverse();
    
    return result;
}

AList.prototype.merge = function(sl) {
    var slci = sl.currentIndex;
    
    var key = null;
    var value = null;
    
    
    sl.rewind();
    while (sl.valid()) {
        key = sl.key();
        value = sl.current();
        
        this.set(key, value);
        
        sl.next();
    }
    
    sl.currentIndex = slci;
    
}

AList.prototype.count = function () {
    return this.keys.length;
}

AList.prototype.isEmpty = function () {
    return (this.count() < 1) ? true : false;
}

AList.prototype.getKeyIndex = function(name) {
    var sz = this.keys.length;
    var i = 0;
    
    for (i = 0; i < sz; i++) {
        if (this.keys[i] == name) {
            return i;
        }
    }
    
    return -1;
}


AList.prototype.has = function(name) {
    if (this.getKeyIndex(name) < 0) {
        return false;
    }
    
    return true;
}

AList.prototype.set = function(name, value) {
    var ki = this.getKeyIndex(name);
    if (ki < 0) {
        // il s'agit d'un ajout
        this.keys.push(name);
        ki = this.getKeyIndex(name);
        this.values[ki] = value;
        
        return;
    }
    
    // il s'agit d'un remplacement
    this.values[ki] = value;
}

AList.prototype.get = function(name) {
    var ki = this.getKeyIndex(name);
    if (ki < 0) {
        return null;
    }
    
    return this.values[ki];
}

AList.prototype.remove = function(name) {
    var ki = this.getKeyIndex(name);
    if (ki < 0) {
        return false;
    }
    
    this.keys.splice(ki, 1);
    this.values.splice(ki, 1);
    
    return true;
}

AList.prototype.clear = function() {
    this.values = new Array();
    this.keys = new Array();
    
    this.currentIndex = 0;
}


AList.prototype.isValidIndex = function(i) {
    if (this.keys.length < 1) {
        return false;
    }
    
    if (i < 0) {
        return false;
    }
    
    if (i < this.keys.length) {
        return true;
    }
    
    return false;
}

AList.prototype.current = function() {
    if (this.valid() == false) {
        return null;
    }
    
    return this.get(this.key());
}


AList.prototype.key = function() {
    if (this.valid() == false) {
        return null;
    }
    
    return this.keys[this.currentIndex];
}

AList.prototype.next = function() {
    this.currentIndex++;
}

AList.prototype.rewind = function() {
    this.currentIndex = 0;
}

AList.prototype.valid = function() {
    return this.isValidIndex(this.currentIndex);
}

AList.prototype.join = function(join1, join2) {
    var ci = this.currentIndex;
    
    var result = new Array();
    var key = null;
    var value = null;
    
    
    this.rewind();
    while (this.valid()) {
        key = this.key();
        value = this.current();
        
        result.push(key + join2 + value);
        
        
        this.next();
    }
    
    
    
    
    this.currentIndex = ci;
    
    return result.join(join1);
}



AList.prototype.filter = function (functionRef) {
    if (typeof functionRef != 'function') {
        return new Array();
    }
    
    var target = arguments[1] || null;
    
    var result = new Array();
    
    
    this.rewind();
    while (this.valid()) {
        if (functionRef.apply(target, [this.current(), this.key(), this]) != true) {
            this.next();
            continue;
        }
        
        result.push(this[i]);
        this.next();
    }
    
    return result;
}

AList.prototype.map = function (functionRef) {
    if (typeof functionRef != 'function') {
        return new Array();
    }
    
    var target = arguments[1] || null;
    
    var result = new Array();
    
    this.rewind();
    while (this.valid()) {
        result.push(
            functionRef.apply(target, [this.current(), this.key(), this]));
        this.next();
    }
    
    return result;
}

AList.prototype.forEach = function (functionRef) {
    if (typeof functionRef != 'function') {
        return;
    }
    
    var target = arguments[1] || null;
    
    
    this.rewind();
    while (this.valid()) {
        functionRef.apply(target, [this.current(), this.key(), this]);
        this.next();
    }
    
}

AList.prototype.every = function (functionRef) {
    if (typeof functionRef != 'function') {
        return false;
    }
    
    var target = arguments[1] || null;
    
    
    this.rewind();
    while (this.valid()) {
        if (functionRef.apply(target, [this.current(), this.key(), this]) == true) {
            this.next();
            continue;
        }
        
        return false
    }
    
    return true;
}

AList.prototype.every = function (functionRef) {
    if (typeof functionRef != 'function') {
        return false;
    }
    
    var target = arguments[1] || null;
    
    this.rewind();
    while (this.valid()) {
        if (functionRef.apply(target, [this.current(), this.key(), this]) == true) {
            return true;
        }
        this.next();
    }
    
    return false;
}
