type LabelPageParam = [pageIndex: number, pageRect: LabelTemplate]

type LabelPrintStyleParam = [id: string | number, name: string, value: string | number]

enum LabelCodeType {

  INITA = 'PRINT_INITA',

  ADD_TEXT = 'ADD_PRINT_TEXT',

  ADD_TEXTA = 'ADD_PRINT_TEXTA',

  ADD_HTML = 'ADD_PRINT_HTM',

  ADD_IMAGE = 'ADD_PRINT_IMAGE',

  ADD_TABLE = 'ADD_PRINT_TABLE',

  ADD_BARCODE = 'ADD_PRINT_BARCODE',

  ADD_BARCODEA = 'ADD_PRINT_BARCODEA',

  ADD_SHAPE = 'ADD_PRINT_SHAPE',

  ADD_RECT = 'ADD_PRINT_RECT',

  ADD_ELLIPSE = 'ADD_PRINT_ELLIPSE',

  ADD_LINE = 'ADD_PRINT_LINE',

  SET_STYLE = 'SET_PRINT_STYLEA'

}

class LabelNumber {

  static Unit = 'mm'

  readonly number: number

  readonly strValue: string

  constructor(value: string | number, tempNumber?: number) {
    if (typeof value === 'string') {
      const number = Number(value.replace(/[^0-9.]+/g, ''))
      const unit = value.replace(/[0-9.]+/g, '')
      this.number = this.unit2mm(number, unit, tempNumber!)
      this.strValue = this.number + LabelNumber.Unit
    } else {
      this.number = value
      this.strValue = value + LabelNumber.Unit
    }
  }

  private unit2mm = (number: number, unit: string, tempNumber: number): number => {
    switch (unit) {
      case 'mm':
        return number
      case 'cm':
        return number * 10
      case '%':
        return number === 0 ? 0 : tempNumber * (number / 100)
      case 'pt':// 磅
        return Math.floor(number / 2.88 * 100) / 100
      case 'in':// 英寸
        return Math.floor(number / 0.03937 * 100) / 100
      default:
        return Math.floor(number / 3.78 * 100) / 100
    }
  }

}

interface LabelTemplate {
  tempTop: LabelNumber
  tempLeft: LabelNumber
  tempWidth: LabelNumber
  tempHeight: LabelNumber
  labelTexts: LabelText[]
  labelHtmls: LabelHtml[]
  labelImages: LabelImage[]
  labelTables: LabelTable[]
  labelBarCodes: LabelBarCode[]
  labelRects: LabelRect[]
  labelEllipses: LabelEllipse[]
  labelShapes: LabelShape[]
  labelLines: LabelLine[]
}

interface FormTemplate {
  header: Rect
  headerLine: Rect
  logo: Rect
  headerTitle: Rect
  body: Rect
  title: TitleRect
  subTitle: Rect
  subTitle1: TitleRect
  subTitle2: TitleRect
  subTitle3: TitleRect
  table: Rect
  footer: Rect
  footerTitle: Rect
  footerLine: Rect
  printer: Rect
  date: Rect
  num: Rect
  sum: Rect
}

interface DetailTemplate {
  header: Rect
  logo: Rect
  code: CodeRect
  codeLabel: Rect
  extraTitle: Rect
  title: Rect
  subTitle: Rect
  subTitle1: Rect
  subTitle2: Rect
  subTitle3: Rect
  html: Rect
  footer: Rect
  date: Rect
  printer: Rect
  num: Rect
  sum: Rect
}

interface CodeRect extends Rect {
  codeType: 'QRCode' | 'code39'
  label: string
}

interface TitleRect extends Rect {
  itemType: number
}

interface Label {
  top: LabelNumber
  left: LabelNumber
  width: LabelNumber
  height: LabelNumber
  fieldName?: string
  styles?: LabelPrintStyleParam[]
}

// 文本
interface LabelText extends Label {
  content: string
}
// 富文本
interface LabelHtml extends LabelText {

}

interface LabelImage extends Label {
  url: string

}
// 表格
interface LabelTable extends Label {
  content: string
}

// 条码
interface LabelBarCode extends Label {
  codeType: string
  codeValue: string
}
// 斜线
interface LabelLine extends Label {
  lineStyle: number // 0--实线 1--破折线 2--点线 3--点划线 4--双点划线
  lineWidth: number
}
// 矩形
interface LabelRect extends LabelLine {

}

// 椭圆
interface LabelEllipse extends LabelLine {

}

// 图形
interface LabelShape extends LabelLine {
  shapeType: number // 0--仰角直线 1--俯角直线 2--矩形框线 3--椭圆线 4--实心矩形 5--实心椭圆
  fillColor: string
}

interface Rect {
  top: number
  left: number
  width: number
  height: number
  content?: string
}

export {
  FormTemplate, DetailTemplate, LabelNumber, LabelPrintStyleParam, LabelCodeType, LabelPageParam, LabelTemplate,
  LabelText, LabelHtml, LabelImage, LabelTable, LabelBarCode, LabelEllipse, LabelLine, LabelRect, LabelShape,
  Rect, CodeRect, TitleRect
}