import { LasalRuntimeSigElement, SigPolymer } from '../../sigmatek/sig-element/sig-element.js';
import { waitForPropertyReady } from '../../sigmatek/sig-element/sig-element-helpers.js';
import { ListviewAgStandardFilter } from '../sig-control-listview-ag-filter/sig-control-listview-ag-filter.js';
import { ListviewAgHtmlCellRenderer, ListviewAgHtmlLoadingCellRenderer } from './sig-control-listview-ag-renderer.js';
import '../../sigmatek/sig-utils-ag-grid-polymer/sig-utils-ag-grid-polymer.js';
import '../../sigmatek/sig-utils-ag-grid/sig-utils-ag-grid-styles.js';
import '../sig-control-scrollbar/sig-control-scrollbar-css.js';
import * as Gestures from '../../../../rt/node_modules/@polymer/polymer/lib/utils/gestures.js';

export class LasalRuntimeSigControlListviewAg extends LasalRuntimeSigElement {

    constructor() {
        super();

        if (window.sigApi) {
            this.tmApi = window.sigApi.textManager;
        } else {
            this._log('API not ready!', 'ERROR');
        }

        this.computedStyle = window.getComputedStyle(this);

        this.controlTextList = this.getControlTextListName();
        this.textsReady = this._getLocaleTexts().then((texts) => {
            this.texts = texts;
        });

        this.sigApp = document.querySelector('sig-app');

        this.sigAddRequiredProperty('gridRenderMode');
        this.sigAddRequiredProperty('ignoreGridOptionsDefaults');
        this.sigAddRequiredProperty('gridOptions');
        this.sigAddRequiredProperty('gridRowHeight');
        this.sigAddRequiredProperty('gridHeaderHeight');
        this.sigAddRequiredProperty('gridOverflowX');
        this.sigAddRequiredProperty('gridOverflowY');

        this.gridInitDone = false;
        this.firstInitStarted = false;
        this.grid = null;
        this.gridId = 'grid';
        this.gridApi = null;
        this.gridColumnApi = null;
        this.gridDebug = false;
        this.gridTheme = 'ag-theme-alpine';
        this.gridCurrentPageIndex = 0;
        this.gridOverflowXOldval = 'auto';
        this.gridOverflowYOldval = 'auto';
        this.gridMaxRows = 100;
        this.gridAutoRowHeightDelay = 50;
        this.gridAllowZooming = true;
        this.applyTouchActionPanSafariMobile = true;
        this.resetHeightOnColumnResize = false;
        this.gridRestoreFocusOnPaginationChanged = false;

        this.gridUnSortIcon = true;
        this.gridSuppressMenuHide = true;
        this.gridSuppressRowClickSelection = true;
        this.gridSuppressRowDeselection = false;
        this.gridSuppressCellSelection = true;
        this.gridSuppressDragLeaveHidesColumns = true;
        this.gridSuppressRowHoverHighlight = true;
        this.gridSuppressMarkOnLongpress = false;
        this.gridScrollbarWidth = 0; 
        this.gridContext = { parent: this };
        this.gridRowModelType = 'clientSide'
        this.gridVirtualizationDisabled = false;
        this.gridInfiniteInitialRowCount = 1;
        this.gridRowBuffer = 10;
        this.gridCacheBlockSize = 100;
        this.gridCacheOverflowSize = 50;
        this.gridMaxConcurrentDatasourceRequests = 1;
        this.gridMaxBlocksInCache = 10;
        this.gridStandardFilter = 'standardFilter';
        this.gridHtmlCellRenderer = 'htmlCellRenderer';
        this.gridLoadingCellRenderer = 'loadingCellRenderer';

        this.gridOptionsDefaults = null;
        this.gridOptionsMerged = null;

        this.ignoreGridOptionsDefaults = false;

        this.headerNavigableFromFirstRow = false;

        this.lastClickEventPath = [];
        this.viewport = null;
        this.viewPortScrollTop = 0;
        this.clickDelay = 100;
        this.longpressDelay = 500;
        this.longpressTimeout = null;
        this.isLongPress = false;
        this.focusedCell = null;
        this.gridDownEventIsTouch = false;
        this.viewportIsDragged = false;
        this.gridDownEvent = evt => {
            this._gridCellDown(evt);
        }
        this.gridUpEvent = evt => {
            this._gridCellUp(evt);
        }
        this.gridTrackEvent = evt => {
            this._gridTrack(evt);
        }
        this.gridMousedownEventCapture = evt => {
            if (this.isMobile() && !this.gridDownEventIsTouch) {
                evt.stopPropagation();
                this._log('Event propagation stopped, because orginal down event was not on a grid cell!');
            }
        }

        this.loadingTimeout = null;
        this.loadingTimeoutDelay = 500;

        this._addEventListeners();

        this.scrollbarXElementClass = 'ag-body-horizontal-scroll';
        this.scrollbarXObserver = new ResizeObserver(entries => this._detectScrollbarX(entries));
        this.scrollbarYElementClass = 'ag-body-viewport';
        this.scrollbarYObserver = new ResizeObserver(entries => this._detectScrollbarY(entries));
    }

    static get properties() {
        let props = {
            gridRenderMode: {
                type: String,
                value: 'native', 
                observer: '_updateGridRenderMode'
            },
            gridOptions: {
                type: Object,
                value: () => { return {} },
                observer: '_updateGridOptions'
            },
            gridName: {
                type: String,
                value: 'grid',
                reflectToAttribute: true
            },
            gridHideHeader: {
                type: Boolean,
                value: false,
                observer: '_updateGridHideHeader'
            },
            gridHeaderHeight: {
                type: Number,
                value: 26,
                observer: '_updateGridHeaderHeight'
            },
            gridRowHeight: {
                type: Number,
                value: 26,
                observer: '_updateGridRowHeight'
            },
            gridReadonly: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            gridDisableMultiselect: {
                type: Boolean,
                value: false,
                observer: '_updateGridDisableMultiselect'
            },
            gridPaginationEnabled: {
                type: Boolean,
                value: false,
                observer: '_updateGridPaginationEnabled'
            },
            gridPaginationPageSize: {
                type: Number,
                value: 100,
                observer: '_updateGridPaginationPageSize'
            },
            gridPaginationAutoPageSize: {
                type: Boolean,
                value: false,
                reflectToAttribute: true,
                observer: '_updateGridPaginationAutoPageSize'
            },
            hasScrollX: {
                type: Boolean,
                value: false,
                reflectToAttribute: true,
            },
            hasScrollY: {
                type: Boolean,
                value: false,
                reflectToAttribute: true,
            },
            gridSizeColumnsToFit: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultSortable: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultFilter: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultResizeable: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultAutoHeight: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultMoveable: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultWrapText: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridColDefaultWidth: {
                type: Number,
                value: 0,
                observer: '_updateColDefaults'
            },
            gridColDefaultMinWidth: {
                type: Number,
                value: 0,
                observer: '_updateColDefaults'
            },
            gridColDefaultMaxWidth: {
                type: Number,
                value: 0,
                observer: '_updateColDefaults'
            },
            gridColDefaultsLockPinned: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            gridOverflowX: {
                type: String,
                value: 'auto',
                reflectToAttribute: true,
                observer: '_updateGridOverflowX'
            },
            gridOverflowY: {
                type: String,
                value: 'auto',
                reflectToAttribute: true,
                observer: '_updateGridOverflowY'
            },
            gridRenderHtml: {
                type: Boolean,
                value: false,
                observer: '_updateColDefaults'
            },
            designtimeShowPaginator: {
                type: Boolean,
                value: false,
                observer: '_updateDesigntimeShowPaginator'
            },
            designtimeShowOverlay: {
                type: Boolean,
                value: false,
                observer: '_updateDesigntimeShowOverlay'
            },
        }
        return props;
    }

    static get is() {
        return "sig-control-listview-ag";
    }

    static get importMeta() { return import.meta; }

