// 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';
//ColorpickerBase with functionality shared by all colorpickers
import LasalRuntimeSigControlColorpickerBase from './sig-control-colorpicker-base.js';
/****************************************************************************************************
 * @class LasalRuntimeSigControlColorpickerBarArea
 * @extends {LasalRuntimeSigControlColorpickerBase}
 ****************************************************************************************************/
export class LasalRuntimeSigControlColorpickerBarArea extends LasalRuntimeSigControlColorpickerBase {
    
    /****************************************************************************************************
     * 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
     * 
     * @readonly
     * @static
     ****************************************************************************************************/
    static get importMeta() {
        return import.meta;
    }

    /****************************************************************************************************
     * Return the component style and template as a template literal
     *
     * @readonly
     * @static
     ****************************************************************************************************/
    static get template() {
        return SigPolymer.html`
        <style include="sig-element-css">
            :host {
                /* Basic styling of the component */
                color: var(--theme-sig-control-colorpicker-bar-area-color, inherit);
                background-color: var(--theme-sig-control-colorpicker-bar-area-background-color, transparent);
                border-width: var(--theme-sig-control-colorpicker-bar-area-border-width, inherit);
                border-color: var(--theme-sig-control-colorpicker-bar-area-border-color, inherit);
                border-style: var(--theme-sig-control-colorpicker-bar-area-border-style, none);
                border-radius: var(--theme-sig-control-colorpicker-bar-area-border-radius, none);

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

                height: auto;
                width: auto;

                z-index: 7;
            }

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

            .clearfix:after {
                @apply --clearfix
            }

            .sig-control-colorpicker-bar-area {
                box-sizing: border-box;
                height: 100%;
                width: 100%;
                position: relative;
                border-width: var(--theme-sig-control-colorpicker-picker-border-width, 0px);
                border-style: var(--theme-sig-control-colorpicker-picker-border-style, none);
                border-color: var(--theme-sig-control-colorpicker-picker-border-color, transparent);
                border-radius: var(--theme-sig-control-colorpicker-picker-border-radius, 3px);
                background-color: var(--theme-sig-control-colorpicker-picker-background-color, rgba(255,255,255,1));
                padding-left: 10px;
                padding-right: 10px;
            }

            #colorSelectArea {
                display: flex;
                flex-wrap: wrap;
                justify-content: space-evenly;
                margin: auto;
            }

            .color {
                height: 30px;
                width: 50px;
                box-sizing: border-box;
                border: 1px solid black;
                margin: 1px
            }

            sig-control-input,
            sig-control-button {
                --theme-sig-element-top: 0;
                --theme-sig-element-left: 0;
                display: inline-block;
                position: relative;
            }

            sig-control-input {
                --theme-sig-element-height: var(--theme-sig-control-colorpicker-picker-input-height, 35px);
                --theme-sig-element-width: var(--theme-sig-control-colorpicker-picker-input-width, 80px);
                --theme-sig-control-input-background-color: var(--theme-sig-control-colorpicker-picker-input-background-color, rgba(255, 255, 255, 1));
                /*--theme-sig-control-input-value-background-color: var(--theme-sig-control-colorpicker-picker-input-value-background-color, rgba(215, 215, 215, 1));*/
                --theme-sig-control-input-value-active-color: var(--theme-sig-control-colorpicker-picker-input-value-active-color, rgba(40,50,45,1));
                --theme-sig-control-input-value-active-background-color: var(--theme-sig-control-colorpicker-picker-input-value-active-background-color, rgba(174, 200, 26, 1));
                --theme-sig-control-input-color: var(--theme-sig-control-colorpicker-picker-input-color, rgba(40,50, 45, 1));
                --theme-sig-control-input-border-color: var(--theme-sig-control-colorpicker-picker-input-border-color, rgba(40,50,45, 1));
                --theme-sig-control-input-border-width: var(--theme-sig-control-colorpicker-picker-input-border-width, 1px);
                --theme-sig-control-input-border-style: var(--theme-sig-control-colorpicker-picker-input-border-style, solid);
                --theme-sig-control-input-background-color-direction: var(--theme-sig-control-colorpicker-picker-input-background-color-direction, to bottom);
                --theme-sig-control-input-value-active-background-color-stop: var(--theme-sig-control-colorpicker-picker-input-value-active-background-color-stop
                    /* , rgba(174, 200, 26, 1) */
                    );
                --theme-sig-control-input-active-background-color-direction: var(--theme-sig-control-colorpicker-picker-input-active-background-color-direction, to bottom);
                --theme-sig-control-input-border-radius: var(--theme-sig-control-colorpicker-picker-input-border-radius, 3px);
                --theme-sig-control-input-border-color-direction: var(--theme-sig-control-colorpicker-picker-input-border-color-direction, to bottom);
                --theme-sig-control-input-shadow-size: var(--theme-sig-control-colorpicker-picker-input-shadow-size, 0px);
                --theme-sig-control-input-activ-border-color: var(--theme-sig-control-colorpicker-picker-input-activ-border-color
                    /* , inherit */
                    );
                --theme-sig-control-input-activ-border-color-direction: var(--theme-sig-control-colorpicker-picker-input-activ-border-color-direction, to bottom);
                --theme-sig-control-input-pressed-shadow-size: var(--theme-sig-control-colorpicker-picker-input-pressed-shadow-size, 0px);
                --theme-sig-control-input-value-text-align: var(--theme-sig-control-colorpicker-picker-input-value-text-align, center);
                --theme-sig-control-input-margin-leftright: var(--theme-sig-control-colorpicker-picker-input-margin-leftright, 0px);
                --theme-sig-control-input-margin-top: var(--theme-sig-control-colorpicker-picker-input-margin-top, 5px);
                --theme-sig-control-input-unit-text-align: var(--theme-sig-control-colorpicker-picker-input-unit-text-align, center);
                --theme-sig-control-input-unit-margin-leftright: var(--theme-sig-control-colorpicker-picker-input-unit-margin-leftright, 0px);
                --theme-sig-control-input-unit-margin-bottom: var(--theme-sig-control-colorpicker-picker-input-unit-margin-bottom, 5px);
                --theme-sig-control-input-unit-text-size: var(--theme-sig-control-colorpicker-picker-input-unit-text-size, inherit);
                --theme-sig-control-input-unit-color: var(--theme-sig-control-colorpicker-picker-input-unit-color, inherit);
            }
            #hexcontainer sig-control-input {
                --theme-sig-element-width: var(--theme-sig-control-colorpicker-picker-hex-input-width, var(--theme-sig-control-colorpicker-picker-input-width, 80px));
            }

            #colorpickermarker1 {
                position: absolute;
                box-sizing: border-box;
                background-color: blue;
                top: 0;
                left: 0;
                transform: translate3d(calc(0px - 50%), 0, 0);
                width: var(--theme-sig-control-colorpicker-bar-area-marker-width, 20px);
                height: var(--theme-sig-control-colorpicker-bar-area-marker-height, 20px);
                border: 1px solid black;
                border-radius: var(--theme-sig-control-colorpicker-picker-marker-border-radius, 500px);
            }

            #colorpickermarker2 {
                position: absolute;
                box-sizing: border-box;
                background-color: blue;
                top: 0;
                left: 0;
                transform: translate3d(calc(0px - 50%), 0, 0);
                width: var(--theme-sig-control-colorpicker-bar-area-marker-width, 20px);
                height: var(--theme-sig-control-colorpicker-bar-area-marker-height, 20px);
                border: 1px solid black;
                border-radius: var(--theme-sig-control-colorpicker-picker-marker-border-radius, 500px);
            }

            #colorSelectArea {
                position: relative;
            }

            #canvas {
                position: absolute;
            }

            .hidden {
                display: none;
            }

            sig-control-button {
                margin-right: var(--theme-sig-control-colorpicker-picker-button-spacing, 10px) !important;
                --theme-sig-element-height: var(--theme-sig-control-colorpicker-picker-button-height, 50px);
                --theme-sig-element-width: var(--theme-sig-control-colorpicker-picker-button-width, 100px);
                --theme-sig-control-button-color: var(--theme-sig-control-colorpicker-picker-button-color, rgba(255, 255, 255, 1));
                --theme-sig-control-button-background-color: var(--theme-sig-control-colorpicker-picker-button-background-color, rgba(40, 50, 45, 1));
                --theme-sig-control-button-border-color: var(--theme-sig-control-colorpicker-picker-button-border-color, transparent);
                --theme-sig-control-button-border-width: var(--theme-sig-control-colorpicker-picker-button-border-width, 0px);
                --theme-sig-control-button-border-radius: var(--theme-sig-control-colorpicker-picker-button-border-radius, 3px);
                --theme-sig-control-button-border-style: var(--theme-sig-control-colorpicker-picker-button-border-style, none);
                --theme-sig-control-button-pressed-background-color: var(--theme-sig-control-colorpicker-picker-button-pressed-background-color, rgba(174, 200, 26, 1));
                --theme-sig-control-button-pressed-color: var(--theme-sig-control-colorpicker-picker-button-pressed-color, rgba(255, 255, 255, 1));
                --theme-sig-control-button-background-color-direction: var(--theme-sig-control-colorpicker-picker-button-background-color-direction, to bottom);
                --theme-sig-control-button-border-color-direction: var(--theme-sig-control-colorpicker-picker-button-border-color-direction, to bottom);
                --theme-sig-control-button-shadow-size: var(--theme-sig-control-colorpicker-picker-button-shadow-size, 0px);
                --theme-sig-control-button-text-align: var(--theme-sig-control-colorpicker-picker-button-text-align, center);
                --theme-sig-control-button-vertical-align: var(--theme-sig-control-colorpicker-picker-button-vertical-align, middle);
                --theme-sig-control-button-background-image: var(--theme-sig-control-colorpicker-picker-button-background-image, none);
                --theme-sig-control-button-background-repeat: var(--theme-sig-control-colorpicker-picker-button-background-repeat, no-repeat);
                --theme-sig-control-button-background-position-x: var(--theme-sig-control-colorpicker-picker-button-background-position-x, center);
                --theme-sig-control-button-background-position-y: var(--theme-sig-control-colorpicker-picker-button-background-position-y, center);
                --theme-sig-control-button-background-size: var(--theme-sig-control-colorpicker-picker-button-background-size, cover);
                --theme-sig-control-button-pressed-background-color-direction: var(--theme-sig-control-colorpicker-picker-button-pressed-background-color-direction, to bottom);
                --theme-sig-control-button-pressed-background-image: var(--theme-sig-control-colorpicker-picker-button-pressed-background-image, inherit);
                --theme-sig-control-button-pressed-border-color-direction: var(--theme-sig-control-colorpicker-picker-button-pressed-border-color-direction, to bottom);
                --theme-sig-control-button-pressed-shadow-size: var(--theme-sig-control-colorpicker-picker-button-pressed-shadow-size, 0px);
                --theme-sig-control-led-width: 10px;
                --theme-sig-control-led-height: 10px;
                --theme-sig-control-button-led-border-width: var(--theme-sig-control-colorpicker-picker-button-led-border-width, 1px);
                --theme-sig-control-button-led-border-color: var(--theme-sig-control-colorpicker-picker-button-led-border-color, rgba(0, 0, 0, 0));
                --theme-sig-control-button-led-border-radius: var(--theme-sig-control-colorpicker-picker-button-led-border-radius, 5px);
                --theme-sig-control-button-led-background-color: var(--theme-sig-control-colorpicker-picker-button-led-background-color, #ccc);
                --theme-sig-control-button-led-background-image: var(--theme-sig-control-colorpicker-picker-button-led-background-image, none);
                --theme-sig-control-button-led-pressed-background-color: var(--theme-sig-control-colorpicker-picker-button-led-pressed-background-color, #070);
                --theme-sig-control-button-led-pressed-background-image: var(--theme-sig-control-colorpicker-picker-button-led-pressed-background-image, none);
                --theme-sig-control-button-led-background-size: var(--theme-sig-control-colorpicker-picker-button-led-background-size, cover);
                --theme-sig-control-button-led-background-repeat: var(--theme-sig-control-colorpicker-picker-button-led-background-repeat, no-repeat);
                --theme-sig-control-button-led-margin-height: var(--theme-sig-control-colorpicker-picker-button-led-margin-height, 3px);
                --theme-sig-control-button-led-margin-width: var(--theme-sig-control-colorpicker-picker-button-led-margin-width, 3px);
            }

            sig-control-button:last-child {
                margin-right: 0 !important;
            }

            .table-cell label {
                color: var(--theme-sig-control-colorpicker-picker-label-color, rgba(40, 50, 45, 1));
                margin-right: var(--theme-sig-control-colorpicker-picker-label-margin, 5px);
            }

            .table-cell {
                box-sizing: border-box;
                display: inline-flex;
                width: 33%;
                justify-content: flex-end;
                align-items: center;
            }
            #hexcontainer .table-cell {
                width:100%;
            }

            #canvasContainer {
                position: relative;
                width: 100%;
                top: 50%;
                transform: translateY(-50%);
            }

            #controlButtons {
                white-space: nowrap;
            }
            #colorinputs {
                margin-bottom: var(--theme-sig-control-colorpicler-picker-colorinputs-margin-bottom, 10px);
            }
            #rgbcontainer,
            #hexcontainer, 
            #hslcontainer {
                white-space: nowrap;
                display: flex;
                justify-content: flex-end;
            }
        </style>
        <div class="sig-control-colorpicker-bar-area clearfix">
            <div id="colorSelectArea"></div>
            <div id="colorinputs">
                <div id="rgbcontainer">
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="rgbred" type="numeric" limit-low="0" limit-high="255"></sig-control-input>
                    </div>
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="rgbgreen" type="numeric" limit-low="0" limit-high="255"></sig-control-input>
                    </div>
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="rgbblue" type="numeric" limit-low="0" limit-high="255"></sig-control-input>
                    </div>
                </div>
                <div id="hslcontainer">
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="hslhue"  type="numeric" limit-low="0" limit-high="360"></sig-control-input>
                    </div>
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="hslsaturation" type="numeric" limit-low="0" limit-high="1"></sig-control-input>
                    </div>
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="hslvalue" type="numeric" limit-low="0" limit-high="1"></sig-control-input>
                    </div>
                </div>
                <div id="hexcontainer">
                    <div class="table-cell">
                        <label></label>
                        <sig-control-input id="hexr" type="hex" limit-low="0" limit-high="255"></sig-control-input>
                    </div>
                </div>
            </div>
            <div id="controlButtons">
                <sig-control-button id="OK"></sig-control-button>
                <sig-control-button id="CANCEL"></sig-control-button>
                <sig-control-button id="SHOWCOLORINPUTS"></sig-control-button>
            </div>
        </div>
        `;
    }

