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

export class LasalRuntimeSigControlDAVisuChannelConfig extends LasalRuntimeSigElementLight {

    /***************************************************************************************************************************
     * Defines the custom tag name. Must match the dom module id
     ***************************************************************************************************************************/
    static get is() {
        return 'sig-control-da-graphchannelconfig';
    }

    /***************************************************************************************************************************
     * 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-light-css'>
            :host {
                /* Basic styling of the component */
                color: var(--theme-sig-control-da-graphchannelconfig-color, inherit);
                background-color: var(--theme-sig-control-da-graphchannelconfig-background-color, transparent);

                border-width: var(--theme-sig-control-da-graphchannelconfig-border-width, 0px);
                border-color: var(--theme-sig-control-da-graphchannelconfig-border-color, inherit);
                border-style: var(--theme-sig-control-da-graphchannelconfig-border-style, none);
                border-radius: var(--theme-sig-control-da-graphchannelconfig-border-radius, 0px);

                /* Basic box model settings */
                display: none;
                position: absolute;
            }

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

            /* only show control in designmode */
            :host([isdesignmode]) {
                display: block;
            }


        </style>
        `;
    }

    static get properties() {
        return {                                                              
        };
    }

    /***************************************************************************************************************************
     * Called when the element has been created,
     * but before property values are set and local DOM is initialized.
     ***************************************************************************************************************************/
    constructor() {
        super();
        //only do if not in designmode
        if (!this.isdesignmode) {
            //  Create shortcuts to the common apis makes the code more readable
            if (window.sigApi) {
                this.propApi = window.sigApi.properties;
                this.constApi = window.sigApi.SIG_CONST;
                this.datapointApi = window.sigApi.datapointManager;
                this.vmApi = window.sigApi.vm;
            } else {
                this._log('constructor(): API not ready!', 'ERROR');
            }

            //Set default values
            this.visuchannelid = 0;
            this.recordingmask = 2048;
            this.channelactive = 1;            
            this.splitview = 0;
            this.splitarea = 0;
            this.unitpos = 0;
            this.scaletype = -1; //own axis
            this.scalepos = 0;
            this.minscale = 0;
            this.maxscale = 0;
            this.linewidth = 1;
            this.linestyle = 0;
            this.zerolineactive = 0;
            this.zerolineoffset = 0;
            this.valueperdivision = 0; 
            //------------------------------------------------------------------------------------------------------------------

            //add required properties
            this.sigAddRequiredProperty('graphinstanceid');
            this.sigAddRequiredProperty('visuchannelid');
            this.sigAddRequiredProperty('recordingmask');
            this.sigAddRequiredProperty('defaultchannel');
            this.sigAddRequiredProperty('selectedchannel');
            this.sigAddRequiredProperty('channelactive');
            this.sigAddRequiredProperty('scalepos');
            this.sigAddRequiredProperty('splitview');
            this.sigAddRequiredProperty('splitarea');
            this.sigAddRequiredProperty('unitpos');
            this.sigAddRequiredProperty('scaletype');
            this.sigAddRequiredProperty('maxscale');
            this.sigAddRequiredProperty('minscale');
            this.sigAddRequiredProperty('defaultcolor');
            this.sigAddRequiredProperty('selectedcolor');
            this.sigAddRequiredProperty('linewidth'); 
            this.sigAddRequiredProperty('linestyle');
            this.sigAddRequiredProperty('zerolineactive');
            this.sigAddRequiredProperty('zerolineoffset');
            this.sigAddRequiredProperty('valueperdivision'); 
            
            //request instance of datamanager
            this.DA_DataManager = DA_DataManager.requestInstance();
        }
    }

    /**
     * required properties are ready so login to datamanager
     */
    sigOnRequiredPropertiesReady() {
        super.sigOnRequiredPropertiesReady();
        this._getProperties();
    }    

    async _getProperties() {
        //get properies structure
        this.propsStruct = {
            graphInstID: this.graphinstanceid,
            visuChlID: this.visuchannelid,
            recordMask: this._getPropertyInfo('recordingmask', this.recordingmask),
            defaultChl: this._getPropertyInfo('defaultchannel'),
            selectedChl: this._getPropertyInfo('selectedchannel'),
            channelActive: this._getPropertyInfo('channelactive', this.channelactive),
            scalePos: this._getPropertyInfo('scalepos', this.scalepos),
            splitView: this._getPropertyInfo('splitview', this.splitview),
            splitArea: this._getPropertyInfo('splitarea', this.splitarea),
            unitPos: this._getPropertyInfo('unitpos', this.unitpos),
            scaleType: this._getPropertyInfo('scaletype', this.scaletype),
            maxScale: this._getPropertyInfo('maxscale', this.maxscale),
            minScale: this._getPropertyInfo('minscale', this.minscale),
            defaultColor: this.defaultcolor,
            selectedColor: this._getPropertyInfo('selectedcolor'),
            lineWidth: this._getPropertyInfo('linewidth', this.linewidth),
            lineStyle: this._getPropertyInfo('linestyle', this.linestyle),
            zeroLineActive: this._getPropertyInfo('zerolineactive', this.zerolineactive),
            zeroLineOffset: this._getPropertyInfo('zerolineoffset', this.zerolineoffset),
            valuePerDivision: this._getPropertyInfo('valueperdivision', this.valueperdivision)
        }
        if (this.DA_DataManager !== undefined) {
            //check if selected channel is 0 -> in this case write default channel to it
            if (this.propsStruct.selectedChl.value === 0) {
                //check for reference of default channel
                if (this.propsStruct.defaultChl.ref !== undefined) {
                    //check for valid datapoint api
                    if (this.datapointApi !== undefined) {
                        try {
                            const result = await this.datapointApi.getCRCFromId(this.propsStruct.defaultChl.ref.getId());
                            if (result !== undefined) {
                                this.propsStruct.selectedChl.value = result[0];
                                //check if selectedChl is a datapoint
                                if (this.propsStruct.selectedChl.ref) {
                                    await this.datapointApi.writeDataPoint(this.propsStruct.selectedChl.ref.getId(), this.propsStruct.selectedChl.value)
                                }  
                            }
                            else {
                                this._log('_getProperties(): get crc failed', 'ERROR');
                            }
                        }   
                        catch (error) {
                            this._log('_getProperties(): get crc failed -> ' + error, 'ERROR');
                        }                           
                    }
                    else {
                        this._log('_getProperties(): invalid datapoint api', 'ERROR');
                    }
                }
            }
            //login to datamanager
            this.DA_DataManager.loginVisuChannel(this.propsStruct);
        }
    }

    /**
     * method is used to return value and datapoint if given
     * @param {*} name - name of the property
     * @param {*} defaultValue - default value if property is not configured
     */
    _getPropertyInfo(name, defaultValue) {
        //check for valid name
        if (name !== undefined) {
            //check if apis ready
            if ((this.propApi !== undefined) && (this.datapointApi !== undefined) && (this.constApi !== undefined) && (this.vmApi !== undefined)) {
                //structure of return value
                let propStruct = {
                    src: undefined,
                    value: undefined,
                    ref: undefined
                }                
                //get property refernce
                const propRef = this.propApi.getPropertyReference(this.id, name);
                //check if property available
                if (propRef !== null) {
                    //check if dp or constant or scheme
                    propStruct.src = propRef.src;
                    //get property -> must be done extra cause in case of scheme it is resolved already so we loose info if scheme
                    const prop = this.propApi.getProperty(this.id, name);
                    if (prop !== null) {                    
                        //check for scheme
                        if (propStruct.src === this.constApi.PROP_SRC_SCHEME) {
                            //get vm
                            const vm = this.vmApi.getVmById(this.id);
                            if (vm !== null) {
                                //get property blueprint
                                const bluePrint = vm.getPropertyObjByName(name);
                                if (bluePrint !== undefined) {
                                    //for a bluePrint it is neccesarry to have a name and a destination to be observeable
                                    bluePrint.name = name;
                                    bluePrint.dest = sigApi.SIG_CONST.PROP_DEST_VARIABLE;                                    
                                    //create property as reference
                                    propStruct.ref = this.propApi.createProperty(bluePrint, this.constApi.PROP_PREDEF_PROPS_MASK_NONE, true);
                                    propStruct.value = prop.getValue();
                                }
                                else {
                                    this._log("_getPropertyInfo(): failed to get property blueprint", 'ERROR');
                                }                   
                            }
                            else {
                                this._log("_getPropertyInfo(): unable to get vm", 'ERROR');
                            }
                        }
                        else if (propStruct.src === this.constApi.PROP_SRC_DATAPOINT) {
                            //if property is datapoint, ref is datapoint
                            propStruct.ref = prop.getDatapoint();
                            propStruct.value = prop.getValue();
                        }
                        else if (propStruct.src === this.constApi.PROP_SRC_CONSTANT) {
                            //if property is constant value is simply value
                            propStruct.value = prop.getValue();
                        }     
                    }
                    else {
                        this._log("_getPropertyInfo(): failed to get property", 'ERROR');
                    }  
                }
                else {
                    //property not defined so set default value
                    propStruct.src = this.constApi.PROP_SRC_CONSTANT;
                    propStruct.value = defaultValue;
                }
                return propStruct;
            }
            else {
                this._log("_getPropertyInfo(): apis not ready", 'ERROR');
            }
        }
        else {
            this._log("_getPropertyInfo(): invalid property name", 'ERROR');
        }
    }

    /***************************************************************************************************************************
     * gets called if control gets disconnected from dom
     ***************************************************************************************************************************/    
    disconnectedCallback() {
        super.disconnectedCallback();
    }        

}
customElements.define(LasalRuntimeSigControlDAVisuChannelConfig.is, LasalRuntimeSigControlDAVisuChannelConfig);