import { hasOwnProperty as hasOwnProperty$1, merge, isObject as isObject$1 } from 'smob';
export { merge } from 'smob';
import { unref, isRef, isReadonly, mergeProps } from 'vue';

class Store {
    /**
     * Set options for all groups.
     *
     * @param items
     */ setAll(items) {
        const keys = Object.keys(items);
        for(let i = 0; i < keys.length; i++){
            this.setOptions(keys[i], items[keys[i]]);
        }
    }
    /**
     * Set options for a specific group.
     *
     * @param group
     * @param options
     */ setOptions(group, options) {
        if (typeof this.data[group] === 'undefined') {
            this.data[group] = {};
        }
        this.data[group] = options;
    }
    hasOptions(group) {
        return hasOwnProperty$1(this.data, group);
    }
    getOptions(group) {
        if (typeof this.data[group] !== 'undefined') {
            return this.data[group];
        }
        return {};
    }
    hasOption(group, option) {
        return typeof this.data[group] !== 'undefined' && hasOwnProperty$1(this.data[group], option);
    }
    getOption(group, option) {
        if (typeof this.data[group] === 'undefined') {
            return undefined;
        }
        return this.data[group][option];
    }
    constructor(){
        this.data = {};
    }
}

let instance;
function useDefaultsStore() {
    if (typeof instance !== 'undefined') {
        return instance;
    }
    instance = new Store();
    return instance;
}

const instances = {};
function usePresetStore(key) {
    if (typeof instances[key] !== 'undefined') {
        return instances[key];
    }
    const instance = new Store();
    instances[key] = instance;
    return instance;
}
function getRegisteredPresets() {
    return Object.keys(instances);
}

/*
 * Copyright (c) 2021.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */ // eslint-disable-next-line @typescript-eslint/ban-types
function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}

/*
 * Copyright (c) 2023.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */ function isObject(input) {
    return typeof input === 'object' && input !== null && !Array.isArray(input) && !!input;
}

/**
 * Returns true if either scoped or unscoped named slot exists
 *
 * @returns {Array|undefined} VNodes
 *
 * @param name
 * @param $slots
 */ function hasNormalizedSlot(name, $slots = {}) {
    return hasOwnProperty($slots, name);
}
/**
 * Returns VNodes for named slot either scoped or unscoped
 *
 * @param name
 * @param scope
 * @param $slots
 *
 * @returns {Array} VNodes
 */ function normalizeSlot(name, scope = {}, $slots = {}) {
    if (hasOwnProperty($slots, name)) {
        return $slots[name](scope);
    }
    return [];
}

