import Base from '../annotation/base';
import { getActualPoint, getClickPoint, createSvg, createElement } from '../annotation/utils';
import { onClickOutsideUp } from '../ui_utils'

export default class ListBox extends Base {

  constructor({
    container,
    annotation,
    page,
    viewport,
    scale,
    eventBus,
    layer,
    show = false,
    highlight
  }) {
    super({
      container,
      annotation,
      page,
      viewport,
      scale,
      eventBus,
      show,
      highlight
    })

    this.layer = layer
    this.hidden = true
    this.initial = false
    this.outline = null

    this.start = null
    this.end = null

    this.newStart = null
    this.newEnd = null

    this.startCircle = null
    this.endCircle = null

    this.show = show
    this.highlight = highlight

    this.onMousedown = this.handleMouseDown.bind(this)
    this.onMouseup = this.handleMouseUp.bind(this)
    this.onMousemove = this.handleMouseMove.bind(this)
    this.onDelete = this.handleDelete.bind(this)

    this.setProperty = this.setProperty.bind(this)
    this.changeSelectAvailable = this.changeSelectAvailable.bind(this)
    this.handlePropertyPanel = this.handlePropertyPanel.bind(this)
    this.setHighlight = this.setHighlight.bind(this)
    this.render()
  }

  render() {
    this.eventBus._on('setProperty', this.setProperty)
    this.eventBus._on('changeSelectAvailable', this.changeSelectAvailable)
    this.eventBus._on('setHighlightForm', this.setHighlight)

    const annotation = this.annotation

    if (!annotation.items) {
      annotation.items = []
    }
    if (!annotation.fontName) {
      annotation.fontName = 'Helvetica'
    }
    if (annotation.isBold && annotation.isItalic) {
      annotation.fontStyle = 'boldItalic'
    } else if (annotation.isBold) {
      annotation.fontStyle = 'bold'
    } else if (annotation.isItalic) {
      annotation.fontStyle = 'italic'
    } else {
      annotation.fontStyle = 'normal'
    }
    if (!this.annotation.selected && this.annotation.selected !== 0) {
      this.annotation.selected = null
    }

    const { start, end } = this.getActualRect(
      this.viewport,
      this.scale
    )
    this.start = start
    this.end = end

    const rect = this.calculate(start, end)

    const annotationContainer = document.createElement('div')
    annotationContainer.id = annotation.name
    annotationContainer.className = 'annotation'
    annotationContainer.style.top = rect.top + 'px'
    annotationContainer.style.left = rect.left + 'px'
    annotationContainer.style.width = rect.width + 'px'
    annotationContainer.style.height = rect.height + 'px'
    annotationContainer.style.backgroundColor = this.highlight ? '#4982E54D' : ''
    this.annotationContainer = annotationContainer
    this.annotationContainer.addEventListener('mousedown', this.handleClick.bind(this))

    let borderElement = createElement(
      'div',
      {
        left: 0,
        top: 0,
        width: `${Math.abs(rect.width)}px`,
        height: `${Math.abs(rect.height)}px`,
        position: 'relative'
      }
    )

    this.borderElement = borderElement
    let selectElement = createElement(
      'div',
      {
        width: `${Math.abs(rect.width)}px`,
        height: `${Math.abs(rect.height)}px`,
        borderColor: annotation.borderColor,
        borderWidth: (annotation.borderWidth || 1) + 'px',
        borderStyle: annotation.borderStyle || 'solid',
        cursor: 'pointer',
        backgroundColor: annotation.backgroundColor,
        fontSize: annotation.fontSize + 'px',
        fontWeight: annotation.isBold ? 'bold' : 'normal',
        fontStyle: annotation.isItalic ? 'italic' : 'normal',
        fontFamily: annotation.fontName,
        color: annotation.color || '#001A4E',
        overflow: 'auto'
      }
    )
    this.selectElement = selectElement

    this.borderElement.append(this.selectElement)
    this.annotationContainer.append(this.borderElement)
    this.container.append(this.annotationContainer)

    // 添加选项
    if (annotation.items && annotation.items.length > 0) {
      for (var i = 0; i < annotation.items.length; i++) {
        const optionElement = createElement(
          'div',
          {
            width: '100%',
            height: '30px',
            lineHeight: '30px',
            borderBottom: '1px solid #666666',
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap'
          },
          {
            class: 'option'
          }
        )
        optionElement.innerText = annotation.items[i].Value
        if (this.annotation.selected === i) {
          optionElement.style.backgroundColor = '#dcdcdc'
        }
        this.selectElement.appendChild(optionElement)
      }
    }

    this.outerLineContainer = document.createElement('div')
    this.outerLineContainer.className = 'outline-container'
    this.deletetButton = createSvg(
      "svg",
      {
        width: "30",
        height: "30",
        viewBox: "0 0 30 30",
        fill: "none",
        class: 'delete-button'
      },
      {
        width: '30px',
        height: '30px'
      }
    );
    this.deletetButton.addEventListener('click', this.onDelete)
    this.deletetButton.innerHTML = this.deleteSvgStr

    const left = (rect.left + rect.width - 30) + 'px'
    const top = (rect.top + rect.height + 8) + 'px'
    this.deletetButton.style.left = left
    this.deletetButton.style.top = top

    const outerLine = document.createElementNS("http://www.w3.org/2000/svg", "svg");

    outerLine.style.position = 'absolute'
    outerLine.style.zIndex = 1
    outerLine.style.left = `${rect.left - 8}px`
    outerLine.style.top = `${rect.top - 8}px`
    outerLine.style.width = `${rect.width + 8 * 2}px`
    outerLine.style.height = `${rect.height + 8 * 2}px`
    this.outerLine = outerLine

    this.moveRect = createSvg(
      "rect",
      {
        class: "move",
        'data-id': "move",
        stroke: "#4982E6",
        'stroke-width': 1,
        'fill-opacity': 0,
        width: rect.width + 8,
        height: rect.height + 8,
        x: 4,
        y: 4
      }
    );

    this.topLeftRect = createSvg(
      "rect",
      {
        class: "nw-resize",
        'data-id': "nw-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: 1,
        y: 1
      }
    );

    this.LeftRect = createSvg(
      "rect",
      {
        class: "w-resize",
        'data-id': "w-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: 1,
        y: rect.height / 2 + 5
      }
    );

    this.bottomLeftRect = createSvg(
      "rect",
      {
        class: "sw-resize",
        'data-id': "sw-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: 1,
        y: rect.height + 9
      }
    );

    this.bottomRect = createSvg(
      "rect",
      {
        class: "s-resize",
        'data-id': "s-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: rect.width / 2 + 5,
        y: rect.height + 9
      }
    );

    this.bottomRightRect = createSvg(
      "rect",
      {
        class: "se-resize",
        'data-id': "se-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: rect.width + 9,
        y: rect.height + 9
      }
    );

    this.rightRect = createSvg(
      "rect",
      {
        class: "e-resize",
        'data-id': "e-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: rect.width + 9,
        y: rect.height / 2 + 5
      }
    );

    this.topRightRect = createSvg(
      "rect",
      {
        class: "ne-resize",
        'data-id': "ne-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: rect.width + 9,
        y: 1
      }
    );

    this.topRect = createSvg(
      "rect",
      {
        class: "n-resize",
        'data-id': "n-resize",
        fill: "#FFFFFF",
        stroke: "#4982E6",
        'stroke-width': 1,
        width: 6,
        height: 6,
        x: rect.width / 2 + 4,
        y: 1
      }
    );

    this.outerLine.append(this.moveRect)
    this.outerLine.append(this.topLeftRect)
    this.outerLine.append(this.LeftRect)
    this.outerLine.append(this.bottomLeftRect)
    this.outerLine.append(this.bottomRect)
    this.outerLine.append(this.bottomRightRect)
    this.outerLine.append(this.rightRect)
    this.outerLine.append(this.topRightRect)
    this.outerLine.append(this.topRect)
    this.outerLineContainer.append(this.outerLine)
    this.outerLineContainer.append(this.deletetButton)
    this.initial = true

    if (this.layer.toolMode !== 'form') {
      if (this.annotation.isHidden == 1) {
        this.annotationContainer.style.display = 'none'
        this.annotationContainer.style.pointerEvents = 'none'
      } else if (this.annotation.isHidden == 0) {
        this.annotationContainer.style.display = 'block'
        this.annotationContainer.style.pointerEvents = 'auto'
      }
    }

    if (this.show) this.handleClick()
  }