    /****************************************************************************************************
     * define the custom tag name
     *
     * @readonly
     * @static
     ****************************************************************************************************/
    static get is() {
        return "sig-control-colorpicker-bar-area";
    }

    /****************************************************************************************************
     * Called when the element has been created,
     * but before property values are set and local DOM is initialized.
     *Creates an instance of LasalRuntimeSigControlColorpickerBarArea.
     ****************************************************************************************************/
    constructor() {
        super();
        this.grid = null;
        this.colorinputs = null;
        this.busy = false;
        this.parent = null;
        this.canvasContext = null;
        this.marker = null;
        this.mousedown = false;


        this.areaCanvas = null;
        this.barCanvas = null;

        this.areaCanvasContext = null;
        this.barCanvasContext = null;

        this.areaMarker = null;
        this.barMarker = null;

        this.areaOffset = undefined;
        this.barOffset = undefined;

        this.queue = [];
        this.queueBusy = false;


        this.colormap = [];
        this.colorhash = {};

        this.options = {};
    }

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

    /****************************************************************************************************
     * Handles clicks on the ok button
     ****************************************************************************************************/
    _okButtonPointerdownHandler() {
        this.parent.showvalue = this.value;
        this.parent.markerpos.colorpicker1act = this.parent.markerpos.colorpicker1last;
        this.parent.markerpos.colorpicker2act = this.parent.markerpos.colorpicker2last;
        this.parent._closeColorpicker();
    }

