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

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


@implementation VarsS {
}

- (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_vars_S());
	}
	return self;
}

@end


@implementation VarsI {
}

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

@end


@implementation Vars
+ (void) setABool:(BOOL)v {
	char _v = (char)v;
	var_setvars_ABool(_v);
}

+ (BOOL) aBool {
	char r0 = var_getvars_ABool();
	BOOL _r0 = r0 ? YES : NO;
	return _r0;
}

+ (void) setAFloat:(double)v {
	double _v = (double)v;
	var_setvars_AFloat(_v);
}

+ (double) aFloat {
	double r0 = var_getvars_AFloat();
	double _r0 = (double)r0;
	return _r0;
}

+ (void) setAFloat32:(float)v {
	float _v = (float)v;
	var_setvars_AFloat32(_v);
}

+ (float) aFloat32 {
	float r0 = var_getvars_AFloat32();
	float _r0 = (float)r0;
	return _r0;
}

+ (void) setAFloat64:(double)v {
	double _v = (double)v;
	var_setvars_AFloat64(_v);
}

+ (double) aFloat64 {
	double r0 = var_getvars_AFloat64();
	double _r0 = (double)r0;
	return _r0;
}

+ (void) setAString:(NSString*)v {
	nstring _v = go_seq_from_objc_string(v);
	var_setvars_AString(_v);
}

+ (NSString*) aString {
	nstring r0 = var_getvars_AString();
	NSString *_r0 = go_seq_to_objc_string(r0);
	return _r0;
}

+ (void) setAStructPtr:(VarsS*)v {
	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);
	}
	var_setvars_AStructPtr(_v);
}

+ (VarsS*) aStructPtr {
	int32_t r0 = var_getvars_AStructPtr();
	VarsS* _r0 = nil;
	GoSeqRef* _r0_ref = go_seq_from_refnum(r0);
	if (_r0_ref != NULL) {
		_r0 = _r0_ref.obj;
		if (_r0 == nil) {
			_r0 = [[VarsS alloc] initWithRef:_r0_ref];
		}
	}
	return _r0;
}

+ (void) setAnInt:(long)v {
	nint _v = (nint)v;
	var_setvars_AnInt(_v);
}

+ (long) anInt {
	nint r0 = var_getvars_AnInt();
	long _r0 = (long)r0;
	return _r0;
}

+ (void) setAnInt16:(int16_t)v {
	int16_t _v = (int16_t)v;
	var_setvars_AnInt16(_v);
}

+ (int16_t) anInt16 {
	int16_t r0 = var_getvars_AnInt16();
	int16_t _r0 = (int16_t)r0;
	return _r0;
}

+ (void) setAnInt32:(int32_t)v {
	int32_t _v = (int32_t)v;
	var_setvars_AnInt32(_v);
}

+ (int32_t) anInt32 {
	int32_t r0 = var_getvars_AnInt32();
	int32_t _r0 = (int32_t)r0;
	return _r0;
}

+ (void) setAnInt64:(int64_t)v {
	int64_t _v = (int64_t)v;
	var_setvars_AnInt64(_v);
}

+ (int64_t) anInt64 {
	int64_t r0 = var_getvars_AnInt64();
	int64_t _r0 = (int64_t)r0;
	return _r0;
}

+ (void) setAnInt8:(int8_t)v {
	int8_t _v = (int8_t)v;
	var_setvars_AnInt8(_v);
}

+ (int8_t) anInt8 {
	int8_t r0 = var_getvars_AnInt8();
	int8_t _r0 = (int8_t)r0;
	return _r0;
}

+ (void) setAnInterface:(id<VarsI>)v {
	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);
	}
	var_setvars_AnInterface(_v);
}

+ (id<VarsI>) anInterface {
	int32_t r0 = var_getvars_AnInterface();
	VarsI* _r0 = nil;
	GoSeqRef* _r0_ref = go_seq_from_refnum(r0);
	if (_r0_ref != NULL) {
		_r0 = _r0_ref.obj;
		if (_r0 == nil) {
			_r0 = [[VarsI alloc] initWithRef:_r0_ref];
		}
	}
	return _r0;
}

@end


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