  getActualRect(viewport, s,) {
    const annotation = this.annotation
    const { left: x1, top: y1, right: x2, bottom: y2 } = annotation.rect

    const start = getActualPoint(
      {
        x: x1,
        y: y1
      },
      viewport,
      s
    )
    const end = getActualPoint(
      {
        x: x2,
        y: y2
      },
      viewport,
      s
    )
    return {
      start,
      end
    }
  }

  rectCalc({ start, end }) {
    return {
      top: start.y < end.y ? start.y : end.y,
      left: start.x < end.x ? start.x : end.x,
      width: Math.abs(end.x - start.x),
      height: Math.abs(end.y - start.y),
    };
  };

  calculate(start, end) {
    const initRect = this.rectCalc({ start, end });
    const actualBdWidth = (this.annotation.borderWidth || 1) * this.scale

    return {
      top: initRect.top - actualBdWidth,
      left: initRect.left - actualBdWidth,
      width: initRect.width + actualBdWidth * 2,
      height: initRect.height + actualBdWidth * 2,
    }
  }

  getInitialPoint() {
    const s = this.scale
    const startX = this.start.x
    const startY = this.start.y
    const endX = this.end.x
    const endY = this.end.y

    const { width, height, rotation } = this.viewport;
    let x1, y1, x2, y2;
    if (rotation === 0) {
      x1 = startX / s;
      y1 = startY / s;
      x2 = endX / s;
      y2 = endY / s;
    } else if (rotation === 90) {
      x1 = startY / s;
      y1 = startX / s;
      x2 = endY / s;
      y2 = endX / s;
    } else if (rotation === 180) {
      x1 = (width - startX) / s;
      y1 = startY / s;
      x2 = (width - endX) / s;
      y2 = endY / s;
    } else {
      x1 = (height - startY) / s
      y1 = (width - startX) / s
      x2 = (height - endY) / s
      y2 = (width - endX) / s
    }
    return {
      start: {
        x: x1,
        y: y1,
      },
      end: {
        x: x2,
        y: y2,
      },
    };
  }

