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

// +build windows

package main

import (
	"fmt"
	"os"
	"syscall"
	"unsafe"
)

// some help functions

func abortf(format string, a ...interface{}) {
	fmt.Fprintf(os.Stdout, format, a...)
	os.Exit(1)
}

func abortErrNo(funcname string, err error) {
	errno, _ := err.(syscall.Errno)
	abortf("%s failed: %d %s\n", funcname, uint32(errno), err)
}

// global vars

var (
	mh syscall.Handle
	bh syscall.Handle
)

// WinProc called by windows to notify us of all windows events we might be interested in.
func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
	switch msg {
	case WM_CREATE:
		var e error
		// CreateWindowEx
		bh, e = CreateWindowEx(
			0,
			syscall.StringToUTF16Ptr("button"),
			syscall.StringToUTF16Ptr("Quit"),
			WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
			75, 70, 140, 25,
			hwnd, 1, mh, 0)
		if e != nil {
			abortErrNo("CreateWindowEx", e)
		}
		fmt.Printf("button handle is %x\n", bh)
		rc = DefWindowProc(hwnd, msg, wparam, lparam)
	case WM_COMMAND:
		switch syscall.Handle(lparam) {
		case bh:
			e := PostMessage(hwnd, WM_CLOSE, 0, 0)
			if e != nil {
				abortErrNo("PostMessage", e)
			}
		default:
			rc = DefWindowProc(hwnd, msg, wparam, lparam)
		}
	case WM_CLOSE:
		DestroyWindow(hwnd)
	case WM_DESTROY:
		PostQuitMessage(0)
	default:
		rc = DefWindowProc(hwnd, msg, wparam, lparam)
	}
	//fmt.Printf("WndProc(0x%08x, %d, 0x%08x, 0x%08x) (%d)\n", hwnd, msg, wparam, lparam, rc)
	return
}

func rungui() int {
	var e error

	// GetModuleHandle
	mh, e = GetModuleHandle(nil)
	if e != nil {
		abortErrNo("GetModuleHandle", e)
	}

	// Get icon we're going to use.
	myicon, e := LoadIcon(0, IDI_APPLICATION)
	if e != nil {
		abortErrNo("LoadIcon", e)
	}

	// Get cursor we're going to use.
	mycursor, e := LoadCursor(0, IDC_ARROW)
	if e != nil {
		abortErrNo("LoadCursor", e)
	}

	// Create callback
	wproc := syscall.NewCallback(WndProc)

	// RegisterClassEx
	wcname := syscall.StringToUTF16Ptr("myWindowClass")
	var wc Wndclassex
	wc.Size = uint32(unsafe.Sizeof(wc))
	wc.WndProc = wproc
	wc.Instance = mh
	wc.Icon = myicon
	wc.Cursor = mycursor
	wc.Background = COLOR_BTNFACE + 1
	wc.MenuName = nil
	wc.ClassName = wcname
	wc.IconSm = myicon
	if _, e := RegisterClassEx(&wc); e != nil {
		abortErrNo("RegisterClassEx", e)
	}

	// CreateWindowEx
	wh, e := CreateWindowEx(
		WS_EX_CLIENTEDGE,
		wcname,
		syscall.StringToUTF16Ptr("My window"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
		0, 0, mh, 0)
	if e != nil {
		abortErrNo("CreateWindowEx", e)
	}
	fmt.Printf("main window handle is %x\n", wh)

	// ShowWindow
	ShowWindow(wh, SW_SHOWDEFAULT)

	// UpdateWindow
	if e := UpdateWindow(wh); e != nil {
		abortErrNo("UpdateWindow", e)
	}

	// Process all windows messages until WM_QUIT.
	var m Msg
	for {
		r, e := GetMessage(&m, 0, 0, 0)
		if e != nil {
			abortErrNo("GetMessage", e)
		}
		if r == 0 {
			// WM_QUIT received -> get out
			break
		}
		TranslateMessage(&m)
		DispatchMessage(&m)
	}
	return int(m.Wparam)
}

func main() {
	rc := rungui()
	os.Exit(rc)
}