    static get template() {
        return SigPolymer.html`
        <style include="sig-element-css sig-control-scrollbar-css sig-utils-ag-grid-css">
            :host {
                
                color: var(--theme-sig-control-listview-ag-color, inherit);
                background-color: var(--theme-sig-control-listview-ag-background-color, rgba(42, 42, 42, 1));

                
                border-width: var(--theme-sig-control-listview-ag-border-width, 0px);
                border-color: var(--theme-sig-control-listview-ag-border-color, transparent);
                border-style: var(--theme-sig-control-listview-ag-border-style, none);
                border-radius: var(--theme-sig-control-listview-ag-border-radius, 0px);

                
                display: block;
                position: absolute;
                overflow:  hidden;
            }

            :host * {
                
                @apply --notextselect;
                margin: 0;
                padding: 0;
            }

            .clearfix:after {
                
                @apply --clearfix;
            }

            .sig-control-listview-ag {
                
                position: relative;
                width: 100%;
                height: 100%;
                
                text-decoration: inherit;
                box-sizing: border-box;
            }

            
           #grid {
                height:100%;
                width:100%;
                --ag-foreground-color: var(--theme-sig-control-listview-ag-color, inherit);
                --ag-background-color: var(--theme-sig-control-listview-ag-background-color,rgba(42, 42, 42, 1));
                --ag-odd-row-background-color: var(--theme-sig-control-listview-ag-odd-row-background-color, #E5F2F8);
                --ag-header-background-color:  var(--theme-sig-control-listview-ag-header-background-color, rgba(0, 0, 0, 1));
                --ag-header-cell-moving-background-color:  var(--theme-sig-control-listview-ag-header-cell-moving-background-color, rgba(30, 30, 30, 1));
                --ag-header-foreground-color: var(--theme-sig-control-listview-ag-header-color, rgba(255, 255, 255, 1));
                --ag-modal-overlay-background-color: var(--theme-sig-control-listview-ag-overlay-background-color, rgba(102, 102, 102, .6));
            }

            
            #grid.ag-theme-alpine {
                font-family: inherit;
                font-size: inherit ;
                font-style: inherit;
                font-weight: inherit; 
            }

            
            #grid .ag-root-wrapper {
                border: none;
            }

            
            #grid .ag-header {
                border:none;
            }

           #grid .ag-header-row-column {
               font-family: inherit;
               font-size: inherit ;
               font-style: inherit;
               font-weight: inherit;
           }

           #grid .ag-header-cell {
               padding: 0 var(--theme-sig-control-listview-ag-header-cell-padding, 10px);
           }

           
           #grid .ag-header-cell-text {
               text-align:var(--theme-sig-control-listview-ag-header-text-align, left);
               text-decoration: var(--theme-sig-control-listview-ag-header-text-decoration, var(--theme-sig-control-listview-ag-mainfont-text-decoration, none));
               width:100%;
           }

           #grid .ag-header-icon > .ag-icon {
               color: var(--theme-sig-control-listview-ag-header-symbol-color, rgba(153, 153, 153, 1));
               font-size: var(--theme-sig-control-listview-ag-header-symbol-fontsize, 20px);
           }

           #grid .ag-header-icon {
                margin-left:5px;
           } 

           
           #grid .ag-header-icon.ag-sort-ascending-icon,
           #grid .ag-header-icon.ag-sort-descending-icon,
           #grid .ag-header-icon.ag-sort-none-icon {
                margin-left:0;
           }         

           #grid .ag-header-icon-close > .ag-icon {
               font-size: .8em;
           }

           #grid .ag-header-icon.ag-sort-descending-icon > .ag-icon,
           #grid .ag-header-icon.ag-sort-ascending-icon > .ag-icon {
               color: var(--theme-sig-control-listview-ag-header-symbol-active-color, rgba(153, 153, 153, 1));
           }

           #grid .ag-cell {
                border-left:  var(--theme-sig-control-listview-ag-cellseparator-height, 1px) solid var(--theme-sig-control-listview-ag-cellseparator-color, rgba(112, 112, 112, 1));
                border-right: none;
                min-height: var(--theme-sig-control-listview-ag-cell-min-height, var(--theme-sig-control-listview-ag-row-height, 26px));
                line-height: 100%;
                padding: 10px var(--theme-sig-control-listview-ag-row-cell-padding, 10px);
                display: flex;
                justify-content: var(--theme-sig-control-listview-ag-row-cell-text-horizontal-align, flex-start);    
                align-items:var(--theme-sig-control-listview-ag-row-cell-text-vertical-align, center); 
                
            }

            #grid .ag-cell-value {
                text-decoration: var(--theme-sig-control-listview-ag-viewport-text-decoration, var(--theme-sig-control-listview-ag-mainfont-text-decoration, none)) !important;
            }

            #grid .ag-row-no-animation .ag-row {
               
               transition: none;
            }

            
            #grid div[aria-colindex='1'].ag-cell{
                border-left: none;
            }           

            #grid .ag-row {
                background-color: var(--theme-sig-control-listview-ag-row-odd-background-color, rgba(255, 255, 255, 1));
                color: var(--theme-sig-control-listview-ag-row-odd-color, rgba(42, 42, 42, 1));
                border-top: var(--theme-sig-control-listview-ag-lineseparator-height, 1px) solid var(--theme-sig-control-listview-ag-lineseparator-color, rgba(112, 112, 112, 1));
                border-bottom: none;
                font-family: inherit;
                font-size: inherit ;
                font-style: inherit;
                font-weight: inherit;
                text-decoration: inherit;
                min-height: var(--theme-sig-control-listview-ag-row-height, 26px);
            } 

           #grid .ag-row-first {
                border-top:none;
           }

           #grid .ag-row-last {
                border-bottom: var(--theme-sig-control-listview-ag-lineseparator-height, 1px) solid var(--theme-sig-control-listview-ag-lineseparator-color, rgba(112, 112, 112, 1));
           }
        
           #grid .ag-row-even {
                background-color: var(--theme-sig-control-listview-ag-row-even-background-color, rgba(255, 255, 255, 1));
                color: var(--theme-sig-control-listview-ag-row-even-color, rgba(42, 42, 42, 1));
           }

           #grid .ag-row-selected {
                 background-color: var(--theme-sig-control-listview-ag-row-marked-background-color, rgba(160, 160, 160, 1));
                 color: var(--theme-sig-control-listview-ag-row-marked-color, rgba(42, 42, 42, 1));
           }

           :host(:not([grid-readonly])) #grid .ag-row-focus {
                background-color: var(--theme-sig-control-listview-ag-row-active-background-color, rgba(120, 120, 120, 1));
                color: var(--theme-sig-control-listview-ag-row-active-color, rgba(42, 42, 42, 1));
           }

           :host #grid .ag-row-selected.ag-row-focus {
              color: var(--theme-sig-control-listview-ag-row-active-marked-color, rgba(255, 255, 255, 1));
            }

           #grid .ag-paging-panel {
              color: var(--theme-sig-control-listview-ag-paginator-color,rgba(0,0,0,1));
              background-color:  var(--theme-sig-control-listview-ag-paginator-background-color, rgba(190,190,190,1));
              border-top: var(--theme-sig-control-listview-ag-paginator-lineseparator-height, 1px) solid var(--theme-sig-control-listview-ag-paginator-lineseparator-color, rgba(112, 112, 112, 1));
              height: var(--theme-sig-control-listview-ag-paginator-height, 40px);
              justify-content: var(--theme-sig-control-listview-ag-paginator-justify-content, flex-end);
           }
          
           #grid .ag-paging-panel .ag-paging-row-summary-panel,
           #grid .ag-paging-panel .ag-paging-description {
                text-decoration: var(--theme-sig-control-listview-ag-paging-panel-text-decoration, var(--theme-sig-control-listview-ag-mainfont-text-decoration, none)) !important;
           }

           #grid .ag-paging-panel .ag-paging-button {
               color: var(--theme-sig-control-listview-ag-paginator-button-color,rgba(0,0,0,1));
               background-color: var(--theme-sig-control-listview-ag-paginator-button-background-color,rgba(0,0,0,0));
               height: calc(var(--theme-sig-control-listview-ag-paginator-symbol-size,20px) + var(--theme-sig-control-listview-ag-paginator-button-border-width,0px) * 2);
               border: var(--theme-sig-control-listview-ag-paginator-button-border-width, 0px) solid var(--theme-sig-control-listview-ag-paginator-button-border-color, rgba(0, 0, 0, 0));
               border-radius: var(--theme-sig-control-listview-ag-paginator-button-border-radius, 0px);
           }
           
           #grid .ag-paging-panel  .ag-paging-button.ag-disabled {
               color: var(--theme-sig-control-listview-ag-paginator-button-disabled-color,rgba(140,140,140,1));
               background-color: var(--theme-sig-control-listview-ag-paginator-button-disabled-background-color, rgba(0,0,0,0));
               border-color: var(--theme-sig-control-listview-ag-paginator-button-disabled-border-color, rgba(0, 0, 0, 0));
           }

           #grid .ag-paging-panel .ag-icon {
               line-height: var(--theme-sig-control-listview-ag-paginator-symbol-size,20px);
               font-size: var(--theme-sig-control-listview-ag-paginator-symbol-size,20px);
           }

           
           #grid .ag-body-viewport {
            width: 100%;
          }
           
           :host([grid-overflow-y='scroll']) #grid .ag-body-viewport {
               overflow-y: scroll !important;
           }

           :host([grid-overflow-x='scroll']:not([has-scroll-x])) #grid .ag-body-viewport {
               overflow-x: scroll !important;
           }

           :host([grid-overflow-y='auto'][grid-pagination-auto-page-size]) #grid .ag-body-viewport,
           :host([grid-overflow-y='hidden']) #grid .ag-body-viewport {
               overflow-y: hidden !important;
           }

           :host([grid-overflow-x='hidden']) #grid .ag-body-horizontal-scroll {
               display: none !important;
           }    

           
           :host([grid-overflow-x='auto']:not([has-scroll-x])) #grid .ag-center-cols-viewport {
             overflow-x: hidden !important;
           }

           
           :host([grid-overflow-x='auto']:not([has-scroll-x])) #grid .ag-body-horizontal-scroll {
             visibility: hidden;
           }

            
           :host([grid-readonly]) #grid .ag-row,
           :host([grid-readonly]) #grid .ag-cell {
                pointer-events: none !important;
           }

           
            #grid .ag-body-horizontal-scroll {
                position: relative;
            }

           #grid .ag-overlay-loading-center {
               color: var(--theme-sig-control-listview-ag-overlay-loading-color,rgba(160,160,160,1));
               background-color: var(--theme-sig-control-listview-ag-overlay-loading-background-color, rgba(102, 102, 102, 1));
               border-color: var(--theme-sig-control-listview-ag-overlay-loading-border-color, rgba(42, 42, 42, 1));
               box-shadow: none;
           }

           #grid .ag-overlay-no-rows-center {
               color: var(--theme-sig-control-listview-ag-overlay-no-rows-color, rgba(42, 42, 42, 1));
           }
        </style>
        <div id="container" class="sig-control-listview-ag clearfix"></div>`;
    }