    /****************************************************************************************************
     * Fills the Grid with colors
     * @returns
     ****************************************************************************************************/
    _buildColorSelectArea() {
        this.colors = this.options.colors;
        const areaContainer = this.$.colorSelectArea;
        // Make sure container is empty
        areaContainer.innerHTML = '';
        //Set colorSelectArea dimensions
        const areaContainerHeight = this._calculateHeightForColorSelectArea();
        areaContainer.style.height = areaContainerHeight + 'px';
        areaContainer.style.width = this.options.trackwidth + 'px';
        areaContainer.style.paddingTop = `${this.options.areapaddingtop}px`;
        areaContainer.style.paddingBottom = `${this.options.areapaddingbottom}px`;

        //Build the bar
        const barHeight = Math.max(this.options.markerheight, this.options.trackheight);
        let bar = this._buildBar(barHeight);
        bar.style.paddingTop = `${this.options.barpaddingtop}px`;

        //Add bar to the container
        areaContainer.appendChild(bar);
        //const barBounds = this.getControlBounds(bar)
        //Calculate the remaining height for the area
        const areaHeight = areaContainerHeight - bar.offsetHeight - this.options.areapaddingbottom - this.options.areapaddingtop;
        //build the areae
        let area = this._buildArea(areaHeight);
        this._drawArea(this.areaCanvas);

        //Event Listeners for area, and bar
        this._addEventListenersArea(area);
        this._addEventListerersBar(bar);

        //Insert the area before the bar
        //It's esier to position them that way
        areaContainer.insertBefore(area, bar);

        return areaContainer;
    }

