/*************************************************************
 *
 *  Copyright (c) 2025-2026 The MathJax Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * @file Implements a selection info dialog box
 *
 * @author dpvc@mathjax.org (Davide P. Cervone)
 */

import { InfoDialog } from './InfoDialog.js';
import { MJContextMenu } from '../menu/MJContextMenu.js';
import {
  SelectionOrder,
  SelectionGrid,
  SelectionBox,
} from '#menu/selection_box.js';
export { SelectionOrder, SelectionGrid } from '#menu/selection_box.js';

export type selection = { title: string; values: string[]; variable: string };

/**
 * The Selection dialog class
 */
export class SelectionDialog extends SelectionBox {
  /**
   * @override
   */
  constructor(
    title: string,
    signature: string,
    selections: selection[],
    order: SelectionOrder,
    grid: SelectionGrid,
    menu: MJContextMenu
  ) {
    super(title, signature, order, grid);
    this.attachMenu(menu);
    const factory = menu.factory;
    this.selections = selections.map((x) =>
      factory.get('selectionMenu')(factory, x, this)
    );
  }

  /**
   * @override
   */
  public post() {
    //
    // Get the active output jax (to get its adaptor)
    //
    const jax = Array.from(Object.values((this.menu as any).jax)).filter(
      (j) => !!j
    )[0] as any;
    //
    // Use an InfoDialog rather than the mj-context-menu Info object
    //
    const dialog = new InfoDialog({
      title: (this as any).title, // should be protected rather than private
      message: '',
      adaptor: jax.adaptor,
      styles: {
        'mjx-dialog > div': {
          padding: 0,
        },
      },
    });
    dialog.attach();
    //
    // Use the SelectionBox display function
    //
    this.contentDiv = (dialog as any).content as HTMLElement;
    this.display();
  }

  /**
   * @override
   */
  public display() {
    //
    // This is the same as teh SelectionBox() function, but without the super.display() call.
    //
    const THIS = this as any; // the methods below are private, so work around that.
    THIS.order();
    if (!this.selections.length) {
      return;
    }
    const outerDivs: HTMLElement[] = [];
    let maxWidth = 0;
    let balancedColumn: number[] = [];
    const chunks = THIS.getChunkSize(this.selections.length);
    for (let i = 0; i < this.selections.length; i += chunks) {
      const sels = this.selections.slice(i, i + chunks);
      const [div, width, height, column] = THIS.rowDiv(sels);
      outerDivs.push(div);
      maxWidth = Math.max(maxWidth, width);
      sels.forEach((sel) => (sel.html.style.height = height + 'px'));
      balancedColumn = THIS.combineColumn(balancedColumn, column);
    }
    if (THIS._balanced) {
      THIS.balanceColumn(outerDivs, balancedColumn);
      maxWidth = balancedColumn.reduce((x, y) => x + y - 2, 20); // remove 2px for borders
    }
    outerDivs.forEach((div) => (div.style.width = maxWidth + 'px'));
  }
}
