import { LasalRuntimeSigElement, SigPolymer } from '../../sigmatek/sig-element/sig-element.js';

/**
 * @class
 * @classdesc Implements and exports the sig-control-radio-button component.
 * @extends LasalRuntimeSigElement
 */
export class LasalRuntimeSigRadioButtonElement extends LasalRuntimeSigElement {

    /**
     * Returns the component's registered tag name.
     * @readonly
     * @static
     * @returns {String} The component's tag name.
     * @memberof LasalRuntimeSigRadioButtonElement
     */
    static get is() {
        return "sig-control-radio-button";
    }

    /**
     * Returns the import path URL used by Polymer.
     * @readonly
     * @static
     * @returns {String} The import path URL.
     * @memberof LasalRuntimeSigRadioButtonElement
     */
    static get importMeta() { return import.meta; }


    /**
     * Returns the HTML literal of the component.
     * @readonly
     * @static
     * @returns {HTMLLIElement} The template literal of the component. 
     * @memberof LasalRuntimeSigRadioButtonElement
     */
    static get template() {
        return SigPolymer.html`
        <style include="sig-element-css">
            :host {
                /* Basic styling of the component */
                color: inherit;
                background-color: var(--theme-sig-control-radio-button-background-color, inherit);
                background-image: none;
                background-repeat: repeat;
                border-width: var(--theme-sig-control-radio-button-border-width, 0);
                border-color: var(--theme-sig-control-radio-button-border-color, inherit);
                border-style: var(--theme-sig-control-radio-button-border-style, none);
                border-radius: var(--theme-sig-control-radio-button-border-radius, 0);

                /* Basic box model settings */
                display: block;
                position: absolute;

                margin: 0;
                padding: 0;
                overflow: hidden;
            }

            :host * {
                /* Reset margins and paddings for child elements and turn of text selection */
                @apply --notextselect;
                margin: 0;
                padding: 0;
            }

            .clearfix:after {
                /* Import the global clearfix css mixin */
                @apply --clearfix
            }

            .sig-radio-button {
                /* should be relative for use in designer */
                position: relative;
                width: 100%;
                height: 100%;
                cursor: pointer;
            }

            .radio {
                position: absolute;
                margin: auto !important;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                text-align: center;
                cursor: pointer;
                width: var(--theme-sig-control-radio-button-outer-size, 16px);
                height: var(--theme-sig-control-radio-button-outer-size, 16px);
                border-color: var(--theme-sig-control-radio-button-outer-border-color, inherit);
                border-width: var(--theme-sig-control-radio-button-outer-border-width, 2px);
                border-style: var(--theme-sig-control-radio-button-outer-border-style, none);
                border-radius: 100%;
            }

            :host([applybordereffect][checked="0"]) .radio {
                border-top: 1px solid rgba(255, 255, 255, .4);
                border-left: 1px solid rgba(255, 255, 255, .4);
                border-right: 1px solid rgba(0, 0, 0, .4);
                border-bottom: 1px solid rgba(0, 0, 0, .4);
            }

            :host([applybordereffect][checked="1"]) .radio {
                border-top: 1px solid rgba(0, 0, 0, .4);
                border-left: 1px solid rgba(0, 0, 0, .4);
                border-right: 1px solid rgba(255, 255, 255, .4);
                border-bottom: 1px solid rgba(255, 255, 255, .4);
            }

            .inner {
                display: none;
            }

            :host([checked="1"]) .inner {
                display: block;
                position: absolute;
                margin: auto !important;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                text-align: center;
                cursor: pointer;
                width: var(--theme-sig-control-radio-button-inner-size, 10px);
                height: var(--theme-sig-control-radio-button-inner-size, 10px);
                background-color: var(--theme-sig-control-radio-button-inner-background-color, inherit);
                border-radius: 100%;
            }

            :host([checked="0"]) .radio {
                background-color: var(--theme-sig-control-radio-button-radio-background-color, inherit);
            }

            :host([checked="1"]) .radio {
                background-color: var(--theme-sig-control-radio-button-outer-background-color, inherit);
                border-color: var(--theme-sig-control-radio-button-active-outer-border-color, transparent);
            }

            :host([isdesignmode]) .radio,
            :host([isdesignmode]) .inner,
            :host([isdesignmode]) .sig-radio-button {
                cursor: unset;
            }

            #image {
                display: none;
                pointer-events: none;
            }

            :host([checked="1"]) #image[src]:not([src=""]) {                
                display: initial;
                position: absolute;
                top: 0;
                left: 0;
                height: 100%;
                width: 100%;
                box-sizing: border-box;
                padding: var(--theme-sig-control-radio-button-checkmark-image-padding, 0);
                background-origin: content-box;
                background-repeat: no-repeat;
                background-size: 100% 100%;
            }            
        </style>
        <div class="sig-radio-button clearfix" on-tap="_handleTap">
            <div class="radio"></div>
            <div class="inner">
                <img src="[[ccheckmarkimg]]" id="image">
            </div>
        </div>
        `;
    }

