var baseHref = "js/";
document.write('<script src="' + baseHref + 'Vector.js"></script>');
document.write('<script language="JavaScript1.5" src="' + baseHref + 'Association.js"></script>');
//The Map Object


// Map methods
// -- Didn't call it a Hashtable because there is no hashing.
// -- also it uses an Association like the Smalltalk Map.
// by Loren Kohl, May 1997

Map.prototype.put = function(aKey, aValue) {
    var assoc;
    var found = false;
    var i = 0;
    while((i < this.contents.size) && (found == false)) {
        assoc = this.contents.elementAt(i);
        if(assoc.key == aKey) {
            assoc.value = aValue;
            found = true;
        } else {
            i++;
        }
    }
    if(found == false) {
        assoc = new Association(aKey, aValue);
        this.contents.addElement(assoc);
    }
}

Map.prototype.get = function(aKey) {
    var assoc;
    var found = false;
    var i = 0;
    var v;
    while((i < this.contents.size) && (found == false)) {
        assoc = this.contents.elementAt(i);
        if(assoc.key == aKey) {
            found = true;
        } else {
            i++;
        }
    }
    if(found == false) {
        v = null;
    } else {
        v = assoc.value;
    }
    return v;
}

Map.prototype.keys = function() {
    var v = new Vector();
    for(var i = 0; i < this.contents.size; i++) {
        v.addElement(this.contents.elementAt(i).key);
    }
    return v;
}

Map.prototype.remove = function(aKey) {
    var assoc;
    var found = false;
    var i = 0;
    while((i < this.contents.size) && (found == false)) {
        assoc = this.contents.elementAt(i);
        if(assoc.key == aKey) {
            this.contents.removeElementAt(i);
            found = true;
        } else {
            i++;
        }
    }
}

Map.prototype.containsKey = function(aKey) {
    var assoc;
    var found = false;
    var i = 0;
    while((i < this.contents.size) && (found == false)) {
        assoc = this.contents.elementAt(i);
        if(assoc.key == aKey) {
            found = true;
        } else {
            i++;
        }
    }
    return found;
}

// Convert to a string which can be restored using MapFromString(aString).
// Also, after using encode(aString) can be sent through CGI.
Map.prototype.MapToString = function() {
    // Return an UNENCODED cgi data string
    // e.g., ?p=This is a test&d=y

    first = true;
    aString = "";

    for(var i = 0; i < this.contents.size; i++) {
        if(first) {
            first = false;
        } else {
            aString += "&";
        }
        aString += this.contents.elementAt(i).key;
        aString += "=";
        aString += this.contents.elementAt(i).value;
    }

    return aString;
}

// Map constructors
// by Loren Kohl, May 1997

// Create a Map from a string of keys & values created by the MapToString() function.
// aString must be decoded with the decode(aString) function first if it came through CGI.
Map.prototype.MapFromString = function(aString) {
    var d = new Map();
    if(aString.indexOf('=') != -1) {
        var index0 = -1;
        var count = 1;
        while(((index0 + 1) < aString.length) &&
                ((index0 = aString.indexOf('&', index0 + 1)) != -1)) {
            count++;
        }

        var index1 = 0;
        var index2 = 0;
        var keyValue = null;
        var subindex = 0;
        var len = aString.length;

        while(index1 < len) {
            index2 = aString.indexOf('&', index1);
            if(index2 == -1)
                index2 = len;
                keyValue = aString.substring(index1, index2);
                subindex = keyValue.indexOf('=');
                d.put((keyValue.substring(0, subindex)), keyValue.substring(subindex + 1, keyValue.length));
                index1 = index2 + 1;
            }
        }
    return d;
}

function Map() {
    this.contents = new Vector();
}