  updateTool() {
    if (!this.initial) return
    if (this.hidden) {
      if (this.layer.annotationStore.selectedElementName === this.annotation.name) {
        this.layer.selectedElementName = null
      }
      this.outerLineContainer.remove()
    } else {
      if (this.layer.annotationStore.selectedElementName !== this.annotation.name) {
        this.layer.annotationStore.selectedElementName = this.annotation.name
      }
      this.container.append(this.outerLineContainer)
      this.outerLine.addEventListener('mousedown', this.onMousedown)
      this.outerLine.addEventListener('touchstart', this.onMousedown)

      this.eventBus.dispatch('propertyChange', this.annotation)
    }
  }

  handleClick(event) {
    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
    if (this.layer.toolMode === 'form') {
      this.hidden = false
      this.updateTool()

      if (!this.hidden && document.getElementsByClassName('right-panel')[0].className.indexOf('closed') !== -1) {
        document.getElementById('propertyPanelButton').click()
      }

      this.eventBus._on('listBoxPropertyPanelChanged', this.handlePropertyPanel)
      onClickOutsideUp([this.annotationContainer, this.outerLine, this.deletetButton, document.getElementById('propertyPanelButton'), document.getElementsByClassName('right-panel')[0]], this.handleOutside.bind(this))
    } else {
      if (event.target && event.target.className === 'option') {
        const children = event.target.parentNode.children
        for (let i = 0; i < children.length; i++) {
          if (children[i] === event.target) {
            this.annotation.selected = i
            break
          }
        }
        this.handleSelectItemBg()
      }
    }
  }

  handleOutside() {
    if (!this.hidden && this.layer.annotationStore.selectedElementName === this.annotation.name) {
      document.getElementById('propertyPanelButton').click()
    }

    this.hidden = !this.hidden

    if (this.layer.annotationStore.selectedElementName === this.annotation.name) {
      this.layer.annotationStore.selectedElementName = null
    }
    this.outerLine.removeEventListener('mousedown', this.onMousedown)
    this.outerLine.removeEventListener('touchstart', this.onMousedown)
    this.outerLineContainer.remove()

    this.eventBus._off('listBoxPropertyPanelChanged', this.handlePropertyPanel)
  }

