// 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"

static NSString* errDomain = @"go.interfaces";

@implementation GoInterfacesError {
}

- (id)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 = go_seq_to_nserror(_error, errDomain);
	}
	return (_error == nil);
}

@end


@implementation GoInterfacesI {
}

- (id)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 {
}

- (id)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 {
}

- (id)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 {
}

- (id)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 {
}

- (id)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 {
}

- (id)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 {
}

- (id)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 = go_seq_to_nserror(_error, errDomain);
	}
	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];
		GoUniverseerror* _error = nil;
		if (!returnVal) {
			_error = [[goSeqErrorWrapper alloc] initWithError: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();
}
