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 '../panel/font-family-panel.js';
import '../panel/size-panel.js';
import '../panel/font-weight-and-style-panel.js';
import { WithDisposable } from '@blockeditor/lit';
import { baseTheme } from '@toeverything/theme';
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { SmallArrowDownIcon, TextAlignCenterIcon, TextAlignLeftIcon, TextAlignRightIcon, } from '../../../../_common/icons/index.js';
import { countBy, maxBy } from '../../../../_common/utils/iterable.js';
import { CanvasTextFontStyle } from '../../../../surface-block/consts.js';
import { CanvasTextFontFamily, CanvasTextFontWeight, } from '../../../../surface-block/consts.js';
import { TextAlign } from '../../../../surface-block/elements/consts.js';
import { getFontFacesByFontFamily, isFontStyleSupported, isFontWeightSupported, } from '../../../../surface-block/elements/text/utils.js';
import { Bound, CanvasElementType, normalizeShapeBound, normalizeTextBound, } from '../../../../surface-block/index.js';
import { ColorUnit, GET_DEFAULT_LINE_COLOR, LINE_COLORS, } from '../panel/color-panel.js';
import {} from '../text/types.js';
import { createButtonPopper } from '../utils.js';
import { ShapeArrowDownSmallIcon } from './../../../../_common/icons/index.js';
let EdgelessChangeTextMenu = class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
    constructor() {
        super(...arguments);
        this._textColorPopperShow = false;
        this._fontSizePopperShow = false;
        this._fontWeightPopperShow = false;
        this._fontFamilyPopperShow = false;
        this._textAlignPopperShow = false;
        this._colorSelectorPopper = null;
        this._textAlignPopper = null;
        this._textFontFamilyPopper = null;
        this._textFontSizePopper = null;
        this._textFontWeightAndStylePopper = null;
        this._getMostCommonFontFamily = (elements) => {
            const fontFamilies = countBy(elements, (element) => element.fontFamily);
            const max = maxBy(Object.entries(fontFamilies), ([_k, count]) => count);
            return max
                ? max[0]
                : CanvasTextFontFamily.Inter;
        };
        this._getMostCommonFontSize = (elements) => {
            const fontSizes = countBy(elements, (element) => element.fontSize);
            const max = maxBy(Object.entries(fontSizes), ([_k, count]) => count);
            return max ? Number(max[0]) : 16;
        };
        this._getMostCommonFontWeight = (elements) => {
            const fontWeights = countBy(elements, (element) => element.fontWeight);
            const max = maxBy(Object.entries(fontWeights), ([_k, count]) => count);
            return max
                ? max[0]
                : CanvasTextFontWeight.Regular;
        };
        this._getMostCommonFontStyle = (elements) => {
            const fontStyles = countBy(elements, (element) => element.fontStyle);
            const max = maxBy(Object.entries(fontStyles), ([_k, count]) => count);
            return max
                ? max[0]
                : CanvasTextFontStyle.Normal;
        };
        this._getMostCommonColor = (elements) => {
            const colors = countBy(elements, (element) => element.color);
            const max = maxBy(Object.entries(colors), ([_k, count]) => count);
            return max
                ? max[0]
                : GET_DEFAULT_LINE_COLOR();
        };
        this._getMostCommonAlign = (elements) => {
            const aligns = countBy(elements, (element) => element.textAlign);
            const max = maxBy(Object.entries(aligns), ([_k, count]) => count);
            return max
                ? max[0]
                : TextAlign.Left;
        };
        this._updateElementBound = (element) => {
            const elementType = this.elementType;
            if (elementType === CanvasElementType.TEXT) {
                // the change of font family will change the bound of the text
                const newBound = normalizeTextBound(element, new Bound(element.x, element.y, element.w, element.h));
                this.surface.updateElement(element.id, {
                    xywh: newBound.serialize(),
                });
            }
            else {
                const newBound = normalizeShapeBound(element, new Bound(element.x, element.y, element.w, element.h));
                this.surface.updateElement(element.id, {
                    xywh: newBound.serialize(),
                });
            }
        };
        this._setTextColor = (color) => {
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, {
                    color,
                });
            });
        };
        this._setTextAlign = (align) => {
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, {
                    textAlign: align,
                });
            });
        };
        this._setFontFamily = (fontFamily) => {
            const currentFontWeight = this._getMostCommonFontWeight(this.elements);
            const fontWeight = isFontWeightSupported(fontFamily, currentFontWeight)
                ? currentFontWeight
                : CanvasTextFontWeight.Regular;
            const currentFontStyle = this._getMostCommonFontStyle(this.elements);
            const fontStyle = isFontStyleSupported(fontFamily, currentFontStyle)
                ? currentFontStyle
                : CanvasTextFontStyle.Normal;
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, {
                    fontFamily,
                    fontWeight,
                    fontStyle,
                });
                this._updateElementBound(element);
            });
        };
        this._setFontSize = (fontSize) => {
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, {
                    fontSize: fontSize,
                });
                this._updateElementBound(element);
            });
        };
        this._setFontWeightAndStyle = (fontWeight, fontStyle) => {
            this.elements.forEach(element => {
                this.surface.updateElement(element.id, {
                    fontWeight,
                    fontStyle,
                });
                this._updateElementBound(element);
            });
        };
    }
    firstUpdated(changedProperties) {
        const _disposables = this._disposables;
        this._colorSelectorPopper = createButtonPopper(this._textColorButton, this._textColorMenu, ({ display }) => {
            this._textColorPopperShow = display === 'show';
        });
        _disposables.add(this._colorSelectorPopper);
        this._textFontFamilyPopper = createButtonPopper(this._textFontFamilyButton, this._textFontFamilyMenu, ({ display }) => {
            this._fontFamilyPopperShow = display === 'show';
        });
        _disposables.add(this._textFontFamilyPopper);
        this._textAlignPopper = createButtonPopper(this._textAlignButton, this._textAlignMenu, ({ display }) => {
            this._textAlignPopperShow = display === 'show';
        });
        _disposables.add(this._textAlignPopper);
        this._textFontSizePopper = createButtonPopper(this._textFontSizeButton, this._textFontSizeMenu, ({ display }) => {
            this._fontSizePopperShow = display === 'show';
        });
        _disposables.add(this._textFontSizePopper);
        this._textFontWeightAndStylePopper = createButtonPopper(this._textFontWeightAndStyleButton, this._textFontWeightAndStyleMenu, ({ display }) => {
            this._fontWeightPopperShow = display === 'show';
        });
        _disposables.add(this._textFontWeightAndStylePopper);
        super.firstUpdated(changedProperties);
    }
    render() {
        const selectedColor = this._getMostCommonColor(this.elements);
        const selectedAlign = this._getMostCommonAlign(this.elements);
        const selectedFontFamily = this._getMostCommonFontFamily(this.elements);
        const selectedFontSize = Math.trunc(this._getMostCommonFontSize(this.elements));
        const selectedFontWeight = this._getMostCommonFontWeight(this.elements);
        const selectedFontStyle = this._getMostCommonFontStyle(this.elements);
        const matchFontFaces = getFontFacesByFontFamily(selectedFontFamily);
        return html `
      ${this.elementType === 'shape'
            ? nothing
            : html `<edgeless-tool-icon-button
              class="text-color-button"
              .tooltip=${this._textColorPopperShow ? '' : 'Text Color'}
              .tipPosition=${'bottom'}
              .active=${false}
              .activeMode=${'background'}
              .iconContainerPadding=${2}
              @click=${() => this._colorSelectorPopper?.toggle()}
            >
              <div class="text-color-unit-container">
                ${ColorUnit(selectedColor)}
              </div>
            </edgeless-tool-icon-button>
            <div class="color-panel-container text-color">
              <edgeless-color-panel
                .value=${selectedColor}
                .options=${LINE_COLORS}
                @select=${(event) => {
                this._setTextColor(event.detail);
            }}
              ></edgeless-color-panel>
            </div>
            <component-toolbar-menu-divider></component-toolbar-menu-divider>`}

      <edgeless-tool-icon-button
        class="text-font-family-button"
        .tooltip=${this._fontSizePopperShow ? '' : 'Font'}
        .tipPosition=${'bottom'}
        .active=${false}
        .iconContainerPadding=${2}
        @click=${() => this._textFontFamilyPopper?.toggle()}
      >
        <div class="button-with-arrow-group">
          <span style=${`font-family:"${selectedFontFamily}";`}>Aa</span
          >${SmallArrowDownIcon}
        </div>
      </edgeless-tool-icon-button>
      <div class="font-family-panel-container text-font-family">
        <edgeless-font-family-panel
          .value=${selectedFontFamily}
          .onSelect=${(value) => this._setFontFamily(value)}
        ></edgeless-font-family-panel>
      </div>

      ${this.elementType === 'shape'
            ? html `<edgeless-tool-icon-button
              class="text-color-button shape"
              .tooltip=${this._textColorPopperShow ? '' : 'Text Color'}
              .tipPosition=${'bottom'}
              .active=${false}
              .activeMode=${'background'}
              .iconContainerPadding=${2}
              @click=${() => this._colorSelectorPopper?.toggle()}
            >
              <div class="text-color-unit-container">
                ${ColorUnit(selectedColor)}
              </div>
            </edgeless-tool-icon-button>
            <div class="color-panel-container text-color">
              <edgeless-color-panel
                .value=${selectedColor}
                .options=${LINE_COLORS}
                @select=${(event) => {
                this._setTextColor(event.detail);
            }}
              ></edgeless-color-panel>
            </div>`
            : nothing}

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

      <edgeless-tool-icon-button
        class="text-font-size-button"
        .tooltip=${this._fontFamilyPopperShow ? '' : 'Font Size'}
        .tipPosition=${'bottom'}
        .active=${false}
        .iconContainerPadding=${2}
        @click=${() => this._textFontSizePopper?.toggle()}
      >
        <div class="font-size-button-group">
          <div class="selected-font-size-label">${selectedFontSize}</div>
          <div class="arrow-down-icon">${ShapeArrowDownSmallIcon}</div>
        </div>
      </edgeless-tool-icon-button>
      <div class="font-size-panel-container text-font-size">
        <edgeless-size-panel
          .size=${selectedFontSize}
          .labels=${['16', '24', '32', '36', '40', '64', '128']}
          .sizes=${[16, 24, 32, 36, 40, 64, 128]}
          .onSelect=${(fontSize) => {
            this._setFontSize(fontSize);
        }}
          .onPopperCose=${() => this._textFontSizePopper?.hide()}
        ></edgeless-size-panel>
      </div>

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

      <edgeless-tool-icon-button
        class="text-font-weight-and-style-button"
        .disabled=${matchFontFaces.length === 1 &&
            matchFontFaces[0].style === selectedFontStyle &&
            matchFontFaces[0].weight === selectedFontWeight}
        .tooltip=${this._fontWeightPopperShow ? '' : 'Font Style'}
        .tipPosition=${'bottom'}
        .active=${false}
        .iconContainerPadding=${2}
        @click=${() => this._textFontWeightAndStylePopper?.toggle()}
      >
        <div class="button-with-arrow-group">
          <span
            >${`${selectedFontWeight === CanvasTextFontWeight.Light
            ? 'Light'
            : selectedFontWeight === CanvasTextFontWeight.Regular
                ? 'Regular'
                : 'Semibold'}${selectedFontStyle === CanvasTextFontStyle.Italic ? ' Italic' : ''}`}</span
          >${SmallArrowDownIcon}
        </div>
      </edgeless-tool-icon-button>
      <div class="font-weight-and-style-panel-container">
        <edgeless-font-weight-and-style-panel
          .fontFamily=${selectedFontFamily}
          .fontWeight=${selectedFontWeight}
          .fontStyle=${selectedFontStyle}
          .onSelect=${(fontWeight, fontStyle) => this._setFontWeightAndStyle(fontWeight, fontStyle)}
        ></edgeless-font-weight-and-style-panel>
      </div>

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

      <edgeless-tool-icon-button
        class="text-align-button"
        .tooltip=${this._textAlignPopperShow ? '' : 'Alignment'}
        .tipPosition=${'bottom'}
        .active=${false}
        .iconContainerPadding=${2}
        @click=${() => this._textAlignPopper?.toggle()}
      >
        <div class="button-with-arrow-group">
          ${selectedAlign === 'left'
            ? TextAlignLeftIcon
            : selectedAlign === 'center'
                ? TextAlignCenterIcon
                : TextAlignRightIcon}
          ${SmallArrowDownIcon}
        </div>
      </edgeless-tool-icon-button>
      <div class="align-panel-container text-align">
        <edgeless-align-panel
          .value=${selectedAlign}
          .onSelect=${(value) => {
            this._setTextAlign(value);
        }}
        ></edgeless-align-panel>
      </div>
    `;
    }
};
EdgelessChangeTextMenu.styles = css `
    :host {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      color: var(--affine-text-primary-color);
      stroke: none;
      fill: currentColor;
    }

    .text-color-unit-container {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 20px;
      height: 20px;
    }

    .color-panel-container,
    .align-panel-container.text-align,
    .font-size-panel-container,
    .font-family-panel-container,
    .font-weight-and-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;
    }

    .color-panel-container[data-show],
    .align-panel-container[data-show],
    .font-size-panel-container[data-show],
    .font-family-panel-container[data-show],
    .font-weight-and-style-panel-container[data-show] {
      display: block;
    }

    .button-with-arrow-group {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .font-size-button-group {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 60px;
      height: 24px;
    }

    .font-size-button-group .selected-font-size-label {
      width: 40px;
      height: 20px;
      line-height: 20px;
      font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
      font-size: 16px;
      font-style: normal;
      font-weight: 400;
    }

    .font-size-button-group .arrow-down-icon {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .selected-font-size {
      align-self: end;
    }

    .text-align-button svg {
      fill: var(--affine-icon-color);
      stroke: none;
    }

    component-toolbar-menu-divider {
      margin: 0 12px;
      height: 24px;
    }

    .text-color-button.shape {
      margin-left: 12px;
    }
  `;
