// Code generated by gobind. DO NOT EDIT.

package ObjC

// Used to silence this package not used errors
const Dummy = 0

type Foundation_NSDate interface {
	Hash() uint
	Description() string
}

type Foundation_NSObjectC interface {
	Hash() uint
	Description() string
}

type Foundation_NSObjectP interface {
	Hash() uint
	Description() string
}

type Foundation_NSSet interface {
	Hash() uint
	Description() string
}

type Foundation_NSMutableString interface {
	Hash() uint
	Description() string
	DataUsingEncoding(encoding uint) []byte
}

type UIKit_UIResponder interface {
	Hash() uint
	Description() string
}

type UIKit_UIPressesEvent interface {
	Hash() uint
	Description() string
}

type NetworkExtension_NEPacket interface {
	Hash() uint
	Description() string
}

type Objc_GoNSDate interface {
	Hash() uint
	Description() string
	Super() Objc_GoNSDate
}

type Objc_GoNSObject interface {
	Hash() uint
	Description() string
	Super() Objc_GoNSObject
}

type Objc_GoUIResponder interface {
	Hash() uint
	Description() string
	Super() Objc_GoUIResponder
}
// Code generated by gobind. DO NOT EDIT.

package main

// #include "interfaces.h"
import "C"

import "ObjC"
import _seq "golang.org/x/mobile/bind/seq"
import "ObjC/Foundation/NSMutableString"
import "ObjC/NetworkExtension/NEPacket"

type proxy interface{ Bind_proxy_refnum__() int32 }

// Suppress unused package error

var _ = _seq.FromRefNum

const _ = ObjC.Dummy

func init() {
}

type proxy_class_NSDate _seq.Ref

func (p *proxy_class_NSDate) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NSDate) Hash() uint {
	res := C.cproxy_NSDate_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NSDate) Description() string {
	res := C.cproxy_NSDate_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_NSObjectC _seq.Ref

func (p *proxy_class_NSObjectC) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NSObjectC) Hash() uint {
	res := C.cproxy_NSObjectC_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NSObjectC) Description() string {
	res := C.cproxy_NSObjectC_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_NSObjectP _seq.Ref

func (p *proxy_class_NSObjectP) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NSObjectP) Hash() uint {
	res := C.cproxy_NSObjectP_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NSObjectP) Description() string {
	res := C.cproxy_NSObjectP_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_NSSet _seq.Ref

func (p *proxy_class_NSSet) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NSSet) Hash() uint {
	res := C.cproxy_NSSet_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NSSet) Description() string {
	res := C.cproxy_NSSet_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
	NSMutableString.NewWithData = func(data []byte, encoding uint) ObjC.Foundation_NSMutableString {
		_data := fromSlice(data, false)
		_encoding := C.ulong(encoding)
		res := C.cproxy_s_NSMutableString_NewWithData(_data, _encoding)
		var _res ObjC.Foundation_NSMutableString
		_res_ref := _seq.FromRefNum(int32(res))
		if _res_ref != nil {
			if res < 0 { // go object
				_res = _res_ref.Get().(ObjC.Foundation_NSMutableString)
			} else { // foreign object
				_res = (*proxy_class_NSMutableString)(_res_ref)
			}
		}
		return _res
	}

}

type proxy_class_NSMutableString _seq.Ref

func (p *proxy_class_NSMutableString) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NSMutableString) Hash() uint {
	res := C.cproxy_NSMutableString_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NSMutableString) Description() string {
	res := C.cproxy_NSMutableString_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func (p *proxy_class_NSMutableString) DataUsingEncoding(encoding uint) []byte {
	_encoding := C.ulong(encoding)
	res := C.cproxy_NSMutableString_DataUsingEncoding(C.int(p.Bind_proxy_refnum__()), _encoding)
	_res := toSlice(res, true)
	return _res
}

func init() {
}

type proxy_class_UIResponder _seq.Ref

func (p *proxy_class_UIResponder) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_UIResponder) Hash() uint {
	res := C.cproxy_UIResponder_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_UIResponder) Description() string {
	res := C.cproxy_UIResponder_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_UIPressesEvent _seq.Ref

func (p *proxy_class_UIPressesEvent) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_UIPressesEvent) Hash() uint {
	res := C.cproxy_UIPressesEvent_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_UIPressesEvent) Description() string {
	res := C.cproxy_UIPressesEvent_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
	NEPacket.NewWithData = func(data []byte, protocolFamily uint8) ObjC.NetworkExtension_NEPacket {
		_data := fromSlice(data, false)
		_protocolFamily := C.uchar(protocolFamily)
		res := C.cproxy_s_NEPacket_NewWithData(_data, _protocolFamily)
		var _res ObjC.NetworkExtension_NEPacket
		_res_ref := _seq.FromRefNum(int32(res))
		if _res_ref != nil {
			if res < 0 { // go object
				_res = _res_ref.Get().(ObjC.NetworkExtension_NEPacket)
			} else { // foreign object
				_res = (*proxy_class_NEPacket)(_res_ref)
			}
		}
		return _res
	}

}