    /****************************************************************************************************
     * Adds the eventListeners that are needed for the area
     * @param {*} area
     ****************************************************************************************************/
    _addEventListenersArea(area) {

        this.sigAddEventListener('down', (e) => {
            
            //   areaOffset only needs to be calculated only in the down Handler
            //   since that is where all interaction starts
             
            this.areaOffset = area.getBoundingClientRect();

            this._convertGestureEventCoordsToUseableCoords(e, this.areaOffset);
            this.areapointerdownhandler(e);
        }, 'polymerEvent', area);

        this.sigAddEventListener('track', (e) => {
            this._convertGestureEventCoordsToUseableCoords(e, this.areaOffset);
            this.areapointermovehandler(e);
        }, 'polymerEvent', area);

        this.sigAddEventListener('up', (e) => {
            this._convertGestureEventCoordsToUseableCoords(e, this.areaOffset);
            this.areapointeruphandler(e);
        }, 'polymerEvent', area);

    }

   
    /****************************************************************************************************
     * Adds the eventListeners that are needed for the bar
     * @param {*} bar
     ****************************************************************************************************/
    _addEventListerersBar(bar) {

        this.sigAddEventListener('down', (e) => {
            
            //   barOffset only needs to be calculated only in the down Handler
            //   since that is where all interaction starts
             
            this.barOffset = bar.getBoundingClientRect();

            this._convertGestureEventCoordsToUseableCoords(e, this.barOffset);
            this.barpointerdownhandler(e);
        }, 'polymerEvent', bar);

        this.sigAddEventListener('track', (e) => {
            this._convertGestureEventCoordsToUseableCoords(e, this.barOffset);
            this.barpointermovehandler(e);
        }, 'polymerEvent', bar);
        this.sigAddEventListener('up', (e) => {
            this._convertGestureEventCoordsToUseableCoords(e, this.barOffset);
            this.barpointeruphandler(e);
        }, 'polymerEvent', bar);
    }

