// 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';
// Import dependencies
import '../../sigmatek/sig-utils-jquery/sig-utils-jquery.js';
import * as moment from './moment/min/moment-with-locales.js';
/* import './bootstrap-material-datetimepicker/js/bootstrap-material-datetimepicker.js'; */
import '../sig-control-button/sig-control-button.js'
import '../sig-control-button/sig-control-button-css.js'

/****************************************************************************************************
 * @class LasalRuntimeSigDatepickerPickerElement
 * @extends {LasalRuntimeSigElement}
 ****************************************************************************************************/
export class LasalRuntimeSigDatepickerPickerElement 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-datepicker-color, rgba(160, 160, 160, 1)); */

                    /* border-width: var(--theme-sig-control-datepicker-wrapper-border-width, 0px);
                    border-color: var(--theme-sig-control-datepicker-wrapper-border-color, rgba(255,255,255,0));
                    border-style: var(--theme-sig-control-datepicker-wrapper-border-style, none); */

                    /* Basic box model settings */
                    display: block;
                    position: absolute;
                    /* overflow: hidden; */
                    /* border-radius: var(--theme-sig-control-datepicker-wrapper-border-radius, 3px); */
                }

                #wrapper {
                    position: absolute;
                }

                .dtp {
                    /* border-radius: var(--theme-sig-control-datepicker-border-radius, 3px);
                    overflow: hidden; */
                    /* border-radius: var(--theme-sig-control-datepicker-wrapper-border-radius, 3px); */
                }

                :host([visible]) {
                    display: block;
                }

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

                .clearfix:after {
                    @apply --clearfix
                }
                .dtp { 
                    position: relative; 
                    /*top: 0; left: 0; right: 0; bottom: 0;*/ 
                    background: rgba(0, 0, 0, 0.4); 
                    z-index: 2000;
                    font-size: var(--theme-sig-control-datepicker-wrapper-font-size, 14px); 
                    font-family: var(--theme-sig-control-datepicker-wrapper-font-family, inherit);
                    -webkit-user-select: none; 
                    -moz-user-select: none; 
                    -ms-user-select: none; 
                    user-select: none; 
                    border-radius: var(--theme-sig-control-datepicker-wrapper-border-radius, 3px);
                    border-width: var(--theme-sig-control-datepicker-wrapper-border-width, 0px);
                    border-color: var(--theme-sig-control-datepicker-wrapper-border-color, rgba(255,255,255,0));
                    border-style: var(--theme-sig-control-datepicker-wrapper-border-style, none);
                    overflow:hidden;
                }
                .dtp > .dtp-content { 
                    background: #fff;
                    /* max-width: 300px;  */
                    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); 
                    /* max-height: 520px;  */
                    position: relative; /*left: 50%;*/ 
                }
                .dtp > .dtp-content > .dtp-date-view > header.dtp-header { 
                    background: var(--theme-sig-control-datepicker-wrapper-header-background-color, rgba(0, 197, 255, 1)); 
                    color: #fff; 
                    text-align: center; 
                    padding: 0.3em; 
                    display:none 
                }
                
                .dtp div.dtp-date, .dtp div.dtp-time { 
                    background: var(--theme-sig-control-datepicker-wrapper-header-background-color, rgba(0, 197, 255, 1)); 
                    text-align: center; 
                    color: var(--theme-sig-control-datepicker-wrapper-header-color,rgba(255,255,255,1)); 
                    padding: 10px; 
                }
                .dtp div.dtp-date > div { 
                    padding: 0; 
                    margin: 0; 
                }
                .dtp div.dtp-actual-month { 
                    font-size: 1.5em; 
                }
                .dtp div.dtp-actual-num { 
                    font-size: 3em; 
                    line-height: 0.9;
                }
                .dtp div.dtp-actual-maxtime { 
                    font-size: 3em; 
                    line-height: 0.9; 
                }
                .dtp div.dtp-actual-year { 
                    font-size: 1.5em; 
                    color: var(--theme-sig-control-datepicker-wrapper-header-color, rgba(255,255,255,1)); 
                }
                .dtp div.dtp-picker { 
                    padding: 1em; 
                    text-align: center; 
                }
                
                .dtp div.dtp-picker-month, .dtp div.dtp-actual-time {
                    font-weight: 500;
                    text-align: center;
                    color: var(--theme-sig-control-datepicker-wrapper-month-header-color, rgba(165, 171, 176, 1));
                }
                .dtp div.dtp-picker-month {
                    padding-bottom:20px!important; 
                    text-transform: uppercase!important; 
                }
                
                .dtp .dtp-close { 
                    position: absolute; 
                    top: 0.5em; 
                    right: 1em; 
                }
                .dtp .dtp-close > a { 
                    color: orange; 
                }
                .dtp .dtp-close > a > i { 
                    font-size: 1em; 
                }
                
                .dtp table.dtp-picker-days { 
                    margin: 0; 
                    min-height: 251px;
                    width: var(--theme-sig-control-datepicker-wrapper-calendar-width, 250px);
                }
                .dtp table.dtp-picker-days, .dtp table.dtp-picker-days tr, .dtp table.dtp-picker-days tr > td { 
                    border: none; 
                }
                .dtp table.dtp-picker-days tr > td {  
                    font-weight: 700; 
                    font-size: 0.8em; 
                    text-align: center; 
                    padding: 0.5em 0.3em; 
                }
                .dtp table.dtp-picker-days tr > td > span.dtp-select-day {
                    color: var(--theme-sig-control-datepicker-wrapper-inactive-days-color, rgba(210,215,215,1))/* #BDBDBD */!important; 
                    padding: 0.4em 0.5em 0.5em 0.6em;
                }
                .dtp table.dtp-picker-days tr > td > a, .dtp .dtp-picker-time > a { 
                    color: var(--theme-sig-control-datepicker-wrapper-active-days-color, rgba(40,50,45,1))/* #212121 */; 
                    text-decoration: none; 
                    padding: 0.4em 0.5em 0.5em 0.6em; 
                    border-radius: 50%!important; 
                }
                .dtp table.dtp-picker-days tr > td > a.selected{ 
                    background: var(--theme-sig-control-datepicker-wrapper-selected-color,rgba(0, 197, 255, 1)); 
                    color: var(--theme-sig-control-datepicker-wrapper-selected-text-color, rgba(255,255,255,1)); 
                }
                .dtp table.dtp-picker-days tr > th { 
                    color: var(--theme-sig-control-datepicker-wrapper-table-header-color, rgba(40,50,45,1));/* #757575; */ 
                    text-align: center; 
                    font-weight: 700; 
                    padding: 0.4em 0.3em; 
                }
                
                .dtp .p10 > a { 
                    color: var(--theme-sig-control-datepicker-wrapper-header-symbols-color, rgba(255,255,255,1));/* #fff;  */
                    text-decoration: none; 
                    }
                .dtp .p10 { 
                    width: 10%; 
                    display: inline-block; 
                }
                .dtp .p20 { 
                    width: 20%; 
                    display: inline-block; 
                }
                .dtp .p60 { 
                    width: 60%; 
                    display: inline-block; 
                }
                .dtp .p80 { 
                    width: 80%; 
                    display: inline-block; 
                }
                
                .dtp a.dtp-meridien-am, .dtp a.dtp-meridien-pm { 
                    position: relative; 
                    top: 10px; 
                    color: orange;/* #212121;  */
                    font-weight: 500; 
                    padding: 0.7em 0.5em; 
                    border-radius: 50%!important;
                    text-decoration: none; 
                    background: #eee; 
                    font-size:1em; 
                }
                .dtp .dtp-actual-meridien a.selected { 
                    background: #689F38; 
                    color: #fff; 
                }
                
                .dtp .dtp-picker-time > .dtp-select-hour { 
                    cursor: pointer; 
                }
                .dtp .dtp-picker-time > .dtp-select-minute { 
                    cursor: pointer; 
                }
                
                .dtp .dtp-buttons { 
                    padding: 0 1em 1em 1em; 
                    text-align: right; 
                    background-color: var(--theme-sig-control-datepicker-wrapper-background-color, rgba(255,255,255,1));
                }
                
                .dtp.hidden, .dtp .hidden { 
                    /* visibility: hidden; */ 
                    display: none; 
                }
                .dtp .invisible { 
                    visibility: hidden; 
                }
                
                .dtp .left { 
                    float: left; 
                }
                .dtp .right { 
                    float: right; 
                }
                .dtp .clearfix { 
                    clear: both; 
                }
                
                .dtp .center { 
                    text-align: center; 
                }
                
                .dtp-picker-year{
                    margin-bottom: 1px;
                }
                
                .year-picker-item{
                    text-align: center;
                    padding-top: 5px;
                    font-size: large;
                    cursor: pointer;
                    margin: 0 auto;
                    color: var(--theme-sig-control-datepicker-wrapper-yearpicker-item-color, rgba(165, 171, 176, 1));
                }
                
                .dtp-actual-year:hover{
                    cursor: pointer;
                }
                .dtp-actual-year.disabled:hover{
                    cursor: inherit;
                }
                .year-picker-item:hover{
                    /* color:#689F38; */
                }
                
                .year-picker-item.active{
                    color:var(--theme-sig-control-datepicker-wrapper-active-year-color, rgba(175,200,26,1))/* #689F38 */;
                    font-weight: bold;
                }
                
                .dtp-select-year-range{
                    display: inline-block;
                    text-align: center;
                    width: 100%;
                }
                sig-control-button {
                    /** the variables from the css.js file are set here instead of importing
                        because otherwise i cannot override them */
                    --theme-sig-control-button-font-size: 11px;
                    --theme-sig-control-button-color: rgba(160, 160, 160, 1);
                    --theme-sig-control-button-background-color: rgba(64, 66, 72, 1);
                    --theme-sig-control-button-border-color: #000;
                    --theme-sig-control-button-pressed-background-color: rgba(174, 200, 26, 1);
                    --theme-sig-control-button-pressed-color: rgba(42, 42, 42, 1);
                    --theme-sig-control-button-led-border-width: 1px;
                    --theme-sig-control-button-led-border-color: rgba(0, 0, 0, 1);
                    --theme-sig-control-button-led-border-style: solid;
                    --theme-sig-control-button-led-background-color: rgba(204, 204, 204, 1);
                    --theme-sig-control-button-led-pressed-background-color: rgba(0, 119, 0, 1);


                    position:relative;
                    top: 0;
                    left: 0;
                    height: var(--theme-sig-control-datepicker-wrapper-button-height, 50px);
                    width: var(--theme-sig-control-datepicker-wrapper-button-width, 100px);
                    --theme-sig-control-button-border-radius: var(--theme-sig-control-datepicker-wrapper-button-border-radius, 3px);
                    --theme-sig-control-button-border-width: var(--theme-sig-control-datepicker-wrapper-button-border-width, 0px);
                    --theme-sig-control-button-border-color: var(--theme-sig-control-datepicker-wrapper-button-border-color, rgba(255,255,255,0));
                    --theme-sig-control-button-border-style: var(--theme-sig-control-datepicker-wrapper-button-border-style, none);
                    --theme-sig-control-button-background-color: var(--theme-sig-control-datepicker-wrapper-button-background-color, rgba(40,50,45,1));
                    --theme-sig-control-button-pressed-background-color: var(--theme-sig-control-datepicker-wrapper-button-pressed-background-color, rgba(175,200,26,1));
                    --theme-sig-control-button-pressed-color: var(--theme-sig-control-datepicker-wrapper-button-pressed-color);
                    --theme-sig-control-button-color: var(--theme-sig-control-datepicker-wrapper-button-color, rgba(255,255,255,1));
                    display: inline-block;
                    box-shadow: none;

                    font-size: var(--theme-sig-control-datepicker-wrapper-font-size, 14px);
                }

                .dtp-select-month-before,
                .dtp-select-month-after,
                .dtp-select-year-before,
                .dtp-select-year-after,
                .dtp-select-year-range.before,
                .dtp-select-year-range.after {
                    @apply --symbol;
                }
                a.dtp-select-year-range.before,
                a.dtp-select-year-range.after {
                    color: var(--theme-sig-control-datepicker-wrapper-yearpicker-item-color, rgba(165, 171, 176, 1));
                    text-decoration: none;
                }
                .dtp-select-month-before:after{
                    content: '\\f104';
                }
                .dtp-select-year-before:after{
                    content: '\\f104';
                }
                .dtp-select-month-after:after{
                    content: '\\f105';
                }
                .dtp-select-year-after:after{
                    content: '\\f105';
                }
                .dtp-select-year-range.before:after {
                    content: '\\f106';
                }
                .dtp-select-year-range.after:after {
                    content: '\\f107';
                }

                .dtp-date-view {
                    background-color: var(--theme-sig-control-datepicker-wrapper-background-color, rgba(255,255,255,1));
                }
            </style>
            <div class="sig-control-datepicker-picker" id="wrapper">
            </div>
        `;
    }

    /****************************************************************************************************
     * define the custom tag name 
     ****************************************************************************************************/
    static get is() {
        return 'sig-control-datepicker-picker-wrapper'
    }

    /****************************************************************************************************
     * 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() {
        return {
            datepickerid: {
                type: String,
                value: undefined
            },
            visible: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            }
        }
    }

    /****************************************************************************************************
     * called when the element has been created, but before property values are set and local DOM is initialized
     ****************************************************************************************************/
    constructor() {
        super();
        this.datepicker = undefined;
        this.options = {};
        this.windowContainerClass = 'jsPanel-content';
    }

    /****************************************************************************************************
     *  called after property default values are set and local DOM is initialized
     ****************************************************************************************************/
    ready() {
        super.ready();
    }

    /****************************************************************************************************
     * Adds a Datepicker to the wrapper
     ****************************************************************************************************/
    _addDatepicker() {
        if(this.datepicker) {
            this.$.wrapper.appendChild(this.datepicker);
        }
        
    }

    /****************************************************************************************************
     * Set Position
     * From sig-control-enum-list.html
     * @param {*} position
     ****************************************************************************************************/
    _setPosition(position) {
        if (this.parent instanceof HTMLElement) {
            //Opacity to 0.01 so that the component isn't visible
            //NOT display: none or opacity 0 because then the control bounds would be 0
            this.style.opacity = '0.01';

            this.disconnected = false;
            SigPolymer.afterNextRender(this, function (params) {
                let rotation = 0;
                let scaleFactorApp = {
                    x: 1,
                    y: 1
                };
                let scaleFactorParent = {
                    x: 1,
                    y: 1
                };
                let windowOffset = {
                    x: 0,
                    y: 0
                };

                //We need to use getBoundingClientRect(); no other performant way to get position relative to the viewport!
                const parentBounds = this.parent.getBoundingClientRect();
                if (this.isdesignmode) {
                    // In designmode we need to calculate the real rotation 
                    rotation = this._getRealRotation(parseInt(this._getPathRotation(this.parent, this.parent.rotation, 10)));
                } else {
                    // In the normal runtime we get the precalculated value
                    rotation = this._getRealRotation(parseInt(this.parent.realrotation, 10));
                }
                this._log("Real Rotation: " + rotation);

                // It seems that getBoundingClientRect() does not take the scaling
                // into account. So we need to calulcate the scalingfactor of the 
                // container in which the enum list is created to normalize the position!
                // No need to calculate this in the designer runtime, there is no scaling applied
                if (!this.isdesignmode) {
                    scaleFactorApp = this._getScaleFactor(this.parent, rotation);
                    // If we run inside the window context we need to caluclate the window offset
                    if (this.parent.context.type === "window") {
                        const window = document.querySelector(`#${this.parent.context.instanceId} .${this.windowContainerClass}`);
                        if (window instanceof HTMLElement) {
                            const windowBounds = window.getBoundingClientRect();
                            windowOffset.x = (windowBounds.left / scaleFactorApp.x) - window.scrollLeft;
                            windowOffset.y = (windowBounds.top / scaleFactorApp.y) - window.scrollTop;
                        }
                    }
                }

                // We nedd to calculate the absolute scale factor of the enum parent control
                // so we can scale the enum optiolist entries
                // No need to calculate this in the designer runtime, there is no scaling applied
                if ((!this.isdesignmode) && (this.scalelist)) {
                    scaleFactorParent = this._getScaleFactor(this.parent, rotation);
                    this.$.list.style.transform = `scale( 1, ${scaleFactorParent.y})`;
                    this.$.list.style.transformOrigin = `0 0`;
                }

                // We need to remove the css vars for height/width while positioning the list, or the
                // container will get caluclated wrong if the options are updated while the list is visible!
                // This may cause some flickering on real slow devices :-(
                if (!this.hidden) {
                    this._removeDimension();
                }
                let hideAgain = false;
                if(this.$.wrapper.querySelector('.dtp').classList.contains('hidden')) {
                    hideAgain = true;
                    this.$.wrapper.querySelector('.dtp').classList.remove('hidden');
                }

                const pickerBounds = this.getControlBounds(this.$.wrapper.querySelector('.dtp'));
                let top = 0,
                    left = 0,
                    // height = pickerBounds.height, //this.offsetHeight * scaleFactorParent.y,
                    // width = pickerBounds.width; //this.offsetWidth * scaleFactorParent.x;
                    height = this.$.wrapper.querySelector('.dtp').offsetHeight,
                    width = this.$.wrapper.querySelector('.dtp').offsetWidth;

                const pTop = parentBounds.top / scaleFactorApp.y;
                const pLeft = parentBounds.left / scaleFactorApp.x;
                const pHeight = parentBounds.height / scaleFactorApp.y;
                const pWidth = parentBounds.width / scaleFactorApp.x;
                const pBottom = parentBounds.bottom / scaleFactorApp.y;
                const pRight = parentBounds.right / scaleFactorApp.x;

                const offsetX = 1;
                const offsetY = 1;

                switch (position) {
                    case 'top':
                        if (rotation === 90) {
                            if (width < pHeight) {
                                width = pHeight;
                            }
                            left = pRight + offsetY;
                            top = pTop;
                        } else if (rotation === 180) {
                            if (width < pWidth) {
                                width = pWidth;
                            }
                            left = pLeft - (width - pWidth);
                            top = pBottom + offsetY;
                        } else if (rotation === 270) {
                            if (width < pHeight) {
                                width = pHeight;
                            }
                            left = pLeft - height - offsetY;
                            top = pTop /* - (width - pHeight) */;
                        } else { // all other angles
                            if (width < pWidth) {
                                width = pWidth;
                            }
                            left = pLeft;
                            top = pTop - height - offsetY;
                        }
                        break;
                    case 'left':
                        if (rotation === 90) {
                            left = pRight - height;
                            top = pTop - width - offsetX;
                        } else if (rotation === 180) {
                            left = pRight + offsetX;
                            top = pBottom - height;
                        } else if (rotation === 270) {
                            left = pLeft;
                            top = pBottom + offsetX;
                        } else { // all other angles
                            left = pLeft - width - offsetX;
                            top = pTop;
                        }
                        break;
                    case 'right':
                        if (rotation === 90) {
                            left = pRight - height;
                            top = pBottom + offsetX;
                        } else if (rotation === 180) {
                            left = pLeft - width - offsetX;
                            top = pBottom - height;
                        } else if (rotation === 270) {
                            left = pLeft;
                            top = pTop - width - offsetX;
                        } else { // all other angles
                            left = pRight + offsetX;
                            top = pTop;
                        }
                        break;
                    default: // bottom
                        if (rotation === 90) {
                            if (width < pHeight) {
                                width = pHeight;
                            }
                            left = pLeft - height - offsetY;
                            top = pTop;
                        } else if (rotation === 180) {
                            if (width < pWidth) {
                                width = pWidth;
                            }
                            left = pLeft - (width - pWidth);
                            top = pTop - height - offsetY;
                        } else if (rotation === 270) {
                            if (width < pHeight) {
                                width = pHeight;
                            }
                            left = pRight + offsetY;
                            top = pTop - (width - pHeight);
                        } else {
                            if (width < pWidth) {
                                width = pWidth;
                            }
                            left = pLeft
                            top = pBottom + offsetY;
                            break;
                        }
                }

                // We need to correct the position if the viewport is scrolled
                // or the context is window and we have a windows offset
                left += window.pageXOffset - windowOffset.x;
                top += window.pageYOffset - windowOffset.y;

                if (top < 0) {
                    top = 0;
                }
                if (left < 0) {
                    left = 0;
                }
                //const screenBounds = this.closest('sig-app').getControlBounds();
                //const screenBounds = document.querySelector('sig-app').getControlBounds();
                // let screenBounds = this.closest('.jsPanel-content');
                // if(!screenBounds) {
                //     screenBounds = this.closest('sig-app');
                // }
                let screenBoundsEl = this.closest('.jsPanel-content');
                if(!screenBoundsEl) {
                    screenBoundsEl = this.closest('sig-app');
                }
                let screenBounds = {
                    height: screenBoundsEl.offsetHeight,
                    width: screenBoundsEl.offsetWidth
                }
                if (top > screenBounds.height) {
                    top = screenBounds.height - height;
                }
                if (left + width > screenBounds.width) {
                    left = screenBounds.width - width;
                }

                switch (rotation) {
                    case 0:
                    case 180:
                        if (top + height > screenBounds.height) {
                            top = screenBounds.height - height;
                        }
                        if (left + width > screenBounds.width) {
                            left = screenBounds.width - width;
                        }
                        break;
                    case 90:
                    case 270:
                        if (top > screenBounds.height) {
                            top = screenBounds.height - width;
                        }
                        if (left + height > screenBounds.width) {
                            left = screenBounds.width - height;
                        }
                        break;
                }
                // We only apply the rotation if it has changed
                // This is needed to make sure the translate gets updated 
                // correctly and avoid double paints
                if (rotation === this.oldRotation) {
                    this._setBounds(top, left, height, width);
                } else {
                    this._setBounds(top, left, height, width, rotation);
                }
                this._log(`Set bounds of "${this.id}" to "T: ${top}, L: ${left}, H: ${height}, W:${width}, R: ${rotation}deg"`);
                this.oldRotation = rotation;
                this.style.opacity = '1';
                this._makeVisible();
                if(hideAgain) {
                    this.$.wrapper.querySelector('.dtp').classList.add('hidden');
                }
            });
        }
    }

    /****************************************************************************************************
     *
     *
     * @param {*} [control=this]
     * @param {number} [rotation=0]
     * @returns the scalefactor
     ****************************************************************************************************/
    _getScaleFactor(control = this, rotation = 0) {
        let scaleFactor = { x: 1, y: 1 };
        if (control instanceof HTMLElement) {
            if (rotation === 90 || rotation === 270) {
                scaleFactor.y = control.getBoundingClientRect().height / control.offsetWidth;
                scaleFactor.x = control.getBoundingClientRect().width / control.offsetHeight;
            } else {
                scaleFactor.y = control.getBoundingClientRect().height / control.offsetHeight;
                scaleFactor.x = control.getBoundingClientRect().width / control.offsetWidth;
            }
        }
        this._log(`Calculated scale factor for rotateion ${rotation} is X = "${scaleFactor.x}" Y = "${scaleFactor.y}`);
        return scaleFactor;
    }

    /****************************************************************************************************
     * returns the rotation
     * @param {number} [rotation=0]
     * @returns
     ****************************************************************************************************/
    _getRealRotation(rotation = 0) {
        return (rotation % 360 + 360) % 360;
    }

    /****************************************************************************************************
     * Removes the sig-element-width and -heigth
     ****************************************************************************************************/
    _removeDimension() {
        // We need to remove the applied the css vars to fallback default width
        this.style.removeProperty('--theme-sig-element-width');
        this.style.removeProperty('--theme-sig-element-height');
    }

    /****************************************************************************************************
     * If the element isn't visible, this function makes it visible
     ****************************************************************************************************/
    _makeVisible() {
        // We delay making the list visible till the first positioning is done. 
        // This avoids that the unpositioned list pops up for a second.
        if (this.style.visibility === 'hidden' && !this.isVisible) {
            this.sigSetTimeout(() => {
                this.style.removeProperty('visibility');
                this.isVisible = true;
            }, this.setVisibleDelay);
        }
    }

    /****************************************************************************************************
     * Gets the rotation for the element + the parents rotation
     * @param {*} control
     * @param {*} pathRotation
     * @returns
     ****************************************************************************************************/
    _getPathRotation(control, pathRotation) {
        let parent = control.parentNode;
        if (parent.tagName.toLowerCase() !== 'sig-composite-control') {
            return pathRotation;
        }
        let isCompositeContainer = true;
        let rotation = pathRotation;
        while (isCompositeContainer) {
            if (parent.tagName.toLowerCase() === 'sig-composite-container') {
                rotation += parseInt(parent.rotation, 10);
                this._log(`Parent: ${parent.id}: ${parent.rotation} / GES: ${rotation}`);
                parent = parent.parentNode;
            } else {
                isCompositeContainer = false;
            }
        }
        return rotation;
    }

    /****************************************************************************************************
     * Sets the control position inside a window
     * which should always be top: 0, left 0
     ****************************************************************************************************/
    _setControlPositionWindow() {
        this.updateStyles({
            '--theme-sig-element-top': 0 + 'px',
            '--theme-sig-element-left': 0 + 'px'
        });
        // Control Bounds of the Control itself
        // const cControlBounds = this.getControlBounds(this.$.wrapper);
        const cControlBounds = {
            width: this.$.wrapper.offsetWidth,
            height: this.$.wrapper.offsetHeight,
            left: this.$.wrapper.offsetLeft,
            top: this.$.wrapper.offsetTop
        }
        // If the colorpicker is opened in window mode, 
        // there is no need for special positioning
        if (this.options.type === 'window') {
            this._sizeWindow(cControlBounds);
            this._setWindowPosition();
        }

    }

    /****************************************************************************************************
     * If the colorpicker is shown in a window, 
     * set the window size correctly
     * @param {*} controlBounds
     ****************************************************************************************************/
    _sizeWindow(controlBounds) {
        const containerWindowContent = this.closest('.jsPanel-content')
        const containerWindow = this.closest('.jsPanel');
        // Height of the window content
        containerWindowContent.style.height = controlBounds.height + 1 + 'px';
        // Width of the window
        containerWindow.style.width = controlBounds.width + 1 + 'px';
        containerWindow.style.height = '';
        containerWindow.resize();
    }

    /****************************************************************************************************
     * If the colorpicker is shown in a window
     * make sure the window is inside the bounds of the display
     ****************************************************************************************************/
    _setWindowPosition() {
        const window = this.closest('.jsPanel');
        // const windowBounds = this.getControlBounds(window);
        const screenBounds = document.querySelector('html').querySelector('sig-app'); //TODO
         // const wTop = windowBounds.top;
        // const wLeft = windowBounds.left;
        // const width = windowBounds.width;
        // const height = windowBounds.height;
        const wTop = window.offsetTop;
        const wLeft = window.offsetLeft;
        const width = window.offsetWidth;
        const height = window.offsetHeight;
        let top = wTop;
        let left = wLeft;

        if (top + height > screenBounds.height) {
            top = screenBounds.height - height;
        }
        if (left + width > screenBounds.width) {
            left = screenBounds.width - width;
        }
        if (top < 0) {
            top = 0;
        }
        if (left < 0) {
            left = 0;
        }

        window.style.top = top + 'px';
        window.style.left = left + 'px';
    }

    /****************************************************************************************************
     * Sets the control position
     * Makes sure the control isn#t out of bounds
     * For dropdowns it also makes sure the dropdown isnt covering the input
     ****************************************************************************************************/
    _setControlPosition() {
        this.updateStyles({
            '--theme-sig-element-top': 0 + 'px',
            '--theme-sig-element-left': 0 + 'px'
        });
        //Check if the colorpicker is a window or dropdown, and call the correct function
        if (this.options.type === 'window') {
            this._setControlPositionWindow();
        } else {
            this._setControlPositionDropdown();
        }
    }

    /****************************************************************************************************
     * Sets the Control Position depending on how the control is rotated
     ****************************************************************************************************/
    _setControlPositionDropdown() {
        this._setPosition();
    }

    /****************************************************************************************************
     * called after the element is detached from the DOM
     * can be called multiple times during the lifetime of an element
     *use this to cleanup your "mess" ;-)
     ****************************************************************************************************/
     disconnectedCallback() {
        super.disconnectedCallback();

        if(this.datepicker instanceof HTMLElement) {
            this.datepicker.remove();
            this.datepicker = null;
        }
    }

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