<template>
    <div :class="bem()">
        <PxColorPaletteButton @click="click" :hsva="hsva" :selected="selected" :pending="pending">
            <PxIcon :class="bem('icon')" v-bind="calcIconAttrs" :style="{ color: calcIconColor }" />
        </PxColorPaletteButton>
        <PxFloat
            :popupClass="bem('popup')"
            v-model:visible="popupVisible"
            variant="none"
            placement="bottom-center"
        >
            <PxColorPanel
                :class="bem('panel')"
                :color="hsva"
                :alphaEnabled="alphaEnabled"
                :eyedropperEnabled="eyedropperMode === 'popup'"
                format="hsva"
                @change="panelColorChange"
            ></PxColorPanel>
        </PxFloat>
    </div>
</template>

<script>
import PxFloat from './PxFloat.vue';
import PxColorPanel from './PxColorPanel.vue';
import PxColorPaletteButton from './PxColorPaletteButton.vue';
import PxBaseColor from '../bases/PxBaseColor.vue';
import propsFilter from '../utils/propsFilter.js';
import { PxIcon, PxIconSrcOrAttrs } from './PxIcon.vue';
import EyeDropperSvg from '../assets/icons/eyedropper.svg?url';
import EllipsisSvg from '../assets/icons/ellipsis.svg?url';

const PxColorPicker = {
    name: 'px-color-picker',
    components: { PxFloat, PxColorPanel, PxColorPaletteButton, PxIcon },
    mixins: [PxBaseColor],
    emits: ['click'],
    props: {
        /**
         * An icon to display inside the button. If a string is provided, it will be interpreted as
         * the src of the icon. If an object is provided, it will be passed directly to the icon
         * component as props (with a filter applied to ensure no fallback attributes).
         */
        icon: { type: [String, Object], default: null },

        /**
         * Convenience prop for setting the icon if the icon prop hasn't been set. Allowed values
         * are 'eyedropper' and 'ellipsis'.
         */
        iconFallback: { type: String, default: null },

        /**
         * Describes how to integrate the eyedropper into the color picker. Allowed values are:
         *  'none' - don't show the eyedropper
         *  'popup' - show the eyedropper in the popup
         *  'only' - only show the eyedropper (instead of the standard dialog)
         */
        eyedropperMode: { type: String, default: 'none' },

        /**
         * Makes the color picker appear selected (passed to the PxColorPaletteButton component)
         */
        selected: { type: Boolean, default: false },

        /**
         * Gives the color picker a pending appearance (passed to the PxColorPaletteButton component)
         */
        pending: { type: Boolean, default: false },
    },
    data() {
        return { popupVisible: false };
    },
    computed: {
        calcIconAttrs() {
            if (this.icon) {
                return PxIconSrcOrAttrs(this.icon);
            } else if (this.iconFallback) {
                switch (this.iconFallback) {
                    case 'eyedropper':
                        return { src: EyeDropperSvg, size: 0.9 };
                    case 'ellipsis':
                        return { src: EllipsisSvg };
                }
            }
        },
        calcIconColor() {
            if (this.pending) {
                return null;
            }
            return this.contrastStr;
        },
    },
    // watch: {},
    // mounted() {},
    methods: {
        panelColorChange(hsva) {
            this.setColorHsva(hsva);
        },
        click() {
            this.$emit('click');
            if (this.eyedropperMode === 'only') {
                this.setColorFromEyedropper();
            } else {
                this.popupVisible = true;
            }
        },
    },
};

// helper function that filters out props that are not defined in the component when using v-bind to
// set PxColorFilter props
function PxColorPickerPropsFilter(attrs) {
    return propsFilter(PxColorPicker)(attrs);
}

// defaut export
export default PxColorPicker;

// named exports
export { PxColorPicker, PxColorPickerPropsFilter };
</script>

<style lang="scss">
@use '../styles/px.scss' as *;

@at-root {
    :root {
        --px-color-picker-popup-bg: #{clr(page-bg)};
    }
}
.px-color-picker {
    &__panel {
        width: 10em;
    }

    &__popup {
        padding: 0.66em;
        border-radius: 0.75em;

        background-color: var(--px-color-picker-popup-bg);
        @include depth-shadow(20, 0.15);
    }

    &__icon {
        position: relative;
        z-index: 1;
    }
}
</style>
