// 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(void) {
	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();
}
