// 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 LasalRuntimeSigTabElement
 * @extends {LasalRuntimeSigElement}
 ****************************************************************************************************/
class LasalRuntimeSigTabElement 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 {
                /* Basic styling of the component */
                color: var(--theme-sig-control-tab-color, rgba(160, 160, 160, 1));

                border-width: var(--theme-sig-control-tab-border-width, 1px);
                border-color: var(--theme-sig-control-tab-border-color, #000);
                border-style: var(--theme-sig-control-tab-border-style, none);

                border-radius: var(--theme-sig-control-tab-border-radius, 0);
                border-top-left-radius: var(--theme-sig-control-tab-border-radius-tl, var(--theme-sig-control-tab-border-radius, 0));
                border-top-right-radius: var(--theme-sig-control-tab-border-radius-tr, var(--theme-sig-control-tab-border-radius, 0));
                border-bottom-right-radius: var(--theme-sig-control-tab-border-radius-br, var(--theme-sig-control-tab-border-radius, 0));
                border-bottom-left-radius: var(--theme-sig-control-tab-border-radius-bl, var(--theme-sig-control-tab-border-radius, 0));

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

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

            .clearfix:after {
                @apply --clearfix
            }

            .sig-control-tab-base {
                display: flex;

                height: 100%;

                background-color: var(--theme-sig-control-tab-base-background-color, inherit);

                background-image: var(--theme-sig-control-tab-base-background-image, none),
                linear-gradient(var(--theme-sig-control-tab-base-background-color-direction, to bottom),
                var(--theme-sig-control-tab-base-background-color, inherit),
                var(--theme-sig-control-tab-base-background-color-stop, var(--theme-sig-control-tab-base-background-color, inherit)));

                border-style: var(--theme-sig-control-tab-base-border-style, none);
                border-color: var(--theme-sig-control-tab-base-border-color, inherit);
                border-width: var(--theme-sig-control-tab-base-border-width, 0px);
                border-radius: var(--theme-sig-control-tab-base-border-radius, 3px);
                overflow: hidden;
                box-sizing: border-box;
            }

            #tabbar {
                white-space: nowrap;
                border-collapse: collapse;
                height: 100%;
                display: inline-flex;
                gap: var(--theme-sig-control-tab-tab-margin, 0px);
            }

            .tab {
                display: inline-block;
                position: relative;
                overflow: hidden;
                vertical-align: top;
                height: 100%;
                /*Positioning of the text*/
                justify-content: var(--theme-sig-control-tab-tab-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-align-items, center);

                /*Border for a tab */
                border-width: var(--theme-sig-control-tab-tab-border-width, 0px);
                border-style: var(--theme-sig-control-tab-tab-border-style, solid);
                border-color: var(--theme-sig-control-tab-tab-border-color, inherit);
                border-radius: var(--theme-sig-control-tab-tab-border-radius, 3px);

                /*Individual border styles for each side */
                border-top-style: var(--theme-sig-control-tab-tab-border-top-style, var(--theme-sig-control-tab-tab-border-style, solid));
                border-right-style: var(--theme-sig-control-tab-tab-border-right-style, var(--theme-sig-control-tab-tab-border-style, solid));
                border-bottom-style: var(--theme-sig-control-tab-tab-border-bottom-style, var(--theme-sig-control-tab-tab-border-style, solid));
                border-left-style: var(--theme-sig-control-tab-tab-border-left-style, var(--theme-sig-control-tab-tab-border-style, solid));

                /*Individual border width for each side */
                border-top-width: var(--theme-sig-control-tab-tab-border-top-width, var(--theme-sig-control-tab-tab-border-width, 0px));
                border-right-width: var(--theme-sig-control-tab-tab-border-right-width, var(--theme-sig-control-tab-tab-border-width, 0px));
                border-bottom-width: var(--theme-sig-control-tab-tab-border-bottom-width, var(--theme-sig-control-tab-tab-border-width, 0px));
                border-left-width: var(--theme-sig-control-tab-tab-border-left-width, var(--theme-sig-control-tab-tab-border-width, 0px));

                /*Individual border color for each side */
                border-top-color: var(--theme-sig-control-tab-tab-border-top-color, var(--theme-sig-control-tab-tab-border-color, inherit));
                border-right-color: var(--theme-sig-control-tab-tab-border-right-color, var(--theme-sig-control-tab-tab-border-color, inherit));
                border-bottom-color: var(--theme-sig-control-tab-tab-border-bottom-color, var(--theme-sig-control-tab-tab-border-color, inherit));
                border-left-color: var(--theme-sig-control-tab-tab-border-left-color, var(--theme-sig-control-tab-tab-border-color, inherit));

                /*Individual border radius for each side */
                border-top-right-radius: var(--theme-sig-control-tab-tab-border-top-right-radius, var(--theme-sig-control-tab-tab-border-radius, 3px));
                border-top-left-radius: var(--theme-sig-control-tab-tab-border-top-left-radius, var(--theme-sig-control-tab-tab-border-radius, 3px));
                border-bottom-right-radius: var(--theme-sig-control-tab-tab-border-bottom-right-radius, var(--theme-sig-control-tab-tab-border-radius, 3px));
                border-bottom-left-radius: var(--theme-sig-control-tab-tab-border-bottom-left-radius, var(--theme-sig-control-tab-tab-border-radius, 3px));

                /*Default background-color for the tabs */
                background-color: var(--theme-sig-control-tab-tab-background-color, inherit);

                background-image: var(--theme-sig-control-tab-tab-background-image, none),
                linear-gradient(var(--theme-sig-control-tab-tab-background-color-direction, to bottom),
                var(--theme-sig-control-tab-tab-background-color, inherit),
                var(--theme-sig-control-tab-tab-background-color-stop, var(--theme-sig-control-tab-tab-background-color, inherit)));

                color: var(--theme-sig-control-tab-tab-color, inherit);

                min-width: var(--theme-sig-control-tab-tab-width, 100px);

                box-sizing: border-box;
            }

            /* do not display tab if checkbit is false */
            .tab[checkbit=false] {
                display: none !important; 
            }

            .tab.image-and-text {
                display: inline-block;
            }

