func (s *Sciter) SetOption(option Sciter_RT_OPTIONS, value uint) (ok bool) {
	coption := C.UINT(option)
	cvalue := C.UINT_PTR(value)
	r := C.SciterSetOption(s.hwnd, coption, cvalue)
	if r == 0 {
		return false
	}
	return true
}
#ifdef WINDOWS
BOOL     SciterTranslateMessage (MSG* lpMsg) ;//{ return SAPI()->SciterTranslateMessage (lpMsg); }
#endif
BOOL     SciterSetOption (HWINDOW hWnd, UINT option, UINT_PTR value )
package sciter
import "C"
import (
	"fmt"
	"log"
	"runtime"
	"strings"
	"unsafe"
)
type Sciter struct {
	hwnd C.HWINDOW
	callbacks map[*CallbackHandler]struct{}
	*eventMapper
	har C.HSARCHIVE
}
var (
	BAD_HWINDOW C.HWINDOW = nil
)
func Wrap(hwnd C.HWINDOW) *Sciter {
	s := &Sciter{
		hwnd:      hwnd,
		callbacks: make(map[*CallbackHandler]struct{}),
	}
	return s
}
func ClassName() string {
	cname := (*uint16)(unsafe.Pointer(C.SciterClassName()))
	return Utf16ToString(cname)
}
func Version(major bool) uint {
	var v C.UINT
	if major {
		v = C.SciterVersion(C.BOOL(1))
	} else {
		v = C.SciterVersion(C.BOOL(0))
	}
	return uint(v)
}
func VersionAsString() string {
	major := Version(true)
	minor := Version(false)
	return fmt.Sprintf("0x%x %x", major, minor)
}
func (s *Sciter) GetHwnd() C.HWINDOW {
	return s.hwnd
}
func SetDLL(dir string) {
	C.SCITER_DLL_PATH = C.CString(dir)
}
func (s *Sciter) DataReady(uri string, data []byte) bool {
	var pData C.LPCBYTE
	if len(data) > 0 {
		pData = (C.LPCBYTE)(unsafe.Pointer(&data[0]))
	}
	ret := C.SciterDataReady(s.hwnd, StringToWcharPtr(uri), pData, C.UINT(len(data)))
	if ret == 0 {
		return false
	}
	loadedUri[uri] = data
	return true
}
var (
	loadedUri = map[string][]byte{}
)
func (s *Sciter) DataReadyAsync(uri string, data []byte, requestId unsafe.Pointer) bool {
	var pData C.LPCBYTE
	if len(data) > 0 {
		pData = (C.LPCBYTE)(unsafe.Pointer(&data[0]))
	}
	curi := StringToWcharPtr(uri)
	cdataLength := C.UINT(len(data))
	crequestId := C.LPVOID(requestId)
	ret := C.SciterDataReadyAsync(s.hwnd, curi, pData, cdataLength, crequestId)
	if ret == 0 {
		return false
	}
	return true
}
func (s *Sciter) LoadFile(filename string) error {
	ret := C.SciterLoadFile(s.hwnd, StringToWcharPtr(filename))
	if ret == 0 {
		return fmt.Errorf("LoadFile with: %s failed", filename)
	}
	return nil
}
func (s *Sciter) LoadHtml(html, baseUrl string) error {
	chtml := (C.LPCBYTE)(unsafe.Pointer(StringToBytePtr(html)))
	csize := C.UINT(len(html))
	cbaseUrl := StringToWcharPtr(baseUrl)
	ret := C.SciterLoadHtml(s.hwnd, chtml, csize, cbaseUrl)
	if ret == 0 {
		return fmt.Errorf("LoadHtml with: %s failed", string(html))
	}
	return nil
}
func goSciterHostCallback(ph unsafe.Pointer, callbackParam unsafe.Pointer) int {
	phdr := (*SciterCallbackNotification)(ph)
	handler := globalCallbackHandlers[int(uintptr(callbackParam))]
	switch phdr.Code {
	case SC_ENGINE_DESTROYED:
		if handler.OnEngineDestroyed != nil {
			return handler.OnEngineDestroyed()
		}
	case SC_LOAD_DATA:
		if handler.OnLoadData != nil {
			return handler.OnLoadData((*ScnLoadData)(unsafe.Pointer(phdr)))
		}
	case SC_DATA_LOADED:
		if handler.OnDataLoaded != nil {
			return handler.OnDataLoaded((*ScnDataLoaded)(unsafe.Pointer(phdr)))
		}
	case SC_ATTACH_BEHAVIOR:
		params := (*ScnAttachBehavior)(unsafe.Pointer(phdr))
		key := params.BehaviorName()
		if behavior, exists := handler.Behaviors[key]; exists {
			if refCount, exists := behaviors[behavior]; exists {
				behaviors[behavior] = refCount + 1
			} else {
				behaviors[behavior] = 1
			}
			el := WrapElement(params.Element())
			el.attachBehavior(behavior)
		} else {
			log.Printf("No such behavior <%s> found", key)
		}
	}
	return 0
}
var (
	sciterhostcallback     = C.LPSciterHostCallback(unsafe.Pointer(C.SciterHostCallback_cgo))
	globalCallbackHandlers = make([]*CallbackHandler, 0)
)
func (s *Sciter) SetCallback(handler *CallbackHandler) {
	if _, ok := s.callbacks[handler]; ok {
		return
	}
	s.callbacks[handler] = struct{}{}
	globalCallbackHandlers = append(globalCallbackHandlers, handler)
	idx := len(globalCallbackHandlers) - 1
	cparam := C.LPVOID(unsafe.Pointer(uintptr(idx)))
	C.SciterSetCallback(s.hwnd, sciterhostcallback, cparam)
}
func SetMasterCSS(data string) (ok bool) {
	cutf8 := C.LPCBYTE(unsafe.Pointer(StringToBytePtr(data)))
	clen := C.UINT(len(data))
	r := C.SciterSetMasterCSS(cutf8, clen)
	if r == 0 {
		return false
	}
	return true
}
func AppendMasterCSS(data string) (ok bool) {
	cutf8 := C.LPCBYTE(unsafe.Pointer(StringToBytePtr(data)))
	clen := C.UINT(len(data))
	r := C.SciterAppendMasterCSS(cutf8, clen)
	if r == 0 {
		return false
	}
	return true
}
func (s *Sciter) SetCSS(css, baseUrl, mediaType string) (ok bool) {
	ccss := C.LPCBYTE(unsafe.Pointer(StringToBytePtr(css)))
	clen := C.UINT(len(css))
	cbaseUrl := StringToWcharPtr(baseUrl)
	cmediaType := StringToWcharPtr(mediaType)
	r := C.SciterSetCSS(s.hwnd, ccss, clen, cbaseUrl, cmediaType)
	if r == 0 {
		return false
	}
	return true
}
func (s *Sciter) SetMediaType(mediaType string) (ok bool) {
	cmediaType := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(mediaType)))
	r := C.SciterSetMediaType(s.hwnd, cmediaType)
	if r == 0 {
		return false
	}
	return true
}
func (s *Sciter) MinWidth() int {
	r := C.SciterGetMinWidth(s.hwnd)
	return int(r)
}
func (s *Sciter) MinHeight(width int) int {
	cwidth := C.UINT(width)
	r := C.SciterGetMinHeight(s.hwnd, cwidth)
	return int(r)
}
func (s *Sciter) Call(functionName string, args ...*Value) (retval *Value, err error) {
	retval = NewValue()
	argc := len(args)
	argv := make([]Value, argc)
	for i := 0; i < argc; i++ {
		argv[i].Copy(args[i])  
		defer argv[i].finalize()
	}
	funcName := C.CString(functionName)
	defer C.free(unsafe.Pointer(funcName))
	cfn := C.LPCSTR(unsafe.Pointer(funcName))
	cargc := C.UINT(argc)
	var cargv *C.SCITER_VALUE
	if len(argv) > 0 {
		cargv = (*C.SCITER_VALUE)(unsafe.Pointer(&argv[0]))
	}
	cretval := (*C.SCITER_VALUE)(unsafe.Pointer(retval))
	r := C.SciterCall(s.hwnd, cfn, cargc, cargv, cretval)
	if r == 0 {
		err = fmt.Errorf("SciterCall failed with function: %s", functionName)
	}
	return
}
func (s *Sciter) Eval(script string) (retval *Value, ok bool) {
	retval = NewValue()
	u16, err := Utf16FromString(script)
	if err != nil {
		return nil, false
	}
	cscriptLength := C.UINT(len(u16))
	cscript := C.LPCWSTR(unsafe.Pointer(&u16[0]))
	cretval := (*C.SCITER_VALUE)(unsafe.Pointer(retval))
	r := C.SciterEval(s.hwnd, cscript, cscriptLength, cretval)
	if r == 0 {
		ok = false
	} else {
		ok = true
	}
	return
}
func (s *Sciter) UpdateWindow() {
	C.SciterUpdateWindow(s.hwnd)
}