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

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


@implementation GoStructsS {
}

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

- (double)x {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_X_Get(refnum);
	double _r0 = (double)r0;
	return _r0;
}

- (void)setX:(double)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double _v = (double)v;
	proxystructs_S_X_Set(refnum, _v);
}

- (double)y {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_Y_Get(refnum);
	double _r0 = (double)r0;
	return _r0;
}

- (void)setY:(double)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double _v = (double)v;
	proxystructs_S_Y_Set(refnum, _v);
}

- (BOOL)identity:(GoStructsS**)ret0_ error:(NSError**)error {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	struct proxystructs_S_Identity_return res = proxystructs_S_Identity(refnum);
	GoStructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(res.r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[GoStructsS alloc] initWithRef:_ret0__ref];
		}
	}
	GoUniverseerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(res.r1);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[GoUniverseerror alloc] initWithRef:_error_ref];
		}
	}
	*ret0_ = _ret0_;
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

- (double)sum {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_Sum(refnum);
	double _ret0_ = (double)r0;
	return _ret0_;
}

@end



@implementation GoStructsS2 {
}

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

- (void)m {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxystructs_S2_M(refnum);
}

- (NSString*)string {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring r0 = proxystructs_S2_String(refnum);
	NSString *_ret0_ = go_seq_to_objc_string(r0);
	return _ret0_;
}

@end


@implementation GoStructsI {
}

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

- (void)m {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxystructs_I_M(refnum);
}

@end



GoStructsS* GoStructsIdentity(GoStructsS* s) {
	int32_t _s;
	if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		_s = go_seq_go_to_refnum(s_proxy._ref);
	} else {
		_s = go_seq_to_refnum(s);
	}
	int32_t r0 = proxystructs__Identity(_s);
	GoStructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[GoStructsS alloc] initWithRef:_ret0__ref];
		}
	}
	return _ret0_;
}

BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** ret0_, NSError** error) {
	int32_t _s;
	if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		_s = go_seq_go_to_refnum(s_proxy._ref);
	} else {
		_s = go_seq_to_refnum(s);
	}
	struct proxystructs__IdentityWithError_return res = proxystructs__IdentityWithError(_s);
	GoStructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(res.r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[GoStructsS alloc] initWithRef:_ret0__ref];
		}
	}
	GoUniverseerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(res.r1);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[GoUniverseerror alloc] initWithRef:_error_ref];
		}
	}
	*ret0_ = _ret0_;
	if (_error != nil && error != nil) {
		*error = _error;
	}
	return (_error == nil);
}

void cproxystructs_I_M(int32_t refnum) {
	@autoreleasepool {
		GoStructsI* o = go_seq_objc_from_refnum(refnum);
		[o m];
	}
}

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