function _class_call_check(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _create_class(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
import { assign, isObject } from "@d3plus/dom";
import { findLocale, translateLocale as dictionaries } from "@d3plus/locales";
import RESET from "./RESET.js";
/**
    Recursive function that resets nested Object configs.

    @private
*/ function nestedReset(obj, defaults) {
    if (isObject(obj)) {
        for(var nestedKey in obj){
            if (({}).hasOwnProperty.call(obj, nestedKey) && !nestedKey.startsWith("_")) {
                var defaultValue = defaults && isObject(defaults) ? defaults[nestedKey] : undefined;
                if (obj[nestedKey] === RESET) {
                    if (defaultValue) obj[nestedKey] = defaultValue;
                    else delete obj[nestedKey];
                } else if (isObject(obj[nestedKey])) {
                    nestedReset(obj[nestedKey], defaultValue);
                }
            }
        }
    }
}
/**
    finds all prototype methods of a class and it's parent classes
    @param obj
    @private
*/ function getAllMethods(obj) {
    var props = [];
    do {
        props = props.concat(Object.getOwnPropertyNames(obj));
        obj = Object.getPrototypeOf(obj);
    }while (obj && obj !== Object.prototype);
    return props.filter(function(e) {
        return e.indexOf("_") !== 0 && ![
            "config",
            "constructor",
            "parent",
            "render"
        ].includes(e);
    });
}
var BaseClass = /*#__PURE__*/ function() {
    "use strict";
    function BaseClass() {
        var _this = this;
        _class_call_check(this, BaseClass);
        _define_property(this, "_locale", void 0);
        _define_property(this, "_on", void 0);
        _define_property(this, "_parent", void 0);
        _define_property(this, "_translate", void 0);
        _define_property(this, "_uuid", void 0);
        _define_property(this, "_configDefault", void 0);
        _define_property(this, "_shapeConfig", void 0);
        this._locale = "en-US";
        this._on = {};
        this._parent = {};
        this._translate = function(d) {
            var locale = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : _this._locale;
            var dictionary = dictionaries[locale];
            var key = d;
            return dictionary && dictionary[key] ? dictionary[key] : d;
        };
        this._uuid = crypto.randomUUID();
    }
    _create_class(BaseClass, [
        {
            key: "config",
            value: function config(_) {
                var _this = this;
                if (!this._configDefault) {
                    var config = {};
                    getAllMethods(Object.getPrototypeOf(this)).forEach(function(k) {
                        var v = _this[k]();
                        if (v !== _this) config[k] = isObject(v) ? assign({}, v) : v;
                    });
                    this._configDefault = config;
                }
                if (arguments.length) {
                    for(var k in _){
                        if (({}).hasOwnProperty.call(_, k)) {
                            if (k in this) {
                                var v = _[k];
                                if (v === RESET) {
                                    if (k === "on") this._on = this._configDefault[k];
                                    else this[k](this._configDefault[k]);
                                } else {
                                    nestedReset(v, this._configDefault[k]);
                                    this[k](v);
                                }
                            } else {
                            // console.warn(
                            //   `${this.constructor.name}.config() received unknown property "${k}".`,
                            // );
                            }
                        }
                    }
                    return this;
                } else {
                    var config1 = {};
                    getAllMethods(Object.getPrototypeOf(this)).forEach(function(k) {
                        config1[k] = _this[k]();
                    });
                    return config1;
                }
            }
        },
        {
            key: "locale",
            value: function locale(_) {
                return arguments.length ? (this._locale = findLocale(_), this) : this._locale;
            }
        },
        {
            key: "on",
            value: function on(_, f) {
                return arguments.length === 2 ? (this._on[_] = f, this) : arguments.length ? typeof _ === "string" ? this._on[_] : (this._on = Object.assign({}, this._on, _), this) : this._on;
            }
        },
        {
            key: "parent",
            value: function parent(_) {
                return arguments.length ? (this._parent = _, this) : this._parent;
            }
        },
        {
            key: "translate",
            value: function translate(_) {
                return arguments.length ? (this._translate = _, this) : this._translate;
            }
        },
        {
            key: "shapeConfig",
            value: function shapeConfig(_) {
                var _this__shapeConfig;
                return arguments.length ? (this._shapeConfig = assign((_this__shapeConfig = this._shapeConfig) !== null && _this__shapeConfig !== void 0 ? _this__shapeConfig : {}, _), this) : this._shapeConfig;
            }
        }
    ]);
    return BaseClass;
}();
/**
    Provides shared configuration, event handling, and locale management inherited by all d3plus classes.
*/ export { BaseClass as default };
