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

/**
 * @class 
 * @classdesc Implements and exports sig-control-da-channelname component.
 * @version 01.00.000
 * @extends LasalRuntimeSigElementLight
 * 
 * @property {String}  sigtext The source text of the component.
 * @property {String}  previewtext The preview text of the component in the style class editor.
 */
export class LasalRuntimeSigDAChannelName extends LasalRuntimeSigElement {

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

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

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

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

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

                .clearfix:after {
                    @apply --clearfix
                }

                .sig-text {
                    /* The container is rendered as a table so we can set the span to table-cell */
                    display: table;
                    width: 100%;
                    height: 100%;
                    text-decoration: inherit;
                }

                #label {
                    /* The container is rendered as a table-cell so we can position the value via vertical-align */
                    display: table-cell;
                    padding: var(--theme-sig-control-da-channelname-value-padding, 0);
                    padding-top: var(--theme-sig-control-da-channelname-value-padding-top, var(--theme-sig-control-da-channelname-value-padding, 0));
                    padding-right: var(--theme-sig-control-da-channelname-value-padding-right, var(--theme-sig-control-da-channelname-value-padding, 0));
                    padding-bottom: var(--theme-sig-control-da-channelname-value-padding-bottom, var(--theme-sig-control-da-channelname-value-padding, 0));
                    padding-left: var(--theme-sig-control-da-channelname-value-padding-left, var(--theme-sig-control-da-channelname-value-padding, 0));
                    text-align: var(--theme-sig-control-da-channelname-value-align, center);
                    vertical-align: var(--theme-sig-control-da-channelname-value-vertical-align, middle);
                    white-space: var(--theme-sig-control-da-channelname-value-white-space, normal);
                    text-decoration: inherit;
                }

                :host([isdesignmode]:hover) {
                    background-color: var(--theme-sig-control-da-channelname-background-color, rgba(255, 255, 255, .3));
                }
            </style>
            <div class="sig-text clearfix">
                <div id="label" class="content">[[sigtextc]]</div>
            </div>
            `
    }

    /**
     * Returns the defined Polymer properties of the component.
     * @readonly
     * @static
     * @returns {Object} The defined Polymer properties
     * @memberof LasalRuntimeSigDAChannelName
     * 
     * @property {String}  sigtextc The computed text of the component.
     */
    static get properties() {
        // property names should always be lower case so we
        // can use them directly on the element as an attribute
        let props = {
            sigtextc: {
                type: String,
                value: '',
                computed: '_computeText(sigtext,isstylepreview)'
            },
            dolinebreak: {
                type: Boolean,
                value: true,
                observer: '_toggleLinebreak'
            }
        }
        return props;
    }

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

        //set default values
        this.visuchannelid = 0;
        this.sigtext = '';

        if (!this.isdesignmode) {
            //  Create shortcuts to the common apis makes the code more readable
            if (window.sigApi) {
                this.datapointApi = window.sigApi.datapointManager;
                this.vmApi = window.sigApi.vm;
                this.menuApi = window.sigApi.menuManager;
                this.propApi = window.sigApi.properties;
                this.constApi = window.sigApi.SIG_CONST;
                this.evtApi = window.sigApi.events;
                this.evtMediaApi = window.sigApi.eventMediator;
            } else {
                this._log('constructor(): API not ready!', 'ERROR');
            }  

            this.sigAddRequiredProperty('graphinstanceid');
            this.sigAddRequiredProperty('visuchannelid');

            //request instance of datamanager
            this.DA_DataManager = DA_DataManager.requestInstance();

            //register events
            this._registerEvents();
        }
    }

    /**
     * method is used to register for events
     */
    _registerEvents() {
        //*******************************************************************************************************
        //** new channel logged in so get channels and draw them
        //*******************************************************************************************************
        this.sigAddEventListener('_DA_NEW_CHANNEL_LOGGED_IN', (e) => {
            if (e.detail !== undefined) {
                //check if already initialized
                if (this.initialized) {
                    //check if channel is ment for graph instance id
                    if ((this.graphinstanceid === e.detail.instID) && (this.visuchannelid === e.detail.chlID)) {
                        this._setChannelName();
                    }
                }
            }
        }, 'jsEvent', window);

        //*******************************************************************************************************
        //** channel name changed
        //*******************************************************************************************************
        this.sigAddEventListener('_DA_CHANNEL_NAME_CHANGED', (e) => {
            if (e.detail !== undefined) {
                //check if already initialized
                if (this.initialized) {
                    //check if datamanager was initialized
                    if (this.DA_DataManager !== undefined) {
                        //get visuchannels
                        const visuChls = this.DA_DataManager.getVisuChannels(this.graphinstanceid);
                        if ((visuChls !== undefined) && (visuChls.size > 0)) {
                            //get configured visu channel
                            const channel = visuChls.get(this.visuchannelid);
                            if (channel !== undefined) {
                                //check if same channel
                                if ((channel.chlReference.stationNumber === e.detail.stationNumber) && (channel.chlReference.chlID === e.detail.chlID)) {
                                    //update channelname
                                    this._setChannelName();
                                }
                            }
                            else {
                                this._log('constructor(): visuchannel not found', 'ERROR');
                            }
                        }
                    }
                }
            }
        }, 'jsEvent', window);

        //*******************************************************************************************************
        //** check for change of source -> limits have to be formatted new
        //*******************************************************************************************************
        this.sigAddEventListener('_DA_SERVER_CHANGED', (e) => {
            if (e.detail !== undefined) {
                //check if already initialized
                if (this.initialized) {
                    //check if datamanager was initialized
                    if (this.DA_DataManager !== undefined) {
                        //get visuchannels
                        const visuChls = this.DA_DataManager.getVisuChannels(this.graphinstanceid);
                        if ((visuChls !== undefined) && (visuChls.size > 0)) {
                            //get configured visu channel
                            const channel = visuChls.get(this.visuchannelid);
                            if (channel !== undefined) {
                                //check if same channel
                                if ((channel.chlReference.stationNumber === e.detail.stationNumber) && (channel.chlReference.chlID === e.detail.chlID)) {
                                    //update channelname
                                    this._setChannelName();
                                }
                            }
                            else {
                                this._log('constructor(): visuchannel not found (server changed)', 'ERROR');
                            }
                        }
                    }
                }
            }
        }, 'jsEvent', window);

        //*******************************************************************************************************
        //** channel reference changed
        //*******************************************************************************************************
        this.sigAddEventListener('_DA_CHANNEL_REFERENCE_CHANGED', (e) => {
            if (e.detail !== undefined) {
                //check if already initialized
                if (this.initialized) {
                    //check if channel is ment for graph instance id
                    if ((this.graphinstanceid === e.detail.instID) && (this.visuchannelid === e.detail.chlID)) {
                        this._setChannelName();
                    }
                }
            }
        }, 'jsEvent', window);

        //*******************************************************************************************************
        //** register for language change event
        //*******************************************************************************************************
        this.sigAddEventListener('LANGUAGE_CHG', () => {
            //check if already initialized
            if (this.initialized) {
                //update channelname
                this._setChannelName();
            }
        }, 'runtimeEvent', this);
    }

    /**
     * required properties are ready so login to datamanager
     */
    sigOnRequiredPropertiesReady() {
        super.sigOnRequiredPropertiesReady();
        //set channelname
        this._setChannelName();
        //set initialized
        this.initialized = true;
    }

    /**
     * set channelname
     */
    async _setChannelName() {
        if (this.DA_DataManager !== undefined) {
            //get visu channels
            const visuChls = this.DA_DataManager.getVisuChannels(this.graphinstanceid);
            if (visuChls !== undefined) {
                const channel = visuChls.get(this.visuchannelid);
                if (channel !== undefined) {
                    let realChl = this.DA_DataManager.getChannelByID(channel.chlReference.stationNumber, channel.chlReference.chlID);
                    if (realChl !== undefined) {
                        if (this.datapointApi !== undefined) {
                            //get channel name
                            try {
                                //get id of channel name datapoint
                                const result = await this.datapointApi.getIdFromLasalId(realChl.chlNameLasalID, channel.chlReference.stationNumber);
                                if ((result !== undefined) && (result[0] !== undefined)) {
                                    const varID = result[0];
                                    //get data point
                                    const datapoint = this.datapointApi.getDatapoint(varID);
                                    if (datapoint !== null) {
                                        let channelName = await datapoint.getValue();
                                        if (channelName === '') {
                                            //if no channelname configured, we take the var text 1 of the source
                                            channelName = await this.datapointApi.getDatapointText(realChl.srcVarID, 'text1');
                                        }
                                        this.sigtext = channelName;
                                    }
                                    else {
                                        this._log('_setChannelName(): get datapoint failed', 'ERROR');
                                    }
                                }
                                else {
                                    this._log('_setChannelName(): get varid failed', 'ERROR');
                                }
                            }
                            catch (error) {
                                this._log('_setChannelName(): get channel name lasal id failed -> ' + error, 'ERROR');
                            }
                        }
                        else {
                            this._log('_setChannelName(): invalid datapoint api', 'ERROR');
                        }
                    }
                    else {
                        this._log('_setChannelName(): get real channel failed', 'ERROR');
                    }
                }
                else {
                    this._log('_setChannelName(): failed to get channel', 'ERROR');
                }
            }
            else {
                this._log('_setChannelName(): get visuchannels failed', 'ERROR');
            }
        }
        else {
            this._log('_setChannelName(): invalid datamanager', 'ERROR');
        }
    }

    /**
     * Computed property method that returns the text string.
     * @private
     * @param {String} _sigtext             - The text source of the component.
     * @param {String} _previewtext         - The text source of the component in style preview.
     * @param {Boolean} _isstylepreview     - If true the preview text is returned.
     * @memberof LasalRuntimeSigDAChannelName
     */
    _computeText(_sigtext, _previewtext, _isstylepreview) {
        if (_sigtext === '' && this.isdesignmode) {
            //check if in style preview
            if (_isstylepreview) {
                return _previewtext;
            }
            else {
                return 'Ch ' + this.visuchannelid
            }
        }
        return _sigtext;
    }

    /**
     * Called when 'Linebreak' checkbox state in Editor changes
     * sets the linebreak of the text depending on checkbox state
     */
    _toggleLinebreak() {
        if (this.dolinebreak) {
            // linebreak on
            this.updateStyles({ '--theme-sig-control-da-channelname-value-white-space': 'normal' });
        } else {
            // linebreak off
            this.updateStyles({ '--theme-sig-control-da-channelname-value-white-space': 'nowrap' });
        }
    }
}
customElements.define(LasalRuntimeSigDAChannelName.is, LasalRuntimeSigDAChannelName);
