// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin linux,!android

// TODO(crawshaw): Run tests on other OSs when more contexts are supported.

package glutil

import (
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"io/ioutil"
	"os"
	"runtime"
	"testing"

	"golang.org/x/mobile/event/config"
	"golang.org/x/mobile/geom"
	"golang.org/x/mobile/gl"
)

func TestImage(t *testing.T) {
	done := make(chan struct{})
	defer close(done)
	go func() {
		runtime.LockOSThread()
		ctx := createContext()
		for {
			select {
			case <-gl.WorkAvailable:
				gl.DoWork()
			case <-done:
				ctx.destroy()
				return
			}
		}
	}()
	start()
	defer stop()

	// GL testing strategy:
	// 	1. Create an offscreen framebuffer object.
	// 	2. Configure framebuffer to render to a GL texture.
	//	3. Run test code: use glimage to draw testdata.
	//	4. Copy GL texture back into system memory.
	//	5. Compare to a pre-computed image.

	f, err := os.Open("../../../testdata/testpattern.png")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	src, _, err := image.Decode(f)
	if err != nil {
		t.Fatal(err)
	}

	const (
		pixW = 100
		pixH = 100
		ptW  = geom.Pt(50)
		ptH  = geom.Pt(50)
	)
	cfg := config.Event{
		Width:       ptW,
		Height:      ptH,
		PixelsPerPt: float32(pixW) / float32(ptW),
	}

	fBuf := gl.CreateFramebuffer()
	gl.BindFramebuffer(gl.FRAMEBUFFER, fBuf)
	colorBuf := gl.CreateRenderbuffer()
	gl.BindRenderbuffer(gl.RENDERBUFFER, colorBuf)
	// https://www.khronos.org/opengles/sdk/docs/man/xhtml/glRenderbufferStorage.xml
	// says that the internalFormat "must be one of the following symbolic constants:
	// GL_RGBA4, GL_RGB565, GL_RGB5_A1, GL_DEPTH_COMPONENT16, or GL_STENCIL_INDEX8".
	gl.RenderbufferStorage(gl.RENDERBUFFER, gl.RGB565, pixW, pixH)
	gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuf)

	if status := gl.CheckFramebufferStatus(gl.FRAMEBUFFER); status != gl.FRAMEBUFFER_COMPLETE {
		t.Fatalf("framebuffer create failed: %v", status)
	}

	allocs := testing.AllocsPerRun(100, func() {
		gl.ClearColor(0, 0, 1, 1) // blue
	})
	if allocs != 0 {
		t.Errorf("unexpected allocations from calling gl.ClearColor: %f", allocs)
	}
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.Viewport(0, 0, pixW, pixH)

	m := NewImage(src.Bounds().Dx(), src.Bounds().Dy())
	b := m.RGBA.Bounds()
	draw.Draw(m.RGBA, b, src, src.Bounds().Min, draw.Src)
	m.Upload()
	b.Min.X += 10
	b.Max.Y /= 2

	// All-integer right-angled triangles offsetting the
	// box: 24-32-40, 12-16-20.
	ptTopLeft := geom.Point{0, 24}
	ptTopRight := geom.Point{32, 0}
	ptBottomLeft := geom.Point{12, 24 + 16}
	ptBottomRight := geom.Point{12 + 32, 16}
	m.Draw(cfg, ptTopLeft, ptTopRight, ptBottomLeft, b)

	// For unknown reasons, a windowless OpenGL context renders upside-
	// down. That is, a quad covering the initial viewport spans:
	//
	//	(-1, -1) ( 1, -1)
	//	(-1,  1) ( 1,  1)
	//
	// To avoid modifying live code for tests, we flip the rows
	// recovered from the renderbuffer. We are not the first:
	//
	// http://lists.apple.com/archives/mac-opengl/2010/Jun/msg00080.html
	got := image.NewRGBA(image.Rect(0, 0, pixW, pixH))
	upsideDownPix := make([]byte, len(got.Pix))
	gl.ReadPixels(upsideDownPix, 0, 0, pixW, pixH, gl.RGBA, gl.UNSIGNED_BYTE)
	for y := 0; y < pixH; y++ {
		i0 := (pixH - 1 - y) * got.Stride
		i1 := i0 + pixW*4
		copy(got.Pix[y*got.Stride:], upsideDownPix[i0:i1])
	}

	drawCross(got, 0, 0)
	drawCross(got, int(ptTopLeft.X.Px(cfg.PixelsPerPt)), int(ptTopLeft.Y.Px(cfg.PixelsPerPt)))
	drawCross(got, int(ptBottomRight.X.Px(cfg.PixelsPerPt)), int(ptBottomRight.Y.Px(cfg.PixelsPerPt)))
	drawCross(got, pixW-1, pixH-1)

	const wantPath = "../../../testdata/testpattern-window.png"
	f, err = os.Open(wantPath)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	wantSrc, _, err := image.Decode(f)
	if err != nil {
		t.Fatal(err)
	}
	want, ok := wantSrc.(*image.RGBA)
	if !ok {
		b := wantSrc.Bounds()
		want = image.NewRGBA(b)
		draw.Draw(want, b, wantSrc, b.Min, draw.Src)
	}

	if !imageEq(got, want) {
		// Write out the image we got.
		f, err = ioutil.TempFile("", "testpattern-window-got")
		if err != nil {
			t.Fatal(err)
		}
		f.Close()
		gotPath := f.Name() + ".png"
		f, err = os.Create(gotPath)
		if err != nil {
			t.Fatal(err)
		}
		if err := png.Encode(f, got); err != nil {
			t.Fatal(err)
		}
		if err := f.Close(); err != nil {
			t.Fatal(err)
		}
		t.Errorf("got\n%s\nwant\n%s", gotPath, wantPath)
	}
}

func drawCross(m *image.RGBA, x, y int) {
	c := color.RGBA{0xff, 0, 0, 0xff} // red
	m.SetRGBA(x+0, y-2, c)
	m.SetRGBA(x+0, y-1, c)
	m.SetRGBA(x-2, y+0, c)
	m.SetRGBA(x-1, y+0, c)
	m.SetRGBA(x+0, y+0, c)
	m.SetRGBA(x+1, y+0, c)
	m.SetRGBA(x+2, y+0, c)
	m.SetRGBA(x+0, y+1, c)
	m.SetRGBA(x+0, y+2, c)
}

func eqEpsilon(x, y uint8) bool {
	const epsilon = 9
	return x-y < epsilon || y-x < epsilon
}

func colorEq(c0, c1 color.RGBA) bool {
	return eqEpsilon(c0.R, c1.R) && eqEpsilon(c0.G, c1.G) && eqEpsilon(c0.B, c1.B) && eqEpsilon(c0.A, c1.A)
}

func imageEq(m0, m1 *image.RGBA) bool {
	b0 := m0.Bounds()
	b1 := m1.Bounds()
	if b0 != b1 {
		return false
	}
	badPx := 0
	for y := b0.Min.Y; y < b0.Max.Y; y++ {
		for x := b0.Min.X; x < b0.Max.X; x++ {
			c0, c1 := m0.At(x, y).(color.RGBA), m1.At(x, y).(color.RGBA)
			if !colorEq(c0, c1) {
				badPx++
			}
		}
	}
	badFrac := float64(badPx) / float64(b0.Dx()*b0.Dy())
	return badFrac < 0.01
}
