func (e *Element) use() error {
	r := C.Sciter_UseElement(e.handle)
	return wrapDomResult(r, "Sciter_UseElement")
}
SCDOM_RESULT  Sciter_UseElement(HELEMENT he) ;//{ return SAPI()->Sciter_UseElement(he); }
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)
}
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
}
func SetOption(option Sciter_RT_OPTIONS, value uint) (ok bool) {
	coption := C.UINT(option)
	cvalue := C.UINT_PTR(value)
	hwnd := BAD_HWINDOW
	r := C.SciterSetOption(hwnd, coption, cvalue)
	if r == 0 {
		return false
	}
	return true
}
func (s *Sciter) SetHomeURL(baseUrl string) (ok bool) {
	cbaseUrl := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(baseUrl)))
	r := C.SciterSetHomeURL(s.hwnd, cbaseUrl)
	if r == 0 {
		return false
	}
	return true
}
func (s *Sciter) OpenArchive(data []byte) {
	s.har = C.SciterOpenArchive((*C.BYTE)(&data[0]), C.UINT(len(data)))
}
func (s *Sciter) GetArchiveItem(uri string) []byte {
	var data C.LPCBYTE
	var length C.UINT
	cdata := (*C.LPCBYTE)(&data)
	r := C.SciterGetArchiveItem(s.har, StringToWcharPtr(uri), cdata, &length)
	if r == 0 {
		return nil
	}
	ret := ByteCPtrToBytes(data, length)
	return ret
}
func (s *Sciter) CloseArchive() {
	C.SciterCloseArchive(s.har)
	s.har = C.HSARCHIVE(nil)
}
func (s *Sciter) SetResourceArchive(data []byte) {
	callback := &CallbackHandler{
		OnLoadData: func(params *ScnLoadData) int {
			if strings.HasPrefix(params.Uri(), "this://app/") {
				url := params.Uri()[11:]
				fileData := s.GetArchiveItem(url)
				if fileData != nil {
					s.DataReady(url, fileData)
				} else {
					log.Println("error: failed to load " + params.Uri())
				}
			}
			return LOAD_OK
		},
	}
	s.OpenArchive(data)
	s.SetCallback(callback)
}
var (
	BAD_HELEMENT = C.HELEMENT(unsafe.Pointer(uintptr(0)))
)
var (
	elementHandlerMap = map[*Element]map[*EventHandler]struct{}{}
)
type Element struct {
	handle C.HELEMENT
	err    error
	*eventMapper
}
func WrapElement(he C.HELEMENT) *Element {
	e := &Element{
		handle: he,
	}
	e.use()
	runtime.SetFinalizer(e, (*Element).finalize)
	return e
}