    /****************************************************************************************************
     * Sig element function
     ****************************************************************************************************/
    connectedCallback() {
        super.connectedCallback();
        const areaContainer = this.$.colorSelectArea.querySelector('#areaContainer');
        const barContainer = this.$.colorSelectArea.querySelector('#barContainer');
        if (!this.isdesignmode && areaContainer && barContainer) {
            this._addEventListenersArea(areaContainer);
            this._addEventListerersBar(barContainer);
        }
    }

    /****************************************************************************************************
     * Handles the pointerdown event
     * @param {*} e
     ****************************************************************************************************/
    barpointerdownhandler(e) {
        this.sigPreventDefault(e);
        this.mousedown = true;
        this._setColorBar(e);
    }

    /****************************************************************************************************
     * Handles the pointerup event
     * @param {*} e
     ****************************************************************************************************/
    barpointeruphandler(e) {
        this.sigPreventDefault(e);
        this.mousedown = false;
    }

    /****************************************************************************************************
     * Handles the pointermove event
     * @param {*} e
     ****************************************************************************************************/
    barpointermovehandler(e) {
        this.sigPreventDefault(e);
        if (!this.mousedown) {
            return
        }

        this._setColorBar(e);
    }

    /****************************************************************************************************
     * Handles the pointerdown event
     * @param {*} e
     ****************************************************************************************************/
    areapointerdownhandler(e) {
        this.sigPreventDefault(e);
        this.mousedown = true;
        this._setColor(e);
    }