    /**
    * Returns the defined Polymer properties of the component.
    * @readonly
    * @static
    * @returns {Object} The defined Polymer properties.
    * @memberof LasalRuntimeSigRadioButtonElement
    * 
    * @property {Number}  value             - Defines the value property of the component.
    * @property {Number}  checked           - Defines if the radio button is checked.
    * @property {Boolean} applybordereffect - Defines if the radio button has border effect applied.
    * @property {String}  ccheckmarkimg     - Image to show active state of radio button
    * @property {Boolean} preview           - Preview setting for designer
    */
    static get properties() {
        // property names should always be lower case so we
        // can use them directly on the element as an attribute
        let props = {
            value: {
                type: Number,
                value: 0,
                reflectToAttribute: true,
                observer: '_stateChanged',
                notify: true
            },
            checked: {
                type: Number,
                value: 0,
                reflectToAttribute: true,
                notify: true
            },
            applybordereffect: {
                type: Boolean,
                value: false,
                reflectToAttribute: true,
            },
            ccheckmarkimg: {
                type: String,
                computed: '_cCheckmarkImg(checkmarkimg)'
            },
            preview: {
                type: Boolean,
                value: false,
                observer: '_previewChanged'
            }
        }
        return props;
    }

    /**
    * Creates an instance of LasalRuntimeSigRadioButtonElement.
    * @constructor
    * @memberof LasalRuntimeSigRadioButtonElement
    */
    constructor() {
        super();
        this.radiobuttonvaluetype = 'normal';

        this.addPredefProps([{
            src: 'value',
            dest: 'state',
            type: window.sigApi.SIG_CONST.PROP_PREDEF_PROPS_TYPE_STATE
        }]);

        this.sigAddRequiredProperty('value');
    }

    /**
     * This callback is called after property values are set and local DOM is initialized.
     * @returns  {Undefined} Undefined
     * @memberof LasalRuntimeSigRadioButtonElement
    */
    ready() {
        super.ready();        
        this.isReady = true;

        if ((this.propsReady) || (this.isdesignmode)) {
            this._updateButtonState(this.value);            
        }
    }

    /****************************************************************************************************
    * called when values are ready
    *
    * @memberof LasalRuntimeSigRadioButtonElement
    ****************************************************************************************************/
    sigOnRequiredPropertiesReady() {
        super.sigOnRequiredPropertiesReady();
        this.propsReady = true;
        
        if (this.isReady) {
            this._updateButtonState(this.value);            
        }
    }
    
    /****************************************************************************************************
    * shows the state according to the passed parameter
    *
    * @memberof LasalRuntimeSigRadioButtonElement
    ****************************************************************************************************/
    _updateButtonState(newstate) {
        if(this.isdesignmode) {
            if(this.preview) {
                this.checked = 1;
            } else {
                this.checked = 0;
            }
        } else {
            const newVal = parseFloat(newstate);        
            if (newVal === 0 || isNaN(newVal)) {
                this.checked = 0;
            } else {
                this.checked = 1;
            }
        }      
    }

