// Copyright 2011 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.

package draw

import (
	"image"
	"image/color"
	"image/ycbcr"
	"testing"
)

const (
	dstw, dsth = 640, 480
	srcw, srch = 400, 300
)

// bench benchmarks drawing src and mask images onto a dst image with the
// given op and the color models to create those images from.
// The created images' pixels are initialized to non-zero values.
func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
	b.StopTimer()

	var dst Image
	switch dcm {
	case color.RGBAModel:
		dst1 := image.NewRGBA(image.Rect(0, 0, dstw, dsth))
		for y := 0; y < dsth; y++ {
			for x := 0; x < dstw; x++ {
				dst1.SetRGBA(x, y, color.RGBA{
					uint8(5 * x % 0x100),
					uint8(7 * y % 0x100),
					uint8((7*x + 5*y) % 0x100),
					0xff,
				})
			}
		}
		dst = dst1
	case color.RGBA64Model:
		dst1 := image.NewRGBA64(image.Rect(0, 0, dstw, dsth))
		for y := 0; y < dsth; y++ {
			for x := 0; x < dstw; x++ {
				dst1.SetRGBA64(x, y, color.RGBA64{
					uint16(53 * x % 0x10000),
					uint16(59 * y % 0x10000),
					uint16((59*x + 53*y) % 0x10000),
					0xffff,
				})
			}
		}
		dst = dst1
	default:
		panic("unreachable")
	}

	var src image.Image
	switch scm {
	case nil:
		src = &image.Uniform{color.RGBA{0x11, 0x22, 0x33, 0xff}}
	case color.RGBAModel:
		src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
		for y := 0; y < srch; y++ {
			for x := 0; x < srcw; x++ {
				src1.SetRGBA(x, y, color.RGBA{
					uint8(13 * x % 0x80),
					uint8(11 * y % 0x80),
					uint8((11*x + 13*y) % 0x80),
					0x7f,
				})
			}
		}
		src = src1
	case color.RGBA64Model:
		src1 := image.NewRGBA64(image.Rect(0, 0, srcw, srch))
		for y := 0; y < srch; y++ {
			for x := 0; x < srcw; x++ {
				src1.SetRGBA64(x, y, color.RGBA64{
					uint16(103 * x % 0x8000),
					uint16(101 * y % 0x8000),
					uint16((101*x + 103*y) % 0x8000),
					0x7fff,
				})
			}
		}
		src = src1
	case color.NRGBAModel:
		src1 := image.NewNRGBA(image.Rect(0, 0, srcw, srch))
		for y := 0; y < srch; y++ {
			for x := 0; x < srcw; x++ {
				src1.SetNRGBA(x, y, color.NRGBA{
					uint8(13 * x % 0x100),
					uint8(11 * y % 0x100),
					uint8((11*x + 13*y) % 0x100),
					0x7f,
				})
			}
		}
		src = src1
	case ycbcr.YCbCrColorModel:
		yy := make([]uint8, srcw*srch)
		cb := make([]uint8, srcw*srch)
		cr := make([]uint8, srcw*srch)
		for i := range yy {
			yy[i] = uint8(3 * i % 0x100)
			cb[i] = uint8(5 * i % 0x100)
			cr[i] = uint8(7 * i % 0x100)
		}
		src = &ycbcr.YCbCr{
			Y:              yy,
			Cb:             cb,
			Cr:             cr,
			YStride:        srcw,
			CStride:        srcw,
			SubsampleRatio: ycbcr.SubsampleRatio444,
			Rect:           image.Rect(0, 0, srcw, srch),
		}
	default:
		panic("unreachable")
	}

	var mask image.Image
	switch mcm {
	case nil:
		// No-op.
	case color.AlphaModel:
		mask1 := image.NewAlpha(image.Rect(0, 0, srcw, srch))
		for y := 0; y < srch; y++ {
			for x := 0; x < srcw; x++ {
				a := uint8((23*x + 29*y) % 0x100)
				// Glyph masks are typically mostly zero,
				// so we only set a quarter of mask1's pixels.
				if a >= 0xc0 {
					mask1.SetAlpha(x, y, color.Alpha{a})
				}
			}
		}
		mask = mask1
	default:
		panic("unreachable")
	}

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		// Scatter the destination rectangle to draw into.
		x := 3 * i % (dstw - srcw)
		y := 7 * i % (dsth - srch)

		DrawMask(dst, dst.Bounds().Add(image.Point{x, y}), src, image.ZP, mask, image.ZP, op)
	}
}

// The BenchmarkFoo functions exercise a drawFoo fast-path function in draw.go.

func BenchmarkFillOver(b *testing.B) {
	bench(b, color.RGBAModel, nil, nil, Over)
}

func BenchmarkFillSrc(b *testing.B) {
	bench(b, color.RGBAModel, nil, nil, Src)
}

func BenchmarkCopyOver(b *testing.B) {
	bench(b, color.RGBAModel, color.RGBAModel, nil, Over)
}

func BenchmarkCopySrc(b *testing.B) {
	bench(b, color.RGBAModel, color.RGBAModel, nil, Src)
}

func BenchmarkNRGBAOver(b *testing.B) {
	bench(b, color.RGBAModel, color.NRGBAModel, nil, Over)
}

func BenchmarkNRGBASrc(b *testing.B) {
	bench(b, color.RGBAModel, color.NRGBAModel, nil, Src)
}

func BenchmarkYCbCr(b *testing.B) {
	bench(b, color.RGBAModel, ycbcr.YCbCrColorModel, nil, Over)
}

func BenchmarkGlyphOver(b *testing.B) {
	bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
}

func BenchmarkRGBA(b *testing.B) {
	bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
}

// The BenchmarkGenericFoo functions exercise the generic, slow-path code.

func BenchmarkGenericOver(b *testing.B) {
	bench(b, color.RGBA64Model, color.RGBA64Model, nil, Over)
}

func BenchmarkGenericMaskOver(b *testing.B) {
	bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Over)
}

func BenchmarkGenericSrc(b *testing.B) {
	bench(b, color.RGBA64Model, color.RGBA64Model, nil, Src)
}

func BenchmarkGenericMaskSrc(b *testing.B) {
	bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Src)
}
