// Import the Lasal Runtime base element into your component
// Import SigPolymer to use Polymer methods: html, afterNextRender, beforeNextRender, debouncer, timeOut
// or if your component's getter template() returns a HTML literal
import { LasalRuntimeSigElement, SigPolymer } from '../../sigmatek/sig-element/sig-element.js';
/****************************************************************************************************
 * @class LasalRuntimeSigControlSwitchButtonImage
 * @extends {LasalRuntimeSigElement}
 ****************************************************************************************************/
export class LasalRuntimeSigControlSwitchButtonImage extends LasalRuntimeSigElement {
    /****************************************************************************************************
     * When the element is loaded, importMeta() assigns reference to the path from 
     * which an element was imported to its importPath property. 
     * Relative URLs in styles are automatically re-written to be relative to the importPath property. 
     * You can use [[importPath]] in your component to load url resources
     ****************************************************************************************************/
    static get importMeta() {
        return import.meta;
    }

    /****************************************************************************************************
     * Return the component style and template as a template literal
     ****************************************************************************************************/
    static get template() {
        return SigPolymer.html`
        <style include="sig-element-css">
            :host {
                display: block;
                position: absolute;
                /*To position Text outside of the container */
                overflow: visible;
            }

            .sig-control-switch-button {
                display: relative;
                height: 100%;
                width: 100%;
            }

            #sig-control-switch-button-track {
                position: absolute;
                height: var(--theme-sig-control-switch-button-track-height, 100%);
                width: calc(100% - var(--theme-sig-control-switch-button-track-padding-left-right, 0px));
                box-sizing: border-box;

                /** Track Top Positioning */
                top: var(--theme-sig-control-switch-button-track-top-position, 50%);
                left: 50%;
                transform: translateY(calc(var(--theme-sig-control-switch-button-track-top-position, 50%) * -1)) translateX(-50%);

                /** Border in General */
                border-radius: var(--theme-sig-control-switch-button-track-border-radius, 25px);

                /** Background */
                background-color: var(--theme-sig-control-switch-button-track-color, inherit);
                background-image: var(--theme-sig-control-switch-button-track-background-image, none);
                background-repeat: no-repeat;
                background-position-x: 0;
                background-position-y: 0;
                background-size: 100% 100%;
            }

            #sig-control-switch-button-thumb-container {
                position: absolute;
                height: 100%;
                max-width: 100%;
                overflow: hidden;
                top: 50%;
                border-radius: var(--theme-sig-control-switch-button-thumb-container-border-radius, 25px);
                box-sizing: border-box;
                background-clip: content-box;

                padding: var(--theme-sig-control-switch-button-thumb-container-padding, 3px);
            }

            #sig-control-switch-button-thumb {
                display: block;
                height: 100%;
                overflow: hidden;
                border-radius: var(--theme-sig-control-switch-button-thumb-container-border-radius, 25px);
                background-color: var(--theme-sig-control-switch-button-thumb-color, inherit);
                box-sizing: border-box;
            }

            #sig-control-switch-button-thumb img {
                height:100%;
                width: auto;
                
            }

            #sig-control-switch-button-thumb img.newChrome {
                margin: 0 calc(var(--theme-sig-control-switch-button-thumb-container-padding, 3px) * -1);
            }

            .moveToAnimation {
                transition: all 0.1s;
            }

            .moveFromAnimation {
                transition: all 0.1s;
            }

            :host([checked="1"]) #sig-control-switch-button-thumb {
                background-color: var(--theme-sig-control-switch-button-thumb-color-active, inherit);
            }

            :host([checked="1"]) #sig-control-switch-button-track {
                background-color: var(--theme-sig-control-switch-button-track-color-active, inherit);
                background-image: var(--theme-sig-control-switch-button-track-background-image-active, none);
            }

            .text {
                display: inline-block;
                position: absolute;
                top: var(--theme-sig-control-switch-button-text-top, 50%);
                left: var(--theme-sig-control-switch-button-text-left, 50%);
                transform: translateY(calc(var(--theme-sig-control-switch-button-text-top, 50%) * -1)) translateX(calc(var(--theme-sig-control-switch-button-text-left, 50%) * -1));
            }

            /** Show The Texts when they need to be shown */
            #text-on {
                display: none;
                top: var(--theme-sig-control-switch-button-text-top, 50%);
                left: var(--theme-sig-control-switch-button-text-left, 50%);
                transform: translateY(calc(var(--theme-sig-control-switch-button-text-top, 50%) * -1)) translateX(calc(var(--theme-sig-control-switch-button-text-left, 50%) * -1));
                padding-top: var(--theme-sig-control-switch-button-text-on-padding-top, 0px);
                padding-left: var(--theme-sig-control-switch-button-text-on-padding-left, 0px);
                padding-right: var(--theme-sig-control-switch-button-text-on-padding-right, 0px);
                padding-bottom: var(--theme-sig-control-switch-button-text-on-padding-bottom, 0px);
            }

            #text-off {
                display: initial;
                color: var(--theme-sig-control-switch-button-text-off-color, #000);
                top: var(--theme-sig-control-switch-button-text-off-top, 50%);
                left: var(--theme-sig-control-switch-button-text-off-left, 50%);
                transform: translateY(calc(var(--theme-sig-control-switch-button-text-off-top, 50%) * -1)) translateX(calc(var(--theme-sig-control-switch-button-text-off-left, 50%) * -1));
                padding-top: var(--theme-sig-control-switch-button-text-off-padding-top, 0px);
                padding-left: var(--theme-sig-control-switch-button-text-off-padding-left, 0px);
                padding-right: var(--theme-sig-control-switch-button-text-off-padding-right, 0px);
                padding-bottom: var(--theme-sig-control-switch-button-text-off-padding-bottom, 0px);

            }

            :host([checked="1"]) #text-on {
                display: initial;
                color: var(--theme-sig-control-switch-button-text-on-color, inherit);
                top: var(--theme-sig-control-switch-button-text-on-top, var(--theme-sig-control-switch-button-text-top, 50%));
                left: var(--theme-sig-control-switch-button-text-on-left, var(--theme-sig-control-switch-button-text-left, 50%))
            }

            :host([checked="1"]) #text-off {
                display: none;
            }

            .imageinactive,
            :host([checked="1"]) .imageactive {
                display: initial;
            }

            .imageactive,
            :host([checked="1"]) .imageinactive {
                display: none;
            }

            #switch-container {
                height: 100%;
            }

            #text-on.text.hide-element,
            #text-off.text.hide-element {
                display: none;
            }
        </style>
        <div class="sig-control-switch-button clearfix " on-tap="_handleTap">
            <div id="switch-container">
                <div id="sig-control-switch-button-track">
                </div>
                <div id="sig-control-switch-button-thumb-container" style="transform: translate(0%, -50%);">
                    <div id="sig-control-switch-button-thumb">
                        <img id="imageactive" class="imageactive" src="[[imgsrcactive]]" alt="" />
                        <img id="imageinactive" class="imageinactive" src="[[imgsrcinactive]]" />
                    </div>
                </div>
                <div id="text-on" class="text text-on">
                    <span>[[ontext]]</span>
                </div>
                <div id="text-off" class="text text-off">
                    <span>[[offtext]]</span>
                </div>
            </div>
        </div>
        `;
    }

