import { createID } from "../util/id";

import { Event } from "../event/event";

import { isValid } from "@visactor/vutils";

import { Factory } from "../core/factory";

import { MarkSet } from "../mark/mark-set";

import { CompilableBase } from "../compile/compilable-base";

import { PREFIX } from "../constant/base";

import { BaseModelSpecTransformer } from "./base-model-transformer";

import { getProperty } from "@visactor/vutils-extension";

export class BaseModel extends CompilableBase {
    getSpec() {
        return this._spec || {};
    }
    getSpecPath() {
        var _a;
        return null === (_a = this._option) || void 0 === _a ? void 0 : _a.specPath;
    }
    getSpecInfoPath() {
        var _a, _b, _c;
        return null !== (_b = null === (_a = this._option) || void 0 === _a ? void 0 : _a.specInfoPath) && void 0 !== _b ? _b : null === (_c = this._option) || void 0 === _c ? void 0 : _c.specPath;
    }
    getData() {
        return this._data;
    }
    get layout() {
        return this._layout;
    }
    getOption() {
        return this._option;
    }
    getMarks() {
        var _a, _b;
        return null !== (_b = null === (_a = this._marks) || void 0 === _a ? void 0 : _a.getMarks()) && void 0 !== _b ? _b : [];
    }
    getMarkNameMap() {
        var _a;
        return null === (_a = this._marks) || void 0 === _a ? void 0 : _a.getMarkNameMap();
    }
    getMarkSet() {
        return this._marks;
    }
    getChart() {
        return this._option.getChart();
    }
    get _theme() {
        var _a;
        return null === (_a = this.getSpecInfo()) || void 0 === _a ? void 0 : _a.theme;
    }
    constructor(spec, option) {
        var _a;
        super(option), this.transformerConstructor = BaseModelSpecTransformer, this.type = "null", 
        this.modelType = "null", this.userId = void 0, this._data = null, this._layout = null, 
        this.specKey = "", this._marks = new MarkSet, this._lastLayoutRect = null, this.id = createID(), 
        this.userId = spec.id, this._spec = spec, this.effect = {}, this.event = new Event(option.eventDispatcher, option.mode), 
        null === (_a = option.map) || void 0 === _a || _a.set(this.id, this);
    }
    _releaseEvent() {
        this.event.release();
    }
    created() {
        this.setAttrFromSpec();
    }
    init(option) {}
    afterInit() {}
    getVisible() {
        var _a;
        return !1 !== (null === (_a = this._spec) || void 0 === _a ? void 0 : _a.visible);
    }
    onLayoutStart(layoutRect, viewRect, ctx) {
        var _a;
        null === (_a = this._layout) || void 0 === _a || _a.onLayoutStart(layoutRect, viewRect, ctx);
    }
    onLayoutEnd(ctx) {
        var _a;
        null === (_a = this._layout) || void 0 === _a || _a.onLayoutEnd(ctx), this.getMarks().forEach((m => m.updateLayoutState(!0, !0)));
    }
    onEvaluateEnd(ctx) {}
    onBeforeRender() {}
    onDataUpdate() {}
    beforeRelease() {}
    clear() {
        this.getMarks().forEach((m => {
            var _a;
            return null === (_a = m.clear) || void 0 === _a ? void 0 : _a.call(m);
        }));
    }
    release() {
        var _a;
        this._releaseEvent(), this._spec = void 0, this.getMarks().forEach((m => m.release())), 
        null === (_a = this._data) || void 0 === _a || _a.release(), this._data = null, 
        this._marks.clear(), super.release();
    }
    updateSpec(spec) {
        const result = this._compareSpec(spec, this._spec);
        return this._spec = spec, result;
    }
    _compareSpec(spec, prevSpec) {
        return {
            change: !1,
            reMake: !1,
            reRender: !1,
            reSize: !1,
            reCompile: !1
        };
    }
    reInit(spec) {
        spec && (this._spec = spec), this.setAttrFromSpec();
    }
    updateLayoutAttribute() {}
    setAttrFromSpec() {
        var _a;
        null === (_a = this._layout) || void 0 === _a || _a.setAttrFromSpec(this._spec, this._option.getChartViewRect());
    }
    _convertMarkStyle(style) {
        return Object.assign({}, style);
    }
    setMarkStyle(mark, style, state, level) {
        isValid(mark) && isValid(style) && mark.setStyle(this._convertMarkStyle(style), state, level);
    }
    initMarkStyleWithSpec(mark, spec, key) {
        if (!isValid(mark) || !isValid(spec)) return;
        const {style: style, state: state} = spec, newSpec = Object.assign({}, spec);
        style && (newSpec.style = this._convertMarkStyle(style)), state && (newSpec.state = {}, 
        Object.keys(state).forEach((key => {
            newSpec.state[key] = this._convertMarkStyle(state[key]);
        }))), mark.initStyleWithSpec(newSpec, key);
    }
    stateKeyToSignalName(key, opt) {
        let name = `${PREFIX}_${this.modelType}_${this.type}_${this.id}_${key}`;
        return opt && (name += `_${opt}`), name;
    }
    compileData() {
        var _a;
        null === (_a = this._data) || void 0 === _a || _a.compile();
    }
    compileMarks(group) {
        this.getMarks().forEach((m => {
            m.compile({
                group: group
            });
        }));
    }
    _createMark(markInfo, option = {}, config) {
        const {type: type, name: name} = markInfo, m = Factory.createMark(type, name, Object.assign({
            model: this,
            map: this._option.map,
            getCompiler: this.getCompiler,
            globalScale: this._option.globalScale
        }, option));
        return m && (m.created(), config && m.setMarkConfig(config)), m;
    }
    _getDataIdKey() {}
    getColorScheme() {
        var _a, _b;
        return null === (_b = (_a = this._option).getTheme) || void 0 === _b ? void 0 : _b.call(_a).colorScheme;
    }
    getSpecInfo() {
        var _a, _b, _c;
        const specInfo = null !== (_c = null === (_b = (_a = this._option).getSpecInfo) || void 0 === _b ? void 0 : _b.call(_a)) && void 0 !== _c ? _c : {};
        return getProperty(specInfo, this.getSpecInfoPath());
    }
    getSpecIndex() {
        const path = this.getSpecPath();
        if (!(null == path ? void 0 : path.length)) return 0;
        const index = Number(path[path.length - 1]);
        return isNaN(index) ? 0 : index;
    }
}
//# sourceMappingURL=base-model.js.map
