package downscale

import (
	"image"
	"image/color"
)

type sub struct {
	image.Image
	image.Rectangle
}

func (sub sub) ColorModel() color.Model { return sub.Image.ColorModel() }
func (sub sub) Bounds() image.Rectangle { return sub.Rectangle }
func (sub sub) At(x, y int) color.Color {
	return sub.Image.At(x, y)
}

type GridDownscale struct {
	image.Image
	newBounds image.Rectangle
}

func blend(c1, c2 color.Color) color.RGBA {
	r1, g1, b1, a1 := c1.RGBA()
	r2, g2, b2, a2 := c2.RGBA()

	r := r1/2 + r2/2
	g := g1/2 + g2/2
	b := b1/2 + b2/2
	a := a1/2 + a2/2

	return color.RGBA{
		R: uint8(r >> 8),
		G: uint8(g >> 8),
		B: uint8(b >> 8),
		A: uint8(a >> 8),
	}
}

func avgColor(img image.Image) (c color.Color) {
	dx, dy := img.Bounds().Dx(), img.Bounds().Dy()
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			c = blend(c, img.At(x, y))
		}
	}
	return
}

func (grid grid) ColorModel() color.Model { return grid.Image.ColorModel }
func (grid grid) Bounds() image.Rectangle { return grid.NewBounds }
func (grid grid) At(x, y int) color.Color {
	b := grid.Image.Bounds()
	dx, dy := b.Dx(), b.Dy()
	cellBounds := image.Rect(
		0, 0,
		dx/grid.newBounds.Dx(),
		dy/grid.newBounds.Dy(),
	)

	r := grid.Image.Bounds().Intersect(
		// move cell
		cellBounds.Add(
			image.Point{
				x * cellBounds.Dx(),
				y * cellBounds.Dy(),
			},
		),
	)

	return avgColor(sub{grid.Image, r})
}