  handleMouseDown(event) {
    if (this.layer.tool) {
      event.stopPropagation()
    }
    const operatorId = event.target.getAttribute('data-id')

    const { pageX, pageY } = getClickPoint(event)
    this.startState = {
      operator: operatorId,
      clickX: pageX,
      clickY: pageY,
    }

    document.addEventListener('mousemove', this.onMousemove)
    document.addEventListener('mouseup', this.onMouseup)
    document.addEventListener('touchmove', this.onMousemove)
    document.addEventListener('touchend', this.onMouseup)

    this.handleClick()
  };

  handleMouseMove(event) {
    if (event.type === 'touchmove') {
      document.querySelector('.document-container').style.overflow = 'hidden'
    }
    this.moving = true
    const { pageX, pageY } = getClickPoint(event)
    const start = this.start
    const end = this.end
    const startState = this.startState

    const { width, height } = this.viewport
    if (startState.operator === 'nw-resize') {
      let x1 = pageX - (startState.clickX - this.start.x);
      let y1 = pageY - (startState.clickY - this.start.y);
      x1 = Math.min(end.x - 5, x1)
      x1 = Math.max(0, x1)
      y1 = Math.min(end.y - 5, y1)
      y1 = Math.max(0, y1)

      this.update({
        start: { x: x1, y: y1 },
        end,
      });
    } else if (startState.operator === 'w-resize') {
      let x1 = pageX - (startState.clickX - this.start.x);
      x1 = Math.min(end.x - 5, x1)
      x1 = Math.max(0, x1)

      this.update({
        start: { x: x1, y: start.y },
        end,
      });
    } else if (startState.operator === 'sw-resize') {
      let x1 = pageX - (startState.clickX - this.start.x);
      let y1 = pageY - (startState.clickY - this.end.y);
      x1 = Math.min(end.x - 5, x1)
      x1 = Math.max(0, x1)
      y1 = Math.min(height, y1)
      y1 = Math.max(start.y + 5, y1)

      this.update({
        start: { x: x1, y: start.y },
        end: { x: end.x, y: y1 },
      });
    } else if (startState.operator === 's-resize') {
      let y1 = pageY - (startState.clickY - this.end.y);
      y1 = Math.min(height, y1)
      y1 = Math.max(start.y + 5, y1)
      this.update({
        start,
        end: { x: end.x, y: y1 },
      });
    } else if (startState.operator === 'se-resize') {
      let x = pageX - (startState.clickX - this.end.x);
      let y = pageY - (startState.clickY - this.end.y);
      x = Math.min(width, x)
      x = Math.max(start.x + 5, x)
      y = Math.min(height, y)
      y = Math.max(start.y + 5, y)
      this.update({
        start,
        end: { x, y },
      });
    } else if (startState.operator === 'e-resize') {
      let x = pageX - (startState.clickX - this.end.x);
      x = Math.min(width, x)
      x = Math.max(start.x + 5, x)
      this.update({
        start,
        end: { x, y: end.y },
      });
    } else if (startState.operator === 'ne-resize') {
      let x = pageX - (startState.clickX - this.end.x);
      let y = pageY - (startState.clickY - this.start.y);
      x = Math.min(width, x)
      x = Math.max(start.x + 5, x)
      y = Math.min(end.y - 5, y)
      y = Math.max(0, y)
      this.update({
        start: { x: start.x, y },
        end: { x, y: end.y },
      });
    } else if (startState.operator === 'n-resize') {
      let y = pageY - (startState.clickY - this.start.y);
      y = Math.min(end.y - 5, y)
      y = Math.max(0, y)
      this.update({
        start: { x: start.x, y },
        end,
      });
    } else if (startState.operator === 'move') {
      let x1 = pageX - (startState.clickX - this.start.x);
      let y1 = pageY - (startState.clickY - this.start.y);
      let x2 = pageX - (startState.clickX - this.end.x);
      let y2 = pageY - (startState.clickY - this.end.y);

      const rect = {
        width: Math.abs(start.x - end.x),
        height: Math.abs(start.y - end.y)
      }
      if (x1 < x2) {
        x1 = Math.max(0, x1)
        x1 = Math.min(width - rect.width, x1)
        x2 = Math.max(rect.width, x2)
        x2 = Math.min(width, x2)
      } else {
        x2 = Math.max(0, x2)
        x2 = Math.min(width - rect.width, x2)
        x1 = Math.max(rect.width, x1)
        x1 = Math.min(width, x1)
      }

      if (y1 < y2) {
        y1 = Math.max(0, y1)
        y1 = Math.min(height - rect.height, y1)
        y2 = Math.max(rect.height, y2)
        y2 = Math.min(height, y2)
      } else {
        y2 = Math.max(0, y2)
        y2 = Math.min(height - rect.height, y2)
        y1 = Math.max(rect.height, y1)
        y1 = Math.min(height, y1)
      }

      this.update({
        start: { x: x1, y: y1 },
        end: { x: x2, y: y2 },
      });
    }
  }

