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

#include <Foundation/Foundation.h>
#include "seq.h"
#include "_cgo_export.h"
#include "Doc.objc.h"


@implementation DocNoDoc {
}

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

- (instancetype)init {
	self = [super init];
	if (self) {
		__ref = go_seq_from_refnum(new_doc_NoDoc());
	}
	return self;
}

@end



@implementation DocS {
}

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

- (instancetype)init {
	self = [super init];
	if (!self) return nil;
	int32_t refnum = proxydoc__NewS();
	__ref = go_seq_from_refnum(refnum);
	return self;
}

- (NSString*)sf {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring r0 = proxydoc_S_SF_Get(refnum);
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

- (void)setSF:(NSString*)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring _v = go_seq_from_objc_string(v);
	proxydoc_S_SF_Set(refnum, _v);
}

- (DocS2*)s2 {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t r0 = proxydoc_S_S2_Get(refnum);
	DocS2* _r0 = nil;
	GoSeqRef* _r0_ref = go_seq_from_refnum(r0);
	if (_r0_ref != NULL) {
		_r0 = _r0_ref.obj;
		if (_r0 == nil) {
			_r0 = [[DocS2 alloc] initWithRef:_r0_ref];
		}
	}
	return _r0;
}

- (void)setS2:(DocS2*)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	int32_t _v;
	if ([v conformsToProtocol:@protocol(goSeqRefInterface)]) {
		id<goSeqRefInterface> v_proxy = (id<goSeqRefInterface>)(v);
		_v = go_seq_go_to_refnum(v_proxy._ref);
	} else {
		_v = go_seq_to_refnum(v);
	}
	proxydoc_S_S2_Set(refnum, _v);
}

- (NSString*)f1 {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring r0 = proxydoc_S_F1_Get(refnum);
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

- (void)setF1:(NSString*)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring _v = go_seq_from_objc_string(v);
	proxydoc_S_F1_Set(refnum, _v);
}

- (NSString*)f2 {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring r0 = proxydoc_S_F2_Get(refnum);
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

- (void)setF2:(NSString*)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring _v = go_seq_from_objc_string(v);
	proxydoc_S_F2_Set(refnum, _v);
}

- (void)after {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxydoc_S_After(refnum);
}

- (void)before {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxydoc_S_Before(refnum);
}

@end



@implementation DocS2 {
}

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

- (instancetype)init {
	self = [super init];
	if (self) {
		__ref = go_seq_from_refnum(new_doc_S2());
	}
	return self;
}

@end


@implementation DocI {
}

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

- (void)im {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxydoc_I_IM(refnum);
}

@end


const BOOL DocC = YES;

@implementation Doc
+ (void) setNoDocVar:(double)v {
	double _v = (double)v;
	var_setdoc_NoDocVar(_v);
}

+ (double) noDocVar {
	double r0 = var_getdoc_NoDocVar();
	double _r0 = (double)r0;
	return _r0;
}

+ (void) setSpecific:(NSString*)v {
	nstring _v = go_seq_from_objc_string(v);
	var_setdoc_Specific(_v);
}

+ (NSString*) specific {
	nstring r0 = var_getdoc_Specific();
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

+ (void) setV:(NSString*)v {
	nstring _v = go_seq_from_objc_string(v);
	var_setdoc_V(_v);
}

+ (NSString*) v {
	nstring r0 = var_getdoc_V();
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

@end


void DocF(void) {
	proxydoc__F();
}

DocS* DocNewS(void) {
	int32_t r0 = proxydoc__NewS();
	DocS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[DocS alloc] initWithRef:_ret0__ref];
		}
	}
	return _ret0_;
}

void cproxydoc_I_IM(int32_t refnum) {
	@autoreleasepool {
		DocI* o = go_seq_objc_from_refnum(refnum);
		[o im];
	}
}

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