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

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


@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 = go_seq_to_nserror(_error, errDomain);
	}
	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 {
}

- (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_I_M(refnum);
}

@end



GoStructsS* GoStructsIdentity(GoStructsS* s) {
	int32_t _s;
	if ([(id<NSObject>)(s) isKindOfClass:[GoStructsS class]]) {
		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 ([(id<NSObject>)(s) isKindOfClass:[GoStructsS class]]) {
		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 = go_seq_to_nserror(_error, errDomain);
	}
	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();
}
