buttons.js

import { hasValue } from './utils';
import { PLACEMENTS, BRAND_MAIN_COLOR, BRAND_SECOND_COLOR, TOOLTIP_DIRECTIONS } from './constants';
import { getIcon } from './svg-icon-service';

/**
 * @typedef {Object} ButtonOptions
 * @property {HTMLElement} targetElement - The DOM element where the button will be attached.
 * @property {boolean} [rounded=false] - Whether the button should have rounded corners.
 * @property {PLACEMENTS} [placement=PLACEMENTS.LAST] - Positioning of the button relative to the target element.
 * @property {string} [text='Visualizer Button'] - Text displayed on the button.
 * @property {string} [mainColor=BRAND_MAIN_COLOR] - Main color of the button, typically used for the background.
 * @property {string} [secondColor=BRAND_SECOND_COLOR] - Secondary color, used for text or accents.
 * @property {number} [borderSize=1] - Border width for the button, in pixels.
 * @property {SVGElement} [svgElement] - Optional SVG icon to include in the button.
 */

/**
 * @typedef {Object} TooltipOptions
 * @property {string} mainColor - HTML color cede.
 * @property {string} secondColor - HTML color code.
 * @property {TooltipDirection} [direction=WizartDeploymentKit.TOOLTIP_DIRECTION.TOP] - side where tooltip will appear.
 * @property {number} [borderSize=1] - value for border-width.
 * @property {Array<string>} [text=['Photograph your wall.', 'Choose a pattern.', 'See it in your space digitally.']] - Tooltip items text.
 */

/**
 * 
 * @class
 */
class Button {

    /**
     * @constructor
     * @param {ButtonOptions} options - The options for the Visualizer instance.
     */
    constructor({ 
        targetElement, 
        rounded=false,
        placement=PLACEMENTS.LAST,
        text = 'Visualizer',
        mainColor=BRAND_MAIN_COLOR, 
        secondColor=BRAND_SECOND_COLOR, 
        borderSize=1,
        svgElement
    } = {}) {
        const button = document.createElement('div');
        button.classList.add('wizart-button');
        button.style.borderWidth = `${borderSize}px`;

        if (rounded) {
            button.classList.add('wizart-button--rounded');
        }

        if (mainColor) {
            Button._changeColor(button, mainColor, secondColor);
        }
    
        const innerDiv = document.createElement('div');
        innerDiv.classList.add('wizart-button__layout');
        
        const img = document.createElement('span');
        if (svgElement) {
            img.innerHTML = svgElement;
        } else {
            const svg = getIcon({name: 'default', color: mainColor, size:25});
            img.innerHTML = svg;
        }
        
        img.classList.add('wizart-button__icon');
        
        const span = document.createElement('span');
        span.classList.add('wizart-button__text');
        span.textContent = text;
    
        innerDiv.appendChild(img);
        innerDiv.appendChild(span);
        button.appendChild(innerDiv);

        this._insertButton(targetElement, button, placement);

        /**
         * Link to the DOM element of button.
         * @property {HTMLElement}
         */
        this.element = button;
    }

    _insertButton(container, button, placement) {
        if (!hasValue(PLACEMENTS, placement)) {
            console.error(`Invalid placement option: ${placement}.`);
            placement = PLACEMENTS.LAST;
        }

        switch (placement) {
            case PLACEMENTS.BEFORE:
                container.parentNode.insertBefore(button, container);
                break;
            case PLACEMENTS.AFTER:
                container.parentNode.insertBefore(button, container.nextSibling);
                break;
            case PLACEMENTS.REPLACE:
                container.replaceWith(button);
                break;
            case PLACEMENTS.FIRST:
                container.insertBefore(button, container.firstChild);
                break;
            case PLACEMENTS.LAST:
            default:
                container.appendChild(button);
        }
    }