            .tab span,
            .tab div {
                margin-left: var(--theme-sig-control-tab-tab-margin-left-right, 5px);
                margin-right: var(--theme-sig-control-tab-tab-margin-left-right, 5px);

                margin-top: var(--theme-sig-control-tab-tab-margin-top-bottom, 5px);
                margin-bottom: var(--theme-sig-control-tab-tab-margin-top-bottom, 5px);
            }

            .tab>div,
            .tab.active>div{
                margin: 0;            
            }

            .tab.image-and-text>span,
            .tab.active.image-and-text>span {
                line-height: calc(var(--theme-sig-element-height) - 2 * var(--theme-sig-control-tab-tab-margin-top-bottom, 5px));
            }

            .tab .inner-container {
                position: absolute;
                box-sizing: border-box;
            }

            .tab.image-and-text .inner-container {
                margin: 0 !important;
            }

            .tab .inner-container .inner-inner-container {
                display: flex;
                box-sizing: border-box;
                margin: 0 !important;
                height: 100%;
                width: 100%;
                padding-left: var(--theme-sig-control-tab-tab-margin-left-right, 5px);
                padding-right: var(--theme-sig-control-tab-tab-margin-left-right, 5px);

                padding-top: var(--theme-sig-control-tab-tab-margin-top-bottom, 5px);
                padding-bottom: var(--theme-sig-control-tab-tab-margin-top-bottom, 5px);

                flex-direction: var(--theme-sig-control-tab-tab-flex-direction, row);
            }

            .tab .inner-inner-container span,
            .tab.active .inner-inner-container span {
                margin-left: var(--theme-sig-control-tab-tab-text-margin-left, 5px);
                margin-top: var(--theme-sig-control-tab-tab-text-margin-top, 5px);
                margin-right: var(--theme-sig-control-tab-tab-text-margin-right, 5px);
                margin-bottom: var(--theme-sig-control-tab-tab-text-margin-bottom, 5px);

                align-self: var(--theme-sig-control-tab-tab-text-align-items, inherit);
            }

            .tab .inner-inner-container div, 
            .tab.active .inner-inner-container div {
                margin-left: var(--theme-sig-control-tab-tab-image-margin-left, 5px);
                margin-top: var(--theme-sig-control-tab-tab-image-margin-top, 5px);
                margin-right: var(--theme-sig-control-tab-tab-image-margin-right, 5px);
                margin-bottom: var(--theme-sig-control-tab-tab-image-margin-bottom, 5px);

                align-self: var(--theme-sig-control-tab-tab-image-align-items, inherit);
            } 

            .tab .inner-container.rotate90 {
                --theme-sig-control-tab-tab-inner-container-rotation-offset: calc((var(--theme-sig-element-height) - var(--theme-sig-control-tab-tab-width, 100px)) / 2);
                height: var(--theme-sig-control-tab-tab-width, 100px);
                width: var(--theme-sig-element-height);
                transform: rotate(90deg) translateX(var(--theme-sig-control-tab-tab-inner-container-rotation-offset)) translateY(var(--theme-sig-control-tab-tab-inner-container-rotation-offset));
            }

            /* different tab width if active */
            .tab.active .inner-container.rotate90 {
                --theme-sig-control-tab-tab-inner-container-rotation-offset: calc((var(--theme-sig-element-height) - var(--theme-sig-control-tab-tab-active-width, 100px)) / 2);
                height: var(--theme-sig-control-tab-tab-active-width, 100px);
            }

            .tab .inner-container.rotate270 {
                --theme-sig-control-tab-tab-inner-container-rotation-offset: calc((var(--theme-sig-element-height) - var(--theme-sig-control-tab-tab-width, 100px)) / -2);
                height: var(--theme-sig-control-tab-tab-width, 100px);
                width: var(--theme-sig-element-height);
                transform: rotate(270deg) translateX(var(--theme-sig-control-tab-tab-inner-container-rotation-offset)) translateY(var(--theme-sig-control-tab-tab-inner-container-rotation-offset));
            }

            /* different tab width if active */
            .tab.active .inner-container.rotate270 {
                --theme-sig-control-tab-tab-inner-container-rotation-offset: calc((var(--theme-sig-element-height) - var(--theme-sig-control-tab-tab-active-width, 100px)) / -2);
                height: var(--theme-sig-control-tab-tab-active-width, 100px);
            }

            .tab .inner-container.rotate180 {
                transform: rotate(180deg);
            }

            .tab div {
                background-size: var(--theme-sig-control-tab-tab-image-background-size, contain);
                height: var(--theme-sig-control-tab-tab-image-height, 100%);
                width: var(--theme-sig-control-tab-tab-image-width, 100%);
                background-repeat: no-repeat;
                background-position: center;
            }