    /****************************************************************************************************
     * define the custom tag name 
     *
     * @readonly
     * @static
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    static get is() {
        return "sig-control-switch-button";
    }

    /****************************************************************************************************
     * define the main porperties of the component
     * reflected property names should always be lower case so it can be used directly on the element as an attribute
     *
     * @readonly
     * @static
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    static get properties() {
        let props = {
            imgsrcactive: {
                type: String,
                value: "",
                observer: '_activeImgChange'
            },
            imgsrcinactive: {
                type: String,
                value: "",
                observer: '_inactiveImgChange'
            },
            value: {
                type: Number,
                value: null,
                reflectToAttribute: false,
                observer: '_stateChanged',
                notify: true,
            },
            checked: {
                type: Number,
                value: 0,
                reflectToAttribute: true,
                notify: true
            },
            ontext: {
                type: String,
                value: '',
            },
            offtext: {
                type: String,
                value: ''
            },
            previewstate: {
                type: Boolean,
                value: false,
                observer: '_designModeSwitchButton'
            }
        }
        return props;
    }

    /****************************************************************************************************
     * Creates an instance of LasalRuntimeSigControlSwitchButtonImage.
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    constructor() {
        super();

        // get refererence to properties api
        this.propApi = window.sigApi.properties;

        // initialize variables
        this.animating = false;
        this.isWindow = false;
        this.window = null;
        this.correctPos = false;
        this.offvalue = 0;
        this.onvalue = 1;
        this.showundefinedon = false;

        // add required properties
        this.sigAddRequiredProperty('value');
        this.sigAddRequiredProperty('onvalue');
        this.sigAddRequiredProperty('offvalue');
        this.sigAddRequiredProperty('previewstate');
        this.sigAddRequiredProperty('showundefinedon');
    }

    /****************************************************************************************************
     * called after property default values are set and local DOM is initialized
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    ready() {
        super.ready();
        this.isReady = true;

        //  Check for newer chrome version;
        //  The sizing of the image is different here
        if(navigator && navigator.userAgent) {
            const userAgent = navigator.userAgent;
            const chromeVersion = userAgent.match(/Chrome\/(.*) Safari/);
            if(chromeVersion && chromeVersion[1]) {
                if(parseFloat(chromeVersion[1].split('.')) >= 83 && parseFloat(chromeVersion[1].split('.')) < 90) {
                    this.$.imageactive.classList.add('newChrome');
                    this.$.imageinactive.classList.add('newChrome');
                }
            }
        }

        // get reference to text elements
        this.textOn = this.$['text-on'];
        this.textOff = this.$['text-off'];

        // event listener for transitionend
        this.thumbContainer = this.$['sig-control-switch-button-thumb-container'];
        this.sigAddEventListener('transitionend', this._thumbAnimationEndHandler.bind(this), 'jsEvent', this.thumbContainer);

        // wait for next render in designer, for getting control bounds
        if (this.isdesignmode) {
            SigPolymer.afterNextRender(this, function () {
                this._initialize();
            });

        // no designer, get control bounds immediately
        } else {
            if (this.propsReady) {
                this._initialize();
            }
        }
    }

    /****************************************************************************************************
    * called when values are ready
    *
    * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    sigOnRequiredPropertiesReady() {
        super.sigOnRequiredPropertiesReady();
        this.propsReady = true;
        if (this.isReady) {
            this._initialize();
        }
    }

    /****************************************************************************************************
     * Initialize the component
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _initialize() {

        if (this.isdesignmode) {
            if (this.previewstate) {
                this.value = this.onvalue;
                this.checked = 1;
            } else {
                this.value = this.offvalue;
                this.checked = 0;
            }
        } else {
            // set actual position of switch
            if (this.value === this.offvalue) {
                this.checked = 0
            } else if (this.value === this.onvalue) {
                this.checked = 1
            } else {
                this.checked = this.showundefinedon ? 1 : 0;
            }
        } 
        
        // initialization is done
        this.initialized = true;

        // set position of switch
        this._setThumbPos();
    }

    /****************************************************************************************************
     * Handler when the animation ends
     * Makes sure the position for the thumb is correct, and removes the animation classes
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _thumbAnimationEndHandler() {
        if (this.initialized) {
            this._setThumbPos();
            this.thumbContainer.classList.remove('moveToAnimation');
            this.thumbContainer.classList.remove('moveFromAnimation');
            this.textOff.classList.remove('hide-element');
            this.textOn.classList.remove('hide-element');
        }
    }

    /****************************************************************************************************
     * Sets the thumb position
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _setThumbPos() {
        if (this.initialized) {
            if (this.value === this.onvalue) {
                this.thumbContainer.style.left = '100%';
                this.thumbContainer.style.transform = 'translate(-100%, -50%)';
            } else if (this.value === this.offvalue) {
                this.thumbContainer.style.left = '0%';
                this.thumbContainer.style.transform = 'translate(0%, -50%)';
            } else {
                if (this.showundefinedon) {
                    this.thumbContainer.style.left = '100%';
                    this.thumbContainer.style.transform = 'translate(-100%, -50%)';
                } else {
                    this.thumbContainer.style.left = '0%';
                    this.thumbContainer.style.transform = 'translate(0%, -50%)';
                }
            }  
        }
    }

    /****************************************************************************************************
     * Handle Tap
     * Sets the value to either min or max Value
     *
     * @param {*} e
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _handleTap(e) {
        if (!this.isdesignmode) {
            if (this.checked) {
                this.value = this.offvalue;
            } else {
                this.value = this.onvalue;
            }
            this._dispatchEvent('tap');
        }
    }

    /****************************************************************************************************
     * State Changed
     * needed for some css
     * checks the value, and sets it correctly if neccessary 
     *
     * @param {*} newstate
     * @param {*} oldstate
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _stateChanged(newstate, oldstate) {
        if (this.initialized) {
            let condition;
            let newstateString;
            if (newstate !== null && newstate !== undefined) {
                // catch the case when in designmode a datapoint is (dis)connected - stop it from overwriting the preview state
                // when connecting newval is "00000000000", when disconnecting it is ""
                newstateString = newstate.toString();
                condition = !(this.isdesignmode && (newstateString == "00000000000" || newstateString == ""));
            } else {
                condition = true;
            }
    
            if (condition) { 
                if (newstate !== null && newstate !== undefined) {
                    const newVal = parseFloat(newstate);
                    let oldChecked = this.checked;
                    if (newVal === this.offvalue) {
                        this.checked = 0
        
                    } else if (newVal === this.onvalue) {
                        this.checked = 1
                    } else {
                        this.checked = this.showundefinedon ? 1 : 0;
                    }
                    this._setThumbPos();
                    if (oldstate !== null && oldstate !== undefined && oldChecked !== this.checked) {
                        this._animateThumbMove();
                    }
                }
                this._dispatchEvent('value-changed');
            }
        }  
    }

    /****************************************************************************************************
     * Switches between on and off state in the design Mode
     * To be able to view and adjust colors/texts for both views
     *
     * @param {*} newVal
     * @return {*} 
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _designModeSwitchButton(newVal) {
        if (!this.isdesignmode) {
            return;
        }
        if (newVal) {
            this.value = this.onvalue;
        } else {
            this.value = this.offvalue;
        }
    }

    /****************************************************************************************************
     * Only needed for the design mode really
     * if the value changes to '', go back to the default value
     *
     * @param {*} newVal
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _activeImgChange(newVal) {
        if (newVal === '') {
            this.imgsrcactive = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC44GzRO2AAAAA1JREFUGFdj+C+pyAAABI4BOoLbnY0AAAAASUVORK5CYII=";
        }  
    }

    /****************************************************************************************************
     * Only needed for the design mode really
     * if the value changes to '', go back to the default value
     *
     * @param {*} newVal
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _inactiveImgChange(newVal) {
        if (newVal === '') {
            this.imgsrcinactive = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC44GzRO2AAAAA1JREFUGFdj+C+pyAAABI4BOoLbnY0AAAAASUVORK5CYII=";
        }
    }

    /****************************************************************************************************
     * Adds the animation classes to the thumb
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    _animateThumbMove() {
        if (this.initialized) {
            let needAnimation = false;
    
            if (this.value === this.offvalue) {
                needAnimation = true;
                this.thumbContainer.classList.add('moveFromAnimation')
            } else if (this.value === this.onvalue) {
                needAnimation = true;
                this.thumbContainer.classList.add('moveToAnimation');
            } else {
                if (this.showundefinedon) {
                    needAnimation = true;
                    this.thumbContainer.classList.add('moveToAnimation');
                } else {
                    needAnimation = true;
                    this.thumbContainer.classList.add('moveFromAnimation')
                }
            }
    
            // if an animation is needed, both texts are hidden
            // and only the needed one is shown once the animation finished
            if (needAnimation) {
                this.textOn.classList.add('hide-element');
                this.textOff.classList.add('hide-element');
            }
        }
    }

    /****************************************************************************************************
     * function is called if component gets resized in designmode
     *
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    designerOnBoundsChanged(){
        // set the thumb again because the element size wasn't not available in former calculations for the thumb button
        SigPolymer.afterNextRender(this, () => { this._setThumbPos() })
    }

    /****************************************************************************************************
     * Will be called when the runtime shows or hides the component by setting "display" to "block" or "none".
     *
     * @param {boolean} isVisible
     * @memberof LasalRuntimeSigControlSwitchButtonImage
    ****************************************************************************************************/
    sigOnVisibilityChange(isVisible) {
        //call base
        super.sigOnVisibilityChange(isVisible);
        if (isVisible) {
            // since transitionend is not fired when dashboard is changed, we execute the function manually
            this._thumbAnimationEndHandler();            
        }
    }
}
customElements.define(LasalRuntimeSigControlSwitchButtonImage.is, LasalRuntimeSigControlSwitchButtonImage)