    /****************************************************************************************************
     * Handles the pointerup event
     * @param {*} e
     ****************************************************************************************************/
    areapointeruphandler(e) {
        this.sigPreventDefault(e);
        this.mousedown = false;
    }


    /****************************************************************************************************
     * Handles the pointermove event
     * @param {*} e
     ****************************************************************************************************/
    areapointermovehandler(e) {
        this.sigPreventDefault(e);
        if (!this.mousedown) {
            return
        }

        this._setColor(e);
    }

    /****************************************************************************************************
     * returns the bar container with the bar
     * @param {*} height
     * @returns
     ****************************************************************************************************/
    _buildBar(height) {
        //breate the barContainer
        const barContainer = this._createElement('div');
        //Set its dimensions
        barContainer.style.height = height + 'px';
        barContainer.style.width = this.options.trackwidth + 'px';
        barContainer.style.position = 'relative';
        barContainer.style.display = 'block';
        barContainer.style.width = '100%';
        barContainer.id = 'barContainer';

        //Create the bar canvas
        const barCanvas = this._createElement('canvas');
        //set the canvas dimensions
        barCanvas.height = height;
        barCanvas.width = this.options.trackwidth;
        barCanvas.style.display = 'block';
        barCanvas.style.borderRadius = '100px';

        //Create the bar markers
        const barMarker = this._createElement('div', 'colorpickermarker1');
        //Set the marker styles
        this._styleMarker(barMarker);
        barMarker.style.transform = 'translateX(-50%)';

        //draw the gradient for the nar
        const barCanvasContext = barCanvas.getContext('2d');
        const barCanvasGradient = barCanvasContext.createLinearGradient(0, 0, this.options.trackwidth, 0);

        //add a colorStop for each color in the colorscheme
        if (this.isdesignmode) {
            barCanvasGradient.addColorStop(0, '#000');
            barCanvasGradient.addColorStop(1, '#fff');
        } else {
            for (let i = 0; i < this.colors.length; i += 1) {
                let stop = i / (this.colors.length - 1)
                barCanvasGradient.addColorStop(stop, this.colors[i]);
            }
        }


        //Fill the canvas with the gradient
        barCanvasContext.fillStyle = barCanvasGradient;
        barCanvasContext.fillRect(0, 0, this.options.trackwidth, height);

        //Add the canvas and the marker to the barContainer
        barContainer.appendChild(barCanvas);
        barContainer.appendChild(barMarker);

        //Set the variables to be able to access them in other functions
        this.barCanvas = barCanvas;
        this.barCanvasContext = barCanvasContext;
        this.barMarker = barMarker;
        return barContainer;
    }