    connectedCallback() {
        super.connectedCallback();
        this._log('Component connected to the DOM');
    }

    ready() {
        super.ready();
        if (this.isdesignmode && !this.isInShadowDom()) this.init();
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        this._unobserveScrollbars();
        this._destroyGrid();
        this.gridOptionsDefaults = null;
        this.gridOptions = null;
        this.tmApi = null;
        this.computedStyle = null;
        this.texts = null;
        this.sigApp = null;
        this.sigClearTimeout(this.longpressTimeout);
        this.sigClearTimeout(this.loadingTimeout);
    }

    _init() {
        if (!this.disconnected) {
            this._appendGridRoot();
            this._mergeOptions();
            this._createGridInstance();
        }
    }

    _createGridInstance() {
        if (this.grid instanceof HTMLElement) {
            switch (this.gridRenderMode) {
                case 'component': 
                    customElements.whenDefined('ag-grid-polymer').then(() => {
                        const grid = document.createElement('ag-grid-polymer');
                        grid.id = this.gridId;
                        grid.gridOptions = this.gridOptionsMerged;
                        grid.classList.add(this.gridTheme);
                        this.grid.replaceWith(grid);
                    });
                    break;
                default: 
                    new agGrid.Grid(this.grid, this.gridOptionsMerged);
                    break;
            }
        } else {
            this._log('Could not create the grid instance. The grid root element is not a valid html element!', 'ERROR');
        }
    }

    _getGridOptionsDefaults() {
        const disableVirtualization = this._isVirtualizationDisabled();
        return {
            components: {
                htmlCellRenderer: ListviewAgHtmlCellRenderer,
                loadingCellRenderer: ListviewAgHtmlLoadingCellRenderer,
                standardFilter: ListviewAgStandardFilter
            },
            rowModelType: this.gridRowModelType,
            columnDefs: this._getColumnDefs(),
            rowData: this._getRowData(),
            defaultColDef: this._getDefaultColDef(),
            rowBuffer: (disableVirtualization) ? this.gridMaxRows : this.gridRowBuffer,
            suppressMaxRenderedRowRestriction: (disableVirtualization) ? true : false,
            suppressColumnVirtualisation: (disableVirtualization) ? true : false,
            popupParent: this.sigApp,
            context: this.gridContext,
            debug: this.gridDebug,
            suppressPropertyNamesCheck: !this.gridDebug,
            localeText: this.texts,
            scrollbarWidth: this._getScrollbarWidth(),
            headerHeight: (this.gridHideHeader) ? 0 : parseInt(this.gridHeaderHeight, 10),
            unSortIcon: this.gridUnSortIcon,
            suppressMenuHide: this.gridSuppressMenuHide,
            rowHeight: this.gridRowHeight,
            rowSelection: (this.gridDisableMultiselect) ? 'single' : 'multiple',
            suppressRowClickSelection: this.gridSuppressRowClickSelection,
            suppressRowDeselection: this.gridSuppressRowDeselection,
            suppressCellSelection: this.gridSuppressCellSelection,
            suppressDragLeaveHidesColumns: this.gridSuppressDragLeaveHidesColumns,
            suppressRowHoverHighlight: this.gridSuppressRowHoverHighlight,
            pagination: this.gridPaginationEnabled,
            paginationPageSize: this.gridPaginationPageSize,
            paginationAutoPageSize: this.gridPaginationAutoPageSize,
            infiniteInitialRowCount: this.gridInfiniteInitialRowCount,
            cacheBlockSize: this.gridCacheBlockSize,
            cacheOverflowSize: this.gridCacheOverflowSize,
            maxConcurrentDatasourceRequests: this.gridMaxConcurrentDatasourceRequests,
            maxBlocksInCache: this.gridMaxBlocksInCache,
            getRowHeight: (params) => {
                return (this.gridColDefaultAutoHeight || this._hasAutoHeightColumns()) ? undefined : this.gridRowHeight;
            },
            getDocument: (shadowRootContext) => {
                return (shadowRootContext) ? this.shadowRoot : document;
            },
            getRowClass: (params) => {
                return this._getRowClass(params);
            },
            onGridReady: (params) => {
                this._onGridReady(params);
            },
            onFirstDataRendered: (params) => {
                this._onFirstDataRendered(params);
            },
            onPaginationChanged: (params) => {
                this._onPaginationChanged(params);
            },
            onColumnResized: (params) => {
                this._onColumnResized(params);
            },
            onColumnVisible: (params) => {
                this._onColumnVisible(params);
            },
            onColumnEverythingChanged: (params) => {
                this._onColumnEverythingChanged(params);
            },
            onCellClicked: (params) => {
                params.event.composedPath = () => this.lastClickEventPath;
                if (!this.isLongpress) this._onCellClicked(params);
            },
            onCellDoubleClicked: (params) => {
                params.event.composedPath = () => this.lastClickEventPath;
                this._onCellDoubleClicked(params);
            },
            onRowClicked: (params) => {
                params.event.composedPath = () => this.lastClickEventPath;
                if (!this.isLongpress) this._onRowClicked(params);
            },
            onRowDoubleClicked: (params) => {
                this._onRowDoubleClicked(params);
            },
            onCellFocused: (params) => {
                this._onCellFocused(params);
            },
            onFilterChanged: (params) => {
                this._onFilterChanged(params);
            },
            onViewportChanged: (params) => {
                this._onViewportChanged(params);
            },
            onCellKeyDown: (params) => {
                this._onCellKeyDown(params);
            },
            onSortChanged: (params) => {
                this._onSortChanged(params);
            },
            onCellLongpress: (params) => {
                this._onCellLongpress(params);
            },
            onRowLongpress: (params) => {
                this._onRowLongpress(params);
            },
            onCellDown: (params) => {
                this._onCellDown(params);
            },
            onCellUp: (params) => {
                this._onCellUp(params);
            },
            onRowDown: (params) => {
                this._onRowDown(params);
            },
            onRowUp: (params) => {
                this._onRowUp(params);
            },
            onGridTrack: (params) => {
                this._onGridTrack(params);
            }
        }
    }

    _mergeOptions() {
        if (this.ignoreGridOptionsDefaults) {
            this.gridOptionsMerged = this.gridOptions;
        } else {
            this.gridOptionsDefaults = this._getGridOptionsDefaults();
            this.gridOptionsMerged = Object.assign(this.gridOptionsDefaults, this.gridOptions);
        }
    }

    _updateGridRenderMode(newval, oldval) {
        if (newval && oldval !== undefined && this.gridInitDone) {
            this._reloadGrid();
        }
    }