            .tab.active {
                background-color: var(--theme-sig-control-tab-tab-active-background-color, inherit);

                background-image: var(--theme-sig-control-tab-tab-active-background-image, none),
                linear-gradient(var(--theme-sig-control-tab-tab-active-background-color-direction, to bottom),
                var(--theme-sig-control-tab-tab-active-background-color, inherit),
                var(--theme-sig-control-tab-tab-active-background-color-stop, var(--theme-sig-control-tab-tab-active-background-color, inherit)));

                /*Positioning of the text*/
                justify-content: var(--theme-sig-control-tab-tab-active-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-active-align-items, center);


                /*Border for a tab */
                border-width: var(--theme-sig-control-tab-tab-active-border-width, 0px);
                border-style: var(--theme-sig-control-tab-tab-active-border-style, solid);
                border-color: var(--theme-sig-control-tab-tab-active-border-color, inherit);
                border-radius: var(--theme-sig-control-tab-tab-active-border-radius, 3px);

                /*Individual border styles for each side */
                border-top-style: var(--theme-sig-control-tab-tab-active-border-top-style, var(--theme-sig-control-tab-tab-active-border-style, solid));
                border-right-style: var(--theme-sig-control-tab-tab-active-border-right-style, var(--theme-sig-control-tab-tab-active-border-style, solid));
                border-bottom-style: var(--theme-sig-control-tab-tab-active-border-bottom-style, var(--theme-sig-control-tab-tab-active-border-style, solid));
                border-left-style: var(--theme-sig-control-tab-tab-active-border-left-style, var(--theme-sig-control-tab-tab-active-border-style, solid));

                /*Individual border width for each side */
                border-top-width: var(--theme-sig-control-tab-tab-active-border-top-width, var(--theme-sig-control-tab-tab-active-border-width, 0px));
                border-right-width: var(--theme-sig-control-tab-tab-active-border-right-width, var(--theme-sig-control-tab-tab-active-border-width, 0px));
                border-bottom-width: var(--theme-sig-control-tab-tab-active-border-bottom-width, var(--theme-sig-control-tab-tab-active-border-width, 0px));
                border-left-width: var(--theme-sig-control-tab-tab-active-border-left-width, var(--theme-sig-control-tab-tab-active-border-width, 0px));

                /*Individual border color for each side */
                border-top-color: var(--theme-sig-control-tab-tab-active-border-top-color, var(--theme-sig-control-tab-tab-active-border-color, inherit));
                border-right-color: var(--theme-sig-control-tab-tab-active-border-right-color, var(--theme-sig-control-tab-tab-active-border-color, inherit));
                border-bottom-color: var(--theme-sig-control-tab-tab-active-border-bottom-color, var(--theme-sig-control-tab-tab-active-border-color, inherit));
                border-left-color: var(--theme-sig-control-tab-tab-active-border-left-color, var(--theme-sig-control-tab-tab-active-border-color, inherit));

                /*Individual border radius for each side */
                border-top-right-radius: var(--theme-sig-control-tab-tab-active-border-top-right-radius, var(--theme-sig-control-tab-tab-active-border-radius, 3px));
                border-top-left-radius: var(--theme-sig-control-tab-tab-active-border-top-left-radius, var(--theme-sig-control-tab-tab-active-border-radius, 3px));
                border-bottom-right-radius: var(--theme-sig-control-tab-tab-active-border-bottom-right-radius, var(--theme-sig-control-tab-tab-active-border-radius, 3px));
                border-bottom-left-radius: var(--theme-sig-control-tab-tab-active-border-bottom-left-radius, var(--theme-sig-control-tab-tab-active-border-radius, 3px));

                color: var(--theme-sig-control-tab-tab-active-color, inherit);

                min-width: var(--theme-sig-control-tab-tab-active-width, 100px);
            }

            .tab .inner-container {
                display: flex;
                height: 100%;
                width: 100%;
                justify-content: var(--theme-sig-control-tab-tab-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-align-items, center);
            }

            .tab .inner-inner-container {
                /*Positioning of the text*/
                justify-content: var(--theme-sig-control-tab-tab-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-align-items, center);
            }
            .tab.active .inner-inner-container {
                /*Positioning of the text*/
                justify-content: var(--theme-sig-control-tab-tab-active-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-active-align-items, center);
            } 

            .tab.active .inner-container {
                justify-content: var(--theme-sig-control-tab-tab-active-justify-content, center);
                align-items: var(--theme-sig-control-tab-tab-active-align-items, center);
            }

