package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"log"
	"os"
	"strconv"
	"time"
)

func red(p image.Image) image.Image {
	bits := ""
	rect := p.Bounds()
	n := image.NewRGBA(rect)
	for i := 0; i < rect.Max.Y; i++ {
		for j := 0; j < rect.Max.X; j++ {
			r, g, _, _ := p.At(j, i).RGBA()
			if i == 310 {
				//c, _, _, _ := p.(*image.NRGBA).At(j, i).RGBA()
				//c := color.RGBAModel.Convert(p.At(j, i)).(color.RGBA).R
				fmt.Fprintf(os.Stderr, "%08b %08b\n", uint8(r), uint8(g))
				fmt.Fprintf(os.Stderr, "%d %d\n", uint8(r), uint8(g))
				//bin := strconv.FormatUint(uint64(c.Y), 2)
				bin := fmt.Sprintf("%08b", uint8(g))
				bits += string(bin[len(bin)-1])
				prntln(" 10110101010001\n", bits)
				time.Sleep(time.Second)
			}
			if r != g {
				n.Set(j, i, color.Black)
				continue
			}
			n.Set(j, i, color.White)
			// y 1648
			// x 1538
		}
	}
	prntln(bits)
	b := bit2bytes(bits)
	_, a := alpha(p)
	for i := 0; i < len(a); i++ {
		a[i] ^= b[i]
	}
	bits = ""
	for _, v := range a {
		bits += fmt.Sprintf("%08b", ^v)
	}
	//prntln(bits)
	prntln(string(bit2bytes(bits)))
	return n
}

func alpha(p image.Image) (image.Image, []byte) {
	bits := ""
	rect := p.Bounds()
	n := image.NewRGBA(rect)
	for i := 0; i < rect.Max.Y; i++ {
		for j := 0; j < rect.Max.X; j++ {
			_, _, _, a := p.At(j, i).RGBA()
			if a == 65021 {
				n.Set(j, i, color.White)
				if i == 310 {
					bits += "1"
				}
				continue
			}
			if a == 65278 {
				n.Set(j, i, color.Black)
				if i == 310 {
					bits += "0"
				}
				continue
			}
			n.Set(j, i, color.White)
		}
	}
	return n, bit2bytes(bits)
}

func prntln(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
}

func bit2bytes(s string) (b []byte) {
	for i := 0; i < len(s)-8; i += 8 {
		n, _ := strconv.ParseUint(s[i:i+8], 2, 8)
		b = append(b, byte(n))
	}
	return
}

func main() {
	f, err := os.Open("challenge.png")
	if err != nil {
		log.Fatal(err)
	}
	p, err := png.Decode(f)
	if err != nil {
		log.Fatal(err)
	}
	n := red(p)
	//n, bits := alpha(p)
	//prntln(string(bits))

	err = png.Encode(os.Stdout, n)
	if err != nil {
		log.Fatal(err)
	}
}
