<template>
  <div class="mx-palette">
    <div class="palette-title">基本图形</div>
    <div v-for="(shape, index) in shapes" :key="index" class="palette-shape" draggable="true"
      @dragstart="handleDragStart($event, shape)" @dblclick="handleDoubleClick(shape)">
      <div class="shape-icon" :style="getShapeStyle(shape)">
        {{ shape.icon }}
      </div>
      <div class="shape-label">{{ shape.label }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { inject } from 'vue'
import { myMxConstants, myMxGraph } from '@/graph/mxGraph'

export interface PaletteShape {
  type: string
  label: string
  width: number
  height: number
  style: Record<string, any>
  icon?: string
  iconColor?: string
}

const graph = inject<Ref<InstanceType<typeof myMxGraph> | null>>('mxgraph-instance')

const shapes: PaletteShape[] = [
  {
    type: myMxConstants.SHAPE_RECTANGLE,
    label: '矩形',
    width: 80,
    height: 60,
    style: {
      [myMxConstants.STYLE_FILLCOLOR]: '#ffffff',
      [myMxConstants.STYLE_STROKECOLOR]: '#2d8cf0'
    },
    icon: '□',
    iconColor: '#2d8cf0'
  }
  // 其他形状定义...
]

function getShapeStyle(shape: PaletteShape) {
  return {
    backgroundColor: shape.style[myMxConstants.STYLE_FILLCOLOR] || '#ffffff',
    borderColor: shape.style[myMxConstants.STYLE_STROKECOLOR] || '#000000',
    color: shape.iconColor
  }
}

function handleDragStart(event: DragEvent, shape: PaletteShape) {
  if (!graph?.value) return

  event.dataTransfer?.setData('text/plain', JSON.stringify(shape))

  const dragPreview = document.createElement('div')
  dragPreview.style.width = `${shape.width}px`
  dragPreview.style.height = `${shape.height}px`
  dragPreview.style.border = `2px dashed ${shape.style[myMxConstants.STYLE_STROKECOLOR]}`
  dragPreview.style.backgroundColor = shape.style[myMxConstants.STYLE_FILLCOLOR] || 'white'
  document.body.appendChild(dragPreview)
  event.dataTransfer?.setDragImage(dragPreview, shape.width / 2, shape.height / 2)

  setTimeout(() => document.body.removeChild(dragPreview), 0)
}

function handleDoubleClick(shape: PaletteShape) {
  if (!graph?.value) return

  const parent = graph.value.getDefaultParent()
  const pt = graph.value.getFreeInsertPoint()

  graph.value.getModel().beginUpdate()
  try {
    graph.value.insertVertex(
      parent,
      null,
      shape.label,
      pt.x,
      pt.y,
      shape.width,
      shape.height,
      shape.type
    )
  } finally {
    graph.value.getModel().endUpdate()
  }
}
</script>
<style lang="scss" scoped>
.mx-palette {
  width: 160px;
  height: 100%;
  border-right: 1px solid #e0e0e0;
  background-color: #f5f5f5;
  overflow-y: auto;
  user-select: none;
}

.palette-title {
  padding: 10px;
  font-weight: bold;
  border-bottom: 1px solid #ddd;
  background-color: #eee;
  position: sticky;
  top: 0;
  z-index: 1;
}

.palette-shape {
  padding: 10px;
  margin: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: white;
  cursor: move;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: all 0.2s;
}

.palette-shape:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.shape-icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid;
  margin-bottom: 5px;
  font-size: 20px;
  border-radius: 3px;
}

.shape-label {
  font-size: 12px;
  text-align: center;
}
</style>