__decorate([
    property({ attribute: false })
], EdgelessChangeTextMenu.prototype, "elements", void 0);
__decorate([
    property({ attribute: false })
], EdgelessChangeTextMenu.prototype, "elementType", void 0);
__decorate([
    property({ attribute: false })
], EdgelessChangeTextMenu.prototype, "surface", void 0);
__decorate([
    state()
], EdgelessChangeTextMenu.prototype, "_textColorPopperShow", void 0);
__decorate([
    state()
], EdgelessChangeTextMenu.prototype, "_fontSizePopperShow", void 0);
__decorate([
    state()
], EdgelessChangeTextMenu.prototype, "_fontWeightPopperShow", void 0);
__decorate([
    state()
], EdgelessChangeTextMenu.prototype, "_fontFamilyPopperShow", void 0);
__decorate([
    state()
], EdgelessChangeTextMenu.prototype, "_textAlignPopperShow", void 0);
__decorate([
    query('.text-color-button')
], EdgelessChangeTextMenu.prototype, "_textColorButton", void 0);
__decorate([
    query('.color-panel-container.text-color')
], EdgelessChangeTextMenu.prototype, "_textColorMenu", void 0);
__decorate([
    query('.text-align-button')
], EdgelessChangeTextMenu.prototype, "_textAlignButton", void 0);
__decorate([
    query('.align-panel-container.text-align')
], EdgelessChangeTextMenu.prototype, "_textAlignMenu", void 0);
__decorate([
    query('.text-font-family-button')
], EdgelessChangeTextMenu.prototype, "_textFontFamilyButton", void 0);
__decorate([
    query('.font-family-panel-container')
], EdgelessChangeTextMenu.prototype, "_textFontFamilyMenu", void 0);
__decorate([
    query('.text-font-size-button')
], EdgelessChangeTextMenu.prototype, "_textFontSizeButton", void 0);
__decorate([
    query('.font-size-panel-container')
], EdgelessChangeTextMenu.prototype, "_textFontSizeMenu", void 0);
__decorate([
    query('.text-font-weight-and-style-button')
], EdgelessChangeTextMenu.prototype, "_textFontWeightAndStyleButton", void 0);
__decorate([
    query('.font-weight-and-style-panel-container')
], EdgelessChangeTextMenu.prototype, "_textFontWeightAndStyleMenu", void 0);
EdgelessChangeTextMenu = __decorate([
    customElement('edgeless-change-text-menu')
], EdgelessChangeTextMenu);
export { EdgelessChangeTextMenu };
//# sourceMappingURL=change-text-menu.js.map