<template>
  <div class="dds-component" :style="{ width: width + 'px', height: height + 'px', position: 'relative' }">
    <svg 
      xmlns="http://www.w3.org/2000/svg" 
      :width="width" 
      :height="height" 
      viewBox="0 0 300 200"
      class="dds-device"
    >      <!-- 信号发生器外壳，扩大屏幕部分 -->
      <rect width="300" height="180" rx="10" ry="10" fill="#2a323c" stroke="#444" stroke-width="2" />
      
      <!-- 信号发生器显示屏，扩大屏幕 -->
      <rect x="20" y="20" width="260" height="140" rx="5" ry="5" fill="#1a1f25" stroke="#555" stroke-width="1" />
      
      <!-- 波形显示 -->
      <path :d="currentWaveformPath" stroke="lime" stroke-width="2" fill="none" />
        
      <!-- 信息显示区域 -->
      <text x="30" y="40" fill="#0f0" font-size="14">{{ displayFrequency }}</text>
      <text x="200" y="40" fill="#0f0" font-size="14">φ: {{ phase }}°</text>
    </svg>
    
    <!-- 输出引脚 -->
    <div 
      v-for="pin in pins" 
      :key="pin.pinId"
      :style="{
        position: 'absolute',
        left: `${pin.x * props.size}px`,
        top: `${pin.y * props.size}px`,
        transform: 'translate(-50%, -50%)'
      }"
      :data-pin-wrapper="`${pin.pinId}`"
      :data-pin-x="`${pin.x * props.size}`"
      :data-pin-y="`${pin.y * props.size}`"
    >
      <Pin
        :ref="el => { if(el) pinRefs[pin.pinId] = el }"
        :label="pin.pinId"
        :constraint="pin.constraint"
        :pinId="pin.pinId"
        @pin-click="$emit('pin-click', $event)"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, watchEffect } from 'vue';
import Pin from './Pin.vue';

// 存储Pin引用
const pinRefs = ref<Record<string, any>>({});

// DDS属性
interface DDSProps {
  size?: number;
  pins?: {
    pinId: string;
    constraint: string;
    x: number;
    y: number;
  }[];
  frequency?: number;
  phase?: number;
  timebase?: number; // 添加时基属性
  waveform?: string;
  savedWaveforms?: string[];
  customWaveformPoints?: number[][];
}

const props = withDefaults(defineProps<DDSProps>(), {
  size: 1,
  pins: () => [
    { pinId: 'OUT', constraint: '', x: 300, y: 90 }, // 调整输出引脚位置
  ],
  frequency: 1000,
  phase: 0,
  timebase: 1, // 默认时基为1
  waveform: 'sine',
  savedWaveforms: () => ['sine', 'square', 'triangle', 'sawtooth'],
  customWaveformPoints: () => []
});

// 组件尺寸
const width = computed(() => 300 * props.size);
const height = computed(() => 180 * props.size); // 减小整体高度

// 波形状态
const frequency = ref(props.frequency);
const phase = ref(props.phase);
const timebase = ref(props.timebase || 1); // 添加时基参数，默认为1
const currentWaveformIndex = ref(0);
const waveformNames = ['正弦波', '方波', '三角波', '锯齿波'];
const waveforms = ['sine', 'square', 'triangle', 'sawtooth'];

watchEffect(()=>{
  console.log(`DDS Porperties: ${frequency.value} ${timebase.value}`)
})

// 波形函数集合
interface WaveformFunction {
  (x: number, width: number, height: number, phaseRad: number): number;
}

interface WaveformFunctions {
  [key: string]: WaveformFunction;
}

const waveformFunctions: WaveformFunctions = {
  // 正弦波函数: sin(2π*x + φ)
  sine: (x: number, width: number, height: number, phaseRad: number): number => {
    return height/2 * Math.sin(2 * Math.PI * (x / width) * 2 + phaseRad);
  },
  
  // 方波函数: 周期性的高低电平
  square: (x: number, width: number, height: number, phaseRad: number): number => {
    const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
    return normX < 0.5 ? height/4 : -height/4;
  },
  
  // 三角波函数: 线性上升和下降
  triangle: (x: number, width: number, height: number, phaseRad: number): number => {
    const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
    return height/2 - height * Math.abs(2 * normX - 1);
  },
  
  // 锯齿波函数: 线性上升,瞬间下降
  sawtooth: (x: number, width: number, height: number, phaseRad: number): number => {
    const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
    return height/2 - height/2 * (2 * normX);
  }
};

// 计算当前显示频率
const displayFrequency = computed(() => {
  if (frequency.value >= 1000000) {
    return `${(frequency.value / 1000000).toFixed(2)} MHz`;
  } else if (frequency.value >= 1000) {
    return `${(frequency.value / 1000).toFixed(2)} kHz`;
  } else {
    return `${frequency.value.toFixed(2)} Hz`;
  }
});

// 格式化时基显示
function formatTimebase(tb: number): string {
  if (tb < 0.1) {
    return `${(tb * 1000).toFixed(0)} ms/div`;
  } else if (tb < 1) {
    return `${(tb * 1000).toFixed(0)} ms/div`;
  } else {
    return `${tb.toFixed(1)} s/div`;
  }
}