type proxy_class_NEPacket _seq.Ref

func (p *proxy_class_NEPacket) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_NEPacket) Hash() uint {
	res := C.cproxy_NEPacket_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_NEPacket) Description() string {
	res := C.cproxy_NEPacket_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_GoNSDate _seq.Ref

func (p *proxy_class_GoNSDate) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_GoNSDate) Hash() uint {
	res := C.cproxy_GoNSDate_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_GoNSDate) Description() string {
	res := C.cproxy_GoNSDate_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func (p *proxy_class_GoNSDate) Super() ObjC.Objc_GoNSDate {
	return &super_GoNSDate{p}
}

type super_GoNSDate struct{ *proxy_class_GoNSDate }

func (p *super_GoNSDate) Hash() uint {
	res := C.csuper_GoNSDate_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *super_GoNSDate) Description() string {
	res := C.csuper_GoNSDate_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_GoNSObject _seq.Ref

func (p *proxy_class_GoNSObject) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_GoNSObject) Hash() uint {
	res := C.cproxy_GoNSObject_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_GoNSObject) Description() string {
	res := C.cproxy_GoNSObject_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func (p *proxy_class_GoNSObject) Super() ObjC.Objc_GoNSObject {
	return &super_GoNSObject{p}
}

type super_GoNSObject struct{ *proxy_class_GoNSObject }

func (p *super_GoNSObject) Hash() uint {
	res := C.csuper_GoNSObject_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *super_GoNSObject) Description() string {
	res := C.csuper_GoNSObject_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func init() {
}

type proxy_class_GoUIResponder _seq.Ref

func (p *proxy_class_GoUIResponder) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_GoUIResponder) Hash() uint {
	res := C.cproxy_GoUIResponder_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *proxy_class_GoUIResponder) Description() string {
	res := C.cproxy_GoUIResponder_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

func (p *proxy_class_GoUIResponder) Super() ObjC.Objc_GoUIResponder {
	return &super_GoUIResponder{p}
}

type super_GoUIResponder struct{ *proxy_class_GoUIResponder }

func (p *super_GoUIResponder) Hash() uint {
	res := C.csuper_GoUIResponder_Hash(C.int(p.Bind_proxy_refnum__()))
	_res := uint(res)
	return _res
}

func (p *super_GoUIResponder) Description() string {
	res := C.csuper_GoUIResponder_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}
// Code generated by gobind. DO NOT EDIT.

// Package main is an autogenerated binder stub for package objc.
//
//   autogenerated by gobind -lang=go objcw
package main

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "objc.h"

*/
import "C"

import (
	"ObjC/Foundation"
	"ObjC/UIKit"
	_seq "golang.org/x/mobile/bind/seq"
	"objcw"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

//export proxyobjc_GoNSDate_NSDate_Set
func proxyobjc_GoNSDate_NSDate_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v Foundation.NSDate
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(Foundation.NSDate)
		} else { // foreign object
			_v = (*proxy_class_NSDate)(_v_ref)
		}
	}
	ref.Get().(*objc.GoNSDate).NSDate = _v
}

//export proxyobjc_GoNSDate_NSDate_Get
func proxyobjc_GoNSDate_NSDate_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoNSDate).NSDate
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyobjc_GoNSDate_Hash
func proxyobjc_GoNSDate_Hash(refnum C.int32_t, param_this C.int32_t) C.nint {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoNSDate)
	var _param_this Foundation.NSDate
	_param_this_ref := _seq.FromRefNum(int32(param_this))
	if _param_this_ref != nil {
		if param_this < 0 { // go object
			_param_this = _param_this_ref.Get().(Foundation.NSDate)
		} else { // foreign object
			_param_this = (*proxy_class_NSDate)(_param_this_ref)
		}
	}
	res_0 := v.Hash(_param_this)
	_res_0 := C.nint(res_0)
	return _res_0
}

