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

//go:build windows
// +build windows

package windriver

import (
	"errors"
	"image"
	"image/color"
	"image/draw"
	"sync"
	"syscall"
	"unsafe"

	"golang.org/x/exp/shiny/driver/internal/win32"
	"golang.org/x/exp/shiny/screen"
)

type textureImpl struct {
	size   image.Point
	dc     syscall.Handle
	bitmap syscall.Handle

	mu       sync.Mutex
	released bool
}

type handleCreateTextureParams struct {
	size   image.Point
	dc     syscall.Handle
	bitmap syscall.Handle
	err    error
}

var msgCreateTexture = win32.AddScreenMsg(handleCreateTexture)

func newTexture(size image.Point) (screen.Texture, error) {
	p := handleCreateTextureParams{size: size}
	win32.SendScreenMessage(msgCreateTexture, 0, uintptr(unsafe.Pointer(&p)))
	if p.err != nil {
		return nil, p.err
	}
	return &textureImpl{
		size:   size,
		dc:     p.dc,
		bitmap: p.bitmap,
	}, nil
}

func handleCreateTexture(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) {
	// This code needs to run on Windows message pump thread.
	// Firstly, it calls GetDC(nil) and, according to Windows documentation
	// (https://msdn.microsoft.com/en-us/library/windows/desktop/dd144871(v=vs.85).aspx),
	// has to be released on the same thread.
	// Secondly, according to Windows documentation
	// (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183489(v=vs.85).aspx),
	// ... thread that calls CreateCompatibleDC owns the HDC that is created.
	// When this thread is destroyed, the HDC is no longer valid. ...
	// So making Windows message pump thread own returned HDC makes DC
	// live as long as we want to.
	p := (*handleCreateTextureParams)(unsafe.Pointer(lParam))

	screenDC, err := win32.GetDC(0)
	if err != nil {
		p.err = err
		return
	}
	defer win32.ReleaseDC(0, screenDC)

	dc, err := _CreateCompatibleDC(screenDC)
	if err != nil {
		p.err = err
		return
	}
	bitmap, err := _CreateCompatibleBitmap(screenDC, int32(p.size.X), int32(p.size.Y))
	if err != nil {
		_DeleteDC(dc)
		p.err = err
		return
	}
	p.dc = dc
	p.bitmap = bitmap
}

func (t *textureImpl) Bounds() image.Rectangle {
	return image.Rectangle{Max: t.size}
}

func (t *textureImpl) Fill(r image.Rectangle, c color.Color, op draw.Op) {
	err := t.update(func(dc syscall.Handle) error {
		return fill(dc, r, c, op)
	})
	if err != nil {
		panic(err) // TODO handle error
	}
}

func (t *textureImpl) Release() {
	if err := t.release(); err != nil {
		panic(err) // TODO handle error
	}
}

func (t *textureImpl) release() error {
	t.mu.Lock()
	defer t.mu.Unlock()

	if t.released {
		return nil
	}
	t.released = true

	err := _DeleteObject(t.bitmap)
	if err != nil {
		return err
	}
	return _DeleteDC(t.dc)
}

func (t *textureImpl) Size() image.Point {
	return t.size
}

func (t *textureImpl) Upload(dp image.Point, src screen.Buffer, sr image.Rectangle) {
	err := t.update(func(dc syscall.Handle) error {
		return src.(*bufferImpl).blitToDC(dc, dp, sr)
	})
	if err != nil {
		panic(err) // TODO handle error
	}
}

// update prepares texture t for update and executes f over texture device
// context dc in a safe manner.
func (t *textureImpl) update(f func(dc syscall.Handle) error) (retErr error) {
	t.mu.Lock()
	defer t.mu.Unlock()

	if t.released {
		return errors.New("windriver: Texture.Upload called after Texture.Release")
	}

	// Select t.bitmap into t.dc, so our drawing gets recorded
	// into t.bitmap and not into 1x1 default bitmap created
	// during CreateCompatibleDC call.
	prev, err := _SelectObject(t.dc, t.bitmap)
	if err != nil {
		return err
	}
	defer func() {
		_, err2 := _SelectObject(t.dc, prev)
		if retErr == nil {
			retErr = err2
		}
	}()

	return f(t.dc)
}
