//File is 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)
	Super() Foundation_NSDate
}

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

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

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

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

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

// File is generated by gobind. Do not edit.

package gomobile_bind

// #cgo CFLAGS: -fobjc-arc -fmodules -fblocks
// #include "interfaces.h"
import "C"

import "ObjC"
import _seq "golang.org/x/mobile/bind/seq"

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 (p *proxy_class_NSDate) Super() ObjC.Foundation_NSDate {
  return &super_NSDate{p}
}

type super_NSDate struct {*proxy_class_NSDate}

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

func (p *super_NSDate) Description() (string) {
	res := C.csuper_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 (p *proxy_class_NSObjectC) Super() ObjC.Foundation_NSObjectC {
  return &super_NSObjectC{p}
}

type super_NSObjectC struct {*proxy_class_NSObjectC}

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

func (p *super_NSObjectC) Description() (string) {
	res := C.csuper_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 (p *proxy_class_NSSet) Super() ObjC.Foundation_NSSet {
  return &super_NSSet{p}
}

type super_NSSet struct {*proxy_class_NSSet}

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

func (p *super_NSSet) Description() (string) {
	res := C.csuper_NSSet_Description(C.int(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	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 (p *proxy_class_UIResponder) Super() ObjC.UIKit_UIResponder {
  return &super_UIResponder{p}
}

type super_UIResponder struct {*proxy_class_UIResponder}

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

func (p *super_UIResponder) Description() (string) {
	res := C.csuper_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 (p *proxy_class_UIPressesEvent) Super() ObjC.UIKit_UIPressesEvent {
  return &super_UIPressesEvent{p}
}

type super_UIPressesEvent struct {*proxy_class_UIPressesEvent}

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

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

// Package gomobile_bind is an autogenerated binder stub for package objc.
//   gobind -lang=go objcw
//
// File is generated by gobind. Do not edit.
package gomobile_bind

/*
#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__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
}
