import { SvgPrimitive } from "./Primitives/Primitive";
import { TextFloodFilterPrimitive } from "./Primitives/TextFilterPrimitive";
import { Size } from "@devexpress/utils/lib/geometry/size";
import { UnitConverter } from "@devexpress/utils/lib/class/unit-converter";
import { DOMManipulator } from "./DOMManipulator";

export const PAGE_BG_TEXTFLOOR_FILTER_IDPREFIX = "page-text-flood";

export class CanvasManagerBase {
    actualZoom: number;
    protected dom: DOMManipulator;
    private elements: {[key: string]: SVGElement} = {};
    protected instanceId: string;

    constructor(actualZoom: number, dom: DOMManipulator, instanceId: string) {
        this.instanceId = instanceId;
        this.actualZoom = actualZoom;
        this.dom = dom;
    }

    protected createAndChangePrimitivesElements(primitives: SvgPrimitive<SVGElement>[], parent: SVGElement) {
        primitives.forEach(primitive => {
            this.createAndChangePrimitiveElement(primitive, parent);
        });
    }
    protected createPrimitiveElement<TEl extends SVGElement, TPrim extends SvgPrimitive<TEl>>(primitive: TPrim, parent: SVGElement, sibling?: SVGElement): TEl {
        return this.dom.createElement(primitive, parent, sibling);
    }
    protected createAndChangePrimitiveElement(primitive: SvgPrimitive<SVGElement>, parent: SVGElement, sibling?: SVGElement): SVGElement {
        const element = this.createPrimitiveElement(primitive, parent, sibling);
        this.dom.changeByPrimitive(element, primitive);
        return element;
    }
    protected changePrimitiveElement(primitive: SvgPrimitive<SVGElement>, element: SVGElement) {
        this.dom.changeByPrimitive(element, primitive);
    }
    protected getOrCreateElement<TEl extends SVGElement, TPrim extends SvgPrimitive<TEl>>(key: string, primitive: TPrim, parent: SVGElement, sibling?: SVGElement): TEl {
        const element = (key && this.elements[key]) || (this.elements[key] = this.createPrimitiveElement(primitive, parent, sibling));
        this.changePrimitiveElement(primitive, element);
        return <TEl>element;
    }
    protected createTextFloodFilter(instanceId: string, key: string, parent: SVGElement, pageColor: number) {
        this.getOrCreateElement(key, new TextFloodFilterPrimitive(PAGE_BG_TEXTFLOOR_FILTER_IDPREFIX + instanceId, pageColor), parent);
    }

    getAbsoluteSize(modelSize: Size): Size {
        return modelSize
            .clone().applyConverter(UnitConverter.twipsToPixelsF)
            .clone().multiply(this.actualZoom, this.actualZoom);
    }
}