    /**
     * An observer method that is fired every time the property 'value' changed.
     * @private
     * @param {Number} newstate The new value of the value property.
     * @param {Number} oldstate The old value of the value property.
     * @returns {Undefined} Undefined
     * @memberof LasalRuntimeSigRadioButtonElement
    */
    _stateChanged(newstate, oldstate) {
        if ((!this.isdesignmode) && (oldstate !== undefined)) {
            const newVal = parseFloat(newstate);        
            if (newVal === 0 || isNaN(newVal)) {
                this.checked = 0;
            } else {
                this.checked = 1;
            }
            this._dispatchEvent('value-changed');
        }      
    }

    
    /**
     * A method that is executed every time the radio button is tapped. It toggles the value property of the radio button.
     * @private
     * @param {Event} event JavaScript tap event.
     * @returns {Undefined} Undefined
     * @memberof LasalRuntimeSigRadioButtonElement
     */
     _handleTap(e) {
        if (!this.isdesignmode) {
            
            /** Get datapoint-name with station of checkbox: "0:Objectname.Servername.BitXX" */
            const prop = sigApi.properties.getProperty(this.id, 'value');
            let dp = undefined;
            let dpName = undefined
            if(prop) {
                if(prop.getDatapoint) {
                    dp = prop.getDatapoint(); 
                } else if(prop.getScheme) {
                    dp = prop.getSelectedProp().getDatapoint();
                }
                
                if(dp){
                    dpName = dp.getFullNameWithStation();
                }
            }

            /**---------------------------------------------------------------------------------------*/
            /** Dataserver is a Bit */
            /**---------------------------------------------------------------------------------------*/
            if (dp && (dp.getTypeId() === window.sigApi.SIG_CONST.TYPE_ID_BIT_ITEM)) {

                /** Get Bit-number from datapoint */
                const dpNameSvr = dpName.slice(0, dpName.lastIndexOf("."));
                let  bitNr = dp.getId() - sigApi.datapointManager.getDatapoint(dpNameSvr).getId();
                let newValue;

                /** Check if handling for radio32 or normal */
                /**---------------------------------------------------------------------------------------*/
                if (this.radiobuttonvaluetype === "normal") {
                    
                    /** Set new value */
                    if (parseFloat(this.value) !== 0) {
                        /** reset bit */
                        newValue = 0;
                    } else {
                        /** set bit */
                        newValue = (1 << (bitNr - 1));
                    }
                    
                /**---------------------------------------------------------------------------------------*/
                } else {
                    
                    /** Set value and MSB for Radio32 */
                    if (parseFloat(this.value) !== 0) {
                        /** reset bit */
                        newValue = 0 << 31;
                        if (bitNr !== 32) {
                            newValue = newValue | (1 << (bitNr - 1));
                        }
                    } else {
                        /** set bit */
                        newValue = 1 << 31;
                        newValue = newValue | (1 << (bitNr - 1));
                    }

                }
                this.dispatch = true;
                sigApi.datapointManager.writeDataPoint(dpNameSvr, (newValue >>> 0));

            /**---------------------------------------------------------------------------------------*/
            /** Dataserver is not a Bit */
            /**---------------------------------------------------------------------------------------*/
            } else {
                if (parseFloat(this.value) !== 0) {
                    /** reset bit */
                    this.value = 0;
                } else {
                    /** set bit */
                    this.value = 1;
                }
            }

            this._dispatchEvent('tap');
        }
    }

    /**
     * Called for checking if a event should be dispatched.
     * @returns {Bool} true to dispatch event
     * @memberof LasalRuntimeSigRadioButtonElement
     */
    shouldDispatchInternalEvent(event) {
    
        // necessary for this.radiobuttonvaluetype === "bit32", otherwise no event is dispatched
        if ((this.dispatch === true) && (event === 'value-changed')) {
            this.dispatch = false;
            return true;
        } else {
            return super.shouldDispatchInternalEvent(event);
        }
    }

    /****************************************************************************************************
     * Called when changing the preview value in the designer
     *
     * @memberof LasalRuntimeSigRadioButtonElement
    ****************************************************************************************************/
    _previewChanged(newstate) {
        this._updateButtonState(newstate);
    }    

    /****************************************************************************************************
     * Calculates the checkmark image;
     *
     * @return {String} the image path, or the default image path
     * @memberof LasalRuntimeSigRadioButtonElement
    ****************************************************************************************************/
    _cCheckmarkImg(checkmarkimg){    
        // set the path
        if(!checkmarkimg || checkmarkimg === '' || checkmarkimg === 'none') {
            return "";
        } else {
            return checkmarkimg;
        }    
    }
}
customElements.define(LasalRuntimeSigRadioButtonElement.is, LasalRuntimeSigRadioButtonElement);