    /****************************************************************************************************
     * returns the container with the area
     * @param {*} height
     * @returns
     ****************************************************************************************************/
    _buildArea(height) {
        //Create the areaContainer, and set its dimensions
        const areaContainer = this._createElement('div');
        areaContainer.height = height + 'px';
        areaContainer.width = this.options.trackwidth + 'px';
        areaContainer.style.position = 'relative';
        areaContainer.style.display = 'block';
        areaContainer.style.width = '100%';
        areaContainer.id = 'areaContainer';

        // create the areaCamvas and set its dimensions
        const areaCanvas = this._createElement('canvas');
        areaCanvas.height = height;
        areaCanvas.width = this.options.trackwidth;
        areaCanvas.style.display = 'block';

        // Create the marker and set its dimensions
        const areaMarker = this._createElement('div', 'colorpickermarker2');
        this._styleMarker(areaMarker);
        areaMarker.style.transform = 'translate3d(-50%, -50%, 0)';

        // Add the canvas and the marker to the 
        areaContainer.appendChild(areaCanvas);
        areaContainer.appendChild(areaMarker);
        this.areaCanvas = areaCanvas;

        let areaCanvasContext = this.areaCanvas.getContext('2d');
        this.areaCanvasContext = areaCanvasContext;
        this.areaMarker = areaMarker;
        return areaContainer;
    }

    /****************************************************************************************************
     * sets the marker styles
     * is it's own function here, because we have two markers to style
     * @param {*} marker
     ****************************************************************************************************/
    _styleMarker(marker) {
        marker.style.width = this.options.markerwidth + 'px';
        marker.style.height = this.options.markerheight + 'px';
        marker.style.position = 'absolute';
        marker.style.border = '1px solid black';
        marker.style.top = 0;
        marker.style.left = 0;
    }

    /****************************************************************************************************
     * Draws the area
     * Has the selected color in the top right,
     * a black gradient from the bottom
     * a white gradient from the left
     * @param {*} areaCanvas
     * @param {string} [color='rgb(255,0,0)']
     * @returns
     ****************************************************************************************************/
    _drawArea(areaCanvas, color = 'rgb(255,0,0)') {
        //If there isn't an areaCanvas, there is nothing we can do
        //return
        if (!areaCanvas) {
            return;
        }

        const areaCanvasContext = areaCanvas.getContext('2d');
        const height = areaCanvas.height;

        //The white gradient
        let gradientWhite = areaCanvasContext.createLinearGradient(0, 0, this.options.trackwidth, 0);
        gradientWhite.addColorStop(0, 'rgba(255,255,255,1)');
        gradientWhite.addColorStop(1, 'rgba(255,255,255,0)');

        //The black gradient
        let gradientBlack = areaCanvasContext.createLinearGradient(0, height, 0, 0)
        gradientBlack.addColorStop(0, 'rgba(0,0,0,1)');
        gradientBlack.addColorStop(1, 'rgba(0,0,0,0)');

        //First fill the canvas with the color
        areaCanvasContext.fillStyle = color;
        areaCanvasContext.fillRect(0, 0, this.options.trackwidth, height);

        //Then layer the black and white over it
        areaCanvasContext.fillStyle = gradientWhite;
        areaCanvasContext.fillRect(0, 0, this.options.trackwidth, height);

        areaCanvasContext.fillStyle = gradientBlack;
        areaCanvasContext.fillRect(0, 0, this.options.trackwidth, height);
    }

    /****************************************************************************************************
     * Sets the marker to the position where the event occured
     * sets the input values to the new color
     * @param {*} e
     * @returns
     ****************************************************************************************************/
    _setColor(e) {
        if (!this.areaCanvasContext) {
            return;
        }
       
        //Get Pos
        let pos = {};
        let x = e.offsetX;
        let y = e.offsetY - this.options.areapaddingtop;

        pos.x = String(x);
        pos.y = String(y);

        if (pos.x > Number(this.areaCanvas.width) || pos.x < 0) {
            return;
        }
        if (pos.y > (Number(this.areaCanvas.height) - Number(this.options.areapaddingtop)) || pos.y < (0 - Number(this.options.areapaddingtop))) {
            return;
        }
        this.parent.markerpos.colorpicker1last = pos;
        //change c1 color on click
        let colorCanv = this.areaCanvasContext.getImageData(pos.x, Number(pos.y) + Number(this.options.areapaddingtop), 1, 1).data.slice(0,4);
        let color = this._getRGBA(colorCanv);
        this._updateInputs(colorCanv);

        //Move Marker
        this.areaMarker.style.transform = 'translate3d(-50%, -50%, 0)';
        this.areaMarker.style.top = `${Number(pos.y) + Number(this.options.areapaddingtop)}px`;
        this.areaMarker.style.left = pos.x + 'px';
        this.areaMarker.style.backgroundColor = color;

        this.areaMarker.style.backgroundColor = color;
    }

