// 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 "Interfaces.objc.h"

@implementation InterfacesError {
}

- (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);
	Universeerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(r0);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[Universeerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

@end


@implementation InterfacesI {
}

- (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 InterfacesI1 {
}

- (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 InterfacesI2 {
}

- (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 InterfacesI3 {
}

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

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

@end


@implementation InterfacesLargerI {
}

- (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 InterfacesSameI {
}

- (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 InterfacesWithParam {
}

- (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 InterfacesAdd3(id<InterfacesI> 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 InterfacesCallErr(id<InterfacesError> 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);
	Universeerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(r0);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[Universeerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

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

int32_t cproxyinterfaces_Error_Err(int32_t refnum) {
	@autoreleasepool {
		InterfacesError* 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 {
		InterfacesI* o = go_seq_objc_from_refnum(refnum);
		int32_t ret0_;
		ret0_ = [o rand];
		int32_t _ret0_ = (int32_t)ret0_;
		return _ret0_;
	}
}

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

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

int32_t cproxyinterfaces_I3_F(int32_t refnum) {
	@autoreleasepool {
		InterfacesI3* o = go_seq_objc_from_refnum(refnum);
		InterfacesI1* ret0_;
		ret0_ = [o f];
		int32_t _ret0_;
		if ([ret0_ conformsToProtocol:@protocol(goSeqRefInterface)]) {
			id<goSeqRefInterface> ret0__proxy = (id<goSeqRefInterface>)(ret0_);
			_ret0_ = go_seq_go_to_refnum(ret0__proxy._ref);
		} else {
			_ret0_ = go_seq_to_refnum(ret0_);
		}
		return _ret0_;
	}
}

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

int32_t cproxyinterfaces_LargerI_Rand(int32_t refnum) {
	@autoreleasepool {
		InterfacesLargerI* o = go_seq_objc_from_refnum(refnum);
		int32_t ret0_;
		ret0_ = [o rand];
		int32_t _ret0_ = (int32_t)ret0_;
		return _ret0_;
	}
}

int32_t cproxyinterfaces_SameI_Rand(int32_t refnum) {
	@autoreleasepool {
		InterfacesSameI* o = go_seq_objc_from_refnum(refnum);
		int32_t ret0_;
		ret0_ = [o rand];
		int32_t _ret0_ = (int32_t)ret0_;
		return _ret0_;
	}
}

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

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