            #navButtons {
                position: relative;
                display: none;
                height: 30px;
                width: 80px;
            }

            :host([chasnavbuttons]) .navButton {
                display: inline-block;
            }

            #tabbarcontainer {
                overflow: hidden;             
                width: 100%;
                display: inline-block;
            }   

            /* if navigationbuttons are active the container needs to be smaller */
            :host([chasnavbuttons]) #tabbarcontainer {
                width: calc(100% - (2 * var(--theme-sig-control-tab-nav-button-width, 30px)));
            }

            .navButton {
                box-sizing: border-box;
                height: 100%;
                width: var(--theme-sig-control-tab-nav-button-width, 30px);
                white-space: nowrap;
                display: none;
                background-color: var(--theme-sig-control-tab-nav-button-background-color, inherit);

                /*a default left arrow */
                background-image: var(--theme-sig-control-tab-nav-button-background-image, url('./button-default.svg'));
                background-size: contain;
                background-repeat: no-repeat;
                background-position: center;

                /*Button border*/
                border-style: var(--theme-sig-control-tab-nav-button-border-style, none);
                border-width: var(--theme-sig-control-tab-nav-button-border-width, 0px);
                border-color: var(--theme-sig-control-tab-nav-button-border-color, inherit);
                border-radius: var(--theme-sig-control-tab-nav-button-border-radius, 3px);
            }

            #nextButton {
                transform: scale(-1, 1);
            }

            .navButton.inactive {
                filter: brightness(var(--theme-sig-control-tab-nav-button-inactive-brightnes, 50%));
            }

            .navButton.pressed {
                background-color: var(--theme-sig-control-tab-nav-button-pressed-background-color, var(--theme-sig-control-tab-nav-button-background-color, inherit));
            }

            /*Nav Button Positioning for the various settings */
            :host([navbuttonsposition="right"]) #prevButton {
                order: 1;
            }

            :host([navbuttonsposition="right"]) #nextButton {
                order: 2;
            }

            :host([navbuttonsposition="right"]) #tabbarcontainer {
                order: 0;
            }

            :host([navbuttonsposition="left"]) #prevButton {
                order: 0;
            }

            :host([navbuttonsposition="left"]) #nextButton {
                order: 1;
            }

            :host([navbuttonsposition="left"]) #tabbarcontainer {
                order: 2;
            }

            :host([navbuttonsposition="side"]) #prevButton {
                order: 0;
            }

            :host([navbuttonsposition="side"]) #nextButton {
                order: 2;
            }

            :host([navbuttonsposition="side"]) #tabbarcontainer {
                order: 1;
            }

            .designerPreviewImg {
                background-image: url('previewTab.svg')
            }
        </style>
        <div class="sig-control-tab-base clearfix" id="base">
            <div id="prevButton" class="navButton"></div>
            <div id="nextButton" class="navButton"></div>
            <div id="tabbarcontainer">
                <div id="tabbar"></div>
            </div>

        </div>
        `;
    }

    /****************************************************************************************************
     * define the custom tag name 
     ****************************************************************************************************/
    static get is() {
        return "sig-control-tab";
    }

    /****************************************************************************************************
     * 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
     ****************************************************************************************************/
    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: undefined,
                notify: true,
                observer: '_valueChanged'
            },
            navbuttonsposition: {
                type: String,
                value: 'side',
                reflectToAttribute: true,
            },
            chasnavbuttons: {
                type: Boolean,
                reflectToAttribute: true
            },
            buttoninterval: {
                type: Number,
                value: 200
            },
            buttonsright: {
                type: Boolean,
                value: true,
                reflectToAttribute: true
            },
            navbuttoniactivebrightness: {
                type: String,
                value: "100%",
                observer: '_setInactiveBtnBrightnes'
            },
            tabrotation: {
                type: Number,
                value: 0,
                observer: '_updateTabRotation'
            }
        }
        return props;
    }

    /****************************************************************************************************
     * Called when the element has been created,
     * but before property values are set and local DOM is initialized.
     ****************************************************************************************************/
    constructor() {
        super();

        // set default values
        this.previewtexts = true;
        this.previewimages = false;
        this.navigationscheme = '';
        this.hasnavbuttons = "always";

        //Texts in an object as well to keep it the same as tabs
        this.texts = {};

        //Images in an object to keep it the same as tabs
        this.images = {};

        //for routes defined in navigation scheme
        this.routes = [];

        //If one of the navigation buttons is currently pressed
        //this variable should have a value != undefined
        this.currentInterval = undefined;

        this.scaleFactor = null;

        //The tabbarcontainerBounds saved here to avoid calculating it multiple times
        this.tabbarcontainerBounds = undefined;

        //The tabs saved here to avoid selecting them all the time
        this.tabs = [];

        //get apis
        this.propApi = window.sigApi.properties;
        this.routeApi = window.sigApi.appRouter;
        this.constApi = window.sigApi.SIG_CONST;
        this.checkbitApi = window.sigApi.checkbitManager;

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

        // add property-observer for designmode only
        if (this.isdesignmode) {
            // create a complex polymer observer for these properties, the second parameter defines if the method should be treated as a dependency
            this._createMethodObserver('_updateDesignmodePreview(previewimages, previewtexts, hasnavbuttons)', true);
        }
    }

    /****************************************************************************************************
     *  called after property default values are set and local DOM is initialized
     ****************************************************************************************************/
    ready() {
        super.ready();
        this._initializeComponent().then(() => {
            //call after buttons were attached to bind eventlisteners to buttons
            this._addEventListeners();            
        });
    }

    /****************************************************************************************************
     * this method is called by the Designer after the component was resized in the LVD
     * newBounds and oldBounds are not always set and may be undefined !
     * @param {*} newBounds new size
     * @param {*} oldBounds old size
     ****************************************************************************************************/
    designerOnBoundsChanged() {
        //Handle everything that needs to be handled on resize in a renderCallback
        //at this point the HTML bounds aren't correct yet
        SigPolymer.afterNextRender(this, () => {
            this.designerOnBoundsChangedCallback();
        })
    }

    /****************************************************************************************************
     * Handler for the render callback
     * the listener is added in the designerOnBoundsChanged method,
     * because at the moment designerOnBoundsChanged is called some HTML doesn't have the correct bounds yet
     ****************************************************************************************************/
    designerOnBoundsChangedCallback() {
        if (this.$ && this.$.tabbar && this.$.tabbar.querySelector('.tab')) {
            //check if navigationbuttons should be there
            this._chasNavButtons();
            this._updateButtonState();
        }
    }

    /****************************************************************************************************
     * Called when the component has a useable height and width
     ****************************************************************************************************/
    async _initializeComponent() {
        //check if initializing already active
        if (this.initActive !== true) {
            //set initialization active
            this.initActive = true;

            //get controlbounds
            this.controlBounds = this.getControlBounds();

            //remove tabs to build them new
            while (this.$.tabbar.firstChild) {
                this.$.tabbar.removeChild(this.$.tabbar.firstChild);
            }
            //reset tabs
            this.tabs = [];        

            await this._setRoutes();

            await this._setTabTexts();

            await this._setTabImages();

            this._buildTabs();

            this._chasNavButtons();

            this._setInactiveBtnBrightnes();

            this._updateButtonState();

            this._updateTabRotation();

            //initially set active tab -> in designer tab 1 is shown as active
            let activeTab = 1;
            if (!this.isdesignmode) {
                //ignore value if navigationscheme is in use
                if (this.routes.length > 0) {
                    //get current route index to find active tab value
                    const currentRoute = this.routeApi.getCurrentRoute();
                    //if prerendered actual route isn't set
                    if (currentRoute) {
                        const routeIndex = currentRoute.getRouteIndex();
                        for (let i=0;i<this.routes.length;i++) {
                            //check if it is the tab which should be active
                            if (this.routes[i].getRouteIndex() === routeIndex) {
                                activeTab = Number(this.tabs[i].getAttribute("data-value"));
                                break;
                            }
                        }
                    }
                }
                else {
                    //value is used
                    activeTab = this.value
                }
            }
            this._setActiveTab(activeTab);

            //apply fonts
            this._applyFonts();  
            
            //reset active info and check if we need to initialize new due to change of properties during initialization
            this.initActive = false;
            if (this.reInit === true) {
                this.reInit = false;
                this._initializeComponent();
            }
        }
        else {
            //initialization should be done again so wait till actual is finished and then start new
            this.reInit = true;
        }
    }

    /****************************************************************************************************
     * get routes defined in navigationscheme and set them to this.routes
     ****************************************************************************************************/
    async _setRoutes() {  
        //does not work in designmode
        if (!this.isdesignmode) {
            //Get all the scheme entries
            const schemeValues = await this.propApi.getSchemeDataWithProperty(this.id, 'navigationscheme').catch(() => {});
            //check if schemevalues available
            if (schemeValues) {
                //get all routes to search for path
                const routes = this.routeApi.getRoutes();
                //get the routeindex
                schemeValues.forEach(branch => {
                    for (let i=0;i<routes.length;i++) {
                        //check if path is the same
                        if (branch.value === routes[i].getPath()) {
                            //save route and exit
                            this.routes[branch.compare.value] = routes[i];
                            break;
                        }
                    }
                });        
            } 
        }    
    }

    /**
     * apply fonts to nodes which were added during runtime -> tabs
     */
    _applyFonts() {
        if (this.fontMap) {
            //we need to switch property name because due to compability we are not allowed to redefine propnames
            this.fontMap.forEach((value, key) => {
                if (key === 'tabfont') {
                    key = '.tab';
                }
                else if (key === 'tabactivefont') {
                    key = '.tab.active';
                }
                //apply to tabs
                this.sigApplyFontObject(key, value);
            });            
        }
    }

    /**
     * gets called if fonts need to be applied
     * @param {*} propName - name of the font property
     * @param {*} fontObj - font object
     */
    sigApplyFontObject(propName, fontObj) {
        //we need to switch property name because due to compability we are not allowed to redefine propnames
        if (propName === 'tabfont') {
            propName = '.tab';
        }
        else if (propName === 'tabactivefont') {
            propName = '.tab.active';
        }  
        super.sigApplyFontObject(propName, fontObj);      
    }

    /****************************************************************************************************
     * Adds Eventlisteners for the previous and next buttons
     * The event listeners for the tabs are added on creation in the _buildTabs() method
     ****************************************************************************************************/
    _addEventListeners() {
        //only do if not in designmode
        if (!this.isdesignmode) {
            //On language change, update the fonts
            this.sigAddEventListener('LANGUAGE_CHG', (maID, miID, message) => {
                this.sigSetTimeout(() => {
                    this._updateTexts();
                },100);
                
            }, 'runtimeEvent');

            //on route change we have to check if it is a route within the navigation scheme
            this.sigAddEventListener('APPROUTE_CHG', (maID, miID, message) => {
                for (let i=0;i<this.routes.length;i++) {
                    //check if it is the tab which should be active
                    if (this.routes[i].getRouteIndex() === message.getRouteIndex()) {
                        this._setActiveTab(Number(this.tabs[i].getAttribute("data-value")));
                        break;
                    }
                }                
            }, 'runtimeEvent');

            //The event listeners for the navigation buttons are added here
            this.sigAddEventListener('down', (e) => {
                this._prevDownHandler();
            }, 'polymerEvent', this.$.prevButton);
            this.sigAddEventListener('down', (e) => {
                this._nextDownHandler();
            }, 'polymerEvent', this.$.nextButton);

            this.sigAddEventListener('up', (e) => {
                this._prevUpHandler();
            }, 'polymerEvent', this.$.prevButton);
            this.sigAddEventListener('up', (e) => {
                this._nextUpHandler();
            }, 'polymerEvent', this.$.nextButton);

            //The track-event listener for the tabbar
            this.sigAddEventListener('track', (e) => {
                this._trackHandler(e);
            }, 'polymerEvent', this.$.tabbar);

            //scroll eventlistener to update buttonstates
            this.sigAddEventListener('scroll', (e) => {
                this._updateButtonState();
            }, 'jsEvent', this.$.tabbarcontainer);

            const tabs = this.$.tabbar.querySelectorAll('.tab');
            for (let tab of tabs) {
                this.sigAddEventListener('tap', (e) => {
                    this._tapHandler(e);
                }, 'polymerEvent', tab)
            }            
        }
    }

    /****************************************************************************************************
     * Handles tap/down events
     * @param {Event} e 
     ****************************************************************************************************/
    _tapHandler(e) {
        const tab = e.target.closest('.tab');
        //check if route index is set
        if (tab.routeIndex !== undefined) {
            const currentRoute = this.routeApi.getCurrentRoute();
            if (currentRoute) {
                if (currentRoute.getRouteIndex() !== tab.routeIndex) {
                    //switch to route
                    this.routeApi.switchToRoute(this.routeApi.getRouteByIndex(tab.routeIndex));                        
                }
            }
        }        
        else {
            //set tab value
            this.value = Number(tab.getAttribute('data-value'));            
        }
    }

    /****************************************************************************************************
     * Handles the track Gesture event
     * 
     * @param {Event} e - the Gesture Event
     ****************************************************************************************************/
    _trackHandler(e) {
        if (e.detail.state === 'start') {
            //get scroll positions
            this.scrollPositionStart = this.$.tabbarcontainer.scrollLeft;
            //get scale factor only at start -> shouldn't change while tracking
            this._getScaleFactor();
        }
        else if (e.detail.state === 'track') {
            e = this._getRotationCorrectedEvent(e);
            this.$.tabbarcontainer.scroll(this.scrollPositionStart - (e.detail.dx / this.scaleFactor), 0);
        }
    }

    /****************************************************************************************************
     * corrects the polymer track event for rotation
     * 
     * @param {Event} e - the Polymer.Gestures track event
     * @returns {Object} - the needed event variables corrected for rotation
     ****************************************************************************************************/
     _getRotationCorrectedEvent(e) {
        const rotation = this._getRealRotation(parseInt(this.realrotation, 10));
        let ret = {};
        ret.detail = {};
        ret.detail.state = e.detail.state;
        if (rotation === 90) {
            ret.detail.dx = e.detail.dy;
        } else if (rotation === 180) {
            ret.detail.dx = -e.detail.dx;
        } else if (rotation === 270) {
            ret.detail.dx = -e.detail.dy;
        } else {
            //if no rotation occured, the event itself is fine;
            return e;
        }
        return ret;
    }

    /****************************************************************************************************
     * Scrolls to the next tab, if available
     * if the next tab is not fully visible, it is scrolled into view
     ****************************************************************************************************/
    _prevDownHandler() {
        if (this.state !== 1) {
            return;
        }
        //check if there are tabs
        if (this.tabs.length === 0) {
            return;
        }
        this.$.prevButton.classList.add('pressed');
        //Find the current tab
        let currentTab = undefined;
        for (let i = 0; i < this.tabs.length; i++) {
            if (this.tabs[i].classList.contains('active')) {
                currentTab = i;
                break;
            }
        }

        //If there is a Tab, make sure it is in view, and set the value to the tabs value
        if (currentTab !== undefined) {
            //check if switch to route is allowed
            let validTab = false;
            //decrease until route with no checkbit or fulfilled one is reached
            while (currentTab > 0) {
                currentTab -= 1;
                if (this.tabs[currentTab].getAttribute('checkbit') !== 'false') {
                    validTab = true;
                    break;
                }    
            }
            //check if valid tab was found otherwise stay
            if (validTab) {
                //Make sure the current tab is at least 0;
                currentTab = Math.max(currentTab, 0);
                this._scrollTabIntoView(currentTab);
                //check if route index is set
                if (this.tabs[currentTab].routeIndex !== undefined) {
                    const currentRoute = this.routeApi.getCurrentRoute();
                    if (currentRoute) {
                        if (currentRoute.getRouteIndex() !== this.tabs[currentTab].routeIndex) {
                            //switch to route
                            this.routeApi.switchToRoute(this.routeApi.getRouteByIndex(this.tabs[currentTab].routeIndex));                        
                        }
                    }
                }
                else {
                    //set data value
                    this.value = Number(this.tabs[currentTab].getAttribute('data-value'));                
                }                
            }
        }

        if (!this.currentInterval) {
            this.currentInterval = this.sigSetInterval(() => {
                this._prevDownHandler()
            }, this.buttoninterval);
        }

        this._updateButtonState();
    }

    /****************************************************************************************************
     * Scrolls to the next tab, if available,
     * if the next tab is not fully visible, it is scrolled into view
     ****************************************************************************************************/
    _nextDownHandler() {
        if (this.state !== 1) {
            return;
        }
        //check if there are tabs
        if (this.tabs.length === 0) {
            return;
        }
        this.$.nextButton.classList.add('pressed');
        //Find the current tab
        let currentTab = undefined;
        for (let i = 0; i < this.tabs.length; i++) {
            if (this.tabs[i].classList.contains('active')) {
                currentTab = i;
                break;
            }
        }

        //If there is a Tab, make sure it is in view, and set the value to the tabs value
        if (currentTab !== undefined) {
            //check if switch to route is allowed
            let validTab = false;
            //increase until route with no checkbit or fulfilled one is reached
            while (currentTab < this.tabs.length - 1) {
                currentTab += 1;
                if (this.tabs[currentTab].getAttribute('checkbit') !== 'false') {
                    validTab = true;
                    break;
                }    
            }
            //check if valid tab was found otherwise stay
            if (validTab) {
                //Make sure the current tab is at most the last available tab;
                currentTab = Math.min(currentTab, this.tabs.length - 1);
                this._scrollTabIntoView(currentTab);
                //check if route index is set
                if (this.tabs[currentTab].routeIndex !== undefined) {
                    const currentRoute = this.routeApi.getCurrentRoute();
                    if (currentRoute) {
                        if (currentRoute.getRouteIndex() !== this.tabs[currentTab].routeIndex) {
                            //switch to route
                            this.routeApi.switchToRoute(this.routeApi.getRouteByIndex(this.tabs[currentTab].routeIndex));                        
                        }
                    }
                }
                else {
                    //set data value
                    this.value = Number(this.tabs[currentTab].getAttribute('data-value'));
                } 
            }       
        }
        if (!this.currentInterval) {
            this.currentInterval = this.sigSetInterval(() => {
                this._nextDownHandler()
            }, this.buttoninterval);
        }
        this._updateButtonState();
    }

    /****************************************************************************************************
     * Scrolls a tab into view
     * 
     * @param {Number} tab - the tab index that sould be scrolled into view
     ****************************************************************************************************/
    _scrollTabIntoView(tab) {
        if (this.tabs.length >= tab) {
            this.tabs[tab].scrollIntoView();
        }       
    }

    /****************************************************************************************************
     * Stops the prevDown interval
     * 
     * @param {Event} e - the Gesture Event
     ****************************************************************************************************/
    _prevUpHandler(e) {
        this.$.prevButton.classList.remove('pressed');
        if (this.currentInterval) {
            this.sigClearInterval(this.currentInterval);
            this.currentInterval = undefined;
        }
    }

    /****************************************************************************************************
     * Stops the nextDown interval
     * 
     * @param {Event} e - the Gesture Event
     ****************************************************************************************************/
    _nextUpHandler(e) {
        this.$.nextButton.classList.remove('pressed');
        if (this.currentInterval) {
            this.sigClearInterval(this.currentInterval);
            this.currentInterval = undefined;
        }
    }

    /****************************************************************************************************
     * Observer for the value property
     * 
     * @param {Number} newval - the new tab value
     ****************************************************************************************************/
    _valueChanged(newval) {
        //Make sure that the first element is always selected in design mode
        //so that there is a preview of how the active element looks
        if (this.isdesignmode) {
            newval = 1;
        }
        //we don't care about value when navigation scheme is used
        else if (this.routes.length > 0) {
            return;
        }
        this._setActiveTab(newval);
    }

    /****************************************************************************************************
     * Gets the Texts from the scheme
     ****************************************************************************************************/
    async _setTabTexts() {
        if (this.isdesignmode) {
            this.texts = {
                0: 'Tab1',
                1: 'Tab2',
                2: 'Tab3'
            }
        } 
        else {
            //Get all the scheme entries
            const schemeValues = await this.propApi.getSchemeDataWithProperty(this.id, 'tabnamesscheme').catch(() => {});
            //check if schemevalues available
            if (schemeValues) {
                //Set the texts
                schemeValues.forEach(val => {
                    this.texts[val.compare.value] = val.value;
                });        
            }
            //if no tabnamescheme available we take the label texts of the dashboards
            else {
                for (let i=0;i<this.routes.length;i++) {
                    if (this.routes[i] !== undefined) {
                        this.texts[i] = this.routes[i].getLabel();
                    }
                }
            }            
        }       
    }

    /****************************************************************************************************
     *Gets the images from the scheme
     ****************************************************************************************************/
    async _setTabImages() {
        if (!this.isdesignmode) {
            //Get all the scheme entries
            const schemeValues = await this.propApi.getSchemeDataWithProperty(this.id, 'tabimagescheme').catch(() => {});
            //check if schemevalues available
            if (schemeValues) {
                //Set the images
                schemeValues.forEach(val => {
                    this.images[val.compare.value] = val.value;
                });
            }            
        }
    }

    /****************************************************************************************************
     * create the divs for the tabs, set the texts
     ****************************************************************************************************/
    _buildTabs() {
        //tabbar in variable, for easier access
        const tabbar = this.$.tabbar;
        tabbar.innerHTML = '';

        //Determine if we use a text scheme or an image scheme
        //If an image scheme was given, it it always used, no matter if a text scheme was also added
        let iterationObj = {};
        let isImage = false;
        let isBoth = false;
        let isRoutes = false;
        if ((!this.isdesignmode) && (this.routes.length > 0)) {
            isRoutes = true;
            iterationObj = this.routes;
        }
        else if(!this.isdesignmode && Object.keys(this.images).length > 0 && Object.keys(this.texts).length > 0 && Object.keys(this.texts).length === Object.keys(this.images).length) {
            isBoth = true;
            iterationObj = this.images;
        }
        else if (Object.keys(this.images).length > 0) {
            iterationObj = this.images;
            isImage = true;
        } 
        else {
            iterationObj = this.texts
        }

        //Create a div for each text
        // and add it to the tabbar
        for (let tabContent in iterationObj) {
            const newtab = document.createElement('div');
            newtab.classList.add('tab');
            if(!this.isdesignmode) {
                //if routes are configured we iterate over them and check if images and texts are available for those tabs
                if (isRoutes) {
                    isBoth = false;
                    isImage = false;
                    //check if text and image available
                    if ((this.texts[tabContent] !== undefined) && (this.images[tabContent] !== undefined)) {
                        //handle html and css for text and image
                        isBoth = true;
                    }
                    else if (this.images[tabContent] !== undefined) {
                        //only image is available
                        isImage = true;
                    }    
                    else {
                        //only text is available
                    }                 
                }

                //2022-10-11 SchMar2: handling like before isn't changed
                if (isBoth) {
                    const tabInnerContainer = document.createElement('div');
                    const tabInnerInnerContainer = document.createElement('div');
                    tabInnerInnerContainer.classList.add('inner-inner-container');
                    tabInnerContainer.classList.add('inner-container');
                    newtab.classList.add('image-and-text');
                    const img = document.createElement('div');
                    img.style.backgroundImage = `url(${this.images[tabContent]}`;
                    tabInnerInnerContainer.append(img);
    
                    const span = document.createElement('span');
                    span.innerText = this.texts[tabContent];
                    tabInnerInnerContainer.append(span);
    
                    tabInnerContainer.append(tabInnerInnerContainer);
                    newtab.append(tabInnerContainer);
                } 
                else if (isImage) {
                    const tabInnerContainer = document.createElement('div');
                    tabInnerContainer.classList.add('inner-container');
                    const img = document.createElement('div');
                    img.style.backgroundImage = `url(${this.images[tabContent]}`;
                    tabInnerContainer.append(img);
                    newtab.append(tabInnerContainer);
                } 
                else {
                    const tabInnerContainer = document.createElement('div');
                    tabInnerContainer.classList.add('inner-container');
                    const span = document.createElement('span');
    
                    span.innerText = this.texts[tabContent];
                    tabInnerContainer.append(span);
                    newtab.append(tabInnerContainer);
                }
            } else {
                if(this.previewtexts && this.previewimages) {
                    const tabInnerContainer = document.createElement('div');
                    const tabInnerInnerContainer = document.createElement('div');
                    tabInnerInnerContainer.classList.add('inner-inner-container');
                    tabInnerContainer.classList.add('inner-container');
                    newtab.classList.add('image-and-text');
                    const img = document.createElement('div');
                    img.classList.add('designerPreviewImg');
                    tabInnerInnerContainer.append(img);
    
                    const span = document.createElement('span');
                    span.innerText = this.texts[tabContent];
                    tabInnerInnerContainer.append(span);
    
                    tabInnerContainer.append(tabInnerInnerContainer);
                    newtab.append(tabInnerContainer);
                } 
                else if (this.previewimages) {
                    const tabInnerContainer = document.createElement('div');
                    tabInnerContainer.classList.add('inner-container');
                    const img = document.createElement('div');
                    img.classList.add('designerPreviewImg');
                    tabInnerContainer.append(img);
                    newtab.append(tabInnerContainer);
                } 
                else if (this.previewtexts) {
                    const tabInnerContainer = document.createElement('div');
                    tabInnerContainer.classList.add('inner-container');
                    const span = document.createElement('span');
    
                    span.innerText = this.texts[tabContent];
                    tabInnerContainer.append(span);
                    newtab.append(tabInnerContainer);
                }
            }
            
            newtab.setAttribute('data-value', tabContent);
            //set routeindex to tab
            if (this.routes[tabContent] !== undefined) {
                newtab.routeIndex = this.routes[tabContent].getRouteIndex();
                //handle checkbits
                this._handleCheckbit(newtab, this.routes[tabContent]);
            }

            tabbar.append(newtab);

            //directly set tab in array
            this.tabs.push(newtab);
        }
    }

    /**
     * handles the checkbit of the route
     * @param {*} tab - tab which handles the route
     * @param {*} route - route which has to be checked for checkbit
     */
    _handleCheckbit(tab, route) {
        if ((tab !== undefined) && (route !== undefined)) {
            //check if route has a checkbit
            if (route.hasCheckbit()) {
                //set checkbit value as attribute
                tab.setAttribute('checkbit', route.getCheckbit());
                //get checkbit property
                const checkbitProp = route.getPropertyObjByName('checkbit');
                if (checkbitProp) {
                    //get checkbit id
                    const checkbitId = checkbitProp.value.split(':')[1];
                    if (checkbitId) {
                        tab.checkbitObserver = (checkbit) => {
                            tab.setAttribute('checkbit', checkbit);
                        }
                        tab.checkbitObserverId = this.checkbitApi.addObserver(checkbitId, tab.checkbitObserver);
                    }
                    else {
                        this._log('_handleCheckbit(): failed to get checkbit id', 'ERROR');
                    }
                }
                else {
                    this._log('_handleCheckbit(): failed to get checkbit property', 'ERROR');
                }
            }            
        }
        else {
            this._log('_handleCheckbit(): invalid input', 'ERROR');
        }
    }

    /****************************************************************************************************
     * Sets adds the .active class to the active tab
     * removes the class from tabs no longer active
     * 
     * @param {Number} tabValue -the data-value of the tab that should be set active.
     ****************************************************************************************************/
    _setActiveTab(tabValue) {
        let activeTabIndex;
        for (let i=0;i<this.tabs.length;i++) {
            //check for the tab to set active
            if ((tabValue == this.tabs[i].getAttribute('data-value')) && (activeTabIndex === undefined)) {
                //set active
                this.tabs[i].classList.add('active');
                activeTabIndex = i;
            }
            else if (this.tabs[i].classList.contains('active')) {
                this.tabs[i].classList.remove('active');
            }
        }
        //update fonts
        this._applyFonts();
        //update has navigation button state
        this._chasNavButtons();
        //scroll into view after buttons were attached
        this._scrollTabIntoView(activeTabIndex);
        this._updateButtonState();        
    }

    /****************************************************************************************************
     * Observer that does all the styling needed when props change
     ****************************************************************************************************/
    _setInactiveBtnBrightnes() {
        const brightnes = parseInt(this.navbuttoniactivebrightness);
        if (brightnes < 10) {
            this.updateStyles({
                '--theme-sig-control-tab-nav-button-inactive-brightnes': '10%'
            })
        } else {
            this.updateStyles({
                '--theme-sig-control-tab-nav-button-inactive-brightnes': parseFloat(this.navbuttoniactivebrightness) + '%'
            });
        }
    }

    /****************************************************************************************************
     * Returns the scalefactor for the component
     * 
     * @returns {Number} - The scalefactor of the component
     ****************************************************************************************************/
    _getScaleFactor() {
        // getBoundingClientRect().height does not return the scaled with on webkit
        const rotation = this._getRealRotation(parseInt(this.realrotation, 10));
        if (rotation === 90 || rotation === 270) {
            this.scaleFactor = this.getBoundingClientRect().height / this.controlBounds.width;
        } else {
            this.scaleFactor = this.getBoundingClientRect().width / this.controlBounds.width;
        }
        return this.scaleFactor;
    }

    /****************************************************************************************************
     * @param {Number} rotation - the rotation you want to convert
     * @return {Number} - the rotation between 0 and 360 deg
     ****************************************************************************************************/
    _getRealRotation(rotation = 0) {
        return (rotation % 360 + 360) % 360;
    }

    /****************************************************************************************************
     * Adds/removes the inactive class from the buttons as needed
     ****************************************************************************************************/
    _updateButtonState() {
        //Nothing to do if there are no navbuttons
        if (!this.chasnavbuttons) {
            return;
        }
        if (this.tabs.length === 0) {
            return;
        }
        let currentRouteIdx = null;
        //check if routes are used
        if (this.routes.length > 0) {
            //get current route -> not available if prerendered
            const currentRoute = this.routeApi.getCurrentRoute();
            if (currentRoute) {
                currentRouteIdx = currentRoute.getRouteIndex();
            }
        }
        //check if previous button should be active
        if ((this.$.tabbarcontainer.scrollLeft === 0) && 
            ((this.tabs[0].routeIndex === currentRouteIdx) || (this.value == this.tabs[0].getAttribute('data-value')))) {
            this.$.prevButton.classList.add('inactive');
        } else {
            //If it is scrolled theere is a previous button to be shown
            // -> prevButton active
            this.$.prevButton.classList.remove('inactive');
        }

        //check if next button should be active
        if ((this.$.tabbarcontainer.scrollLeft >= (this.$.tabbarcontainer.scrollWidth - this.$.tabbarcontainer.offsetWidth)) && 
            ((this.tabs[this.tabs.length - 1].routeIndex === currentRouteIdx) || (this.value == this.tabs[this.tabs.length - 1].getAttribute('data-value')))) {
            this.$.nextButton.classList.add('inactive');
        } else {
            // if the last tab isn't fully visible
            // or there are still other tabs not shown
            // -> next Button active
            this.$.nextButton.classList.remove('inactive');
        }
    }

    /****************************************************************************************************
     * Updates the texts used in the tabs
     ****************************************************************************************************/
    async _updateTexts() {
        await this._setTabTexts();
        for(let i = 0; i<this.tabs.length;i++) {
            const span = this.tabs[i].querySelector('span');
            if(span) {
                span.innerText = this.texts[i];
            }
        }
    }

    /****************************************************************************************************
     * Computed value for chasnavbuttons
     ****************************************************************************************************/
    _chasNavButtons() {
        if (this.hasnavbuttons === 'always') {
            this.chasnavbuttons = true
        } else if (this.hasnavbuttons === 'never') {
            this.chasnavbuttons = false;
        } else {
            const tabbarWidth = this.$.tabbar.offsetWidth;
            const controlBounds = this.getControlBounds();
            if (tabbarWidth > controlBounds.width) {
                this.chasnavbuttons = true;
            } else {
                this.chasnavbuttons = false;
            }
        }
    }

    /****************************************************************************************************
     * Called when a CSS Variable is changed
    *
    * @param {Object} cssObj - an Object containing the changed CSS variables, and their values
    * @param {boolean} [doBoundsCheck=false] - only relevant in designmode, leave as false
     ****************************************************************************************************/
    sigApplyCSSValue(cssObj, doBoundsCheck = false) {
        super.sigApplyCSSValue(cssObj, doBoundsCheck);
        //Only needed in design mode cause width of tabs shouldn't change during runtime
        if ((this.isdesignmode) && 
            ((cssObj.hasOwnProperty('--theme-sig-control-tab-nav-button-width')) || 
             (cssObj.hasOwnProperty('--theme-sig-control-tab-tab-active-width')) || 
             (cssObj.hasOwnProperty('--theme-sig-control-tab-tab-width')))) {
            this.designerOnBoundsChangedCallback();
        }
    }
    
    /****************************************************************************************************
     * If Images or texts are shown / hidden, the control needs to be redrawn
     *
     ****************************************************************************************************/
    async _updateDesignmodePreview() {
        //observer can be called also during runtime so check only for designmode as it is the observer for preview props
        if(this.isdesignmode) {
            this._initializeComponent();   
        }
    }

    /****************************************************************************************************
     * To have the rotated content fit in the tab, the dimensions have to be set correctly
     * This also only works for rotations that are a multiple of 90.
     ****************************************************************************************************/
    _updateTabRotation() {
        let tabs = this.$.tabbar.querySelectorAll('.inner-container');
        for(let tab of tabs) {
            tab.classList.remove('rotate90');
            tab.classList.remove('rotate180')
            tab.classList.remove('rotate270')
            tab.classList.remove('rotate0')

            switch(this.tabrotation) {
                case 90: tab.classList.add('rotate90');
                break;
                case 180: tab.classList.add('rotate180');
                break;
                case 270: tab.classList.add('rotate270');
                break;
                default: tab.classList.add('rotate0');
            }
        }
    }

    /**
     * gets called if element is destroyed
     */
    disconnectedCallback() {
        //remove checkbit observer
        for (let i=0;i<this.tabs.length;i++) {
            if (this.tabs[i].checkbitObserverId !== undefined) {
                this.checkbitApi.removeObserver(this.tabs[i].checkbitObserverId);
            }
        }
        //call base to do the rest
        super.disconnectedCallback();
    }
}
customElements.define(LasalRuntimeSigTabElement.is, LasalRuntimeSigTabElement);