  handleDelete(event) {
    if (this.layer.tool && event) {
      event.stopPropagation()
    }
    this.handleOutside()
    this.annotationContainer.remove()

    this.annotation.isDelete = true
    const annotationData = {
      type: 'delete',
      annotation: {
        operate: "del-annot",
        name: this.annotation.name,
        pageIndex: this.page
      }
    }
    this.annotation.annotPtr && (annotationData.annotation.annotPtr = this.annotation.annotPtr)
    if (!event) {
      annotationData.type = 'empty'
    }
    this.eventBus.dispatch('annotationChange', annotationData)
  }

  handleMouseUp(event) {
    if (this.layer.tool) {
      event.stopPropagation()
    }
    if (event.type === 'touchend') {
      document.querySelector('.document-container').style.overflow = 'auto'
    }
    this.moving = false
    document.removeEventListener('mousemove', this.onMousemove)
    document.removeEventListener('mouseup', this.onMouseup)
    document.removeEventListener('touchmove', this.onMousemove)
    document.removeEventListener('touchend', this.onMouseup)

    const { pageX, pageY } = getClickPoint(event)
    if (pageX === this.startState.clickX && pageY === this.startState.clickY) return

    this.start = this.newStart
    this.end = this.newEnd

    const annotation = this.annotation
    const { start, end } = this.getInitialPoint()

    const rect = {
      left: start.x,
      top: start.y,
      right: end.x,
      bottom: end.y
    }

    this.eventBus.dispatch('annotationChange', {
      type: 'modify',
      annotation: {
        operate: "mod-form",
        name: annotation.name,
        pageIndex: this.page,
        pagePtr: annotation.pagePtr,
        annotPtr: annotation.annotPtr,
        rect
      }
    })
  }

  update({ start, end }) {
    const rect = this.calculate(start, end)

    this.newStart = start
    this.newEnd = end

    this.annotationContainer.style.top = rect.top + 'px'
    this.annotationContainer.style.left = rect.left + 'px'
    this.annotationContainer.style.width = rect.width + 'px'
    this.annotationContainer.style.height = rect.height + 'px'

    this.annotationContainer.style.width = `${rect.width}px`;
    this.annotationContainer.style.height = `${rect.height}px`;

    this.borderElement.style.width = `${rect.width}px`;
    this.borderElement.style.height = `${rect.height}px`;

    this.selectElement.style.width = `${rect.width}px`;
    this.selectElement.style.height = `${rect.height}px`;

    this.outerLine.style.left = `${rect.left - 8}px`
    this.outerLine.style.top = `${rect.top - 8}px`
    this.outerLine.style.width = `${rect.width + 8 * 2}px`
    this.outerLine.style.height = `${rect.height + 8 * 2}px`

    const left = (rect.left + rect.width - 30) + 'px'
    const top = (rect.top + rect.height + 8) + 'px'
    this.deletetButton.style.left = left
    this.deletetButton.style.top = top

    this.moveRect.setAttribute('width', rect.width + 9)
    this.moveRect.setAttribute('height', rect.height + 9)

    this.LeftRect.setAttribute("y", rect.height / 2 + 5)

    this.bottomLeftRect.setAttribute("y", rect.height + 9)

    this.bottomRect.setAttribute("x", rect.width / 2 + 5)
    this.bottomRect.setAttribute("y", rect.height + 9)


    this.bottomRightRect.setAttribute("x", rect.width + 9)
    this.bottomRightRect.setAttribute("y", rect.height + 9)


    this.rightRect.setAttribute("x", rect.width + 9)
    this.rightRect.setAttribute("y", rect.height / 2 + 5)


    this.topRightRect.setAttribute("x", rect.width + 9)

    this.topRect.setAttribute("x", rect.width / 2 + 5)
  }

