// 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 ([r conformsToProtocol:@protocol(goSeqRefInterface)]) {
		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 ([e conformsToProtocol:@protocol(goSeqRefInterface)]) {
		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];
		NSError *_error = nil;
		if (!returnVal) {
			_error = error;
		}
		int32_t __error;
		if ([_error conformsToProtocol:@protocol(goSeqRefInterface)]) {
			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 ([returnVal conformsToProtocol:@protocol(goSeqRefInterface)]) {
			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();
}
