// 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 {
}

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

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

@end



@implementation DocS {
}

- (nonnull instancetype)initWithRef:(_Nonnull 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* _Nonnull)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* _Nonnull)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* _Nullable)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* _Nullable)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* _Nonnull)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* _Nonnull)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* _Nonnull)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* _Nonnull)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 {
}

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

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

@end


@implementation DocI {
}

- (nonnull 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* _Nonnull)v {
	nstring _v = go_seq_from_objc_string(v);
	var_setdoc_Specific(_v);
}

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

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

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

@end


void DocF(void) {
	proxydoc__F();
}

DocS* _Nullable 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();
}