  handlePropertyPanel(props) {
    const annotation = this.annotation
    if (this.layer.annotationStore.selectedElementName !== annotation.name) return

    let updatePropsNum = 0
    for (const key in props) {
      for (const item in annotation) {
        if (item === key && this.annotation[item] !== props[key] && key !== 'items') {
          this.annotation[item] = props[key]
          updatePropsNum++

          annotation[item] = props[key]
          if (key === 'backgroundColor') {
            if (props[key] === '') {
              props.clearBackgroundColor = true
            }
            this.selectElement.style[key] = props[key]
          }
          if (key === 'fontSize') {
            this.selectElement.style.fontSize = props[key] + 'px'
          }
          if (key === 'color') {
            this.selectElement.style.color = props[key]
          }
          if (key === 'fontName') {
            this.selectElement.style.fontFamily = props[key]
          }
          if (key === 'fontStyle') {
            const fontStyle = props[key]
            if (fontStyle === 'boldItalic') {
              this.selectElement.style.fontStyle = 'italic'
              this.selectElement.style.fontWeight = 'bold'
              annotation.isBold = true
              annotation.isItalic = true
            } else if (fontStyle === 'bold') {
              this.selectElement.style.fontStyle = 'normal'
              this.selectElement.style.fontWeight = 'bold'
              annotation.isBold = true
              annotation.isItalic = false
            } else if (fontStyle === 'italic') {
              this.selectElement.style.fontStyle = 'italic'
              this.selectElement.style.fontWeight = 'normal'
              annotation.isBold = false
              annotation.isItalic = true
            } else {
              annotation.isItalic = false
              annotation.isBold = false
              this.selectElement.style.fontStyle = 'normal'
              this.selectElement.style.fontWeight = 'normal'
            }
          }
        }
      }

      if (key === 'item') {
        if (annotation.items.includes(props.item)) {
          delete props.item
          continue
        } else {
          updatePropsNum++

          annotation.items.push({
            Value: props.item,
            String: props.item
          })

          const optionElement = createElement(
            'div',
            {
              width: '100%',
              height: '30px',
              lineHeight: '30px',
              borderBottom: '1px solid #666666',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap'
            },
            {
              class: 'option'
            }
          )

          optionElement.value = props.item
          optionElement.innerHTML = props.item
          this.selectElement.appendChild(optionElement)

          props.item = {
            value: props.item,
            index: annotation.items.length - 1
          }
        }
      }

      if (key === 'deleteItemIndex') {
        updatePropsNum++

        const deleteItemIndex = props.deleteItemIndex
        if (annotation.selected === props.deleteItemIndex) {
          annotation.selected = null
        }
        annotation.items.splice(deleteItemIndex, 1)
        this.selectElement.children[deleteItemIndex].remove()
      }

      if (key === 'moveOption') {
        updatePropsNum++

        const fromIndex = props.moveOption.fromIndex
        const toIndex = props.moveOption.toIndex

        const items = annotation.items
        if (fromIndex > toIndex) {
          items.splice(fromIndex - 1, 2, items[fromIndex], items[fromIndex - 1])
        } else {
          items.splice(fromIndex, 2, items[fromIndex + 1], items[fromIndex])
        }
        props.moveOption.item = {
          Value: items[toIndex].Value,
          String: items[toIndex].String
        }

        const optionElement = this.selectElement.children[fromIndex]
        optionElement.remove()

        this.selectElement.insertBefore(optionElement, this.selectElement.children[toIndex])
      }
    }

    if (updatePropsNum > 0) {
      const annotationData = {
        operate: "mod-form",
        name: this.annotation.name,
        pageIndex: this.page,
        pagePtr: this.annotation.pagePtr,
        annotPtr: this.annotation.annotPtr,
      }
      if (!annotation.items.length) {
        props.clearOption = true
      }

      const isFont = ['fontSize', 'fontName', 'color', 'fontStyle'].some(item => props[item])
      if (isFont) {
        annotationData.fontSize = annotation.fontSize
        annotationData.color = annotation.color
        const fontArr = {
          Courier: {
            normal: 'Courier',
            bold: 'Courier-Bold',
            italic: 'Courier-Oblique',
            boldItalic: 'Courier-BoldOblique'
          },
          Helvetica: {
            normal: 'Helvetica',
            bold: 'Helvetica-Bold',
            italic: 'Helvetica-Oblique',
            boldItalic: 'Helvetica-BoldOblique'
          },
          Times: {
            normal: 'Times',
            bold: 'Times-Bold',
            italic: 'Times-Italic',
            boldItalic: 'Times-BoldItalic'
          }
        }

        const fontName = annotation.fontName
        if (annotation.isBold && annotation.isItalic) {
          annotationData.fontName = fontArr[fontName].boldItalic
        } else if (annotation.isBold) {
          annotationData.fontName = fontArr[fontName].bold
        } else if (annotation.isItalic) {
          annotationData.fontName = fontArr[fontName].italic
        } else {
          annotationData.fontName = fontArr[fontName].normal
        }
      }

      const updateAnnot = Object.assign({}, annotationData, props)
      !annotation.annotPtr && (updateAnnot.items = annotation.items)

      this.eventBus.dispatch('annotationChange', {
        type: 'modify',
        annotation: updateAnnot
      })
    }
  }

