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

export default class Ink extends Base {
  constructor ({
    container,
    annotation,
    page,
    viewport,
    scale,
    eventBus,
    layer,
    show = false,
    enableReply = true
  }) {
    super({
      container,
      annotation,
      page,
      layer,
      viewport,
      scale,
      eventBus,
    })
    this.enableReply = enableReply

    this.hidden = true
    this.initial = false

    this.start = null
    this.end = null
    this.rect = null

    this.newStart = null
    this.newEnd = null

    this.svgElement = null

    this.startCircle = null
    this.endCircle = null
    this.startState = null

    this.show = show

    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.onOpenReply = this.openReply.bind(this)
    this.onKeydown = this.handleKeydown.bind(this)
    this.inkPath = []
    this.render()
  }

  formatePoint (x, y) {
    const point = getActualPoint(
      {
        x,
        y
      },
      this.viewport,
      this.scale
    )
    return [point.x, point.y]
  }

  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 });

    return {
      top: initRect.top,
      left: initRect.left,
      width: initRect.width,
      height: initRect.height,
    }
  }

  selectAnnotation () {
    if (this.layer.selectedElementName === this.annotation.name) return
    this.handleClick()
  }

  updateTool () {
    if (!this.initial) return
    if (this.hidden) {
      if (this.layer.selectedElementName === this.annotation.name) {
        this.layer.selectedElementName = null
      }
      this.outerLineContainer.remove()
      document.removeEventListener('keydown', this.onKeydown)
    } else {
      if (this.layer.selectedElementName !== this.annotation.name) {
        const annotation = this.annotation
        this.layer.selectedElementName = annotation.name

        const annotationData = {
          ...annotation
        }
        delete annotationData.annotPtr
        delete annotationData.pagePtr
        delete annotationData.operate
        delete annotationData.targetPage

        this.eventBus.dispatch('annotationSelected', annotationData)
      }
      this.container.append(this.outerLineContainer)
      this.outerLine.addEventListener('mousedown', this.onMousedown)
      this.outerLine.addEventListener('touchstart', this.onMousedown)
      document.addEventListener('keydown', this.onKeydown)

      const documentViewer = this.layer.documentViewer
      const scrollElement = documentViewer.getScrollViewElement()
      scrollElement.style.touchAction = 'none'
    }
  }

  handleClick (event) {
    if (this.layer.tool) {
      event && event.stopPropagation()
    }
    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event?.target)) return
    this.hidden = false
    this.updateTool()
    onClickOutside([this.svgElement, this.outerLine, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))
  }

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

    const documentViewer = this.layer.documentViewer
    const scrollElement = documentViewer.getScrollViewElement()
    scrollElement.style.touchAction = 'auto'
  }


  handleMouseDown (event) {
    if (event.button !== 0 && event.type === 'mousedown') return
    if (this.layer.tool) {
      event.stopPropagation()
    }

    this.ratioRateX = this.rect.height / this.rect.width
    this.ratioRateY = this.rect.width / this.rect.height

    const operatorId = event.target.getAttribute('data-id')
  
    const documentViewer = this.layer.documentViewer
    const scrollElement = documentViewer.getScrollViewElement()
    this.scrollTop = scrollElement.scrollTop
    this.scrollLeft = scrollElement.scrollLeft

    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)
    
  };

  handleMouseMove (event) {
    if (event.button !== 0 && event.type === 'mousemove') return
    if (event.type === 'touchmove') {
      document.querySelector('.document-container').addEventListener('scroll', event => event.preventDefault())
    }
    this.moving = true
    let { pageX, pageY } = getClickPoint(event)

    const documentViewer = this.layer.documentViewer
    const scrollElement = documentViewer.getScrollViewElement()
    const scrollTop = scrollElement.scrollTop
    const scrollLeft = scrollElement.scrollLeft
    pageX = pageX + scrollLeft - this.scrollLeft
    pageY = pageY + scrollTop - this.scrollTop

    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)

      if (event.shiftKey || event.type === "touchmove") {
        if (this.ratioRateX) {
          let moveX = x1 - this.start.x
          let moveY = moveX * this.ratioRateX
          y1 = this.start.y + moveY

          if (y1 < 0 || x1 < 0) return
        }
      }

      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)
      let y1 = start.y

      if(event.shiftKey || event.type === "touchmove") {
        y1 = Math.max(height, y1)
        y1 = Math.min(end.y - 5, y1)

        if (this.ratioRateX) {
          let moveX = x1 - this.start.x
          let moveY = moveX * this.ratioRateX
          y1 = this.start.y + moveY
          if (y1 >= height || x1 < 0) return
        }
      }

      this.update({
        start: { x: x1, y: y1 },
        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)

      if(event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let moveX = x1 - this.start.x
          let moveY = moveX * this.ratioRateX
          y1 = this.end.y - moveY
          if (y1 >= height || x1 < 0) return
        }
      }

      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)

      if(event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let moveY = y1 - this.end.y
          let moveX = moveY * this.ratioRateY
          let endX = this.end.x + moveX
          endX = Math.min(width, endX)
          endX = Math.max(start.x + 5, endX)

          if (y1 >= height || endX >= width) return

          this.update({
            start,
            end: { x: endX, y: y1 },
          });
        }
      } else {
        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)

      if (event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let moveX = this.end.x - x
          let moveY = moveX * this.ratioRateX
          y = this.end.y - moveY
  
          if (y >= height || x >= width) return
        }
      }

      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)

      if (event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let y = pageY - (startState.clickY - this.end.y);
          y = Math.min(height, y)
          y = Math.max(start.y + 5, y)

          let moveX = this.end.x - x
          let moveY = moveX * this.ratioRateX
          y = this.end.y - moveY
  
          if (y >= height || x >= width) return

          this.update({
            start,
            end: { x, y },
          });

        }
      } else {
        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)

      if(event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let moveX = this.end.x - x
          let moveY = moveX * this.ratioRateX
          y = this.start.y + moveY
  
          if (y <=0 || x >= width) return
        }
      }

      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)

      if(event.shiftKey || event.type==="touchmove") {
        if (this.ratioRateX) {
          let moveY = y - this.start.y
          let moveX = moveY * this.ratioRateY
          let endX = this.end.x - moveX
          endX = Math.min(width, endX)
          endX = Math.max(start.x + 5, endX)

          if (y >= height || endX >= width) return

          this.update({
            start: { x: start.x, y },
            end:  { x: endX, y: end.y },
          });
        }
      }
      else {
        this.update({
          start: { x: start.x, y },
          end,
        });
      }
     
    } else if (startState.operator === 'move') {
      let x1, y1, x2, y2
      const documentViewer = this.layer.documentViewer

      let windowCoordinates = this.getMouseLocation(event)
      const page = documentViewer.getSelectedPage(windowCoordinates, windowCoordinates)
      if (page.first && page.first !== (this.page + 1)) {
        const pagePoint = documentViewer.windowToPage(windowCoordinates, page.first, false)

        const annotationHeight = Math.abs(start.y - end.y)
        x1 = pageX - (startState.clickX - start.x)
        y1 = page.first > (this.page + 1) ? pagePoint.y : pagePoint.y - annotationHeight
        x2 = pageX - (startState.clickX - this.end.x)
        y2 = page.first > (this.page + 1) ? pagePoint.y + annotationHeight : pagePoint.y
        this.page = page.first - 1

        this.annotationContainer.remove()
        this.outerLineContainer.remove()
        const container = documentViewer.pdfViewer._pages[this.page].compdfAnnotationLayer.div
        container.append(this.annotationContainer)
        container.append(this.outerLineContainer)

        this.container = container
      } else {
        x1 = pageX - (startState.clickX - start.x);
        y1 = pageY - (startState.clickY - start.y);
        x2 = pageX - (startState.clickX - end.x);
        y2 = pageY - (startState.clickY - end.y);

        const windowPoint1 = documentViewer.pageToWindow({
          x: x1,
          y: y1
        }, this.page + 1, false)
        const windowPoint2 = documentViewer.pageToWindow({
          x: x2,
          y: y2
        }, this.page + 1, false)
        let x = 0, y = 0
        if (pageY > startState.clickY) {
          y = scrollElement.offsetHeight - (windowPoint2.y - scrollElement.scrollTop - scrollElement.offsetTop)
          y = y < 100 ? 5 : 0
        } else if (pageY < startState.clickY) {
          y = windowPoint1.y - scrollElement.scrollTop - scrollElement.offsetTop
          y = y < 100 ? -5 : 0
        }
        if (pageX > startState.clickX) {
          x = scrollElement.offsetWidth - (windowPoint2.x - scrollElement.scrollLeft - scrollElement.offsetLeft)
          x = x < 100 ? 5 : 0
        } else if (pageX < startState.clickX) {
          x = (windowPoint1.x - scrollElement.scrollLeft - scrollElement.offsetLeft)
          x = x < 100 ? -5 : 0
        }

        if (x || y) {
          scrollElement.scrollTop += y
          scrollElement.scrollLeft += x
        }

        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 },
      });
    }
    startState.clickX = pageX
    startState.clickY = pageY

  }

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

    this.delete()
    const annotationData = {
      type: 'delete',
      annotation: {
        operate: "del-annot",
        name: this.annotation.name,
        pageIndex: this.page
      }
    }
    this.annotation.annotPtr && (annotationData.annotation.annotPtr = this.annotation.annotPtr)

    this.eventBus.dispatch('annotationChange', annotationData)
  }

  delete () {
    this.handleOutside()
    this.annotationContainer?.remove()
    this.annotation.isDelete = true
    this.layer.deleteAnnotationInLayer({
      name: this.annotation.name
    })
  }

  handleKeydown (event) {
    // if (event.key === 'Delete' || event.key === 'Backspace') {
    //   this.handleDelete()
    // }
  }

  handleMouseUp (event) {
    if (event.button !== 0 && event.type === 'mouseup') return
    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)
    this.scrollLeft = 0
    this.scrollTop = 0

    this.startState = null

    const initialStart = getInitialPoint(this.start, this.viewport, this.scale)
    const initialEnd = getInitialPoint(this.end, this.viewport, this.scale)
    const rect = {
      left: initialStart.x,
      top: initialStart.y,
      right: initialEnd.x,
      bottom: initialEnd.y
    }

    const annotation = this.annotation
    if (rect === annotation.rect && annotation.pageIndex === this.page) return
    annotation.rect = rect

    let inkPointes = []
    for (let i = 0; i < this.inkPath.length; i++) {
      const inkPathPoints = []
      for (let j = 0; j < this.inkPath[i].length; j++) {
        inkPathPoints.push({
          PointX: this.inkPath[i][j].x / this.scale + initialStart.x,
          PointY: initialStart.y + this.inkPath[i][j].y / this.scale
        })
      }
      inkPointes.push(inkPathPoints)
    }
    annotation.inkPointes = inkPointes
    if (annotation.pageIndex !== this.page) {
      const annotationData = {
        type: 'delete',
        annotation: {
          operate: "del-annot",
          name: annotation.name,
          pageIndex: annotation.pageIndex,
          annotPtr: annotation.annotPtr
        }
      }
      this.eventBus.dispatch('annotationChange', annotationData)

      const newAnnotationData = Object.assign({}, annotation)
      delete newAnnotationData.annotPtr
      delete newAnnotationData.pagePtr
      delete newAnnotationData.name
      newAnnotationData.operate = 'add-annot'
      newAnnotationData.pageIndex = this.page
      this.eventBus.dispatch('annotationChange', {
        type: 'add',
        show: true,
        annotation: newAnnotationData
      })

      this.annotationContainer.remove()
      this.outerLineContainer.remove()
    } else {
      this.eventBus.dispatch('annotationChange', {
        type: 'modify',
        annotation: {
          operate: "mod-annot",
          name: this.annotation.name,
          pageIndex: this.page,
          pagePtr: this.annotation.pagePtr,
          annotPtr: this.annotation.annotPtr,
          inkPointes,
          rect
        }
      })
    }
  }

  handlePoint (point) {
    const rect = this.rect
    const newPoint = getInitialPoint(
      {
        x: point[0] + rect.left,
        y: point[1] + rect.top
      },
      this.viewport,
      this.scale
    )
    return newPoint.x + ',' + newPoint.y
  }

  update ({ start, end }) {
    const rect = this.calculate(start, end)
    if (this.startState && this.startState.operator !== 'move') {
      let rateX = (rect.width / this.rect.width)
      let rateY = (rect.height / this.rect.height)

      for (let i = 0; i < this.inkPath.length; i++) {
        for (let j = 0; j < this.inkPath[i].length; j++) {
          this.inkPath[i][j].x = rateX * this.inkPath[i][j].x
          this.inkPath[i][j].y = rateY * this.inkPath[i][j].y
        }
      }
    }

    this.rect = rect
    this.start = start
    this.end = end

    const annotation = this.annotation
    const actualbdwidth = this.annotation.borderWidth * this.scale

    this.annotationContainer.style.top = rect.top - actualbdwidth + 'px'
    this.annotationContainer.style.left = rect.left - actualbdwidth + 'px'
    this.annotationContainer.style.width = rect.width + actualbdwidth * 2 + 'px'
    this.annotationContainer.style.height = rect.height + actualbdwidth * 2 + 'px'

    this.svgElement.setAttribute("viewBox", `${-actualbdwidth} ${-actualbdwidth} ${rect.width + actualbdwidth * 2} ${rect.height + actualbdwidth * 2}`)
    this.svgElement.innerHTML=''
    for (let i = 0;i < this.inkPath.length; i++) {
      if (this.inkPath[i].length > 1) {
        const svgPath = document.createElementNS("http://www.w3.org/2000/svg", 'path');
        let d = 'M '+(this.inkPath[i][0].x).toFixed(2)+" "+(this.inkPath[i][0].y).toFixed(2)
        for (let j = 1; j < this.inkPath[i].length; j++) {
          d = d + " L " + (this.inkPath[i][j].x).toFixed(2) + " " + (this.inkPath[i][j].y).toFixed(2)
        }
        svgPath.setAttribute('d', d)
        svgPath.setAttribute("stroke", annotation.borderColor)
        svgPath.setAttribute("stroke-width", actualbdwidth)
        svgPath.setAttribute("stroke-opacity", annotation.opacity || 1.0)
        svgPath.setAttribute("fill", 'none')
        svgPath.setAttribute("fill-opacity", 0)

        if (actualbdwidth < 5) {
          const svgCoverPath = document.createElementNS("http://www.w3.org/2000/svg", 'path');
          svgCoverPath.setAttribute('d', d)
          svgCoverPath.setAttribute("stroke", annotation.borderColor)
          svgCoverPath.setAttribute("stroke-width", actualbdwidth < 5 ? 5 : actualbdwidth)
          svgCoverPath.setAttribute("stroke-opacity", 0)
          svgCoverPath.setAttribute("fill", 'none')
          svgCoverPath.setAttribute("fill-opacity", 0)
          svgPath.style.pointerEvents = 'none'
  
          this.svgElement.append(svgCoverPath)
        }
        this.svgElement.append(svgPath)
      } else if(this.inkPath[i].length == 1) {
        const svgCircle = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
        svgCircle.setAttribute('cx', (this.inkPath[i][0].x).toFixed(2))
        svgCircle.setAttribute('cy', (this.inkPath[i][0].y).toFixed(2))
        svgCircle.setAttribute('r', actualbdwidth/2)
        svgCircle.setAttribute("fill", annotation.borderColor)
        this.svgElement.append(svgCircle)
      }
    }

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

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

    this.replyButton.style.left = (rect.left + rect.width - 65) + 'px'
    this.replyButton.style.top = (rect.top + rect.height + 8) + 'px'
    
    this.moveRect.setAttribute('width',  rect.width + 8)
    this.moveRect.setAttribute('height',  rect.height + 8)
    
    this.LeftRect.setAttribute("y", rect.height / 2 + 4)

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

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



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


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

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

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

  render() {
    const annotation = this.annotation
    let { left, top, right, bottom } = annotation.rect
    left = parseFloat(left * this.scale)
    bottom = parseFloat(bottom * this.scale)
    right = parseFloat(right * this.scale)
    top = parseFloat(top * this.scale)
    const rect = {
      left,
      top,
      bottom,
      right,
      width: right - left,
      height: bottom - top
    }
    this.rect = rect
    this.start = { x: rect.left, y: rect.top }
    this.end = { x: rect.right, y: rect.bottom }

    if (!annotation.borderColor) {
      annotation.borderColor = '#000000'
    }

    const inkPointes = annotation.inkPointes
    for (let i = 0; i < inkPointes.length; i++) {
      let points = inkPointes[i]
      let pointArray=[]
      for (let j = 0; j < points.length; j++) {
        let point = points[j]
        let pos = this.formatePoint(parseFloat(point.PointX), parseFloat(point.PointY))
        pointArray.push({
          x: parseFloat(pos[0].toFixed(2)) - this.rect.left,
          y: parseFloat((pos[1]).toFixed(2)) - this.rect.top
        })
      }
      if (pointArray.length > 0) {
        this.inkPath.push(pointArray)
      }
    }

    const actualbdwidth = this.annotation.borderWidth * this.scale
    
    const annotationContainer = document.createElement('div')
    annotationContainer.id = annotation.name
    annotationContainer.className = 'annotation'
    annotationContainer.style.top = rect.top - actualbdwidth + 'px'
    annotationContainer.style.left = rect.left - actualbdwidth + 'px'
    annotationContainer.style.width = rect.width + actualbdwidth * 2 + 'px'
    annotationContainer.style.height = rect.height + actualbdwidth * 2 + 'px'
    this.annotationContainer = annotationContainer

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

    this.svgElement.setAttribute("viewBox", `${-actualbdwidth} ${-actualbdwidth} ${rect.width + actualbdwidth * 2} ${rect.height + actualbdwidth * 2}`)
    this.svgElement.addEventListener('mousedown', this.handleClick.bind(this))

    for (let i = 0; i < this.inkPath.length; i++) {
      if (this.inkPath[i].length > 1) {
        const svgPath = document.createElementNS("http://www.w3.org/2000/svg", 'path');
        let d='M ' + (this.inkPath[i][0].x).toFixed(2) + " " + (this.inkPath[i][0].y).toFixed(2)
        for (let j = 1; j < this.inkPath[i].length; j++) {
          d = d + " L " + (this.inkPath[i][j].x).toFixed(2) + " " + (this.inkPath[i][j].y).toFixed(2)
        }
        svgPath.setAttribute('d', d)
        svgPath.setAttribute("stroke", annotation.borderColor)
        svgPath.setAttribute("stroke-width", actualbdwidth)
        svgPath.setAttribute("stroke-opacity", annotation.opacity || 1.0)
        svgPath.setAttribute("fill", 'none')
        svgPath.setAttribute("fill-opacity", 0)

        if (actualbdwidth < 5) {
          const svgCoverPath = document.createElementNS("http://www.w3.org/2000/svg", 'path');
          svgCoverPath.setAttribute('d', d)
          svgCoverPath.setAttribute("stroke", annotation.borderColor)
          svgCoverPath.setAttribute("stroke-width", actualbdwidth < 5 ? 5 : actualbdwidth)
          svgCoverPath.setAttribute("stroke-opacity", 0)
          svgCoverPath.setAttribute("fill", 'none')
          svgCoverPath.setAttribute("fill-opacity", 0)
          svgPath.style.pointerEvents = 'none'
  
          this.svgElement.append(svgCoverPath)
        }
        this.svgElement.append(svgPath)
      } else if (this.inkPath[i].length == 1) {
        const svgCircle = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
        svgCircle.setAttribute('cx', (this.inkPath[i][0].x).toFixed(2))
        svgCircle.setAttribute('cy', (this.inkPath[i][0].y).toFixed(2))
        svgCircle.setAttribute('r', actualbdwidth/2)

        svgCircle.setAttribute("fill", annotation.borderColor)
        this.svgElement.append(svgCircle)
      }
    }

    this.annotationContainer.append(this.svgElement)
    this.container.append(this.annotationContainer)
    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 leftPos = (rect.left + rect.width - 30) + 'px'
    const topPos = (rect.top + rect.height + 8) + 'px'
    this.deletetButton.style.left = leftPos
    this.deletetButton.style.top = topPos

    this.replyButton = createElement(
      'div',
      {
        width: '30px',
        height: '30px',
        background: '#DDE9FF',
        borderRadius: '2px',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center'
      },
      {
        class: 'reply-button'
      }
    );
    this.replyButton.addEventListener('click', this.onOpenReply)
    this.replyButton.innerHTML = this.replySvgStr
    this.replyButton.style.left = (rect.left + rect.width - 65) + 'px'
    this.replyButton.style.top = (rect.top + rect.height + 8) + 'px'
    
    const outerLine = document.createElementNS("http://www.w3.org/2000/svg", "svg")
    outerLine.style.position = 'absolute'
    outerLine.style.zIndex = 1
    outerLine.style.left = `${rect.left - 7}px`
    outerLine.style.top = `${rect.top - 7}px`
    outerLine.style.width = `${rect.width + 7 * 2}px`
    outerLine.style.height = `${rect.height + 7 * 2}px`
    this.outerLine = outerLine

    this.moveRect = createSvg(
      "rect",
      {
        class: "move",
        'data-id': "move",
        stroke: "#1460F3",
        'stroke-width': 1,
        'fill-opacity': 0,
        width: rect.width + 8,
        height: rect.height + 8,
        x: 3,
        y: 3
      }
    );
    
    this.topLeftRect = createSvg(
      "rect",
      {
        class: "nw-resize",
        'data-id': "nw-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: 0,
        y: 0
      }
    );

    this.LeftRect = createSvg(
      "rect",
      {
        class: "w-resize",
        'data-id': "w-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: 0,
        y: rect.height / 2 + 4
      }
    );

    this.bottomLeftRect = createSvg(
      "rect",
      {
        class: "sw-resize",
        'data-id': "sw-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: 0,
        y: rect.height + 8
      }
    );

    this.bottomRect = createSvg(
      "rect",
      {
        class: "s-resize",
        'data-id': "s-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: rect.width / 2 + 4,
        y: rect.height + 8
      }
    );
    
    this.bottomRightRect = createSvg(
      "rect",
      {
        class: "se-resize",
        'data-id': "se-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: rect.width + 8,
        y: rect.height + 8
      }
    );

    this.rightRect = createSvg(
      "rect",
      {
        class: "e-resize",
        'data-id': "e-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: rect.width + 8,
        y: rect.height / 2 + 4
      }
    );

    this.topRightRect = createSvg(
      "rect",
      {
        class: "ne-resize",
        'data-id': "ne-resize",
        fill: "#1460F3",
        stroke: "none",
        width: 6,
        height: 6,
        x: rect.width + 8,
        y: 0
      }
    );

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

    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.enableReply && this.outerLineContainer.append(this.replyButton)
    this.initial = true
    if (this.show) {
      !this.layer.addMode && this.selectAnnotation()
      this.show = false
    }
  }

  openReply () {
    this.eventBus.dispatch('openAnnotationReply', this.annotation)
  }
}
