// Package main is an autogenerated binder stub for package doc.
//   gobind -lang=go doc
//
// File is generated by gobind. Do not edit.
package main

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "doc.h"

*/
import "C"

import (
	"doc"
	_seq "golang.org/x/mobile/bind/seq"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

//export new_doc_NoDoc
func new_doc_NoDoc() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.NoDoc)))
}

//export proxydoc_S_SF_Set
func proxydoc_S_SF_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).SF = _v
}

//export proxydoc_S_SF_Get
func proxydoc_S_SF_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).SF
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_S2_Set
func proxydoc_S_S2_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	// Must be a Go object
	var _v *doc.S2
	if _v_ref := _seq.FromRefNum(int32(v)); _v_ref != nil {
		_v = _v_ref.Get().(*doc.S2)
	}
	ref.Get().(*doc.S).S2 = _v
}

//export proxydoc_S_S2_Get
func proxydoc_S_S2_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).S2
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxydoc_S_F1_Set
func proxydoc_S_F1_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).F1 = _v
}

//export proxydoc_S_F1_Get
func proxydoc_S_F1_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).F1
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_F2_Set
func proxydoc_S_F2_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).F2 = _v
}

//export proxydoc_S_F2_Get
func proxydoc_S_F2_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).F2
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_After
func proxydoc_S_After(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S)
	v.After()
}

//export proxydoc_S_Before
func proxydoc_S_Before(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S)
	v.Before()
}

//export new_doc_S
func new_doc_S() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.S)))
}

//export new_doc_S2
func new_doc_S2() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.S2)))
}

//export proxydoc_I_IM
func proxydoc_I_IM(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(doc.I)
	v.IM()
}

type proxydoc_I _seq.Ref

func (p *proxydoc_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxydoc_I) IM() {
	C.cproxydoc_I_IM(C.int32_t(p.Bind_proxy_refnum__()))
}

//export var_setdoc_NoDocVar
func var_setdoc_NoDocVar(v C.double) {
	_v := float64(v)
	doc.NoDocVar = _v
}

//export var_getdoc_NoDocVar
func var_getdoc_NoDocVar() C.double {
	v := doc.NoDocVar
	_v := C.double(v)
	return _v
}

//export var_setdoc_Specific
func var_setdoc_Specific(v C.nstring) {
	_v := decodeString(v)
	doc.Specific = _v
}

//export var_getdoc_Specific
func var_getdoc_Specific() C.nstring {
	v := doc.Specific
	_v := encodeString(v)
	return _v
}

//export var_setdoc_V
func var_setdoc_V(v C.nstring) {
	_v := decodeString(v)
	doc.V = _v
}

//export var_getdoc_V
func var_getdoc_V() C.nstring {
	v := doc.V
	_v := encodeString(v)
	return _v
}

//export proxydoc__F
func proxydoc__F() {
	doc.F()
}

//export proxydoc__NewS
func proxydoc__NewS() C.int32_t {
	res_0 := doc.NewS()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}