    /****************************************************************************************************
     * Sets the Color and Marker of the Bar
     * @param {*} e
     * @returns
     ****************************************************************************************************/
    _setColorBar(e) {
        if (!this.barCanvasContext || !this.areaMarker) {
            return;
        }

        // Get Pos
        let pos = {};
        let x = e.offsetX;
        let y = e.offsetY;

        pos.x = String(x);
        pos.y = String(y);

        if (pos.x > Number(this.barCanvas.width) || pos.x < 0) {
            return;
        }
        if (pos.y > (Number(this.barCanvas.height) + Number(this.options.barpaddingtop)) || pos.y < (0 + Number(this.options.barpaddingtop))) {
            return;
        }
        this.parent.markerpos.colorpicker2last = pos;
        //Get the color on the events position
        let colorCanv = this.barCanvasContext.getImageData(pos.x, pos.y - Number(this.options.barpaddingtop), 1, 1).data.slice(0,4);
        let color = this._getRGBA(colorCanv);

        //Draw the area with the new color
        this._drawArea(this.areaCanvas, color);
        //Update the area marker color
        //const areaMarkerBounds = this.getControlBounds(this.areaMarker);
        //this._setColor({ offsetX: areaMarkerBounds.left, offsetY: areaMarkerBounds.top });
        this._setColor({ offsetX: this.areaMarker.offsetLeft, offsetY: this.areaMarker.offsetTop });

        //Set the bar marker
        this.barMarker.style.transform = 'translate3d(-50%, -50%, 0)';
        //this.barMarker.style.top = `${Number(this.markerheight / 2) + Number(this.options.barpaddingtop)}px`;
        this.barMarker.style.top = `${this.barCanvas.height / 2 + Number(this.options.barpaddingtop)}px`
        this.barMarker.style.left = pos.x + 'px';
        this.barMarker.style.backgroundColor = color;

        this.barMarker.style.backgroundColor = color;
    }

    /****************************************************************************************************
      * Sets the Inputs to the parents value
     * Moves the Marker if the color can be found on the canvas
     * @param {*} value
     ****************************************************************************************************/
    _initializeOnOpen(value) {
        if (value) {
            let workVal = value;
            let offsetX = 0;
            let offsetY = 0;

            /**
             * a = b || 0 => if b is a falsey value like undefined or null, a is set to 0
             * Sets the offsetX and offsetY to either the parents markerpos or 0
             * */
            if (this.parent.markerpos.colorpicker1act) {
                offsetX = this.parent.markerpos.colorpicker1act.x || 0;
                offsetY = this.parent.markerpos.colorpicker1act.y || 0;
            }

            //Set the area marker
            this.queue.push(
                {
                    funct: '_setColor',
                    params: [
                        {
                            offsetX,
                            offsetY: Number(offsetY) + Number(this.options.areapaddingtop)
                        }]
                });
            offsetX = 0;
            offsetY = 0;

            // Sets the offsetX and offsetY to the parenst marker pos (for the bar marker), or 0
            if (this.parent.markerpos.colorpicker2act) {
                offsetX = this.parent.markerpos.colorpicker2act.x || 0;
                offsetY = this.parent.markerpos.colorpicker2act.y || 0;
            }

            //Set the bar marker
            this.queue.push(
                {
                    funct: '_setColorBar',
                    params: [
                        {
                            offsetX,
                            offsetY: Number(offsetY) + Number(this.options.areapaddingtop)
                        }]
                });
            this._doQueue();
        }
    }

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