// 计算当前显示时基
const displayTimebase = computed(() => formatTimebase(timebase.value));

// 生成波形路径
const currentWaveformPath = computed(() => {
  const width = 240;
  const height = 100; // 更大的波形显示高度，因为我们增加了屏幕高度
  const xOffset = 30;
  const yOffset = 50; // 上移位置以适应新布局
  const currentWaveform = waveforms[currentWaveformIndex.value];
  const phaseRadians = phase.value * Math.PI / 180;
  
  // 时基和频率共同影响周期数量
  // 频率因素 - 频率越高，一个屏幕内显示的周期越多
  // 使用对数缩放可以更好地表示广泛范围的频率变化
  const freqLog = Math.log10(frequency.value) - 2; // 从100Hz开始作为基准
  const frequencyFactor = Math.max(0.1, Math.min(10, freqLog)); // 限制在合理范围内
  
  // 时基影响周期数量 - 时基越小，显示的周期越多
  const timebaseFactor = 1 / timebase.value;
  
  // 组合因素
  const scaleFactor = timebaseFactor * frequencyFactor;
  
  let path = `M${xOffset},${yOffset + height/2}`;
  
  // 使用波形函数生成路径
  const waveFunction = waveformFunctions[currentWaveform];
  
  // 生成路径点
  for (let x = 0; x <= width; x++) {
    // 应用组合缩放因素 - 影响x轴的缩放
    const scaledX = x * scaleFactor;
    const y = waveFunction(scaledX, width, height, phaseRadians);
    path += ` L${x + xOffset},${yOffset + height/2 - y}`;
  }
  
  return path;
});

// 波形操作函数
function selectWaveform(index: number) {
  currentWaveformIndex.value = index;
}

function increaseFrequency() {
  if (frequency.value < 10) {
    frequency.value += 0.1;
  } else if (frequency.value < 100) {
    frequency.value += 1;
  } else if (frequency.value < 1000) {
    frequency.value += 10;
  } else if (frequency.value < 10000) {
    frequency.value += 100;
  } else if (frequency.value < 100000) {
    frequency.value += 1000;
  } else {
    frequency.value += 10000;
  }
  frequency.value = Math.min(frequency.value, 10000000); // 最大10MHz
}

function decreaseFrequency() {
  if (frequency.value <= 10) {
    frequency.value -= 0.1;
  } else if (frequency.value <= 100) {
    frequency.value -= 1;
  } else if (frequency.value <= 1000) {
    frequency.value -= 10;
  } else if (frequency.value <= 10000) {
    frequency.value -= 100;
  } else if (frequency.value <= 100000) {
    frequency.value -= 1000;
  } else {
    frequency.value -= 10000;
  }
  frequency.value = Math.max(frequency.value, 0.1); // 最小0.1Hz
  frequency.value = parseFloat(frequency.value.toFixed(1)); // 修复浮点数精度问题
}

function increasePhase() {
  phase.value += 15;
  if (phase.value >= 360) {
    phase.value -= 360;
  }
}

function decreasePhase() {
  phase.value -= 15;
  if (phase.value < 0) {
    phase.value += 360;
  }
}

// 监听props变化
watch(
  () => props.frequency,
  (newValue) => {
    if (newValue !== undefined && newValue !== frequency.value) {
      frequency.value = newValue;
    }
  }
);

watch(
  () => props.phase,
  (newValue) => {
    if (newValue !== undefined && newValue !== phase.value) {
      phase.value = newValue;
    }
  }
);

watch(
  () => props.timebase,
  (newValue) => {
    if (newValue !== undefined && newValue !== timebase.value) {
      timebase.value = newValue;
    }
  }
);

watch(
  () => props.waveform,
  (newValue) => {
    if (newValue !== undefined) {
      const index = waveforms.indexOf(newValue);
      if (index !== -1) {
        currentWaveformIndex.value = index;
      }
    }
  }
);

onMounted(() => {
  // 初始化波形类型
  if (props.waveform) {
    const index = waveforms.indexOf(props.waveform);
    if (index !== -1) {
      currentWaveformIndex.value = index;
    }
  }
  
  // 初始化时基
  if (props.timebase !== undefined) {
    timebase.value = props.timebase;
  }
});

// 暴露属性和方法
defineExpose({
  frequency,
  phase,
  timebase,
  currentWaveformIndex,
  selectWaveform,
  increaseFrequency,
  decreaseFrequency,
  increasePhase,
  decreasePhase
});
</script>

<style scoped>
.dds-component {
  display: inline-block;
  position: relative;
}
</style>

<!-- 导出默认属性函数供外部使用 -->
<script lang="ts">
export function getDefaultProps() {
  return {
    size: 1,
    pins: [
      { pinId: 'OUT', constraint: '', x: 300, y: 90 }, // 调整输出引脚位置
    ],
    frequency: 1000,
    phase: 0,
    timebase: 1, // 添加默认时基
    waveform: 'sine',
    savedWaveforms: ['sine', 'square', 'triangle', 'sawtooth'],
    customWaveformPoints: []
  };
}
</script>
