import * as mixins from "../../core/property_mixins";
import * as p from "../../core/properties";
import { Signal0 } from "../../core/signaling";
import { Location, OutputBackend, ResetPolicy } from "../../core/enums";
import { concat, remove_by } from "../../core/util/array";
import { difference } from "../../core/util/set";
import { isString } from "../../core/util/types";
import { LayoutDOM } from "../layouts/layout_dom";
import { Axis } from "../axes/axis";
import { Grid } from "../grids/grid";
import { Annotation } from "../annotations/annotation";
import { Title } from "../annotations/title";
import { LinearScale } from "../scales/linear_scale";
import { Toolbar } from "../tools/toolbar";
import { HTML } from "../dom/html";
import { Range } from "../ranges/range";
import { Scale } from "../scales/scale";
import { ColumnDataSource } from "../sources/column_data_source";
import { Renderer } from "../renderers/renderer";
import { DataRenderer } from "../renderers/data_renderer";
import { GlyphRenderer } from "../renderers/glyph_renderer";
import { Tool } from "../tools/tool";
import { DataRange1d } from "../ranges/data_range1d";
import { PlotView } from "./plot_canvas";
export { PlotView };
export class Plot extends LayoutDOM {
    static __name__ = "Plot";
    use_map = false;
    reset = new Signal0(this, "reset");
    constructor(attrs) {
        super(attrs);
    }
    static {
        this.prototype.default_view = PlotView;
        this.mixins([
            ["outline_", mixins.Line],
            ["background_", mixins.Fill],
            ["border_", mixins.Fill],
        ]);
        this.define(({ Bool, Float, Str, List, Dict, Or, Ref, Null, Nullable, Struct, Opt }) => ({
            toolbar: [Ref(Toolbar), () => new Toolbar()],
            toolbar_location: [Nullable(Location), "right"],
            toolbar_sticky: [Bool, true],
            toolbar_inner: [Bool, false],
            frame_width: [Nullable(Float), null],
            frame_height: [Nullable(Float), null],
            frame_align: [Or(Bool, Struct({ left: Opt(Bool), right: Opt(Bool), top: Opt(Bool), bottom: Opt(Bool) })), true],
            // revise this when https://github.com/microsoft/TypeScript/pull/42425 is merged
            title: [Or(Ref(Title), Str, Null), "", {
                    convert: (title) => isString(title) ? new Title({ text: title }) : title,
                }],
            title_location: [Nullable(Location), "above"],
            above: [List(Or(Ref(Annotation), Ref(Axis))), []],
            below: [List(Or(Ref(Annotation), Ref(Axis))), []],
            left: [List(Or(Ref(Annotation), Ref(Axis))), []],
            right: [List(Or(Ref(Annotation), Ref(Axis))), []],
            center: [List(Or(Ref(Annotation), Ref(Grid))), []],
            renderers: [List(Ref(Renderer)), []],
            x_range: [Ref(Range), () => new DataRange1d()],
            y_range: [Ref(Range), () => new DataRange1d()],
            x_scale: [Ref(Scale), () => new LinearScale()],
            y_scale: [Ref(Scale), () => new LinearScale()],
            extra_x_ranges: [Dict(Ref(Range)), {}],
            extra_y_ranges: [Dict(Ref(Range)), {}],
            extra_x_scales: [Dict(Ref(Scale)), {}],
            extra_y_scales: [Dict(Ref(Scale)), {}],
            lod_factor: [Float, 10],
            lod_interval: [Float, 300],
            lod_threshold: [Nullable(Float), 2000],
            lod_timeout: [Float, 500],
            hidpi: [Bool, true],
            output_backend: [OutputBackend, "canvas"],
            min_border: [Nullable(Float), 5],
            min_border_top: [Nullable(Float), null],
            min_border_left: [Nullable(Float), null],
            min_border_bottom: [Nullable(Float), null],
            min_border_right: [Nullable(Float), null],
            inner_width: [Float, p.unset, { readonly: true }],
            inner_height: [Float, p.unset, { readonly: true }],
            outer_width: [Float, p.unset, { readonly: true }],
            outer_height: [Float, p.unset, { readonly: true }],
            match_aspect: [Bool, false],
            aspect_scale: [Float, 1],
            reset_policy: [ResetPolicy, "standard"],
            hold_render: [Bool, false],
            attribution: [List(Or(Str, Ref(HTML))), []],
        }));
        this.override({
            width: 600,
            height: 600,
            outline_line_color: "#e5e5e5",
            border_fill_color: "#ffffff",
            background_fill_color: "#ffffff",
        });
    }
    add_layout(renderer, side = "center") {
        const renderers = this.properties[side].get_value();
        this.setv({ [side]: [...renderers, renderer] });
    }
    remove_layout(renderer) {
        const del = (items) => {
            remove_by(items, (item) => item == renderer);
        };
        del(this.left);
        del(this.right);
        del(this.above);
        del(this.below);
        del(this.center);
    }
    get data_renderers() {
        return this.renderers.filter((r) => r instanceof DataRenderer);
    }
    add_renderers(...renderers) {
        this.renderers = [...this.renderers, ...renderers];
    }
    add_glyph(glyph, source = new ColumnDataSource(), attrs = {}) {
        const renderer = new GlyphRenderer({ ...attrs, data_source: source, glyph });
        this.add_renderers(renderer);
        return renderer;
    }
    add_tools(...tools) {
        const computed_tools = tools.map((tool) => tool instanceof Tool ? tool : Tool.from_string(tool));
        this.toolbar.tools = [...this.toolbar.tools, ...computed_tools];
    }
    remove_tools(...tools) {
        this.toolbar.tools = [...difference(new Set(this.toolbar.tools), new Set(tools))];
    }
    get panels() {
        return [...this.side_panels, ...this.center];
    }
    get side_panels() {
        const { above, below, left, right } = this;
        return concat([above, below, left, right]);
    }
}
//# sourceMappingURL=plot.js.map