package win32api

import (
	"errors"
	"strconv"
	"syscall"
	"unsafe"
)

func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
	shell32, err := syscall.LoadLibrary("shell32.dll")
	var op, param, directory uintptr
	if err != nil {
		return errors.New("Can't Load Shell32 API")
	}
	defer syscall.FreeLibrary(shell32)
	ShellExecute, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteW")
	if err != nil {
		return errors.New("Can't Load ShellExecute API")
	}
	if len(lpOperation) != 0 {
		op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
	}
	if len(lpParameters) != 0 {
		param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
	}
	if len(lpDirectory) != 0 {
		directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
	}
	r, _, _ := syscall.Syscall6(uintptr(ShellExecute), 6,
		uintptr(hwnd),
		op,
		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
		param,
		directory,
		uintptr(nShowCmd))
	if r < 32 {
		return errors.New("ERROR:" + strconv.Itoa(int(r)))
	}
	return nil
}

/**
func ShellExecuteEX2(hwnd HWND, lpVerb, lpFile, lpParameters, lpDirectory string, nShow int) error {
	var newcmd SHELLEXECUTEINFOW
	newcmd.cbSize = DWORD(unsafe.Sizeof(newcmd))
	newcmd.hwnd = hwnd
	newcmd.lpVerb = lpVerb
	newcmd.lpFile = lpFile
	newcmd.lpParameters = lpParameters
	newcmd.lpDirectory = lpDirectory
	newcmd.nShow = nShow
	shell32, err := syscall.LoadLibrary("shell32.dll")
	if err != nil {
		return errors.New("Can't Load Shell32 API")
	}
	defer syscall.FreeLibrary(shell32)
	ShellExecuteEx, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteExW")
	if err != nil {
		return errors.New("Can't Load ShellExecuteEx API")
	}
	r, _, _ := syscall.Syscall6(ShellExecuteEx, 1, uintptr(unsafe.Pointer(&newcmd)), 0, 0, 0, 0, 0)
	fmt.Println(strconv.Itoa(int(r)))
	fmt.Println(strconv.Itoa(int(newcmd.hInstApp)))
	if r != 0 {
		return errors.New("Error Recured")
	}
	return nil
}
*/

func ShellExecuteEx(muzika *SHELLEXECUTEINFOW) error {
	shell32, err := syscall.LoadLibrary("shell32.dll")

	if err != nil {
		return errors.New("Can't Load Shell32 API")
	}
	defer syscall.FreeLibrary(shell32)
	ShellExecuteEx, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteExW")
	if err != nil {
		return errors.New("Can't Load ShellExecuteEx API")
	}
	r, _, errno := syscall.Syscall6(ShellExecuteEx, 1, uintptr(unsafe.Pointer(muzika)), 0, 0, 0, 0, 0)
	if r == 0 {
		return error(errno)
	}
	return nil
}
