// Copyright 2010-2012 The W32 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 w32

import (
	"errors"
	"fmt"
	"syscall"
	"unsafe"
)

const (
	Ok                        = 0
	GenericError              = 1
	InvalidParameter          = 2
	OutOfMemory               = 3
	ObjectBusy                = 4
	InsufficientBuffer        = 5
	NotImplemented            = 6
	Win32Error                = 7
	WrongState                = 8
	Aborted                   = 9
	FileNotFound              = 10
	ValueOverflow             = 11
	AccessDenied              = 12
	UnknownImageFormat        = 13
	FontFamilyNotFound        = 14
	FontStyleNotFound         = 15
	NotTrueTypeFont           = 16
	UnsupportedGdiplusVersion = 17
	GdiplusNotInitialized     = 18
	PropertyNotFound          = 19
	PropertyNotSupported      = 20
	ProfileNotFound           = 21
)

func GetGpStatus(s int32) string {
	switch s {
	case Ok:
		return "Ok"
	case GenericError:
		return "GenericError"
	case InvalidParameter:
		return "InvalidParameter"
	case OutOfMemory:
		return "OutOfMemory"
	case ObjectBusy:
		return "ObjectBusy"
	case InsufficientBuffer:
		return "InsufficientBuffer"
	case NotImplemented:
		return "NotImplemented"
	case Win32Error:
		return "Win32Error"
	case WrongState:
		return "WrongState"
	case Aborted:
		return "Aborted"
	case FileNotFound:
		return "FileNotFound"
	case ValueOverflow:
		return "ValueOverflow"
	case AccessDenied:
		return "AccessDenied"
	case UnknownImageFormat:
		return "UnknownImageFormat"
	case FontFamilyNotFound:
		return "FontFamilyNotFound"
	case FontStyleNotFound:
		return "FontStyleNotFound"
	case NotTrueTypeFont:
		return "NotTrueTypeFont"
	case UnsupportedGdiplusVersion:
		return "UnsupportedGdiplusVersion"
	case GdiplusNotInitialized:
		return "GdiplusNotInitialized"
	case PropertyNotFound:
		return "PropertyNotFound"
	case PropertyNotSupported:
		return "PropertyNotSupported"
	case ProfileNotFound:
		return "ProfileNotFound"
	}
	return "Unknown Status Value"
}

var (
	token uintptr

	modgdiplus = syscall.NewLazyDLL("gdiplus.dll")

	procGdipCreateBitmapFromFile     = modgdiplus.NewProc("GdipCreateBitmapFromFile")
	procGdipCreateBitmapFromHBITMAP  = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
	procGdipCreateHBITMAPFromBitmap  = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
	procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
	procGdipCreateBitmapFromStream   = modgdiplus.NewProc("GdipCreateBitmapFromStream")
	procGdipDisposeImage             = modgdiplus.NewProc("GdipDisposeImage")
	procGdiplusShutdown              = modgdiplus.NewProc("GdiplusShutdown")
	procGdiplusStartup               = modgdiplus.NewProc("GdiplusStartup")
)

func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
	var bitmap *uintptr
	ret, _, _ := procGdipCreateBitmapFromFile.Call(
		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
		uintptr(unsafe.Pointer(&bitmap)))

	if ret != Ok {
		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
	}

	return bitmap, nil
}

func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
	var bitmap *uintptr
	ret, _, _ := procGdipCreateBitmapFromResource.Call(
		uintptr(instance),
		uintptr(unsafe.Pointer(resId)),
		uintptr(unsafe.Pointer(&bitmap)))

	if ret != Ok {
		return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
	}

	return bitmap, nil
}

func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
	var bitmap *uintptr
	ret, _, _ := procGdipCreateBitmapFromStream.Call(
		uintptr(unsafe.Pointer(stream)),
		uintptr(unsafe.Pointer(&bitmap)))

	if ret != Ok {
		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
	}

	return bitmap, nil
}

func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
	var hbitmap HBITMAP
	ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
		uintptr(unsafe.Pointer(bitmap)),
		uintptr(unsafe.Pointer(&hbitmap)),
		uintptr(background))

	if ret != Ok {
		return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
	}

	return hbitmap, nil
}

func GdipDisposeImage(image *uintptr) {
	procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
}

func GdiplusShutdown() {
	procGdiplusShutdown.Call(token)
}

func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
	ret, _, _ := procGdiplusStartup.Call(
		uintptr(unsafe.Pointer(&token)),
		uintptr(unsafe.Pointer(input)),
		uintptr(unsafe.Pointer(output)))

	if ret != Ok {
		panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
	}
}