  setProperty(props) {
    const annotation = this.annotation
    if (props.name !== annotation.name) return

    for (const key in props) {
      for (const item in annotation) {
        if (item === key && annotation[item] !== props[key]) {
          annotation[item] = props[key]

          if (key === 'backgroundColor') {
            this.selectElement.style[key] = props[key]
          }
        }
      }
    }

    const annotationData = {
      operate: "mod-form",
      pageIndex: this.page,
      pagePtr: annotation.pagePtr,
      annotPtr: annotation.annotPtr,
    }

    const isFont = ['fontSize', 'fontName', 'color', 'fontStyle'].some(item => props[item])
    if (isFont) {
      annotationData.fontSize = annotation.fontSize
      annotationData.color = annotation.color
      const fontArr = {
        Courier: {
          normal: 'Courier',
          bold: 'Courier-Bold',
          italic: 'Courier-Oblique',
          boldItalic: 'Courier-BoldOblique'
        },
        Helvetica: {
          normal: 'Helvetica',
          bold: 'Helvetica-Bold',
          italic: 'Helvetica-Oblique',
          boldItalic: 'Helvetica-BoldOblique'
        },
        Times: {
          normal: 'Times',
          bold: 'Times-Bold',
          italic: 'Times-Italic',
          boldItalic: 'Times-BoldItalic'
        }
      }

      const fontName = annotation.fontName
      if (annotation.isBold && annotation.isItalic) {
        annotationData.fontName = fontArr[fontName].boldItalic
      } else if (annotation.isBold) {
        annotationData.fontName = fontArr[fontName].bold
      } else if (annotation.isItalic) {
        annotationData.fontName = fontArr[fontName].italic
      } else {
        annotationData.fontName = fontArr[fontName].normal
      }
    }

    const updateAnnot = Object.assign({}, annotationData, props)
    this.eventBus.dispatch('annotationChange', {
      type: 'modify',
      annotation: updateAnnot
    })
  }

  changeSelectAvailable() {
    if (this.layer.toolMode === 'form') {
      this.selectElement.style.pointerEvents = 'none'
    } else {
      this.selectElement.style.pointerEvents = 'auto'
    }
  }

  handleSelectItemBg() {
    for (const opt of this.selectElement.children) {
      opt.style.backgroundColor = 'unset'
    }
    if (this.selectElement.children[this.annotation.selected]) {
      this.selectElement.children[this.annotation.selected].style.backgroundColor = '#dcdcdc'
    }
    this.setProperty({
      selected: this.annotation.selected,
      name: this.annotation.name
    })
  }

  setHighlight (bool) {
    this.highlight = bool
    this.annotationContainer.style.backgroundColor = this.highlight ? '#4982E54D' : ''
  }
}