function isPromise(p) {
    return isObject(p) && (p instanceof Promise || // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    typeof p.then === 'function');
}

function unrefWithDefault(value, alt) {
    const raw = unref(value);
    if (typeof raw === 'undefined') {
        return alt;
    }
    return raw;
}
function setMaybeRefValue(input, value) {
    if (isRef(input)) {
        if (!isReadonly(input)) {
            input.value = value;
        }
        return input;
    }
    input = value;
    return input;
}
function extendMaybeRefObject(input, value) {
    const keys = Object.keys(value);
    if (isRef(input)) {
        if (!isReadonly(input)) {
            for(let i = 0; i < keys.length; i++){
                input.value[keys[i]] = value[keys[i]];
            }
        }
    } else {
        for(let i = 0; i < keys.length; i++){
            input[keys[i]] = value[keys[i]];
        }
    }
    return input;
}
function pushMaybeRefArrayValue(input, value) {
    if (isRef(input)) {
        input.value.push(value);
    } else {
        input.push(value);
    }
    return value;
}
function spliceMaybeRefArray(input, index, amount) {
    if (isRef(input)) {
        input.value.splice(index, amount);
    } else {
        input.splice(index, amount);
    }
    return input;
}
function getMaybeRefArrayValue(input, index) {
    if (isRef(input)) {
        return input.value[index];
    }
    return input[index];
}
function extendMaybeRefArrayValue(input, index, value) {
    const item = getMaybeRefArrayValue(input, index);
    if (isRef(input)) {
        input.value[index] = merge(value, item);
    } else {
        input[index] = merge(value, item);
    }
    return input;
}
function findIndexOfMaybeRefArray(input, filterFn) {
    if (isRef(input)) {
        return input.value.findIndex(filterFn);
    }
    return input.findIndex(filterFn);
}

function isVNodeClassOption(name) {
    return name.toLowerCase().indexOf('class') !== -1;
}
function isVNodeStyleOption(name) {
    return name.toLowerCase().indexOf('style') !== -1;
}
function isVNodeListenerOption(name) {
    return name.startsWith('on');
}
function isVNodePropsOption(name) {
    return name.toLowerCase().indexOf('props') !== -1;
}
function isVNodeOption(name) {
    return isVNodeClassOption(name) || isVNodeStyleOption(name) || isVNodeListenerOption(name) || isVNodePropsOption(name);
}
function mergeVNodeOption(key, target, source) {
    if (typeof target === 'undefined') {
        return source;
    }
    if (typeof source === 'undefined') {
        return target;
    }
    if (isVNodeClassOption(key)) {
        const { class: clazz } = mergeProps({
            class: target
        }, {
            class: source
        });
        return clazz;
    }
    if (isVNodeStyleOption(key)) {
        const { style } = mergeProps({
            style: target
        }, {
            style: source
        });
        return style;
    }
    if (isVNodeListenerOption(key)) {
        const { [key]: listener } = mergeProps({
            [key]: target
        }, {
            [key]: source
        });
        return listener;
    }
    if (isVNodePropsOption(key)) {
        return mergeProps(target, source);
    }
    return target ?? source;
}

function mergeOption(key, target, source) {
    if (isVNodeOption(key)) {
        return mergeVNodeOption(key, target, source);
    }
    if (isObject$1(target) && isObject$1(source)) {
        return merge(target, source);
    }
    return target ?? source;
}

function isOptionInputConfigWithPresets(input) {
    if (!isObject$1(input)) {
        return false;
    }
    const { presets } = input;
    if (!isObject$1(presets)) {
        return false;
    }
    const keys = Object.keys(presets);
    for(let i = 0; i < keys.length; i++){
        if (!hasOwnProperty(presets, keys[i]) || typeof presets[keys[i]] !== 'boolean') {
            return false;
        }
    }
    return true;
}
function isOptionInputConfigWithDefaults(input) {
    if (!isObject$1(input)) {
        return false;
    }
    const { defaults } = input;
    return typeof defaults === 'boolean';
}
function isOptionInputConfig(value) {
    return isOptionInputConfigWithPresets(value) || isOptionInputConfigWithDefaults(value);
}
function extractValueFromOptionInputValue(input) {
    if (isOptionInputConfig(input)) {
        if (input.value) {
            return input.value;
        }
        return undefined;
    }
    return input;
}

function buildOption(context) {
    let value;
    const presetConfig = {};
    if (isOptionInputConfigWithPresets(context.value)) {
        const keys = Object.keys(context.value.presets);
        for(let i = 0; i < keys.length; i++){
            presetConfig[keys[i]] = context.value.presets[keys[i]];
        }
        if (typeof context.value.value !== 'undefined') {
            value = context.value.value;
        }
    }
    if (!isOptionInputConfig(context.value)) {
        value = context.value;
    }
    if (typeof value === 'undefined') {
        if (!isOptionInputConfigWithDefaults(context.value) || context.value.defaults) {
            const defaultStore = useDefaultsStore();
            if (defaultStore.hasOption(context.component, context.key)) {
                value = defaultStore.getOption(context.component, context.key);
            }
        }
    }
    const registeredPresets = getRegisteredPresets();
    for(let i = 0; i < registeredPresets.length; i++){
        if (hasOwnProperty(presetConfig, registeredPresets[i]) && !presetConfig[registeredPresets[i]]) {
            continue;
        }
        const presetStore = usePresetStore(registeredPresets[i]);
        if (presetStore.hasOption(context.component, context.key)) {
            value = mergeOption(context.key, value, presetStore.getOption(context.component, context.key));
        }
    }
    if (typeof value === 'undefined') {
        return context.alt;
    }
    return value;
}
function buildOptionOrFail(context) {
    const target = buildOption(context);
    if (typeof target === 'undefined' && !hasOwnProperty(context, 'alt')) {
        throw new Error(`A value for option ${context.key} of component ${context.component} is required.`);
    }
    return target;
}
function createOptionBuilder(component) {
    const build = (context)=>buildOption({
            ...context,
            component
        });
    const buildOrFail = (context)=>buildOptionOrFail({
            ...context,
            component
        });
    return {
        build,
        buildOrFail
    };
}

function applyPluginBaseOptions(options) {
    if (options.presets) {
        const presetKeys = Object.keys(options.presets);
        for(let i = 0; i < presetKeys.length; i++){
            const store = usePresetStore(presetKeys[i]);
            store.setAll(options.presets[presetKeys[i]]);
        }
    }
    if (options.defaults) {
        const store = useDefaultsStore();
        store.setAll(options.defaults);
    }
}

export { Store, applyPluginBaseOptions, createOptionBuilder, extendMaybeRefArrayValue, extendMaybeRefObject, extractValueFromOptionInputValue, findIndexOfMaybeRefArray, getMaybeRefArrayValue, getRegisteredPresets, hasNormalizedSlot, hasOwnProperty, isObject, isOptionInputConfig, isOptionInputConfigWithDefaults, isOptionInputConfigWithPresets, isPromise, isVNodeClassOption, isVNodeListenerOption, isVNodeOption, isVNodePropsOption, isVNodeStyleOption, mergeOption, mergeVNodeOption, normalizeSlot, pushMaybeRefArrayValue, setMaybeRefValue, spliceMaybeRefArray, unrefWithDefault, useDefaultsStore, usePresetStore };
//# sourceMappingURL=index.mjs.map
