import { IPageMain, IPageColumnDefs } from "../Page/Page";
import {
  IPageContentCell,
  IPageContent,
  IPageContentCellIndex,
} from "../Page/Content";
import { IGridCellDetails } from "./GridCell";
import { IGridSelection } from "./Grid";

export interface IGridPageContentCell extends IPageContentCell {
  index: IPageContentCellIndex;
}
export interface IGridPageContent extends IPageContent {
  [index: number]: IGridPageContentCell[];
}

export interface IGridPageCellPos {
  x: number;
  y: number;
}

export interface IGridPageMerges {
  [index: number]: number[];
}

export interface IGridPage {
  structured: boolean;
  uuid: string;
  scale: number;
  content: IGridPageContent;
  originalContent: IGridPageContent;
  deltaContent: IPageContent;
  rows: number;
  cols: number;
  hiddenColumns: number[];
  hiddenRows: number[];
  rowHeights: number[];
  colWidths: number[];
  width: number;
  height: number;
  borderRightWidth: number;
  borderBottomWidth: number;
  selectedCols: any[];
  selectedRows: any[];
  selectedCells: any[];
  scrollTop: number;
  scrollLeft: number;
  scrollbarSize: number;
  scrollbarWidth: number;
  scrollbarHeight: number;
  selection: IGridSelection;
  columnFilters: boolean;
  headings: boolean;
  touch: boolean;
  columnsDefs: IPageColumnDefs[];
  canSort: boolean;
  sorting: boolean;
  headingsHeight: number;
  filtersOffset: number;
  headingsWidth: number;
  softMerges: boolean;
  tabToLine: boolean;
  cellMapColor: string;
  cellMapErrorColor: string;
  disableFocusOnF2: boolean;
  mappingNavigation: boolean;
  mapping: any;
  reset(): void;
  rowPos(row: number): number;
  colPos(col: number): number;
  cellPos(row: number, col: number): IGridPageCellPos;
  resetSelection(): void;
  getColDefWidth(col: number): number;
  isRightClick(evt: any): boolean;
}

class GridPage implements IGridPage {
  // public page!: IPageService;
  public softMerges: boolean = true;
  public structured: boolean = false;
  public columnFilters: boolean = false;
  public uuid: string = "";
  public scale: number = 1;
  public content: IGridPageContent = [];
  public originalContent: IGridPageContent = [];
  public deltaContent: IPageContent = [];
  public rows: number = 0;
  public cols: number = 0;
  public hiddenColumns: number[] = [];
  public hiddenRows: number[] = [];
  public rowHeights: number[] = [];
  public colWidths: number[] = [];
  public width: number = 0;
  public height: number = 0;
  public borderRightWidth: number = 0;
  public borderBottomWidth: number = 0;
  public selectedCols: any[] = [];
  public selectedRows: any[] = [];
  public selectedCells: any[] = [];
  public scrollTop: number = 0;
  public scrollLeft: number = 0;
  public scrollbarSize: number = 0;
  public scrollbarWidth: number = 0;
  public scrollbarHeight: number = 0;
  public selection: IGridSelection = {
    rowFrom: -1,
    rowTo: -1,
    colFrom: -1,
    colTo: -1,
    heading: false,
    inside: false,
    selected: false,
    keyboard: false,
    type: "cell",
  };
  public headings: boolean = false;
  public touch: boolean = false;
  public columnsDefs: IPageColumnDefs[] = [];
  public canSort: boolean = false;
  public sorting: boolean = false;
  public headingsHeight: number = 20;
  public headingsWidth: number = 40;
  public tabToLine: boolean = false;
  public cellMapColor: string = '';
  public cellMapErrorColor: string = '';
  public disableFocusOnF2: boolean = false;
  public mappingNavigation: boolean = false;
  public mapping: any = [];

  public get filtersOffset(): number {
    return this.columnFilters ? 30 : 0;
  }
  public reset(): void {
    this.scale = 0;
    this.content = [];
    this.originalContent = [];
    this.deltaContent = [];
    this.rows = 0;
    this.cols = 0;
    this.hiddenColumns = [];
    this.hiddenRows = [];
    this.rowHeights = [];
    this.colWidths = [];
    this.width = 0;
    this.height = 0;
    this.selectedCells = [];
    this.selectedCols = [];
    this.selectedRows = [];
    this.scrollTop = 0;
    this.scrollLeft = 0;
    this.columnsDefs = [];
    // this.scrollbarWidth = 0;
  }
  public resetSelection(): void {
    this.selectedCells = [];
    this.selectedCols = [];
    this.selectedRows = [];
    this.selection = {
      rowFrom: -1,
      rowTo: -1,
      colFrom: -1,
      colTo: -1,
      heading: false,
      inside: false,
      selected: false,
      keyboard: false,
      type: "cell",
    };
  }
  public rowPos(row: number): number {
    return this.rowHeights.slice(0, row).reduce((a: any, b: any) => a + b, 0);
  }
  public colPos(col: number): number {
    return this.colWidths.slice(0, col).reduce((a: any, b: any) => a + b, 0);
  }
  public cellPos(row: number, col: number): IGridPageCellPos {
    return {
      x: this.colWidths.slice(0, col).reduce((a: any, b: any) => a + b, 0),
      y: this.rowHeights.slice(0, row).reduce((a: any, b: any) => a + b, 0),
    };
  }
  public setSelectedCell(cell: IGridCellDetails): void {
    this.selectedCells.push(cell);
  }
  public getColDefWidth(col: number): number {
    if (
      this.columnsDefs[col] &&
      this.columnsDefs[col].style &&
      this.columnsDefs[col].style!.width
    ) {
      return parseFloat(this.columnsDefs[col].style!.width!);
    }
    return 0;
  }
  public isRightClick(evt: any): boolean {
    let isRightMB = false;
    if ("which" in evt)
      // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
      isRightMB = evt.which === 3;
    else if ("button" in evt)
      // IE, Opera
      isRightMB = evt.button === 2;
    return isRightMB;
  }
}

export default GridPage;
