// Copyright 2020 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 x11driver

import (
	"image"
	"sync"

	"github.com/jezek/xgb"
	"github.com/jezek/xgb/xproto"

	"golang.org/x/exp/shiny/driver/internal/swizzle"
)

const (
	xPutImageReqSizeMax   = (1 << 16) * 4
	xPutImageReqSizeFixed = 28
	xPutImageReqDataSize  = xPutImageReqSizeMax - xPutImageReqSizeFixed
)

type bufferFallbackImpl struct {
	xc *xgb.Conn

	buf  []byte
	rgba image.RGBA
	size image.Point

	mu       sync.Mutex
	nUpload  uint32
	released bool
}

func (b *bufferFallbackImpl) Size() image.Point       { return b.size }
func (b *bufferFallbackImpl) Bounds() image.Rectangle { return image.Rectangle{Max: b.size} }
func (b *bufferFallbackImpl) RGBA() *image.RGBA       { return &b.rgba }

func (b *bufferFallbackImpl) preUpload() {
	// Check that the program hasn't tried to modify the rgba field via the
	// pointer returned by the bufferFallbackImpl.RGBA method. This check doesn't catch
	// 100% of all cases; it simply tries to detect some invalid uses of a
	// screen.Buffer such as:
	//	*buffer.RGBA() = anotherImageRGBA
	if len(b.buf) != 0 && len(b.rgba.Pix) != 0 && &b.buf[0] != &b.rgba.Pix[0] {
		panic("x11driver: invalid Buffer.RGBA modification")
	}

	b.mu.Lock()
	defer b.mu.Unlock()

	if b.released {
		panic("x11driver: Buffer.Upload called after Buffer.Release")
	}
	if b.nUpload == 0 {
		swizzle.BGRA(b.buf)
	}
	b.nUpload++
}

func (b *bufferFallbackImpl) postUpload() {
	b.mu.Lock()
	defer b.mu.Unlock()

	b.nUpload--
	if b.nUpload != 0 {
		return
	}

	if !b.released {
		swizzle.BGRA(b.buf)
	}
}

func (b *bufferFallbackImpl) Release() {
	b.mu.Lock()
	defer b.mu.Unlock()

	b.released = true
}

func (b *bufferFallbackImpl) upload(xd xproto.Drawable, xg xproto.Gcontext, depth uint8, dp image.Point, sr image.Rectangle) {
	originalSRMin := sr.Min
	sr = sr.Intersect(b.Bounds())
	if sr.Empty() {
		return
	}
	dp = dp.Add(sr.Min.Sub(originalSRMin))
	b.preUpload()

	b.putImage(xd, xg, depth, dp, sr)

	b.postUpload()
}

// putImage issues xproto.PutImage requests in batches.
func (b *bufferFallbackImpl) putImage(xd xproto.Drawable, xg xproto.Gcontext, depth uint8, dp image.Point, sr image.Rectangle) {
	widthPerReq := b.size.X
	rowPerReq := xPutImageReqDataSize / (widthPerReq * 4)
	dataPerReq := rowPerReq * widthPerReq * 4
	dstX := dp.X
	dstY := dp.Y
	start := 0
	end := 0

	for end < len(b.buf) {
		end = start + dataPerReq
		if end > len(b.buf) {
			end = len(b.buf)
		}

		data := b.buf[start:end]
		heightPerReq := len(data) / (widthPerReq * 4)

		xproto.PutImage(
			b.xc, xproto.ImageFormatZPixmap, xd, xg,
			uint16(widthPerReq), uint16(heightPerReq),
			int16(dstX), int16(dstY),
			0, depth, data)

		start = end
		dstY += rowPerReq
	}
}
