"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DictionaryWithPropertyDefitionKey = exports.DictionaryWithNumericKey = exports.DictionaryWithStringKey = exports.PropertyDefinitionDictionary = exports.StringPropertyDefinitionBaseDictionary = exports.Dictionary = void 0;
const ExtensionMethods_1 = require("./ExtensionMethods");
class Dictionary {
    constructor(keyPickerFunc) {
        this.keys = [];
        this.keysToObjs = {};
        this.objects = {}; // {[key:string]:TValue};
        if (typeof keyPickerFunc !== 'function')
            throw new Error("Dictionary - keyPickerFunc must be a function");
        this.keyPicker = keyPickerFunc;
    }
    /** get all keys */
    get Keys() {
        var keys = [];
        for (var key of this.keys) {
            keys.push(this.keysToObjs[key]);
        }
        return keys;
    }
    /**get all items in key,value pair array */
    get Items() {
        var items = [];
        for (var k of this.keys) {
            items.push({ key: this.keysToObjs[k], value: this.objects[k] });
        }
        return items;
    }
    /** get all values */
    get Values() {
        var ret = [];
        for (var key of this.keys) {
            ret.push(this.objects[key]);
        }
        return ret;
    }
    /** get number of objects in dictionary */
    get length() { return this.keys.length; }
    /** get number of objects in the dictionary */
    get Count() { return this.length; }
    /** get string values of all keys */
    getStringKeys() { return this.keys; }
    /** add value or update the value for key */
    Add(key, value) { return this.addUpdate(key, value); }
    /** add value or update the value for key */
    addUpdate(key, value) {
        var strKey = this.keyPicker(key);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey))
            throw new Error("Dictionary - invalid key object, keyPicker return null");
        if (!this.containsKey(strKey)) {
            this.keys.push(strKey);
        }
        this.keysToObjs[strKey] = key;
        this.objects[strKey] = value;
    }
    /** Set value for key */
    set(key, value) {
        this.addUpdate(key, value);
    }
    setEntry(oldKey, newKey) {
        var strKey = oldKey;
        if (typeof oldKey !== 'string')
            strKey = this.keyPicker(oldKey);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey))
            throw new Error("Dictionary - invalid key object, keyPicker return null");
        if (this.containsKey(strKey)) {
            throw new Error("Dictionary - does not contain old key");
        }
        var oldval = this.objects[strKey];
        //oldval =   null:value;
        this.remove(strKey);
        this.addUpdate(newKey, oldval);
    }
    get(key) {
        var strKey = key;
        if (typeof key !== 'string')
            strKey = this.keyPicker(key);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey))
            throw new Error("Dictionary - invalid key object, keyPicker return null");
        return this.objects[strKey];
    }
    tryGetValue(key, outValue) {
        outValue.outValue = null;
        outValue.success = false;
        var strKey = key;
        if (typeof key !== 'string')
            strKey = this.keyPicker(key);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey)) {
            outValue.exception = new Error("Dictionary - invalid key,not a string value or keyPicker return null");
            return false;
        }
        if (this.containsKey(strKey)) {
            outValue.outValue = this.objects[strKey];
            outValue.success = true;
            return true;
        }
        return false;
    }
    remove(key) {
        var strKey = key;
        if (typeof key !== 'string')
            strKey = this.keyPicker(key);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey))
            throw new Error("Dictionary - invalid key,not a string value or keyPicker return null");
        if (!this.containsKey(strKey))
            return false;
        var keyindex = this.keys.indexOf(strKey);
        var delKeyAr = this.keys.splice(keyindex, 1);
        var delkeyObj = delete this.keysToObjs[strKey];
        var delObj = delete this.objects[strKey];
        return delKeyAr.length > 0 && delkeyObj && delObj;
    }
    containsKey(key) {
        var strKey = key;
        if (typeof key !== 'string')
            strKey = this.keyPicker(key);
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(strKey))
            throw new Error("Dictionary - invalid key object, keyPicker return null");
        if (this.keys.indexOf(strKey) >= 0)
            return true;
        return false;
    }
    /** clear dictionary */
    clear() {
        this.keys = [];
        this.keysToObjs = {};
        this.objects = {};
    }
}
exports.Dictionary = Dictionary;
/**@internal */
class StringPropertyDefinitionBaseDictionary extends Dictionary {
}
exports.StringPropertyDefinitionBaseDictionary = StringPropertyDefinitionBaseDictionary;
/**@internal */
class PropertyDefinitionDictionary extends StringPropertyDefinitionBaseDictionary {
}
exports.PropertyDefinitionDictionary = PropertyDefinitionDictionary;
/**@internal */
class DictionaryWithStringKey extends Dictionary {
    constructor() {
        super((value) => value);
    }
}
exports.DictionaryWithStringKey = DictionaryWithStringKey;
/**@internal */
class DictionaryWithNumericKey extends Dictionary {
    constructor() {
        super((value) => value.toString());
    }
}
exports.DictionaryWithNumericKey = DictionaryWithNumericKey;
/**@internal */
class DictionaryWithPropertyDefitionKey extends Dictionary {
    constructor() {
        super((value) => value.Name);
    }
}
exports.DictionaryWithPropertyDefitionKey = DictionaryWithPropertyDefitionKey;
class PropDictionary2 {
    constructor() {
        this.keys = [];
        this.objects = {}; // {[key:string]:TValue};
    }
    get KeyNames() { return this.keys; }
    get Keys() {
        var ret = [];
        for (var key in this.objects) {
            ret.push(this.objects[key].keyObject);
        }
        return ret;
    }
    get Items() {
        var all = [];
        for (var obj in this.objects) {
            all.push({ key: this.objects[obj].keyObject, value: this.objects[obj].value });
        }
        return all;
    }
    get Values() {
        var ret = [];
        for (var key in this.objects) {
            ret.push(this.objects[key].value);
        }
        return ret;
    }
    get length() { return this.keys.length; }
    add(key, value) {
        var keyString = key.Name;
        if (this.keys.indexOf(key.Name) == -1) {
            this.keys.push(keyString);
        }
        this.objects[keyString] = { key: keyString, keyObject: key, value: value };
    }
    set(key, value) {
        this.add(key, value);
    }
    setEntry(oldKeyString, oldKey, value, isNull = false) {
        if (this.keys.indexOf(oldKeyString) == -1 || typeof this.objects[oldKeyString] === 'undefined') {
            throw new Error("invalid old keystring");
        }
        var oldval = isNull ? null : value || this.objects[oldKeyString].value;
        //oldval =   null:value;
        this.objects[oldKeyString] = { key: oldKey.Name, keyObject: oldKey, value: value || oldval };
    }
    get(key) {
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(key.Name))
            throw new Error("invalid operation, object does not have valid Name property");
        //if(this.keys.indexOf(key.Name)>=0)
        var val = this.objects[key.Name];
        return val ? val.value : undefined;
    }
    tryGet(key, outValue) {
        outValue.outValue = null;
        outValue.success = false;
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(key.Name))
            outValue.exception = new Error("invalid operation, object does not have valid Name property");
        if (this.containsKey(key)) {
            var val = this.objects[key.Name];
            outValue.outValue = val ? val.value : null;
            return true;
        }
        return false;
    }
    remove(key) {
        if (ExtensionMethods_1.StringHelper.IsNullOrEmpty(key.Name))
            throw new Error("missing keyString");
        return delete this.objects[key.Name];
    }
    containsKey(key) {
        if (this.keys.indexOf(key.Name) >= 0 || typeof this.objects[key.Name] !== 'undefined')
            return true;
        return false;
    }
    clear() {
        this.keys = [];
        this.objects = {};
    }
}
//# sourceMappingURL=AltDictionary.js.map