import { VegaRTEExtension } from '../extension.abstract';
import { RTETableBlock } from './dto/table-block';
import { RTETableBlockRenderer } from './renderers/table-renderer';
import { RTETableHeadRenderer } from './renderers/table-head-renderer';
import { RTETableRowBlockRenderer } from './renderers/table-row-renderer';
import { RTETableCellRenderer } from './renderers/table-cell-renderer';
import { RTETableBodyRenderer } from './renderers/table-body-renderer';
import { RTETableHeadBlock } from './dto/table-head-block';
import { RTETableRowBlock } from './dto/table-row-block';
import { RTETableCellBlock } from './dto/table-cell-block';
import { RTETableBodyBlock } from './dto/table-body-block';
import { RTETableHeadCellBlock } from './dto/table-head-cell-block';
import { RTETableHeadCellRenderer } from './renderers/table-head-cell-renderer';
import { RTETableToolbarButtonRenderer } from './table-toolbar-button-renderer';
import { InsertTableBlockStrategy } from './action-handler-strategies/insert-table-block-strategy';
import { VegaRTEContent } from '../../dto/content-state';
import { INSERT_TABLE_BLOCK } from './actions/insert-table-block-action';
import { RTETextBlock } from '../../dto/blocks/text-block';
import { RTEImageBlock } from '../../dto/blocks/image-block';
import { PreventCellContentDeleteInterceptor } from './action-handler-interceptors/prevent-cell-content-delete-interceptor';
import { ModifyContentActionType } from '../../dto/actions/modify-content-action.abstract';
import { DELETE_TABLE_BLOCK } from './actions/delete-table-block-action';
import { DeleteTableBlockStrategy } from './action-handler-strategies/delete-table-block-strategy';
import { PreventCellChildrenRemoveInterceptor } from './action-handler-interceptors/prevent-cell-children-remove-interceptor';
import { RTETableCaptionBlock } from './dto/table-caption-block';
import { RTETableCaptionRenderer } from './renderers/table-caption-renderer';
import { DELETE_TABLE_ROW } from './actions/delete-table-row-action';
import { DeleteTableRowStrategy } from './action-handler-strategies/delete-table-row-strategy';
import { RTETableSelection } from './table-selection';
import { ToggleHeaderRowStrategy } from './action-handler-strategies/toggle-header-row-strategy';
import { TOGGLE_HEADER_ROW } from './actions/toggle-header-row-action';
import { INSERT_TABLE_COLUMN } from './actions/insert-table-column-action';
import { InsertTableColumnStrategy } from './action-handler-strategies/insert-table-column-strategy';
import { DELETE_TABLE_COLUMN } from './actions/delete-table-column-action';
import { DeleteTableColumnStrategy } from './action-handler-strategies/delete-table-column-strategy';
import { TOGGLE_HEADER_TABLE_COLUMN } from './actions/toggle-header-table-column-action';
import { CREATE_SEGMENT_TABLE_CELL } from './actions/create-segment-table-cell-action';
import { REPLACE_TABLE_CELL } from './actions/replace-table-cell-action';
import { SPLIT_TABLE_CELL } from './actions/split-table-cell-action';
import { CreateSegmentTableCellStrategy } from './action-handler-strategies/create-segment-table-cell-strategy';
import { ReplaceTableCellStrategy } from './action-handler-strategies/replace-table-cell-strategy';
import { SplitTableCellStrategy } from './action-handler-strategies/split-table-cell-strategy';
import { ToggleHeaderTableColumnStrategy } from './action-handler-strategies/toggle-header-table-column-strategy';
import { SELECT_TABLE_COLUMN } from './actions/select-table-column-action';
import { SelectTableColumnStrategy } from './action-handler-strategies/select-table-column-strategy';
import { PreventRowInsertInterceptor } from './action-handler-interceptors/prevent-row-insert-interceptor';
import { MERGE_CELLS } from './actions/merge-cells-action';
import { MergeCellsStrategy } from './action-handler-strategies/merge-cells-strategy';
import { TableToTableBlockStrategy } from './element-to-dto-strategies/table-to-table-block-strategy';
import { TheadToTableHeadBlockStrategy } from './element-to-dto-strategies/thead-to-table-head-block-strategy';
import { TbodyToTableBodyBlockStrategy } from './element-to-dto-strategies/tbody-to-table-body-block-strategy';
import { TrToTableRowBlockStrategy } from './element-to-dto-strategies/tr-to-table-row-block-strategy';
import { TdToTableCellBlockStrategy } from './element-to-dto-strategies/td-to-table-cell-block-strategy';
import { CaptionToCaptionBlockStrategy } from './element-to-dto-strategies/caption-to-caption-block-strategy';
import { TableAnnotationHandler } from './annotation-handler/table-annotation-handler';
import { TableCellAnnotationHandler } from './annotation-handler/table-cell-annotation-handler';
import { TableHeadCellAnnotationHandler } from './annotation-handler/table-head-cell-annotation-handler';
import { UpdateTablePropertiesAction } from './actions/update-table-properties-action';
import { UpdateTablePropertiesStrategy } from './action-handler-strategies/update-table-properties-strategy';
import { RTE_TABLE_DEFAULT_COLORS } from './constants/styles.constants';
import { UpdateTableCellPropertiesStrategy } from './action-handler-strategies/update-table-cell-properties-strategy';
import { RTETableCellAnnotationsAction } from './actions/table-cell-annotations-action';
import { RTETableHeadCellAnnotationsAction } from './actions/table-head-cell-annotations-action';
import { RTETableColorManager } from './utils/table-color-manager';
import { SPLIT_CELL_HORIZONTALLY } from './actions/split-cell-horizontally-action';
import { SplitCellHorizontallyStrategy } from './action-handler-strategies/split-cell-horizontally-strategy';
import { SPLIT_CELL_VERTICALLY } from './actions/split-cell-vertically-action';
import { SplitCellVerticallyStrategy } from './action-handler-strategies/split-cell-vertically-strategy';
import { INSERT_TABLE_ROW_INTO_DIFFERENT_SECTION } from './actions/insert-table-row-into-different-section-action';
import { InsertTableRowIntoDifferentSectionStrategy } from './action-handler-strategies/insert-table-row-into-different-section-strategy';
import { INSERT_TABLE_ROW_INTO_SAME_SECTION } from './actions/insert-table-row-into-same-section-action';
import { InsertTableRowIntoSameSectionStrategy } from './action-handler-strategies/insert-table-row-into-same-section-strategy';
import { PreventTableInsertParagraphInterceptor } from './action-handler-interceptors/prevent-table-insert-paragraph-interceptor';
import { TableBlockFilterStylesStrategy } from './filter-styles-strategies/table-block/table-block-filter-styles-strategy';
import { TableCaptionFilterStylesStrategy } from './filter-styles-strategies/table-caption/table-caption-filter-styles-strategy';
import { TableCellFilterStylesStrategy } from './filter-styles-strategies/table-cell/table-cell-filter-styles-strategy';
/**
 * Function extension class for Vega Rich Text Editor.
 */