    _updateGridHideHeader(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this._setHeaderHeight();
        }
    }

    _updateGridHeaderHeight(newval, oldval) {
        if (newval && oldval !== undefined && this.gridInitDone) {
            this._setHeaderHeight(newval);
        }
    }

    _updateGridRowHeight(newval, oldval) {
        if (newval && oldval !== undefined && this.gridInitDone) {
            this._setRowHeight(newval);
        }
    }

    _updateGridDisableMultiselect(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            if (newval)
                this._setGridOptionsProperty('rowSelection', 'single');
            else {
                this._setGridOptionsProperty('rowSelection', 'multiple');
            }
            this._deselectAllRows();
        }
    }

    _updateGridPaginationEnabled(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this._setGridOptionsProperty('pagination', newval, true);
        }
    }

    _updateGridPaginationPageSize(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this.gridApi.paginationSetPageSize(parseInt(newval, 10));
        }
    }

    _updateGridPaginationAutoPageSize(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this._setGridOptionsProperty('gridPaginationAutoPageSize', newval, true);
        }
    }

    _updateGridOptions(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this._reloadGrid();
        }
    }

    _updateColDefaults(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this._reloadGrid();
        }
    }

    _updateGridOverflowX(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this.gridOverflowXOldval = oldval;
        }

    }

    _updateGridOverflowY(newval, oldval) {
        if (newval !== undefined && oldval !== undefined && this.gridInitDone) {
            this.gridOverflowYOldval = oldval;
        }
    }

    _updateDesigntimeShowPaginator(newval, oldval) {
        if (this.isstylepreview && newval !== undefined && oldval !== undefined) {
            if (newval) this.gridPaginationEnabled = true;
            else this.gridPaginationEnabled = false;
        }
    }


    _updateDesigntimeShowOverlay(newval, oldval) {
        if (this.isstylepreview && newval !== undefined && oldval !== undefined) {
            if (newval) this._showLoadingOverlay();
            else this._hideOverlay();
        }
    }

    _destroyGrid() {
        if (this.gridApi && this.grid instanceof HTMLElement) {
            this._removeGridListeners();
            this.gridApi.destroy();
            this.gridInitDone = false;
            this.gridApi = null;
            this.gridColumnApi = null;
            this.gridOptionsMerged = null;
            this.viewport = null;
            this.focusedCell = null;
            this.sigClearTimeout(this.loadingTimeout);
        } else {
            this._log('Could not destroy the grid instance. No grid api found!', 'WARN');
        }
    }

    _setGridOptionsProperty(property, value, reload = false, refresh = false) {
        if (property !== undefined && value !== undefined) {
            this.gridOptionsMerged[property] = value;
            if (refresh) this._refreshGrid();
            if (reload) this._reloadGrid();
        }
    }

    _appendGridRoot() {
        if (this.$.container instanceof HTMLElement) {
            if (this.grid instanceof HTMLElement) this.grid.remove();
            const div = document.createElement('div');
            div.id = this.gridId;
            div.classList.add(this.gridTheme);
            this.$.container.append(div);
            this.grid = this.shadowRoot.getElementById(this.gridId);
        } else {
            this._log('Could not find the grid container, can not append grid root', 'ERROR');
        }
    }

    _reloadGrid() {
        this._destroyGrid();
        this._init();
    }

    _refreshGrid(refreshCells = false, doLayout = false) {
        if (this.gridApi) {
            this.gridApi.refreshHeader();
            this._setRowHeight();
            if (refreshCells) this.gridApi.refreshCells({ force: true });
            if (doLayout) this.gridApi.doLayout(); 
            if (this.gridSizeColumnsToFit) this.gridApi.sizeColumnsToFit();
        } else {
            this._log('Could not refresh the grid instance. No grid api found!', 'ERROR');
        }
    }

    _showLoadingOverlay() {
        if (this.gridApi) this.gridApi.showLoadingOverlay();
    }

    _showNoRowsOverlay() {
        if (this.gridApi) this.gridApi.showNoRowsOverlay();
    }

    _hideOverlay() {
        if (this.gridApi) this.gridApi.hideOverlay();
    }

    _applyDesigntimeSettings() {
        if (this.isstylepreview) {
            this._updateDesigntimeShowOverlay(this.designtimeShowOverlay, !this.designtimeShowOverlay);
            this._updateDesigntimeShowPaginator(this.designtimeShowPaginator, !this.designtimeShowPaginator);
        }
    }

    _onGridReady(params) {
        if (params) {
            this._applyFontMap();
            this.gridApi = params.api;
            this.gridColumnApi = params.columnApi;
            this.loadingTimeout = this.sigSetTimeout(() => {
                this._showLoadingOverlay();
            }, this.loadingTimeoutDelay);
            this._hasAutoHeightColumns();
            this._addGridListeners();
            this._observeScrollbars();
            this.gridInitDone = true;
        }
        this._callParentFunction('onGridReady', params);
    }

    _onFirstDataRendered(params) {
        this._refreshGrid(true);
        this._setFocusOnFirstCell();
        if (this.loadingTimeout) {
            this.sigClearTimeout(this.loadingTimeout);
            this.loadingTimeout = null;
            this._hideOverlay();
        }
        if (this.isstylepreview) {
            this._selectRow(0);
            this._selectRow(1);
            this._applyDesigntimeSettings();
        }
        this._callParentFunction('onFirstDataRendered', params);
    }

    _onPaginationChanged(params) {
        if (this.gridApi && this.gridPaginationEnabled) {
            const currentPageIndex = this.gridApi.paginationGetCurrentPage();
            if (this.gridCurrentPageIndex !== currentPageIndex) {
                this._setFocusOnFirstCell();
                this.gridCurrentPageIndex = currentPageIndex;
            } else {
                if (this.gridRestoreFocusOnPaginationChanged) this._restoreFocus();
            }
        }
        this._callParentFunction('onPaginationChanged', params);
    }

    _onCellClicked(params) {
        this._callParentFunction('onCellClicked', params);
    }

    _onCellDoubleClicked(params) {
        this._callParentFunction('onCellDoubleClicked', params);
    }

    _onRowClicked(params) {
        this._callParentFunction('onRowClicked', params);
    }

    _onRowDoubleClicked(params) {
        this._callParentFunction('onRowDoubleClicked', params);
    }

    _onColumnResized(params) {
        if (this.resetHeightOnColumnResize) {
            this._setRowMinHeight();
            if (params.finished) {
                this.sigSetTimeout(() => this._setRowMinHeight('100%'), this.gridAutoRowHeightDelay);
            }
        }
        this._callParentFunction('onColumnResized', params);
    }

    _onColumnVisible(params) {
        this._callParentFunction('onColumnVisible', params);
    }

    _onColumnEverythingChanged(params) {
        this._callParentFunction('onColumnEverythingChanged', params);
    }

    _onCellFocused(params) {
        this._callParentFunction('onCellFocused', params);
    }

    _onFilterChanged(params) {
        this._restoreFocus();
        this._callParentFunction('onFilterChanged', params);
    }

    _onSortChanged(params) {
        this._restoreFocus();
        this._callParentFunction('onSortChanged', params);
    }

    _onViewportChanged(params) {
        this._callParentFunction('onViewportChanged', params);
    }

    _onCellKeyDown(params) {
        if (!this.headerNavigableFromFirstRow) this._restoreFocus();
        if (params && params.event && !this.isdesignmode && this.gridReadonly === false) {
            const evt = params.event;
            const key = evt.keyCode;
            const ctrlKey = evt.ctrlKey;
            const shiftKey = evt.shiftKey;
            const altKey = evt.altKey;
            switch (key) {
                case 65:
                    if (ctrlKey && !shiftKey && !altKey) {
                        this._selectAllRows();
                    } else if (ctrlKey && shiftKey && !altKey) {
                        this._deselectAllRows();
                    }
                    break;
                default:
                    this._log(evt);
                    break;
            }
        }
        this._callParentFunction('onCellKeyDown', params);
    }


    _onCellLongpress(params) {
        this._callParentFunction('onCellLongpress', params);
    }

    _onRowLongpress(params) {
        const row = params.node;
        if (!this.gridSuppressMarkOnLongpress) row.setSelected(!row.isSelected(), this.gridDisableMultiselect);
        this._callParentFunction('onRowLongpress', params);
    }

    _onCellDown(params) {
        this._callParentFunction('onCellDown', params);
    }

    _onCellUp(params) {
        this._callParentFunction('onCellUp', params);
    }

    _onRowDown(params) {
        this._callParentFunction('onRowDown', params);
    }

    _onRowUp(params) {
        this._callParentFunction('onRowUp', params);
    }

    _onGridTrack(params) {
        this._callParentFunction('onGridTrack', params);
    }


    _callParentFunction(fnc, params) {
        if (typeof fnc === 'string') {
            const parent = this.getParentHostElement();
            if (parent instanceof HTMLElement && typeof parent[fnc] === 'function') parent[fnc](params);
        } else {
            this._log('Please supply a valid function name to call on ther parent.', 'ERROR');
        }
    }

    _getRowClass(params) {
        if (this.isstylepreview && params.node.rowIndex === 2) return 'ag-row-focus';
    }

    _getColumnDefs() {
        let cols;
        if (this.isstylepreview) {
            cols = [
                {
                    headerName: 'ID',
                    field: 'id',
                    valueGetter: 'node.id',
                    checkboxSelection: (this.isdesignmode && this.gridShowCheckbox) ? true : false,
                    filter: false,
                    width: 50
                },
                { headerName: "Column 1", field: "col1" },
                { headerName: "Column 2", field: "col2", flex: 1 },
                { headerName: "Column 3", field: "col3", flex: 1 }
            ];
        } else {
            cols = [
                {
                    headerName: 'ID',
                    field: 'id',
                    valueGetter: 'node.id',
                    checkboxSelection: (this.isdesignmode && this.gridShowCheckbox) ? true : false,
                    filter: false,
                    width: 60
                },
                { headerName: "Firstname", field: "firstname" },
                { headerName: "Lastname", field: "lastname" },
                { headerName: "Age", field: "age" }
            ];
        }
        return cols;
    }

    _getRowData(maxSets = 200) {
        let rows = [];
        if (this.isstylepreview) {
            rows = [
                { col1: "Row selected & marked", col2: "Data", col3: "Data" },
                { col1: "Row marked", col2: "Data", col3: "Data" },
                { col1: "Row selected", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
                { col1: "Row standard", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
                { col1: "Row standard", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
                { col1: "Row standard", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
                { col1: "Row standard", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
                { col1: "Row standard", col2: "Data", col3: "Data" },
                { col1: "Row alternate", col2: "Data", col3: "Data" },
            ];
        } else {
            const rowSet = [
                { firstname: "Franz", lastname: "Grossmann - Celica Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", age: 35 },
                { firstname: "Eva", lastname: "Stadler", age: 32 },
                { firstname: "Ludiwg", lastname: "Lupaka", age: 72 },
                { firstname: "Stefanie", lastname: "Mayer", age: 17 },
                { firstname: "Markus", lastname: "Reiterer", age: 27 }
            ];
            for (let setsCount = 0; setsCount < maxSets; setsCount++) {
                rows = rows.concat(rowSet);
            }
        }
        this.gridMaxRows = rows.length;
        return rows;
    }

    _getDefaultColDef() {
        return {
            sortable: this.gridColDefaultSortable,
            headerComponentParams: this._getHeaderTemplate(),
            resizable: this.gridColDefaultResizeable,
            wrapText: this.gridColDefaultWrapText,
            autoHeight: this.gridColDefaultAutoHeight,
            width: (this.gridColDefaultWidth > 0) ? this.gridColDefaultWidth : undefined,
            minWidth: (this.gridColDefaultMinWidth > 0) ? this.gridColDefaultMinWidth : undefined,
            maxWidth: (this.gridColDefaultMaxWidth > 0) ? this.gridColDefaultMaxWidth : undefined,
            suppressMovable: !this.gridColDefaultMoveable,
            lockPinned: !this.gridColDefaultsLockPinned,
            filter: (this.gridColDefaultFilter) ? this.gridStandardFilter : false,
            filterParams: {
                options: {
                }
            },
            cellRenderer: (this.gridRenderHtml) ? this.gridHtmlCellRenderer : undefined,
            cellRendererParams: {
                options: {
                }
            }
        };
    }

    _getHeaderTemplate() {
        return {
            template:
                '<div class="ag-cell-label-container" role="presentation">' +
                '  <span ref="eMenu" class="ag-header-icon ag-header-cell-menu-button"></span>' +
                '  <div ref="eLabel" class="ag-header-cell-label" role="presentation">' +
                '    <span ref="eSortOrder" class="ag-header-icon ag-sort-order" ></span>' +
                '    <span ref="eSortAsc" class="ag-header-icon ag-sort-ascending-icon" ></span>' +
                '    <span ref="eSortDesc" class="ag-header-icon ag-sort-descending-icon" ></span>' +
                '    <span ref="eSortNone" class="ag-header-icon ag-sort-none-icon" ></span>' +
                '    <span ref="eText" class="ag-header-cell-text" role="columnheader"></span>' +
                '    <span ref="eFilter" class="ag-header-icon ag-filter-icon"></span>' +
                '  </div>' +
                '</div>'
        };
    }

    _isVirtualizationDisabled() {
        return (this.gridVirtualizationDisabled && this.gridRowModelType === 'clientSide') ? true : false;
    }

    async _getLocaleTexts() {
        if (this.tmApi) {
            const textList = await this.tmApi.getTextsAsync(this._getTextsObject());
            return (textList) ? textList[this.controlTextList] : {};
        } else {
            return this._getTextsObject()[this.controlTextList];
        }
    }

    _setHeaderHeight(height = this.gridHeaderHeight) {
        if (this.gridApi) this.gridApi.setHeaderHeight((this.gridHideHeader) ? 0 : parseInt(height, 10));
    }

    _setRowHeight(height = this.gridRowHeight) {
        this.style.setProperty("--theme-sig-control-listview-ag-row-height", height + 'px');
        if (this.gridApi && (this.isdesignmode || (!this.isdesignmode && this.resetHeightOnColumnResize))) {
            this._setRowMinHeight();
            this.gridApi.resetRowHeights();
            this.sigSetTimeout(() => this._setRowMinHeight('100%'), this.gridAutoRowHeightDelay);
        }
    }

    _setRowMinHeight(minHeight) {
        if (minHeight) this.style.setProperty('--theme-sig-control-listview-ag-cell-min-height', minHeight);
        else this.style.removeProperty('--theme-sig-control-listview-ag-cell-min-height');
    }

    _deselectAllRows() {
        if (this.gridApi) this.gridApi.deselectAll();
    }

    _setFocusOnFirstCell() {
        if (this.gridApi && this.gridColumnApi) {
            const firstCol = this.gridColumnApi.getAllDisplayedColumns()[0];
            const firstRow = this.gridApi.getFirstDisplayedRow();
            this._setFocusedCell(firstRow, firstCol);
        }
    }

    _setFocusedCell(row, col, position = null) {
        if (this.gridApi && row !== undefined && col !== undefined) {
            this.gridApi.setFocusedCell(row, col);
            this.gridApi.ensureColumnVisible(col);
            this.gridApi.ensureIndexVisible(row, position);
        }
    }

    _getScrollbarWidth() {
        const scrollbarWidth = (this.gridScrollbarWidth === 0) ? parseInt(this.computedStyle.getPropertyValue('--theme-sig-control-scrollbar-width'), 10) : this.gridScrollbarWidth;
        return (isNaN(scrollbarWidth)) ? undefined : scrollbarWidth;
    }

    _getFocusedCell() {
        return (this.gridApi) ? this.gridApi.getFocusedCell() : null;
    }

    _detectScrollbars(params) {
        console.warn(`[${this.tagName}] _detectScrollbars() is deprecated and will be removed.`);
        return;
    }

    _addGridListeners() {
        if (this.gridReadonly) return;
        this.viewport = this.shadowRoot.querySelector('div.ag-body-viewport');
        if (this.viewport instanceof HTMLElement) {
            this.sigAddEventListener('down', this.gridDownEvent, 'polymerEvent', this.viewport);
            this.sigAddEventListener('up', this.gridUpEvent, 'polymerEvent', this.viewport);
            this.sigAddEventListener('track', this.gridTrackEvent, 'polymerEvent', this);
            this.sigAddEventListener('mousedown', this.gridMousedownEventCapture, 'jsEvent', this.viewport, { capture: true });
            this._allowZooming();
        }
    }

    _removeGridListeners() {
        if (this.gridReadonly || this.viewport === null) return;
        this.sigRemoveEventListener('down', this.gridDownEvent, 'polymerEvent', this.viewport);
        this.sigRemoveEventListener('up', this.gridUpEvent, 'polymerEvent', this.viewport);
        this.sigRemoveEventListener('track', this.gridTrackEvent, 'polymerEvent', this);
        this.sigRemoveEventListener('mousedown', this.gridMousedownEventCapture, 'jsEvent', this.viewport, { capture: true });
        this.viewport = null;
    }

    _gridCellDown(evt) {
        const evtPath = evt.path || evt.composedPath();
        this.lastClickEventPath = evtPath;
        const isCellClick = this._isCellClick(evtPath);
        if (isCellClick) {
            const isTouchInput = this._isTouchInput(evt.detail.sourceEvent);
            let focusedCell;
            if (isTouchInput) {
                this.gridDownEventIsTouch = true;
                focusedCell = this._getClickedCellByPath(evtPath);
                this._setFocusedCell(focusedCell.rowIndex, focusedCell.column.colId);
            } else focusedCell = this._getFocusedCell();
            if (focusedCell) {
                this.focusedCell = focusedCell;
                const cellParams = this._buildCellParams(evt, focusedCell, 'cellDown');
                const rowParams = this._buildRowParams(evt, focusedCell, 'rowDown');
                if (typeof this.gridOptionsMerged.onCellDown === 'function') this.gridOptionsMerged.onCellDown(cellParams);
                if (typeof this.gridOptionsMerged.onRowDown === 'function') this.gridOptionsMerged.onRowDown(rowParams);
                this._setupLongpressTimeout(evt);
            }
        }
    }

    _gridCellUp(evt) {
        const evtPath = evt.path || evt.composedPath();
        this.lastClickEventPath = evtPath;
        const isCellClick = this._isCellClick(evtPath);
        if (isCellClick) {
            const focusedCell = this.focusedCell;
            if (focusedCell) {
                const cellParams = this._buildCellParams(evt, focusedCell, 'cellUp');
                const rowParams = this._buildRowParams(evt, focusedCell, 'rowUp');
                if (typeof this.gridOptionsMerged.onCellUp === 'function') this.gridOptionsMerged.onCellUp(cellParams);
                if (typeof this.gridOptionsMerged.onRowUp === 'function') this.gridOptionsMerged.onRowUp(rowParams);
                this._clearLongpressTimeout();
            }
        }
        this.sigSetTimeout(() => {
            this.gridDownEventIsTouch = false;
        }, this.clickDelay);
    }

    _gridTrack(evt) {
        if (evt && evt.detail) {
            const focusedCell = this.focusedCell;
            const state = evt.detail.state;
            switch (state) {
                case 'start':
                    this.viewportIsDragged = true;
                    break;
                case 'track':
                    break;
                case 'end':
                    this.viewportIsDragged = false;
                    break;
            }
            const trackParams = this._buildTrackParams(evt, focusedCell, 'gridTrack');
            if (typeof this.gridOptionsMerged.onGridTrack === 'function') this.gridOptionsMerged.onGridTrack(trackParams);
        }
    }

    _setupLongpressTimeout(evt) {
        const focusedCell = this.focusedCell;
        const cellParams = this._buildCellParams(evt, focusedCell, 'cellLongpress');
        const cellParamsEventPath = (cellParams && cellParams.event) ? cellParams.event.composedPath() : null;
        const rowParams = this._buildRowParams(evt, focusedCell, 'rowLongpress');
        const rowParamsEventPath = (rowParams && rowParams.event) ? rowParams.event.composedPath() : null;
        this.longpressTimeout = this.sigSetTimeout(() => {
            if (!this.viewportIsDragged) {
                this.isLongpress = true;
                if (cellParamsEventPath) cellParams.event.composedPath = () => cellParamsEventPath;
                if (typeof this.gridOptionsMerged.onCellLongpress === 'function') this.gridOptionsMerged.onCellLongpress(cellParams);
                if (rowParamsEventPath) rowParams.event.composedPath = () => rowParamsEventPath;
                if (typeof this.gridOptionsMerged.onRowLongpress === 'function') this.gridOptionsMerged.onRowLongpress(rowParams);
            }
        }, this.longpressDelay);
    }

    _clearLongpressTimeout() {
        this.sigClearTimeout(this.longpressTimeout);
        this.longpressTimeout = null;
        this.focusedCell = null;
        this.sigSetTimeout(() => {
            this.isLongpress = false;
        }, this.clickDelay);
    }

    _isCellClick(path) {
        let isCellClick = false,
            hasCell = false,
            hasRow = false;
        if (path && path.length > 0) {
            for (let index = 0; index < path.length; index++) {
                const element = path[index];
                if (element instanceof HTMLElement) {
                    if (element.classList.contains('ag-cell')) hasCell = true;
                    if (element.classList.contains('ag-row')) hasRow = true;
                    if (hasCell && hasRow) {
                        isCellClick = true;
                        break;
                    }
                }
            }
        } else {
            this._log('Can not check if the cell was clicked. You need to pass a valid event path.', 'ERROR');
        }
        return isCellClick;
    }

    _getClickedCellByPath(path) {
        let clickedCell = null;
        let rowIndex, colId;
        if (path && path.length > 0) {
            for (let index = 0; index < path.length; index++) {
                const element = path[index];
                if (element instanceof HTMLElement) {
                    if (element.classList.contains('ag-cell')) colId = element.getAttribute('col-id');
                    if (element.classList.contains('ag-row')) rowIndex = parseInt(element.getAttribute('row-index'), 10);
                    if (rowIndex !== undefined && colId !== undefined) break;
                }
            }
            if (rowIndex !== undefined && colId !== undefined) {
                const column = this.gridColumnApi.getColumn(colId);
                const rowPinned = this.gridApi.getRowNode(rowIndex.toString()).rowPinned;
                clickedCell = {
                    rowIndex: rowIndex,
                    rowPinned: (rowPinned) ? rowPinned : undefined,
                    column: column
                }
            }
        } else {
            this._log('Can not build clicked cell object!', 'ERROR');
        }
        return clickedCell;
    }

    _buildCellParams(evt, focusedCell, type) {
        let params = {};
        if (evt && focusedCell && type) {
            const rowIndex = focusedCell.rowIndex
            const rowPinned = focusedCell.rowPinned;
            const node = this.gridApi.getDisplayedRowAtIndex(parseInt(rowIndex, 10));
            const column = focusedCell.column;
            params = {
                api: this.gridApi,
                colDef: (column) ? column.colDef : undefined,
                column: column,
                columnApi: this.gridColumnApi,
                context: this.gridContext,
                data: (node) ? node.data : undefined,
                event: evt,
                node: node,
                rowIndex: rowIndex,
                rowPinned: (rowPinned) ? rowPinned : undefined,
                type: type,
                value: (column) ? this.gridApi.getValue(column.colId, node) : undefined
            }
        } else {
            this._log('Can not build cell params!', 'ERROR');
        }
        return params;
    }

    _buildRowParams(evt, focusedCell, type) {
        let params = null;
        if (evt && focusedCell && type) {
            const rowIndex = focusedCell.rowIndex
            const rowPinned = focusedCell.rowPinned;
            const node = this.gridApi.getDisplayedRowAtIndex(parseInt(rowIndex, 10));
            params = {
                api: this.gridApi,
                columnApi: this.gridColumnApi,
                context: this.gridContext,
                data: (node) ? node.data : undefined,
                event: evt,
                node: node,
                rowIndex: rowIndex,
                rowPinned: (rowPinned) ? rowPinned : undefined,
                source: undefined, 
                type: type
            }
        } else {
            this._log('Can not build row params!', 'ERROR');
        }
        return params;
    }

    _buildTrackParams(evt, focusedCell, type) {
        let params = null;
        let rowIndex, rowPinned, node;
        if (evt && type) {
            if (focusedCell) {
                rowIndex = focusedCell.rowIndex
                rowPinned = focusedCell.rowPinned;
                node = this.gridApi.getDisplayedRowAtIndex(parseInt(rowIndex, 10));
            }
            params = {
                api: this.gridApi,
                columnApi: this.gridColumnApi,
                context: this.gridContext,
                data: (node) ? node.data : undefined,
                event: evt,
                node: (node) ? node : null,
                rowIndex: (rowIndex) ? rowIndex : undefined,
                rowPinned: (rowPinned) ? rowPinned : undefined,
                source: undefined, 
                type: type
            }
        } else {
            this._log('Can not build track params!', 'ERROR');
        }
        return params;
    }

    _selectRow(rowIndex) {
        if (this.gridApi && !isNaN(parseInt(rowIndex, 10))) {
            const node = this.gridApi.getRowNode(rowIndex.toString());
            if (node) node.setSelected(true);
        }
    }

    _deselectRow(rowIndex) {
        if (this.gridApi && !isNaN(parseInt(rowIndex, 10))) {
            const node = this.gridApi.getRowNode(rowIndex.toString());
            if (node) node.setSelected(false);
        }
    }

    _selectAllRows() {
        if (this.gridApi && this.gridRowModelType === 'clientSide') this.gridApi.selectAll();
        else this._log('"Select all" is only available on clientSide role model type or the grid api is not rerady');
    }

    _getSelectedRows() {
        return (this.gridApi) ? this.gridApi.getSelectedRows() : null;
    }

    _setFilterModel(model) {
        if (this.gridApi) this.gridApi.setFilterModel(model);
    }

    _resetAllSort() {
        if (this.gridColumnApi) {
            const savedColumnState = this.gridColumnApi.getColumnState();
            if (Array.isArray(savedColumnState)) {
                savedColumnState.forEach(column => {
                    if (column.sort !== null) column.sort = null;
                });
            }
            this.gridColumnApi.applyColumnState({ state: savedColumnState });
        }
    }

    _resetAllFilter() {
        if (this.gridApi) this.gridApi.setFilterModel(null);
    }

    _restoreFocus() {
        SigPolymer.afterNextRender(this, () => {
            const focusedCell = this._getFocusedCell();
            const rowCount = (this.gridApi) ? this.gridApi.getDisplayedRowCount() : 0;
            if (focusedCell && rowCount > 0) this._setFocusedCell(focusedCell.rowIndex, focusedCell.column.colId);
        });
    }

    _hasAutoHeightColumns() {
        let columnAutoHeightSum = 0;
        if (this.gridApi) {
            const columnDefs = this.gridApi.getColumnDefs();
            if (columnDefs) {
                columnDefs.forEach(defition => {
                    if (defition.autoHeight) columnAutoHeightSum++;
                });
            }
        }

        if (columnAutoHeightSum > 1) {
            this.resetHeightOnColumnResize = true;
            this._setRowMinHeight('100%');
        }
        else {
            this.resetHeightOnColumnResize = false;
            this._setRowMinHeight();
        }
        return columnAutoHeightSum > 0;
    }

    _addEventListeners() {
        this.sigAddEventListener('LANGUAGE_CHG', (majorId, minorId, msg) => {
            this._onLangChg(majorId, minorId, msg);
        }, 'runtimeEvent');
    }

    designerOnLanguageChanged() {
        this._onLangChg();
    }

    async designerOnObjectStoreUpdate(data) {
        const textListChanged = await this.tmApi.isTextListUpdate(data, this.controlTextList);
        if (textListChanged) this._onLangChg();
    }


    designerOnBoundsChanged(newBounds, oldBounds) {
        if (this.gridApi) this._refreshGrid(true, true);
    }

    async _onLangChg(majorId, minorId, msg) {
        if (this.tmApi) {
            this.texts = await this._getLocaleTexts();
            this._reloadGrid();
        }
    }

    _getTextsObject() {
        return {
            [this.controlTextList]: {
                selectAll: '(Select All)',
                selectAllSearchResults: '(Select All Search Results)',
                searchOoo: 'Search...',
                blanks: '(Blanks)',
                noMatches: 'No matches',

                filterOoo: 'Filter...',
                equals: 'Equals',
                notEqual: 'Not equal',
                empty: 'Choose One',

                lessThan: 'Less than',
                greaterThan: 'Greater than',
                lessThanOrEqual: 'Less than or equal',
                greaterThanOrEqual: 'Greater than or equal',
                inRange: 'In range',
                inRangeStart: 'to',
                inRangeEnd: 'from',

                contains: 'Contains',
                notContains: 'Not contains',
                startsWith: 'Starts with',
                endsWith: 'Ends with',

                dateFormatOoo: 'yyyy-mm-dd',

                andCondition: 'AND',
                orCondition: 'OR',

                applyFilter: 'Apply',
                resetFilter: 'Reset',
                clearFilter: 'Clear',
                cancelFilter: 'Cancel',

                textFilter: 'Text Filter',
                numberFilter: 'Number Filter',
                dateFilter: 'Date Filter',
                setFilter: 'Set Filter',

                columns: 'Columns',
                filters: 'Filters',

                pivotMode: 'Pivot Mode',
                groups: 'Row Groups',
                rowGroupColumnsEmptyMessage: 'Drag here to set row groups',
                values: 'Values',
                valueColumnsEmptyMessage: 'Drag here to aggregate',
                pivots: 'Column Labels',
                pivotColumnsEmptyMessage: 'Drag here to set column labels',

                group: 'Group',

                loadingOoo: 'Loading...',
                noRowsToShow: 'No Rows To Show',
                enabled: 'Enabled',

                pinColumn: 'Pin Column',
                pinLeft: 'Pin Left',
                pinRight: 'Pin Right',
                noPin: 'No Pin',
                valueAggregation: 'Value Aggregation',
                autosizeThiscolumn: 'Autosize This Column',
                autosizeAllColumns: 'Autosize All Columns',
                groupBy: 'Group by',
                ungroupBy: 'Un-Group by',
                resetColumns: 'Reset Columns',
                expandAll: 'Expand All',
                collapseAll: 'Close All',
                copy: 'Copy',
                ctrlC: 'Ctrl+C',
                copyWithHeaders: 'Copy With Headers',
                paste: 'Paste',
                ctrlV: 'Ctrl+V',
                export: 'Export',
                csvExport: 'CSV Export',
                excelExport: 'Excel Export (.xlsx)',
                excelXmlExport: 'Excel Export (.xml)',

                sum: 'Sum',
                min: 'Min',
                max: 'Max',
                none: 'None',
                count: 'Count',
                avg: 'Average',
                filteredRows: 'Filtered',
                selectedRows: 'Selected',
                totalRows: 'Total Rows',
                totalAndFilteredRows: 'Rows',
                more: 'More',
                to: 'to',
                of: 'of',
                page: 'Page',
                nextPage: 'Next Page',
                lastPage: 'Last Page',
                firstPage: 'First Page',
                previousPage: 'Previous Page',

                pivotChartAndPivotMode: 'Pivot Chart & Pivot Mode',
                pivotChart: 'Pivot Chart',
                chartRange: 'Chart Range',

                columnChart: 'Column',
                groupedColumn: 'Grouped',
                stackedColumn: 'Stacked',
                normalizedColumn: '100% Stacked',

                barChart: 'Bar',
                groupedBar: 'Grouped',
                stackedBar: 'Stacked',
                normalizedBar: '100% Stacked',

                pieChart: 'Pie',
                pie: 'Pie',
                doughnut: 'Doughnut',

                line: 'Line',

                xyChart: 'X Y (Scatter)',
                scatter: 'Scatter',
                bubble: 'Bubble',

                areaChart: 'Area',
                area: 'Area',
                stackedArea: 'Stacked',
                normalizedArea: '100% Stacked',

                histogramChart: 'Histogram',

                pivotChartTitle: 'Pivot Chart',
                rangeChartTitle: 'Range Chart',
                settings: 'Settings',
                data: 'Data',
                format: 'Format',
                categories: 'Categories',
                defaultCategory: '(None)',
                series: 'Series',
                xyValues: 'X Y Values',
                paired: 'Paired Mode',
                axis: 'Axis',
                navigator: 'Navigator',
                color: 'Color',
                thickness: 'Thickness',
                xType: 'X Type',
                automatic: 'Automatic',
                category: 'Category',
                number: 'Number',
                time: 'Time',
                xRotation: 'X Rotation',
                yRotation: 'Y Rotation',
                ticks: 'Ticks',
                width: 'Width',
                height: 'Height',
                length: 'Length',
                padding: 'Padding',
                spacing: 'Spacing',
                chart: 'Chart',
                title: 'Title',
                titlePlaceholder: 'Chart title - double click to edit',
                background: 'Background',
                font: 'Font',
                top: 'Top',
                right: 'Right',
                bottom: 'Bottom',
                left: 'Left',
                labels: 'Labels',
                size: 'Size',
                minSize: 'Minimum Size',
                maxSize: 'Maximum Size',
                legend: 'Legend',
                position: 'Position',
                markerSize: 'Marker Size',
                markerStroke: 'Marker Stroke',
                markerPadding: 'Marker Padding',
                itemSpacing: 'Item Spacing',
                itemPaddingX: 'Item Padding X',
                itemPaddingY: 'Item Padding Y',
                layoutHorizontalSpacing: 'Horizontal Spacing',
                layoutVerticalSpacing: 'Vertical Spacing',
                strokeWidth: 'Stroke Width',
                offset: 'Offset',
                offsets: 'Offsets',
                tooltips: 'Tooltips',
                callout: 'Callout',
                markers: 'Markers',
                shadow: 'Shadow',
                blur: 'Blur',
                xOffset: 'X Offset',
                yOffset: 'Y Offset',
                lineWidth: 'Line Width',
                normal: 'Normal',
                bold: 'Bold',
                italic: 'Italic',
                boldItalic: 'Bold Italic',
                predefined: 'Predefined',
                fillOpacity: 'Fill Opacity',
                strokeOpacity: 'Line Opacity',
                histogramBinCount: 'Bin count',
                columnGroup: 'Column',
                barGroup: 'Bar',
                pieGroup: 'Pie',
                lineGroup: 'Line',
                scatterGroup: 'X Y (Scatter)',
                areaGroup: 'Area',
                histogramGroup: 'Histogram',
                groupedColumnTooltip: 'Grouped',
                stackedColumnTooltip: 'Stacked',
                normalizedColumnTooltip: '100% Stacked',
                groupedBarTooltip: 'Grouped',
                stackedBarTooltip: 'Stacked',
                normalizedBarTooltip: '100% Stacked',
                pieTooltip: 'Pie',
                doughnutTooltip: 'Doughnut',
                lineTooltip: 'Line',
                groupedAreaTooltip: 'Area',
                stackedAreaTooltip: 'Stacked',
                normalizedAreaTooltip: '100% Stacked',
                scatterTooltip: 'Scatter',
                bubbleTooltip: 'Bubble',
                histogramTooltip: 'Histogram',
                noDataToChart: 'No data available to be charted.',
                pivotChartRequiresPivotMode: 'Pivot Chart requires Pivot Mode enabled.',
                filterFor: 'Filter for',
                filterPlaceholder: 'Enter a filter value',
                filterWindowTitle: 'Enter a filter value to filter rows',
            }
        }
    }

    sigOnRequiredPropertiesReady() {
        super.sigOnRequiredPropertiesReady();
        if (!this.isInShadowDom() && !this.gridInitDone && !this.firstInitStarted) {
            this.init();
            this.firstInitStarted = true;
        }
    }

    sigApplyFontObject(propName, fontObj) {
        super.sigApplyFontObject(propName, fontObj);
        const textDecoration = (fontObj.underline) ? 'underline' : 'none';
        switch (propName) {
            case 'elementMainFont':
                this.style.setProperty('--theme-sig-control-listview-ag-mainfont-text-decoration', textDecoration);
                this.style.removeProperty('text-decoration');
                break;
            case '#grid .ag-header':
                this.style.setProperty('--theme-sig-control-listview-ag-header-text-decoration', textDecoration);
                break;
            case '#grid .ag-body-viewport':
                this.style.setProperty('--theme-sig-control-listview-ag-viewport-text-decoration', textDecoration);
                break;
            case '#grid .ag-paging-panel':
                this.style.setProperty('--theme-sig-control-listview-ag-paging-panel-text-decoration', textDecoration);
                break;
        }
    }

    _getViewportPixelRangeBounds() {
        const bounds = { top: 0, left: 0, bottom: 0, right: 0 };
        if (this.gridApi) {
            const hBounds = this.gridApi.getVerticalPixelRange();
            const vBounds = this.gridApi.getHorizontalPixelRange();
            bounds.top = (hBounds.top) ? hBounds.top : 0;
            bounds.left = (vBounds.left) ? vBounds.left : 0;
            bounds.bottom = (hBounds.bottom) ? hBounds.bottom : 0;
            bounds.right = (vBounds.right) ? vBounds.right : 0;
        }
        return bounds;
    }

    _allowZooming() {
        if (this.sigApp instanceof HTMLElement && this.sigApp.allowZooming) {
            if (this.gridAllowZooming) {
                if (this.isFirefox() && !this.isAppleMobile()) {
                    Gestures.setTouchAction(this, 'manipulation');
                } else {
                    Gestures.setTouchAction(this, 'pan-x pan-y pinch-zoom');
                }
            } else if (this.isAppleMobile() && this.applyTouchActionPanSafariMobile) {
                Gestures.setTouchAction(this.viewport, 'pan-x pan-y');
                const viewportCols = this.viewport.querySelector('.ag-center-cols-viewport');
                if (viewportCols) Gestures.setTouchAction(viewportCols, 'pan-x pan-y');
            }
        }
    }


    moveCursorDown() {
        if (this.gridApi) {
            const cell = this.gridApi.getFocusedCell();
            const rowCount = this.gridApi.getDisplayedRowCount();
            const pageSize = this.gridApi.paginationGetPageSize(); 
            const pageNumber = this.gridApi.paginationGetCurrentPage();
            const lastRowOnPageIndex = pageSize * (pageNumber + 1);

            if (cell && cell.rowIndex >= lastRowOnPageIndex - 1) return;
            if (cell && cell.rowIndex <= rowCount - 2) {
                this._setFocusedCell(cell.rowIndex + 1, cell.column.colId, 'bottom');
            }
        }
    }

    moveCursorUp() {
        if (this.gridApi) {
            const cell = this.gridApi.getFocusedCell();
            const pageSize = this.gridApi.paginationGetPageSize();
            const pageNumber = this.gridApi.paginationGetCurrentPage();
            const firstRowOnPageIndex = pageSize * pageNumber + 1;

            if (cell && cell.rowIndex < firstRowOnPageIndex) return;
            if (cell) this._setFocusedCell(cell.rowIndex - 1, cell.column.colId);

        }
    }

    moveCursorTop() {
        if (this.gridApi) {
            if (this.gridPaginationEnabled) {
                this.gridApi.paginationGoToFirstPage();
            }
            const rowCount = this.gridApi.getDisplayedRowCount();
            if (rowCount > 0) {
                const cell = this.gridApi.getFocusedCell();
                if (cell) this._setFocusedCell(0, cell.column.colId, 'top');
                this._restoreFocus();
            }
        }
    }

    moveCursorBottom() {
        if (this.gridApi) {
            const cell = this.gridApi.getFocusedCell();
            const rowCount = this.gridApi.getDisplayedRowCount();
            if (rowCount > 0) {
                if (this.gridPaginationEnabled) {
                    this.gridApi.paginationGoToLastPage();

                    SigPolymer.afterNextRender(this, () => {
                        if (cell) {
                            this._setFocusedCell(rowCount - 1, cell.column.colId, 'bottom');
                        }
                        this._restoreFocus();
                    });
                } else {
                    if (cell) {
                        this._setFocusedCell(rowCount - 1, cell.column.colId, 'bottom');
                    }
                    this._restoreFocus();
                }
            }
        }
    }

    moveCursorToRow(rowIndex, position = 'middle') {
        if (this.gridApi) {
            const rowCount = this.gridApi.getDisplayedRowCount();
            const realRowIndex = rowIndex - 1;
            if (realRowIndex >= 0 && realRowIndex < rowCount) {
                const cell = this.gridApi.getFocusedCell();
                const pageSize = this.gridApi.paginationGetPageSize();
                const firstRowOnPage = this.gridApi.paginationGetCurrentPage() * pageSize
                const lastRowOnpage = this.gridApi.paginationGetCurrentPage() * pageSize + pageSize;

                if (realRowIndex > lastRowOnpage || realRowIndex < firstRowOnPage) {
                    this.gridApi.paginationGoToPage(Math.floor(realRowIndex / pageSize));
                }

                SigPolymer.afterNextRender(this, () => {
                    if (cell) {
                        this._setFocusedCell(realRowIndex, cell.column.colId, position);
                    }
                    this._restoreFocus();
                });
            }
        }
    }

    moveCursorPageDown() {
        if (this.gridApi) {
            if (this.gridPaginationEnabled) {
                if (this.gridApi.paginationGetCurrentPage() + 1 < this.gridApi.paginationGetTotalPages())
                    this.gridApi.paginationGoToNextPage();
            } else {
                const rowCount = this.gridApi.getDisplayedRowCount();
                const cell = this.gridApi.getFocusedCell();
                if (rowCount > 0 && cell && cell.rowIndex < rowCount - 1) {
                    let nextRow, i, cellRow;
                    let viewportScrollTop = this.viewport.scrollTop;
                    const viewportHeight = this.viewport.offsetHeight;
                    cellRow = this.gridApi.getDisplayedRowAtIndex(cell.rowIndex);

                    if (cellRow && (cellRow.rowTop > viewportHeight + viewportScrollTop || cellRow.rowTop < viewportScrollTop)) {
                        this._setFocusedCell(cell.rowIndex, cell.column.colId, 'top');
                        viewportScrollTop = this.viewport.scrollTop;
                    }

                    for (i = 1; i <= rowCount; i++) {
                        nextRow = this.gridApi.getDisplayedRowAtIndex(cell.rowIndex + i);
                        if (nextRow && nextRow.rowIndex < rowCount) {
                            if (nextRow.rowTop + nextRow.rowHeight > viewportHeight + viewportScrollTop) break;
                        } else {
                            return;
                        }
                    }

                    const newRowIdx = cell.rowIndex + i;
                    this._setFocusedCell(newRowIdx, cell.column.colId, 'top');
                }
            }
        }
    }

    moveCursorPageUp() {
        if (this.gridApi) {
            if (this.gridPaginationEnabled) {
                if (this.gridApi.paginationGetCurrentPage() > 0)
                    this.gridApi.paginationGoToPreviousPage();
            } else {
                const rowCount = this.gridApi.getDisplayedRowCount();
                const lastFocusedCell = this.gridApi.getFocusedCell();

                if (rowCount > 0 && lastFocusedCell && lastFocusedCell.rowIndex > 0) {
                    const findFirstVisibleRow = () => {
                        const cell = this.gridApi.getFocusedCell();
                        if (cell) {
                            const viewportHeight = this.viewport.offsetHeight;
                            let previousRow, i, cellRow,
                                viewportScrollTop = this.viewport.scrollTop;

                            cellRow = this.gridApi.getDisplayedRowAtIndex(cell.rowIndex);

                            if (cellRow && (cellRow.rowTop > viewportHeight + viewportScrollTop || cellRow.rowTop < viewportScrollTop)) {
                                this._setFocusedCell(cell.rowIndex, cell.column.colId, 'top');
                                viewportScrollTop = this.viewport.scrollTop;
                            }

                            for (i = 1; i < rowCount; i++) {
                                previousRow = this.gridApi.getDisplayedRowAtIndex(cell.rowIndex - i);
                                if (previousRow && previousRow.rowIndex >= 0) {
                                    if (previousRow.rowTop <= viewportScrollTop) break;
                                } else {
                                    i = cell.rowIndex;
                                    break;
                                }
                            }
                            return cell.rowIndex - i;
                        } else {
                            return 0;
                        }
                    }

                    let previousRowIdx = findFirstVisibleRow();
                    this._setFocusedCell(previousRowIdx, lastFocusedCell.column.colId, 'bottom');

                    previousRowIdx = findFirstVisibleRow() + 1;
                    if (previousRowIdx == 1) previousRowIdx = 0;
                    this._setFocusedCell(previousRowIdx, lastFocusedCell.column.colId, 'top');
                }
            }
        }
    }

    resetAllFilter() {
        this._resetAllFilter();
    }

    resetAllSort() {
        this._resetAllSort();
    }

    setFilterModel(model = null) {
        this._setFilterModel(model);
    }

    setFocusOnCell(rowIndex, column, position = null) {
        this._setFocusedCell(rowIndex, column.colId, position);
    }

    refresh(refreshCells = false) {
        this._refreshGrid(refreshCells);
    }

    reload() {
        this._reloadGrid();
    }

    getSelectedRows() {
        return this._getSelectedRows();
    }

    selectRow(rowIndex) {
        this._selectRow(rowIndex);
    }

    deselectRow(rowIndex) {
        this._deselectRow(rowIndex);
    }

    selectAllRows() {
        this._selectAllRows();
    }

    deselectAllRows() {
        this._deselectAllRows();
    }

    getFocusedCell() {
        return this._getFocusedCell();
    }

    init() {
        if (!this.disconnected) {
            Promise.all([waitForPropertyReady('agGrid'), this.textsReady]).then(() => {
                this.sigSetTimeout(() => {
                    this._init();
                }, 0);
            }).catch(error => {
                log.error(error);
            });
        }
    }

    destroy(resetDefaults = false) {
        this._destroyGrid(resetDefaults);
    }

    restoreFocus() {
        this._restoreFocus();
    }

    getViewportPixelRangeBounds() {
        return this._getViewportPixelRangeBounds();
    }

    _observeScrollbars() {
        const scrollbarX = this.shadowRoot.querySelector('.' + this.scrollbarXElementClass);
        if (scrollbarX instanceof Element) this.scrollbarXObserver.observe(scrollbarX);
        const scrollbarY = this.shadowRoot.querySelector('.' + this.scrollbarYElementClass);
        if (scrollbarY instanceof Element) this.scrollbarYObserver.observe(scrollbarY);
    }

    _unobserveScrollbars() {
        this.scrollbarXObserver.disconnect();
        this.scrollbarYObserver.disconnect();
    }

    _detectScrollbarX(entries) {
        if (!entries && !entries.length) return;
        const target = entries[0].target
        const rect = entries[0].contentRect;
        const size = (this.gridOptionsMerged && this.gridOptionsMerged.scrollbarWidth) ? this.gridOptionsMerged.scrollbarWidth : 0;
        if (target.classList.contains(this.scrollbarXElementClass)) {
            this.hasScrollX = (rect.height === size) ? true : false;
        }
    }

    _detectScrollbarY(entries) {
        if (!entries && !entries.length) return;
        const target = entries[0].target
        const overflowY = window.getComputedStyle(target).overflowY;
        const disabledValues = ['hidden', 'visible', 'overlay', 'unset', 'revert', 'inital'];
        const enabledValues = ['scroll'];
        if (disabledValues.includes(overflowY)) {
            this.hasScrollY = false;
            return;
        }
        if (enabledValues.includes(overflowY)) {
            this.hasScrollY = true;
            return;
        }
        if (target.classList.contains(this.scrollbarYElementClass)) {
            this.hasScrollY = (target.scrollHeight - target.offsetHeight !== 0) ? true : false;
        }
    }
}
customElements.define(LasalRuntimeSigControlListviewAg.is, LasalRuntimeSigControlListviewAg);