    static _changeColor(button, color, secondColor) {
        button.style.color = color;
        button.style.borderColor = color;

        if (secondColor) {
            button.style.background = secondColor;
        }
    }

    /**
     * 
     * @param {*} callback 
     */
    onClick(callback) {
        this.element.addEventListener('click', callback);
    }
}

/**
 * Creates and inserts a predefined Wizart button element into the DOM.
 * @function
 * @memberof WizartDeploymentKit
 * @param {ButtonOptions} options - The options for the Visualizer instance.
 * @returns {Button} The created button instance.
 * 
 * @example
 * const targetElement = document.getElementById('button-open');
 * const openVisualizerButton = WizartDeploymentKit.createButton({targetElement: targetElement, text: 'See product in your room'});
 * openVisualizerButton.onClick(() => visualizer.show());
 */
const createButton = ({
    targetElement, 
    rounded=false,
    placement=PLACEMENTS.LAST, 
    text='Visualizer Button',
    mainColor=BRAND_MAIN_COLOR, 
    secondColor=BRAND_SECOND_COLOR, 
    borderSize=1,
    svgElement
} = {}) => {
    const button = new Button({ targetElement, rounded, mainColor, secondColor, borderSize, text, placement, svgElement });

    return button;
};

/**
 * Adds tooltip to the button.
 * @function
 * @memberof WizartDeploymentKit
 * @param {HTMLElement} buttonElement 
 * @param {TooltipOptions} options - The tooltip settings.
 * 
 * @example
 * WizartDeploymentKit.addTooltip(openVisualizerButton.element, { direction: WizartDeploymentKit.TOOLTIP_DIRECTION.BOTTOM });
 */
const addTooltip = (buttonElement, {
    mainColor=BRAND_MAIN_COLOR, 
    secondColor=BRAND_SECOND_COLOR, 
    direction=TOOLTIP_DIRECTIONS.TOP, 
    borderSize=1,
    text=[]
}={}) => {
    buttonElement.classList.add('wizart-button--modified');
    const tooltipContainer = document.createElement('div');
    tooltipContainer.classList.add('wizart-tooltip-container');

    const tooltip = document.createElement('div');
    tooltip.classList.add('wizart-button__tooltip');
    tooltip.style.width = `${buttonElement.offsetWidth}px`;
    tooltip.style.borderWidth = `${borderSize}px`;
    tooltip.style.left = `-${borderSize}px`;

    if (mainColor) {
        tooltip.style.color = mainColor;
        tooltip.style.borderColor = mainColor;
    }

    if (secondColor) {
        tooltip.style.background = secondColor;
    }

    if (direction === TOOLTIP_DIRECTIONS.TOP) {
        tooltip.style.bottom = `${buttonElement.offsetHeight - borderSize}px`;
        tooltip.style.borderBottom = 'none';
    } else {
        tooltip.style.top = `${buttonElement.offsetHeight - borderSize}px`;
        tooltip.style.borderTop = 'none';
    }
    
    const content = [
        { icon: 'makePhoto', text: text[0] || 'Photograph your wall.' },
        { icon: 'selectProduct', text: text[1] || 'Choose a pattern.' },
        { icon: 'seeInRoom', text: text[2] || 'See it in your space digitally.' }
    ];
    
    content.forEach(item => {
        const line = document.createElement('div');
        line.classList.add('wizart-button__tooltip-content');
        
        const svg = getIcon({name: item.icon, color: mainColor, size:25});
        const icon = document.createElement('div');
        icon.classList.add('wizart-button__tooltip-icon');
        icon.innerHTML = svg;
        
        const text = document.createElement('span');
        text.classList.add('wizart-button__tooltip-text');
        text.textContent = item.text;
        
        line.appendChild(icon);
        line.appendChild(text);
        tooltip.appendChild(line);
        tooltipContainer.append(tooltip);
    });
    
    buttonElement.appendChild(tooltipContainer);
};

export {
    createButton,
    addTooltip
};