export class VegaRTETableExtension extends VegaRTEExtension {
  /**
   * Instantiate the table extension
   *
   * @param {VegaRTEColorSchema[]} colors - The table border color and background color list.
   */
  constructor(colors = RTE_TABLE_DEFAULT_COLORS) {
    super();
    this.toolbarButtonRenderer = new RTETableToolbarButtonRenderer();
    this.tableBlockRenderer = new RTETableBlockRenderer();
    this.tableRowBlockRenderer = new RTETableRowBlockRenderer();
    this.tableCellRenderer = new RTETableCellRenderer();
    this.tableHeadCellRenderer = new RTETableHeadCellRenderer();
    this.tableSelection = new RTETableSelection();
    RTETableColorManager.setTableColors(colors);
    this.registerToolbarButtonRenderer('table', this.toolbarButtonRenderer);
    this.registerBlockBasicStrategies(RTETableBlock.name);
    this.registerBlockBasicStrategies(RTETableHeadBlock.name);
    this.registerBlockBasicStrategies(RTETableHeadCellBlock.name);
    this.registerBlockBasicStrategies(RTETableRowBlock.name);
    this.registerBlockBasicStrategies(RTETableCellBlock.name);
    this.registerBlockBasicStrategies(RTETableBodyBlock.name);
    this.registerRenderer('table-block', this.tableBlockRenderer);
    this.registerRenderer('table-head', new RTETableHeadRenderer());
    this.registerRenderer('table-head-cell', this.tableHeadCellRenderer);
    this.registerRenderer('table-row', this.tableRowBlockRenderer);
    this.registerRenderer('table-cell', this.tableCellRenderer);
    this.registerRenderer('table-body', new RTETableBodyRenderer());
    this.registerRenderer('table-caption', new RTETableCaptionRenderer());
    this.registerNode('table-block', RTETableBlock);
    this.registerNode('table-head', RTETableHeadBlock);
    this.registerNode('table-head-cell', RTETableHeadCellBlock);
    this.registerNode('table-row', RTETableRowBlock);
    this.registerNode('table-cell', RTETableCellBlock);
    this.registerNode('table-body', RTETableBodyBlock);
    this.registerNode('table-caption', RTETableCaptionBlock);
    this.registerElementToBlockDTOClassStrategy(new TableToTableBlockStrategy());
    this.registerElementToBlockDTOClassStrategy(new TheadToTableHeadBlockStrategy());
    this.registerElementToBlockDTOClassStrategy(new TbodyToTableBodyBlockStrategy());
    this.registerElementToBlockDTOClassStrategy(new TrToTableRowBlockStrategy());
    this.registerElementToBlockDTOClassStrategy(new TdToTableCellBlockStrategy());
    this.registerElementToBlockDTOClassStrategy(new CaptionToCaptionBlockStrategy());
    // Register custom annotation handlers for table elements
    this.registerAnnotationHandler(new TableAnnotationHandler());
    this.registerAnnotationHandler(new TableCellAnnotationHandler());
    this.registerAnnotationHandler(new TableHeadCellAnnotationHandler());
  }
  /**
   * Initializes the extension with the given context
   *
   * @param {RTEExtensionContext} context - extension context
   */
  initialExtension(context) {
    this.tableSelection.init(context);
    const tableExtensionContext = Object.assign(Object.assign({}, context), { tableSelection: this.tableSelection });
    super.initialExtension(tableExtensionContext);
  }
  /**
   * @inheritDoc
   */
  destroyExtension() {
    this.tableSelection.destroy();
  }
}
(() => {
  const insertTableBlockStrategy = new InsertTableBlockStrategy();
  const deleteTableBlockStrategy = new DeleteTableBlockStrategy();
  VegaRTEExtension.registerActionHandleStrategy(VegaRTEContent.name, INSERT_TABLE_BLOCK, insertTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(VegaRTEContent.name, DELETE_TABLE_BLOCK, deleteTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(RTETableCellBlock.name, DELETE_TABLE_BLOCK, deleteTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(RTETableHeadCellBlock.name, DELETE_TABLE_BLOCK, deleteTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(RTETextBlock.name, INSERT_TABLE_BLOCK, insertTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(RTEImageBlock.name, INSERT_TABLE_BLOCK, insertTableBlockStrategy);
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, INSERT_TABLE_ROW_INTO_DIFFERENT_SECTION, new InsertTableRowIntoDifferentSectionStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, INSERT_TABLE_ROW_INTO_SAME_SECTION, new InsertTableRowIntoSameSectionStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, DELETE_TABLE_ROW, new DeleteTableRowStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, TOGGLE_HEADER_ROW, new ToggleHeaderRowStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, INSERT_TABLE_COLUMN, new InsertTableColumnStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, DELETE_TABLE_COLUMN, new DeleteTableColumnStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, TOGGLE_HEADER_TABLE_COLUMN, new ToggleHeaderTableColumnStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableRowBlock.name, SPLIT_TABLE_CELL, new SplitTableCellStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableRowBlock.name, CREATE_SEGMENT_TABLE_CELL, new CreateSegmentTableCellStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableRowBlock.name, REPLACE_TABLE_CELL, new ReplaceTableCellStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableCellBlock.name, SPLIT_CELL_HORIZONTALLY, new SplitCellHorizontallyStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableCellBlock.name, SPLIT_CELL_VERTICALLY, new SplitCellVerticallyStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableHeadCellBlock.name, SPLIT_CELL_HORIZONTALLY, new SplitCellHorizontallyStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableHeadCellBlock.name, SPLIT_CELL_VERTICALLY, new SplitCellVerticallyStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, SELECT_TABLE_COLUMN, new SelectTableColumnStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, MERGE_CELLS, new MergeCellsStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableBlock.name, UpdateTablePropertiesAction.name, new UpdateTablePropertiesStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableCellBlock.name, RTETableCellAnnotationsAction.name, new UpdateTableCellPropertiesStrategy());
  VegaRTEExtension.registerActionHandleStrategy(RTETableHeadCellBlock.name, RTETableHeadCellAnnotationsAction.name, new UpdateTableCellPropertiesStrategy());
  VegaRTEExtension.registerActionHandlerInterceptor(RTETextBlock.name, ModifyContentActionType.DELETE_BLOCK_CONTENT, new PreventCellContentDeleteInterceptor());
  VegaRTEExtension.registerActionHandlerInterceptor(RTETableRowBlock.name, ModifyContentActionType.INSERT_CHILDREN_BEFORE, new PreventRowInsertInterceptor());
  VegaRTEExtension.registerActionHandlerInterceptor(RTETableCellBlock.name, ModifyContentActionType.DELETE_CHILDREN, new PreventCellChildrenRemoveInterceptor());
  VegaRTEExtension.registerActionHandlerInterceptor(RTETableHeadCellBlock.name, ModifyContentActionType.DELETE_CHILDREN, new PreventCellChildrenRemoveInterceptor());
  VegaRTEExtension.registerActionHandlerInterceptor(RTETableBlock.name, ModifyContentActionType.INSERT_NEW_PARAGRAPH, new PreventTableInsertParagraphInterceptor());
  VegaRTEExtension.registerFilterStylesStrategy(RTETableBlock.name, new TableBlockFilterStylesStrategy());
  VegaRTEExtension.registerFilterStylesStrategy(RTETableCaptionBlock.name, new TableCaptionFilterStylesStrategy());
  VegaRTEExtension.registerFilterStylesStrategy(RTETableCellBlock.name, new TableCellFilterStylesStrategy());
  VegaRTEExtension.registerFilterStylesStrategy(RTETableHeadCellBlock.name, new TableCellFilterStylesStrategy('th'));
})();
