import { FlowDirectionType } from '../../model';
import { ConditionalControlElement } from '../base/conditional-control-element';
export class PipeElement extends ConditionalControlElement {
    constructor(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId) {
        super(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId);
        this.initDefaultData(this.model);
        const children = this.$element.children();
        if (!children || !children.length) {
            return;
        }
        // Pipe use PipeWall
        if (this.model.isPipeWall) {
            const elePipeOuterwall = children.eq(0);
            if (elePipeOuterwall) {
                elePipeOuterwall.attr('stroke', this.model.pipeWallColor);
                elePipeOuterwall.attr('stroke-width', this.model.pipeDiameter);
            }
        }
        this.elePipeInnerwall = children.eq(this.model.isPipeWall ? 1 : 0);
        this.elePipeInnerwall.attr('stroke', this.model.backGroundColor);
        if (this.model.pipeDiameter - 2 * this.model.pipeWallSize <= 0) {
            this.elePipeInnerwall.attr('stroke-width', 1);
        }
        else {
            this.elePipeInnerwall.attr('stroke-width', this.model.pipeDiameter - 2 * this.model.pipeWallSize);
        }
        this.elePipeInnerwall.attr('stroke-opacity', 1);
        // Pipe use FlowBlock
        if (this.model.isFlowBlock) {
            const strBlock = this.model.blockLength + ',' + this.model.blockMargin;
            this.elePipeFlowBlock = children.eq(this.model.isPipeWall ? 2 : 1);
            this.elePipeFlowBlock.attr('d', children.first().attr('d'));
            this.elePipeFlowBlock.attr('stroke', this.model.blockColor);
            this.elePipeFlowBlock.attr('stroke-width', this.model.blockWidth);
            this.elePipeFlowBlock.attr('stroke-dasharray', strBlock);
            this.elePipeFlowBlock.attr('stroke-opacity', 1);
            this.elePipeFlowBlock.css('display', 'block');
        }
        this.pathLength = this.model.blockLength + this.model.blockMargin;
        // is not use vaiable to control, then flow in default
        if (this.model.isFlowBlock && !this.model.isFlow) {
            this.elePipeFlowBlock.append(this.getAnimate());
        }
        setTimeout(() => {
            this.initFrameNode();
        }, 0);
    }
    initDefaultData(model) {
        // 向前兼容
        if (model.isPipeWall === undefined) {
            model.isPipeWall = true;
        }
        if (model.isFlowBlock === undefined) {
            model.isFlowBlock = true;
        }
        if (model.pipeWallColor === undefined) {
            this.model.pipeWallColor = '#333';
        }
        if (model.pipeDiameter === undefined) {
            model.pipeDiameter = 14;
        }
        if (model.backGroundColor === undefined) {
            model.backGroundColor = '#ffffff';
        }
        if (model.pipeWallSize === undefined) {
            model.pipeWallSize = 1;
        }
        if (model.blockLength === undefined) {
            model.blockLength = 12;
        }
        if (model.blockMargin === undefined) {
            model.blockMargin = 6;
        }
        if (model.blockColor === undefined) {
            model.blockColor = '#0081ff';
        }
        if (model.blockWidth === undefined) {
            model.blockWidth = 6;
        }
    }
    updateElement(result) {
        this.updateElementStates(result.states);
        if (!this.model.isFlow) {
            return;
        }
        this.startOrStopPipeFlow(result.value);
    }
    initFrameNode() {
        const arcPath = Snap(this.$element.find('path:last')[0]);
        const b = arcPath.getBBox(true);
        let height = this.model.pipeDiameter;
        let width = b.width + 1;
        height = height < b.height ? b.height : height;
        height = height < 20 ? 20 : height;
        let x = height / 2;
        if (b.height > 0) {
            x = 6;
            height += 15;
            width += 2;
        }
        else {
            x -= 1;
            if (height === 20) {
                x -= 3;
            }
        }
        this.rootElement.append('rect').attr('id', 'StateFrame')
            .attr('width', width).attr('height', height).attr('x', x).attr('fill', 'none');
    }
    startOrStopPipeFlow(isStart) {
        if (!this.elePipeFlowBlock) {
            return;
        }
        this.elePipeFlowBlock.children().remove();
        if (isStart) {
            this.elePipeFlowBlock.append(this.getAnimate());
        }
    }
    getAnimate() {
        switch (this.model.flowDirection) {
            case FlowDirectionType.Positive:
                return this.getAnimateElement(this.pathLength, 0);
            case FlowDirectionType.Negative:
                return this.getAnimateElement(0, this.pathLength);
            default:
                throw new Error('Unknown flowDirection:' + this.model.flowDirection);
        }
    }
    getAnimateElement(from, to) {
        const document = this.$element[0].ownerDocument;
        const animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
        animate.setAttribute('attributeType', 'XML');
        animate.setAttribute('attributeName', 'stroke-dashoffset');
        animate.setAttribute('from', from.toString());
        animate.setAttribute('to', to.toString());
        animate.setAttribute('by', '3');
        animate.setAttribute('dur', '1s');
        animate.setAttribute('repeatCount', 'indefinite');
        return animate;
    }
}
