import { __esDecorate, __runInitializers } from "tslib";
import { ThingKind } from './kinds.js';
import { observed } from '../decorators/observed.js';
let Thing = (() => {
    let _classSuper = EventTarget;
    let _name_decorators;
    let _name_initializers = [];
    let _name_extraInitializers = [];
    let _displayName_decorators;
    let _displayName_initializers = [];
    let _displayName_extraInitializers = [];
    let _description_decorators;
    let _description_initializers = [];
    let _description_extraInitializers = [];
    let _version_decorators;
    let _version_initializers = [];
    let _version_extraInitializers = [];
    return class Thing extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _name_decorators = [observed()];
            _displayName_decorators = [observed()];
            _description_decorators = [observed()];
            _version_decorators = [observed()];
            __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
            __esDecorate(this, null, _displayName_decorators, { kind: "accessor", name: "displayName", static: false, private: false, access: { has: obj => "displayName" in obj, get: obj => obj.displayName, set: (obj, value) => { obj.displayName = value; } }, metadata: _metadata }, _displayName_initializers, _displayName_extraInitializers);
            __esDecorate(this, null, _description_decorators, { kind: "accessor", name: "description", static: false, private: false, access: { has: obj => "description" in obj, get: obj => obj.description, set: (obj, value) => { obj.description = value; } }, metadata: _metadata }, _description_initializers, _description_extraInitializers);
            __esDecorate(this, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        kind = ThingKind;
        #name_accessor_storage = __runInitializers(this, _name_initializers, void 0);
        /**
         * The name of the thing.
         */
        get name() { return this.#name_accessor_storage; }
        set name(value) { this.#name_accessor_storage = value; }
        #displayName_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _displayName_initializers, void 0));
        /**
         * Optional value to overwrite the `name` in the UI.
         * The primary descriptive field is the `name`. The display name is only used in the presentation of the data.
         */
        get displayName() { return this.#displayName_accessor_storage; }
        set displayName(value) { this.#displayName_accessor_storage = value; }
        #description_accessor_storage = (__runInitializers(this, _displayName_extraInitializers), __runInitializers(this, _description_initializers, void 0));
        /**
         * The description of the thing.
         */
        get description() { return this.#description_accessor_storage; }
        set description(value) { this.#description_accessor_storage = value; }
        #version_accessor_storage = (__runInitializers(this, _description_extraInitializers), __runInitializers(this, _version_initializers, void 0));
        /**
         * The version number of the thing.
         */
        get version() { return this.#version_accessor_storage; }
        set version(value) { this.#version_accessor_storage = value; }
        /**
         * Returns one in this order:
         * - displayName
         * - name
         * - 'Unnamed object'
         *
         * @deprecated Use `getLabel()` instead.
         */
        get renderLabel() {
            return this.displayName || this.name || 'Unnamed object';
        }
        /**
         * Creates a basic description from a name.
         */
        static fromName(name) {
            const thing = new Thing({
                name,
                kind: ThingKind,
            });
            return thing;
        }
        /**
         * Creates a new thing instance.
         *
         * @param input The thing definition used to restore the state.
         */
        static fromJSON(input = {}, defaults = {}) {
            const result = new Thing();
            const { name, displayName, description, version } = input || {};
            if (typeof name === 'string') {
                result.name = name;
            }
            else if (typeof defaults.name === 'string') {
                result.name = defaults.name;
            }
            if (typeof displayName === 'string') {
                result.displayName = displayName;
            }
            else if (typeof defaults.displayName === 'string') {
                result.displayName = defaults.displayName;
            }
            if (description) {
                result.description = description;
            }
            else if (typeof defaults.description === 'string') {
                result.description = defaults.description;
            }
            if (version) {
                result.version = version;
            }
            else if (typeof defaults.version === 'string') {
                result.version = defaults.version;
            }
            return result;
        }
        /**
         * @param input The thing definition used to restore the state.
         */
        constructor(input) {
            super();
            __runInitializers(this, _version_extraInitializers);
            let init;
            if (typeof input === 'string') {
                init = JSON.parse(input);
            }
            else if (typeof input === 'object') {
                init = input;
            }
            else {
                init = {
                    kind: ThingKind,
                };
            }
            this.new(init);
        }
        /**
         * Creates a new thing clearing anything that is so far defined.
         *
         * Note, this throws an error when the server is not a thing.
         */
        new(init) {
            if (!Thing.isThing(init)) {
                throw new Error(`Not a thing.`);
            }
            const { description, name, version, displayName } = init;
            this.kind = ThingKind;
            this.name = name;
            this.displayName = displayName;
            this.description = description;
            this.version = version;
        }
        notifyChange() {
            this.dispatchEvent(new Event('change'));
        }
        static validate(input, options = {}) {
            const { strict } = options;
            if (input && typeof input === 'object') {
                const typed = input;
                if (strict && typed.kind !== ThingKind) {
                    return false;
                }
                return true;
            }
            return false;
        }
        /**
         * Checks whether the input is a definition of a server.
         */
        static isThing(input) {
            const typed = input;
            if (input && typed.kind === ThingKind) {
                return true;
            }
            return false;
        }
        toJSON() {
            const result = {
                kind: ThingKind,
            };
            if (typeof this.name === 'string') {
                result.name = this.name;
            }
            if (typeof this.displayName === 'string') {
                result.displayName = this.displayName;
            }
            if (this.description) {
                result.description = this.description;
            }
            if (this.version) {
                result.version = this.version;
            }
            return result;
        }
        /**
         * Returns one in this order:
         * - `this.displayName`
         * - `this.name`
         * - `defaultName`
         * - 'Unnamed object'
         *
         * @param defaultName The default name to use when no other is available.
         */
        getLabel(defaultName) {
            return this.displayName || this.name || defaultName || 'Unnamed object';
        }
    };
})();
export { Thing };
//# sourceMappingURL=Thing.js.map