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

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

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

@protocol goSeqRefInterface
-(GoSeqRef*) ref;
@end

#define _DESCRIPTOR_ "structs"

#define _CALL_Identity_ 1
#define _CALL_IdentityWithError_ 2

#define _GO_structs_S_DESCRIPTOR_ "go.structs.S"
#define _GO_structs_S_FIELD_X_GET_ (0x00f)
#define _GO_structs_S_FIELD_X_SET_ (0x01f)
#define _GO_structs_S_FIELD_Y_GET_ (0x10f)
#define _GO_structs_S_FIELD_Y_SET_ (0x11f)
#define _GO_structs_S_Identity_ (0x00c)
#define _GO_structs_S_Sum_ (0x10c)

@implementation GoStructsS {
}

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

- (double)X {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_FIELD_X_GET_, &in_, &out_);
	double ret_ = go_seq_readFloat64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret_;
}

- (void)setX:(double)v {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_writeFloat64(&in_, v);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_FIELD_X_SET_, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

- (double)Y {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_FIELD_Y_GET_, &in_, &out_);
	double ret_ = go_seq_readFloat64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret_;
}

- (void)setY:(double)v {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_writeFloat64(&in_, v);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_FIELD_Y_SET_, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

- (BOOL)Identity:(GoStructsS**)ret0_ error:(NSError**)error {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_Identity_, &in_, &out_);
	GoSeqRef* ret0__ref = go_seq_readRef(&out_);
	if (ret0_ != NULL) {
		*ret0_ = ret0__ref.obj;
		if (*ret0_ == NULL) {
			*ret0_ = [[GoStructsS alloc] initWithRef:ret0__ref];
		}
	}
	NSString* _error = go_seq_readUTF8(&out_);
	if ([_error length] != 0 && error != nil) {
		NSMutableDictionary* details = [NSMutableDictionary dictionary];
		[details setValue:_error forKey:NSLocalizedDescriptionKey];
		*error = [NSError errorWithDomain:errDomain code:1 userInfo:details];
	}
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ([_error length] == 0);
}

- (double)Sum {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeRef(&in_, self.ref);
	go_seq_send(_GO_structs_S_DESCRIPTOR_, _GO_structs_S_Sum_, &in_, &out_);
	double ret0_ = go_seq_readFloat64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret0_;
}

@end

GoStructsS* GoStructsIdentity(GoStructsS* s) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	if ([(id<NSObject>)(s) isKindOfClass:[GoStructsS class]]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		go_seq_writeRef(&in_, s_proxy.ref);
	} else {
		go_seq_writeObjcRef(&in_, s);
	}
	go_seq_send(_DESCRIPTOR_, _CALL_Identity_, &in_, &out_);
	GoSeqRef* ret0__ref = go_seq_readRef(&out_);
	GoStructsS* ret0_ = ret0__ref.obj;
	if (ret0_ == NULL) {
		ret0_ = [[GoStructsS alloc] initWithRef:ret0__ref];
	}
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret0_;
}

BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** ret0_, NSError** error) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	if ([(id<NSObject>)(s) isKindOfClass:[GoStructsS class]]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		go_seq_writeRef(&in_, s_proxy.ref);
	} else {
		go_seq_writeObjcRef(&in_, s);
	}
	go_seq_send(_DESCRIPTOR_, _CALL_IdentityWithError_, &in_, &out_);
	GoSeqRef* ret0__ref = go_seq_readRef(&out_);
	if (ret0_ != NULL) {
		*ret0_ = ret0__ref.obj;
		if (*ret0_ == NULL) {
			*ret0_ = [[GoStructsS alloc] initWithRef:ret0__ref];
		}
	}
	NSString* _error = go_seq_readUTF8(&out_);
	if ([_error length] != 0 && error != nil) {
		NSMutableDictionary* details = [NSMutableDictionary dictionary];
		[details setValue:_error forKey:NSLocalizedDescriptionKey];
		*error = [NSError errorWithDomain:errDomain code:1 userInfo:details];
	}
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ([_error length] == 0);
}

