package main

import (
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"os"
)

type XORMask struct {
	dst, src image.Image
}

func (m XORMask) ColorModel() color.Model { return color.Gray16Model }
func (m XORMask) Bounds() image.Rectangle { return m.dst.Bounds() }
func (m XORMask) At(x, y int) color.Color {
	srcColor := m.src.At(x, y)
	dstColor := m.dst.At(x, y)

	if ((dstColor == color.Black) || (srcColor == color.Black)) &&
		!((dstColor == color.Black) && (srcColor == color.Black)) {
		return color.Black
	}
	return color.White
}

func main() {
	img, err := png.Decode(os.Stdin)
	if err != nil {
		panic(err)
	}

	grayImg := image.NewGray16(img.Bounds())
	for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
		for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ {
			c := img.At(x, y)
			grayImg.Set(x, y, color.Gray16Model.Convert(c))
		}
	}
	canvas := image.NewRGBA(img.Bounds())
	circle := Circles(canvas.Bounds(), canvas.Bounds().Dy()/6)
	for i := 0; i < 24; i++ {
		c := <-circle
		draw.Draw(canvas, c.Bounds(), xor{c, canvas}, c.Bounds().Min, draw.Src)
	}

	err = png.Encode(
		os.Stdout, XORMask{
			grayImg,
			BlackAndWhite{
				Exchange{
					canvas,
				},
			},
		},
	)
	if err != nil {
		panic(err)
	}

}
