/**
 * A simple map implementation in JavaScript.  This map class generates a random key for 
 * objects and the stores that key in the object itself, which is then used later when
 * looking up the value for an object in the map.  Because of this, separately 
 * instantiated objects will not map to the same value in the map.  In this regard, this 
 * map class doesn't behave like maps in other languages such as Java or Ruby, but it
 * still might be useful for some scenarios.
 *
 * Copyright Chris TenHarmsel, 2009
 * chris@tenharmsel.com
 * http://www.staticmethod.net
 * Version: 0.2
 */

var JsMap = function() {
    var _internalMap = {};
    var _internalArray = new Array();

    /*
     * Private function for getting the key for an object
     */
    function getKey(obj) {
        var key = _internalArray.indexOf(obj);
        if(key == -1) {
            _internalArray.push(obj);
            key = _internalArray.indexOf(obj);
        }
        return "OR." + key;
    };

    /*
     * Internal put method, has access to the internal map and array
     */
    this._put = function(key, value) {
        var objKey = getKey(key);
        _internalMap[objKey] = value;
    };

    /*
     * Internal get method, has access to the internal map and array
     */
    this._get = function(key) {
        var objKey = getKey(key);
        var value = _internalMap[objKey];
        if(value == null) {
            // this means it wasn't in the map, we should remove the new key we just made
            this._remove(key);
        }
        return value;
    };

    /*
     * Internal remove method, has access to the internal map and array
     */
    this._remove = function(key) {
        var objKey = getKey(key);
        if( _internalMap[objKey] != null ) {
            delete(_internalMap[objKey]);
        }
        // Remove the reference in the internal array
        var idx = _internalArray.indexOf(key);
        if(idx != -1) {
            delete(_internalArray[idx]);
        }
    };

    /*
     * Internal size method, has access to the internal map and array
     */
    this.size = function() {
        count = 0;
        for(var i in _internalMap) {
            count++;
        }
        return count;
    };

};

/*
 * Put method, adds a value associated with the specified key to the map.
 */
JsMap.prototype.put = function(key, value) {
    this._put(key, value);
};

/*
 * Get method, gets a value associated with the specified key from the map.
 */
JsMap.prototype.get = function(key) {
    return this._get(key);
};

/*
 * Remove method, removes a value associated with the specified key from the map.
 */
JsMap.prototype.remove = function(key) {
    this._remove(key);
};
