import { GraphType } from '../../../config';
import { Flicker } from '../../../model';
import { GraphUtil } from '../../../utils';
export class GraphStateElement {
    constructor(graphSetting, width, height, graphStore, logger, version, faultFlickers) {
        this.graphSetting = graphSetting;
        this.width = width;
        this.height = height;
        this.graphStore = graphStore;
        this.logger = logger;
        this.version = version;
        this.faultFlickers = faultFlickers;
        this.graphs = new Map();
        this.activeState = 0;
        this.faultFlickerStatus = false;
        this.faultFlickerInterval = undefined;
        this._element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
    }
    get Element() {
        return this._element;
    }
    switchToState(stateId) {
        this.activeState = stateId;
        if (this.graphs.has(stateId)) {
            const graph = this.graphs.get(stateId);
            // 已经发出过图形请求，不再重复请求。
            if (graph == null) {
                return;
            }
            this.changeGraph(stateId, graph);
        }
        else {
            // 标记，防止重复请求图形。
            this.graphs.set(stateId, null);
            this.graphStore.getGraph(this.graphSetting.id, stateId, GraphUtil.getExtendedStyle(this.graphSetting, stateId))
                .subscribe(graphResult => {
                this.graphs.set(stateId, graphResult);
                if (this.activeState === stateId) {
                    this.changeGraph(stateId, graphResult);
                }
            });
        }
    }
    changeGraph(stateId, graphResult) {
        if (!graphResult.failed) {
            const graph = graphResult.graph;
            switch (graph.graphType) {
                case GraphType.Image:
                case GraphType.SVG:
                    const imageElement = this.getImageElement();
                    imageElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', graph.source);
                    this.doFaultFlicker(imageElement, stateId);
                    break;
                default:
                    this.logger.error(new Error(`Unknown graph ${graph.graphType}.`));
                    this.removeImageElement();
                    break;
            }
        }
        else {
            this.removeImageElement();
        }
    }
    getImageElement() {
        if (!this.imageElement) {
            this.imageElement = document.createElementNS('http://www.w3.org/2000/svg', 'image');
            this.imageElement.setAttribute('width', this.width + '');
            this.imageElement.setAttribute('height', this.height + '');
            this.imageElement.setAttribute('fill', 'none');
            this.imageElement.setAttribute('preserveAspectRatio', 'none');
            this.imageElement.setAttribute('crossorigin', 'anonymous');
            this._element.appendChild(this.imageElement);
        }
        return this.imageElement;
    }
    removeImageElement() {
        if (this.imageElement) {
            this._element.removeChild(this.imageElement);
            delete this.imageElement;
        }
    }
    doFaultFlicker(imageElement, stateId) {
        if (this.version > 3 && this.faultFlickers) {
            this.clearFlickerInterval(imageElement);
            const faultFlicker = this.faultFlickers.find(t => t.id === stateId);
            if (faultFlicker && faultFlicker.faultFlicker) {
                if (faultFlicker.faultFlicker.flicker === Flicker.Image) {
                    this.faultFlickerInterval = setInterval(() => {
                        if (this.faultFlickerStatus) {
                            imageElement.setAttributeNS(null, 'display', 'block');
                            this.faultFlickerStatus = false;
                        }
                        else {
                            imageElement.setAttributeNS(null, 'display', 'none');
                            this.faultFlickerStatus = true;
                        }
                    }, faultFlicker.faultFlicker.frequency * 500);
                }
            }
        }
    }
    clearFlickerInterval(imageElement) {
        if (this.faultFlickerInterval) {
            clearInterval(this.faultFlickerInterval);
            if (this.faultFlickerStatus) {
                imageElement.setAttributeNS(null, 'display', 'block');
            }
        }
    }
}
