package drawhelper

import (
	"image"
	"image/color"

	"git.lxtend.com/lixiangwuxian/imagedd/util"
)

// 辅助函数：在图像上绘制宽线条
func DrawThickLineOnImage(img *image.RGBA, x0, y0, x1, y1, width int, color color.Color) {
	// 获取颜色分量
	r, g, b, a := color.RGBA()
	r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)

	bounds := img.Bounds()

	// 使用Bresenham算法绘制线段作为中心线
	dx := util.Abs(x1 - x0)
	dy := util.Abs(y1 - y0)
	sx, sy := 1, 1
	if x0 >= x1 {
		sx = -1
	}
	if y0 >= y1 {
		sy = -1
	}
	err := dx - dy

	// 计算线宽的一半（向下取整）
	halfWidth := width / 2

	// 绘制线条
	x, y := x0, y0
	for {
		// 绘制宽线条（在中心点周围绘制圆形区域）
		for wy := -halfWidth; wy <= halfWidth; wy++ {
			for wx := -halfWidth; wx <= halfWidth; wx++ {
				// 只绘制在线宽范围内的点（圆形区域）
				if wx*wx+wy*wy <= halfWidth*halfWidth {
					DrawPointIfInBounds(img, bounds, x+wx, y+wy, r8, g8, b8, a8)
				}
			}
		}

		if x == x1 && y == y1 {
			break
		}

		e2 := 2 * err
		if e2 > -dy {
			err -= dy
			x += sx
		}
		if e2 < dx {
			err += dx
			y += sy
		}
	}
}

// 辅助函数：在图像上绘制线段
func DrawLineOnImage(img *image.RGBA, x0, y0, x1, y1 int, color color.Color) {
	r, g, b, a := color.RGBA()
	r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)

	// 输出颜色值用于调试
	// log.Printf("绘制线条: 颜色 RGBA(%d,%d,%d,%d)", r8, g8, b8, a8)

	bounds := img.Bounds()

	// 使用Bresenham算法绘制线段
	dx := util.Abs(x1 - x0)
	dy := util.Abs(y1 - y0)
	sx, sy := 1, 1
	if x0 >= x1 {
		sx = -1
	}
	if y0 >= y1 {
		sy = -1
	}
	err := dx - dy

	for {
		// 绘制点，但只在有效范围内
		DrawPointIfInBounds(img, bounds, x0, y0, r8, g8, b8, a8)

		if x0 == x1 && y0 == y1 {
			break
		}

		e2 := 2 * err
		if e2 > -dy {
			err -= dy
			x0 += sx
		}
		if e2 < dx {
			err += dx
			y0 += sy
		}
	}
}

// 辅助函数：在图像上绘制圆
func DrawCircleOnImage(img *image.RGBA, x0, y0 int, radius float64, color color.Color) {
	r, g, b, a := color.RGBA()
	r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)

	// 使用Bresenham算法绘制圆
	x := float64(0)
	y := float64(radius)
	d := 3 - 2*radius

	bounds := img.Bounds()

	for {
		// 绘制8个对称点，但只在图像范围内
		DrawPointIfInBounds(img, bounds, x0+int(x), y0+int(y), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0+int(x), y0-int(y), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0-int(x), y0+int(y), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0-int(x), y0-int(y), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0+int(y), y0+int(x), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0+int(y), y0-int(x), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0-int(y), y0+int(x), r8, g8, b8, a8)
		DrawPointIfInBounds(img, bounds, x0-int(y), y0-int(x), r8, g8, b8, a8)

		if d < 0 {
			d += 4*x + 6
		} else {
			d += 4*(x-y) + 10
			y--
		}
		x++

		if x > y {
			break
		}
	}
}

// 辅助函数：在图像上设置像素，但只在有效范围内
func DrawPointIfInBounds(img *image.RGBA, bounds image.Rectangle, x, y int, r, g, b, a uint8) {
	if x >= bounds.Min.X && x < bounds.Max.X && y >= bounds.Min.Y && y < bounds.Max.Y {
		// 记录绘制的像素位置和颜色，便于调试
		// if (r > 0 || g > 0 || b > 0) && a > 0 {
		// 	log.Printf("绘制像素: (%d,%d) RGBA(%d,%d,%d,%d)", x, y, r, g, b, a)
		// }

		idx := (y-bounds.Min.Y)*img.Stride + (x-bounds.Min.X)*4
		img.Pix[idx] = r
		img.Pix[idx+1] = g
		img.Pix[idx+2] = b
		img.Pix[idx+3] = a
	}
}