//export new_objc_GoNSDate
func new_objc_GoNSDate() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(objc.GoNSDate)))
}

//export proxyobjc_GoNSObject_C_Set
func proxyobjc_GoNSObject_C_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v Foundation.NSObjectC
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(Foundation.NSObjectC)
		} else { // foreign object
			_v = (*proxy_class_NSObjectC)(_v_ref)
		}
	}
	ref.Get().(*objc.GoNSObject).C = _v
}

//export proxyobjc_GoNSObject_C_Get
func proxyobjc_GoNSObject_C_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoNSObject).C
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyobjc_GoNSObject_P_Set
func proxyobjc_GoNSObject_P_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v Foundation.NSObjectP
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(Foundation.NSObjectP)
		} else { // foreign object
			_v = (*proxy_class_NSObjectP)(_v_ref)
		}
	}
	ref.Get().(*objc.GoNSObject).P = _v
}

//export proxyobjc_GoNSObject_P_Get
func proxyobjc_GoNSObject_P_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoNSObject).P
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyobjc_GoNSObject_Description
func proxyobjc_GoNSObject_Description(refnum C.int32_t, param_this C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoNSObject)
	var _param_this Foundation.NSObjectC
	_param_this_ref := _seq.FromRefNum(int32(param_this))
	if _param_this_ref != nil {
		if param_this < 0 { // go object
			_param_this = _param_this_ref.Get().(Foundation.NSObjectC)
		} else { // foreign object
			_param_this = (*proxy_class_NSObjectC)(_param_this_ref)
		}
	}
	res_0 := v.Description(_param_this)
	_res_0 := encodeString(res_0)
	return _res_0
}

//export new_objc_GoNSObject
func new_objc_GoNSObject() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(objc.GoNSObject)))
}

//export proxyobjc_GoUIResponder_UIResponder_Set
func proxyobjc_GoUIResponder_UIResponder_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v UIKit.UIResponder
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(UIKit.UIResponder)
		} else { // foreign object
			_v = (*proxy_class_UIResponder)(_v_ref)
		}
	}
	ref.Get().(*objc.GoUIResponder).UIResponder = _v
}

//export proxyobjc_GoUIResponder_UIResponder_Get
func proxyobjc_GoUIResponder_UIResponder_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoUIResponder).UIResponder
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyobjc_GoUIResponder_PressesBegan
func proxyobjc_GoUIResponder_PressesBegan(refnum C.int32_t, param_p0 C.int32_t, param_p1 C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*objc.GoUIResponder)
	var _param_p0 Foundation.NSSet
	_param_p0_ref := _seq.FromRefNum(int32(param_p0))
	if _param_p0_ref != nil {
		if param_p0 < 0 { // go object
			_param_p0 = _param_p0_ref.Get().(Foundation.NSSet)
		} else { // foreign object
			_param_p0 = (*proxy_class_NSSet)(_param_p0_ref)
		}
	}
	var _param_p1 UIKit.UIPressesEvent
	_param_p1_ref := _seq.FromRefNum(int32(param_p1))
	if _param_p1_ref != nil {
		if param_p1 < 0 { // go object
			_param_p1 = _param_p1_ref.Get().(UIKit.UIPressesEvent)
		} else { // foreign object
			_param_p1 = (*proxy_class_UIPressesEvent)(_param_p1_ref)
		}
	}
	v.PressesBegan(_param_p0, _param_p1)
}

//export new_objc_GoUIResponder
func new_objc_GoUIResponder() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(objc.GoUIResponder)))
}

//export proxyobjc__CallUcharFunction
func proxyobjc__CallUcharFunction() {
	objc.CallUcharFunction()
}

//export proxyobjc__CreateReadNSMutableString
func proxyobjc__CreateReadNSMutableString() {
	objc.CreateReadNSMutableString()
}

//export proxyobjc__DupNSDate
func proxyobjc__DupNSDate(param_date C.int32_t) C.int32_t {
	var _param_date Foundation.NSDate
	_param_date_ref := _seq.FromRefNum(int32(param_date))
	if _param_date_ref != nil {
		if param_date < 0 { // go object
			_param_date = _param_date_ref.Get().(Foundation.NSDate)
		} else { // foreign object
			_param_date = (*proxy_class_NSDate)(_param_date_ref)
		}
	}
	res_0 := objc.DupNSDate(_param_date)
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}
