// Objective-C API for talking to interfaces Go package.
//   gobind -lang=objc interfaces
//
// File is generated by gobind. Do not edit.

#include <Foundation/Foundation.h>
#include "seq.h"
#include "_cgo_export.h"
#include "GoInterfaces.h"

@implementation GoInterfacesError {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (BOOL)err:(NSError**)error {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxyinterfaces_Error_Err(refnum);
	GoUniverseerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(r0);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[GoUniverseerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

@end


@implementation GoInterfacesI {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (int32_t)rand {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxyinterfaces_I_Rand(refnum);
	int32_t _ret0_ = (int32_t)r0;
	return _ret0_;
}

@end


@implementation GoInterfacesI1 {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (void)j {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxyinterfaces_I1_J(refnum);
}

@end


@implementation GoInterfacesI2 {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (void)g {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxyinterfaces_I2_G(refnum);
}

@end


@implementation GoInterfacesI3 {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (GoInterfacesI1*)f {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxyinterfaces_I3_F(refnum);
	GoInterfacesI1* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[GoInterfacesI1 alloc] initWithRef:_ret0__ref];
		}
	}
	return _ret0_;
}

@end


@implementation GoInterfacesLargerI {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (void)anotherFunc {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxyinterfaces_LargerI_AnotherFunc(refnum);
}

- (int32_t)rand {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxyinterfaces_LargerI_Rand(refnum);
	int32_t _ret0_ = (int32_t)r0;
	return _ret0_;
}

@end


@implementation GoInterfacesSameI {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (int32_t)rand {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxyinterfaces_SameI_Rand(refnum);
	int32_t _ret0_ = (int32_t)r0;
	return _ret0_;
}

@end


@implementation GoInterfacesWithParam {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (void)hasParam:(BOOL)p0 {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	char _p0 = (char)p0;
	proxyinterfaces_WithParam_HasParam(refnum, _p0);
}

@end



int32_t GoInterfacesAdd3(id<GoInterfacesI> r) {
	int32_t _r;
	if ([(id<NSObject>)(r) isKindOfClass:[GoInterfacesI class]]) {
		id<goSeqRefInterface> r_proxy = (id<goSeqRefInterface>)(r);
		_r = go_seq_go_to_refnum(r_proxy._ref);
	} else {
		_r = go_seq_to_refnum(r);
	}
	int32_t r0 = proxyinterfaces__Add3(_r);
	int32_t _ret0_ = (int32_t)r0;
	return _ret0_;
}

BOOL GoInterfacesCallErr(id<GoInterfacesError> e, NSError** error) {
	int32_t _e;
	if ([(id<NSObject>)(e) isKindOfClass:[GoInterfacesError class]]) {
		id<goSeqRefInterface> e_proxy = (id<goSeqRefInterface>)(e);
		_e = go_seq_go_to_refnum(e_proxy._ref);
	} else {
		_e = go_seq_to_refnum(e);
	}
	int32_t r0 = proxyinterfaces__CallErr(_e);
	GoUniverseerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(r0);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[GoUniverseerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

id<GoInterfacesI> GoInterfacesSeven() {
	int32_t r0 = proxyinterfaces__Seven();
	GoInterfacesI* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[GoInterfacesI alloc] initWithRef:_ret0__ref];
		}
	}
	return _ret0_;
}

int32_t cproxyinterfaces_Error_Err(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesError* o = go_seq_objc_from_refnum(refnum);
		NSError* error = nil;
		BOOL returnVal = [o err:&error];
		id<GoUniverseerror> _error = nil;
		if (!returnVal) {
			_error = error;
		}
		int32_t __error;
		if ([(id<NSObject>)(_error) isKindOfClass:[GoUniverseerror class]]) {
			id<goSeqRefInterface> _error_proxy = (id<goSeqRefInterface>)(_error);
			__error = go_seq_go_to_refnum(_error_proxy._ref);
		} else {
			__error = go_seq_to_refnum(_error);
		}
		return __error;
	}
}

int32_t cproxyinterfaces_I_Rand(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesI* o = go_seq_objc_from_refnum(refnum);
		int32_t returnVal = [o rand];
		int32_t _returnVal = (int32_t)returnVal;
		return _returnVal;
	}
}

void cproxyinterfaces_I1_J(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesI1* o = go_seq_objc_from_refnum(refnum);
		[o j];
	}
}

void cproxyinterfaces_I2_G(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesI2* o = go_seq_objc_from_refnum(refnum);
		[o g];
	}
}

int32_t cproxyinterfaces_I3_F(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesI3* o = go_seq_objc_from_refnum(refnum);
		GoInterfacesI1* returnVal = [o f];
		int32_t _returnVal;
		if ([(id<NSObject>)(returnVal) isKindOfClass:[GoInterfacesI1 class]]) {
			id<goSeqRefInterface> returnVal_proxy = (id<goSeqRefInterface>)(returnVal);
			_returnVal = go_seq_go_to_refnum(returnVal_proxy._ref);
		} else {
			_returnVal = go_seq_to_refnum(returnVal);
		}
		return _returnVal;
	}
}

void cproxyinterfaces_LargerI_AnotherFunc(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesLargerI* o = go_seq_objc_from_refnum(refnum);
		[o anotherFunc];
	}
}

int32_t cproxyinterfaces_LargerI_Rand(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesLargerI* o = go_seq_objc_from_refnum(refnum);
		int32_t returnVal = [o rand];
		int32_t _returnVal = (int32_t)returnVal;
		return _returnVal;
	}
}

int32_t cproxyinterfaces_SameI_Rand(int32_t refnum) {
	@autoreleasepool {
		GoInterfacesSameI* o = go_seq_objc_from_refnum(refnum);
		int32_t returnVal = [o rand];
		int32_t _returnVal = (int32_t)returnVal;
		return _returnVal;
	}
}

void cproxyinterfaces_WithParam_HasParam(int32_t refnum, char p0) {
	@autoreleasepool {
		GoInterfacesWithParam* o = go_seq_objc_from_refnum(refnum);
		BOOL _p0 = p0 ? YES : NO;
		[o hasParam:_p0];
	}
}

__attribute__((constructor)) static void init() {
	init_seq();
}
