var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import '../buttons/tool-icon-button.js';
import '../panel/color-panel.js';
import '../panel/shape-style-panel.js';
import '../panel/shape-panel.js';
import './change-text-menu.js';
import './component-toolbar-menu-divider.js';
import { WithDisposable } from '@blockeditor/lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { ChangeShapeIcon, GeneralStyleIcon, LineStyleIcon, ScribbledStyleIcon, ShapeArrowDownSmallIcon, } from '../../../../_common/icons/index.js';
import { LineWidth } from '../../../../_common/types.js';
import { countBy, maxBy } from '../../../../_common/utils/iterable.js';
import { CanvasTextFontFamily } from '../../../../surface-block/consts.js';
import { FILL_COLORS, ShapeType, STROKE_COLORS, } from '../../../../surface-block/elements/shape/consts.js';
import { ShapeStyle, StrokeStyle, } from '../../../../surface-block/index.js';
import { SHAPE_FILL_COLOR_BLACK, SHAPE_TEXT_COLOR_PURE_BLACK, SHAPE_TEXT_COLOR_PURE_WHITE, } from '../../utils/consts.js';
import { lineSizeButtonStyles } from '../buttons/line-size-button.js';
import { GET_DEFAULT_LINE_COLOR, isTransparent } from '../panel/color-panel.js';
import { ColorUnit } from '../panel/color-panel.js';
import { LineStylesPanel, lineStylesPanelStyles, } from '../panel/line-styles-panel.js';
import { createButtonPopper } from '../utils.js';
const ICON_BUTTON_PADDING_TWO = 2;
function getMostCommonShape(elements) {
    const shapeTypes = countBy(elements, (ele) => {
        return ele.shapeType === 'rect' && ele.radius
            ? 'roundedRect'
            : ele.shapeType;
    });
    const max = maxBy(Object.entries(shapeTypes), ([_k, count]) => count);
    return max ? max[0] : null;
}
function getMostCommonFillColor(elements) {
    const colors = countBy(elements, (ele) => {
        return ele.filled ? ele.fillColor : '--affine-palette-transparent';
    });
    const max = maxBy(Object.entries(colors), ([_k, count]) => count);
    return max ? max[0] : null;
}
function getMostCommonStrokeColor(elements) {
    const colors = countBy(elements, (ele) => {
        return ele.strokeColor;
    });
    const max = maxBy(Object.entries(colors), ([_k, count]) => count);
    return max ? max[0] : null;
}
function getMostCommonLineSize(elements) {
    const sizes = countBy(elements, (ele) => {
        return ele.strokeWidth;
    });
    const max = maxBy(Object.entries(sizes), ([_k, count]) => count);
    return max ? Number(max[0]) : LineWidth.LINE_WIDTH_FOUR;
}
function getMostCommonLineStyle(elements) {
    const sizes = countBy(elements, (ele) => {
        switch (ele.strokeStyle) {
            case StrokeStyle.Solid: {
                return 'solid';
            }
            case StrokeStyle.Dashed: {
                return 'dash';
            }
            case StrokeStyle.None: {
                return 'none';
            }
        }
    });
    const max = maxBy(Object.entries(sizes), ([_k, count]) => count);
    return max ? max[0] : null;
}
function doesAllShapesContainText(elements) {
    return elements.every(ele => ele.text);
}
function getMostCommonShapeStyle(elements) {
    const roughnesses = countBy(elements, (ele) => {
        return ele.shapeStyle;
    });
    const max = maxBy(Object.entries(roughnesses), ([_k, count]) => count);
    return max ? max[0] : ShapeStyle.Scribbled;
}
let EdgelessChangeShapeButton = class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
    constructor() {
        super(...arguments);
        this.elements = [];
        this._showPopper = false;
        this._shapePanelPopper = null;
        this._shapeStyleMenuPopper = null;
        this._fillColorMenuPopper = null;
        this._strokeColorMenuPopper = null;
        this._lineStylesPanelPopper = null;
    }
    _getTextColor(fillColor) {
        // When the shape is filled with black color, the text color should be white.
        // When the shape is transparent, the text color should be set according to the theme.
        // Otherwise, the text color should be black.
        const textColor = isTransparent(fillColor)
            ? GET_DEFAULT_LINE_COLOR()
            : fillColor === SHAPE_FILL_COLOR_BLACK
                ? SHAPE_TEXT_COLOR_PURE_WHITE
                : SHAPE_TEXT_COLOR_PURE_BLACK;
        return textColor;
    }
    _setShapeFillColor(color) {
        const textColor = this._getTextColor(color);
        const filled = !isTransparent(color);
        this.elements.forEach(ele => {
            this.surface.updateElement(ele.id, {
                filled,
                fillColor: color,
                color: textColor,
            });
        });
    }
    _setShapeStrokeColor(color) {
        this.elements.forEach(ele => {
            this.surface.updateElement(ele.id, {
                strokeColor: color,
            });
        });
    }
    _setShapeStrokeWidth(strokeWidth) {
        this.elements.forEach(ele => {
            this.surface.updateElement(ele.id, {
                strokeWidth,
            });
        });
    }
    _setShapeStrokeStyle(strokeStyle) {
        this.elements.forEach(ele => {
            this.surface.updateElement(ele.id, {
                strokeStyle,
            });
        });
    }
    _setShapeStyles({ type, value }) {
        if (type === 'size') {
            const strokeWidth = value;
            this._setShapeStrokeWidth(strokeWidth);
        }
        else if (type === 'lineStyle') {
            switch (value) {
                case 'solid': {
                    this._setShapeStrokeStyle(StrokeStyle.Solid);
                    break;
                }
                case 'dash': {
                    this._setShapeStrokeStyle(StrokeStyle.Dashed);
                    break;
                }
                case 'none': {
                    this._setShapeStrokeStyle(StrokeStyle.None);
                    break;
                }
            }
        }
    }
    _setShapeStyle(shapeStyle) {
        this.elements.forEach(ele => {
            this.surface.updateElement(ele.id, {
                shapeStyle: shapeStyle,
                fontFamily: shapeStyle === ShapeStyle.General
                    ? CanvasTextFontFamily.Inter
                    : CanvasTextFontFamily.Kalam,
            });
        });
    }
    firstUpdated(changedProperties) {
        const _disposables = this._disposables;
        this._shapePanelPopper = createButtonPopper(this._changeShapeButton, this._shapePanel, ({ display }) => {
            this._showPopper = display === 'show';
        });
        _disposables.add(this._shapePanelPopper);
        _disposables.add(this._shapePanel.slots.select.on(shapeType => {
            const updatedProps = shapeType === 'roundedRect'
                ? { shapeType: ShapeType.Rect, radius: 0.1 }
                : { shapeType, radius: 0 };
            this.page.captureSync();
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, updatedProps);
            });
        }));
        this._fillColorMenuPopper = createButtonPopper(this._fillColorButton, this._fillColorMenu, ({ display }) => {
            this._showPopper = display === 'show';
        });
        _disposables.add(this._fillColorMenuPopper);
        this._strokeColorMenuPopper = createButtonPopper(this._strokeColorButton, this._strokeColorMenu, ({ display }) => {
            this._showPopper = display === 'show';
        });
        _disposables.add(this._strokeColorMenuPopper);
        this._lineStylesPanelPopper = createButtonPopper(this._lineStylesButton, this._lineStylesPanel, ({ display }) => {
            this._showPopper = display === 'show';
        });
        _disposables.add(this._lineStylesPanelPopper);
        this._shapeStyleMenuPopper = createButtonPopper(this._shapeStyleButton, this._shapeStyleMenu, ({ display }) => {
            this._showPopper = display === 'show';
        });
        _disposables.add(this._shapeStyleMenuPopper);
        super.firstUpdated(changedProperties);
    }
    render() {
        const selectedShape = getMostCommonShape(this.elements);
        const selectedFillColor = getMostCommonFillColor(this.elements) ?? FILL_COLORS[0];
        const selectedStrokeColor = getMostCommonStrokeColor(this.elements) ?? STROKE_COLORS[0];
        const selectedLineSize = getMostCommonLineSize(this.elements) ?? LineWidth.LINE_WIDTH_FOUR;
        const selectedLineStyle = getMostCommonLineStyle(this.elements) ?? 'solid';
        const selectedShapeStyle = getMostCommonShapeStyle(this.elements) ?? ShapeStyle.Scribbled;
        return html `
      <div class="change-shape-toolbar-container">
        <edgeless-tool-icon-button
          .tooltip=${this._showPopper ? '' : 'Switch Type'}
          .tipPosition=${'bottom'}
          .active=${false}
          .iconContainerPadding=${ICON_BUTTON_PADDING_TWO}
          @click=${() => this._shapePanelPopper?.toggle()}
        >
          <div class="change-shape-button">
            ${ChangeShapeIcon} ${ShapeArrowDownSmallIcon}
          </div>
        </edgeless-tool-icon-button>
        <edgeless-shape-panel
          .selectedShape=${selectedShape}
          .shapeStyle=${selectedShapeStyle}
        >
        </edgeless-shape-panel>

        <component-toolbar-menu-divider></component-toolbar-menu-divider>

        <edgeless-tool-icon-button
          .tooltip=${this._showPopper ? '' : 'Style'}
          .tipPosition=${'bottom'}
          .active=${false}
          .iconContainerPadding=${ICON_BUTTON_PADDING_TWO}
          @click=${() => this._shapeStyleMenuPopper?.toggle()}
        >
          <div class="shape-style-button">
            ${selectedShapeStyle === ShapeStyle.General
            ? GeneralStyleIcon
            : ScribbledStyleIcon}
            ${ShapeArrowDownSmallIcon}
          </div>
        </edgeless-tool-icon-button>
        <div class="shape-style-panel-container">
          <edgeless-shape-style-panel
            .value=${selectedShapeStyle}
            .onSelect=${(value) => {
            this._setShapeStyle(value);
        }}
          >
          </edgeless-shape-style-panel>
        </div>

        <component-toolbar-menu-divider></component-toolbar-menu-divider>

        <edgeless-tool-icon-button
          class="fill-color-button"
          .tooltip=${this._showPopper ? '' : 'Fill color'}
          .tipPosition=${'bottom'}
          .active=${false}
          .iconContainerPadding=${ICON_BUTTON_PADDING_TWO}
          @click=${() => this._fillColorMenuPopper?.toggle()}
        >
          <div class="fill-color-container">
            ${ColorUnit(selectedFillColor)}
          </div>
        </edgeless-tool-icon-button>
        <div class="color-panel-container fill-color">
          <edgeless-color-panel
            .value=${selectedFillColor}
            .options=${FILL_COLORS}
            @select=${(e) => this._setShapeFillColor(e.detail)}
          >
          </edgeless-color-panel>
        </div>

        <component-toolbar-menu-divider></component-toolbar-menu-divider>

        <edgeless-tool-icon-button
          class="stroke-color-button"
          .tooltip=${this._showPopper ? '' : 'Border color'}
          .tipPosition=${'bottom'}
          .active=${false}
          .iconContainerPadding=${ICON_BUTTON_PADDING_TWO}
          @click=${() => this._strokeColorMenuPopper?.toggle()}
        >
          <div class="stroke-color-container">
            ${ColorUnit(selectedStrokeColor, { hollowCircle: true })}
          </div>
        </edgeless-tool-icon-button>
        <div class="color-panel-container stroke-color">
          <edgeless-color-panel
            .value=${selectedStrokeColor}
            .options=${STROKE_COLORS}
            .hollowCircle=${true}
            @select=${(e) => this._setShapeStrokeColor(e.detail)}
          >
          </edgeless-color-panel>
        </div>

        <edgeless-tool-icon-button
          class="border-styles-button"
          .tooltip=${this._showPopper ? '' : 'Border style'}
          .tipPosition=${'bottom'}
          .active=${false}
          .iconContainerPadding=${ICON_BUTTON_PADDING_TWO}
          @click=${() => this._lineStylesPanelPopper?.toggle()}
        >
          <div class="line-styles-button">
            ${LineStyleIcon} ${ShapeArrowDownSmallIcon}
          </div>
        </edgeless-tool-icon-button>
        ${LineStylesPanel({
            selectedLineSize,
            selectedLineStyle,
            onClick: event => {
                this._setShapeStyles(event);
            },
        })}
        ${doesAllShapesContainText(this.elements)
            ? html `<component-toolbar-menu-divider></component-toolbar-menu-divider>
              <edgeless-change-text-menu
                .elements=${this.elements}
                .elementType=${'shape'}
                .surface=${this.surface}
              ></edgeless-change-text-menu>`
            : nothing}
      </div>
    `;
    }
};
EdgelessChangeShapeButton.styles = [
    lineSizeButtonStyles,
    lineStylesPanelStyles,
    css `
      .change-shape-toolbar-container {
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--affine-text-primary-color);
        stroke: none;
        fill: currentColor;
      }

      edgeless-shape-panel {
        display: none;
      }

      edgeless-shape-panel[data-show] {
        display: flex;
      }

      .change-shape-button,
      .shape-style-button,
      .line-styles-button {
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .change-shape-button svg,
      .shape-style-button svg,
      .line-styles-button svg {
        fill: var(--affine-icon-color);
      }

      .border-styles-button {
        margin-left: 12px;
      }

      .fill-color-container,
      .stroke-color-container {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 20px;
        height: 20px;
      }

      .color-panel-container,
      .shape-style-panel-container {
        display: none;
        justify-content: center;
        align-items: center;
        background: var(--affine-background-overlay-panel-color);
        box-shadow: var(--affine-shadow-2);
        border-radius: 8px;
      }

      .shape-style-panel-container {
        padding: 8px;
      }

      .color-panel-container[data-show],
      .shape-style-panel-container[data-show] {
        display: flex;
      }

      .shape-color-button-indicator {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 24px;
        height: 24px;
        box-sizing: border-box;
        border-radius: 4px;
        cursor: pointer;
      }

      .shape-color-button-indicator div {
        border-radius: 50%;
        width: 16px;
        height: 16px;
      }

      .line-style-panel {
        display: none;
        padding: 6px;
      }

      .line-style-panel component-toolbar-menu-divider {
        margin: 0 8px;
      }

      .line-style-panel[data-show] {
        display: flex;
      }

      component-toolbar-menu-divider {
        margin: 0 12px;
        height: 24px;
      }
    `,
];
__decorate([
    property({ attribute: false })
], EdgelessChangeShapeButton.prototype, "elements", void 0);
__decorate([
    property({ attribute: false })
], EdgelessChangeShapeButton.prototype, "page", void 0);
__decorate([
    property({ attribute: false })
], EdgelessChangeShapeButton.prototype, "surface", void 0);
__decorate([
    state()
], EdgelessChangeShapeButton.prototype, "_showPopper", void 0);
__decorate([
    query('.change-shape-button')
], EdgelessChangeShapeButton.prototype, "_changeShapeButton", void 0);
__decorate([
    query('edgeless-shape-panel')
], EdgelessChangeShapeButton.prototype, "_shapePanel", void 0);
__decorate([
    query('.shape-style-button')
], EdgelessChangeShapeButton.prototype, "_shapeStyleButton", void 0);
__decorate([
    query('.shape-style-panel-container')
], EdgelessChangeShapeButton.prototype, "_shapeStyleMenu", void 0);
__decorate([
    query('.fill-color-button')
], EdgelessChangeShapeButton.prototype, "_fillColorButton", void 0);
__decorate([
    query('.color-panel-container.fill-color')
], EdgelessChangeShapeButton.prototype, "_fillColorMenu", void 0);
__decorate([
    query('.stroke-color-button')
], EdgelessChangeShapeButton.prototype, "_strokeColorButton", void 0);
__decorate([
    query('.color-panel-container.stroke-color')
], EdgelessChangeShapeButton.prototype, "_strokeColorMenu", void 0);
__decorate([
    query('.line-styles-button')
], EdgelessChangeShapeButton.prototype, "_lineStylesButton", void 0);
__decorate([
    query('.line-style-panel')
], EdgelessChangeShapeButton.prototype, "_lineStylesPanel", void 0);
EdgelessChangeShapeButton = __decorate([
    customElement('edgeless-change-shape-button')
], EdgelessChangeShapeButton);
export { EdgelessChangeShapeButton };
//# sourceMappingURL=change-shape-button.js.map