"""
Package fasta contains fasta parsers and writers.

Fasta is a flat text file format developed in 1985 to store nucleotide and
amino acid sequences. It is extremely simple and well-supported across many
languages. However, this simplicity means that annotation of genetic objects
is not supported.

This package provides a parser and writer for working with Fasta formatted
genetic sequences.

"""
# python wrapper for package github.com/bebop/poly/io/fasta within overall package poly
# This is what you import to use the package.
# File is generated by gopy. Do not edit.
# gopy pkg -vm=python3 github.com/bebop/poly

# the following is required to enable dlopen to open the _go.so file
import os,sys,inspect,collections
try:
	import collections.abc as _collections_abc
except ImportError:
	_collections_abc = collections

cwd = os.getcwd()
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
os.chdir(currentdir)
from . import _poly
from . import go

os.chdir(cwd)

# to use this code in your end-user python file, import it as follows:
# from poly import fasta
# and then refer to everything using fasta. prefix
# packages imported by this package listed below:




# ---- Types ---

# Python type for slice []fasta.Fasta
class Slice_fasta_Fasta(go.GoClass):
	""""""
	def __init__(self, *args, **kwargs):
		"""
		handle=A Go-side object is always initialized with an explicit handle=arg
		otherwise parameter is a python list that we copy from
		"""
		self.index = 0
		if len(kwargs) == 1 and 'handle' in kwargs:
			self.handle = kwargs['handle']
			_poly.IncRef(self.handle)
		elif len(args) == 1 and isinstance(args[0], go.GoClass):
			self.handle = args[0].handle
			_poly.IncRef(self.handle)
		else:
			self.handle = _poly.Slice_fasta_Fasta_CTor()
			_poly.IncRef(self.handle)
			if len(args) > 0:
				if not isinstance(args[0], _collections_abc.Iterable):
					raise TypeError('Slice_fasta_Fasta.__init__ takes a sequence as argument')
				for elt in args[0]:
					self.append(elt)
	def __del__(self):
		_poly.DecRef(self.handle)
	def __str__(self):
		s = 'fasta.Slice_fasta_Fasta len: ' + str(len(self)) + ' handle: ' + str(self.handle) + ' ['
		if len(self) < 120:
			s += ', '.join(map(str, self)) + ']'
		return s
	def __repr__(self):
		return 'fasta.Slice_fasta_Fasta([' + ', '.join(map(str, self)) + '])'
	def __len__(self):
		return _poly.Slice_fasta_Fasta_len(self.handle)
	def __getitem__(self, key):
		if isinstance(key, slice):
			if key.step == None or key.step == 1:
				st = key.start
				ed = key.stop
				if st == None:
					st = 0
				if ed == None:
					ed = _poly.Slice_fasta_Fasta_len(self.handle)
				return Slice_fasta_Fasta(handle=_poly.Slice_fasta_Fasta_subslice(self.handle, st, ed))
			return [self[ii] for ii in range(*key.indices(len(self)))]
		elif isinstance(key, int):
			if key < 0:
				key += len(self)
			if key < 0 or key >= len(self):
				raise IndexError('slice index out of range')
			return Fasta(handle=_poly.Slice_fasta_Fasta_elem(self.handle, key))
		else:
			raise TypeError('slice index invalid type')
	def __setitem__(self, idx, value):
		if idx < 0:
			idx += len(self)
		if idx < len(self):
			_poly.Slice_fasta_Fasta_set(self.handle, idx, value.handle)
			return
		raise IndexError('slice index out of range')
	def __iadd__(self, value):
		if not isinstance(value, _collections_abc.Iterable):
			raise TypeError('Slice_fasta_Fasta.__iadd__ takes a sequence as argument')
		for elt in value:
			self.append(elt)
		return self
	def __iter__(self):
		self.index = 0
		return self
	def __next__(self):
		if self.index < len(self):
			rv = Fasta(handle=_poly.Slice_fasta_Fasta_elem(self.handle, self.index))
			self.index = self.index + 1
			return rv
		raise StopIteration
	def append(self, value):
		_poly.Slice_fasta_Fasta_append(self.handle, value.handle)
	def copy(self, src):
		""" copy emulates the go copy function, copying elements into this list from source list, up to min of size of each list """
		mx = min(len(self), len(src))
		for i in range(mx):
			self[i] = src[i]


#---- Enums from Go (collections of consts with same type) ---


#---- Constants from Go: Python can only ask that you please don't change these! ---


# ---- Global Variables: can only use functions to access ---


# ---- Interfaces ---


# ---- Structs ---

# Python type for struct fasta.Fasta
class Fasta(go.GoClass):
	"""Fasta is a struct representing a single Fasta file element with a Name and its corresponding Sequence.\n"""
	def __init__(self, *args, **kwargs):
		"""
		handle=A Go-side object is always initialized with an explicit handle=arg
		otherwise parameters can be unnamed in order of field names or named fields
		in which case a new Go object is constructed first
		"""
		if len(kwargs) == 1 and 'handle' in kwargs:
			self.handle = kwargs['handle']
			_poly.IncRef(self.handle)
		elif len(args) == 1 and isinstance(args[0], go.GoClass):
			self.handle = args[0].handle
			_poly.IncRef(self.handle)
		else:
			self.handle = _poly.fasta_Fasta_CTor()
			_poly.IncRef(self.handle)
			if  0 < len(args):
				self.Name = args[0]
			if "Name" in kwargs:
				self.Name = kwargs["Name"]
			if  1 < len(args):
				self.Sequence = args[1]
			if "Sequence" in kwargs:
				self.Sequence = kwargs["Sequence"]
	def __del__(self):
		_poly.DecRef(self.handle)
	def __str__(self):
		pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
		sv = 'fasta.Fasta{'
		first = True
		for v in pr:
			if callable(v[1]):
				continue
			if first:
				first = False
			else:
				sv += ', '
			sv += v[0] + '=' + str(v[1])
		return sv + '}'
	def __repr__(self):
		pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
		sv = 'fasta.Fasta ( '
		for v in pr:
			if not callable(v[1]):
				sv += v[0] + '=' + str(v[1]) + ', '
		return sv + ')'
	@property
	def Name(self):
		return _poly.fasta_Fasta_Name_Get(self.handle)
	@Name.setter
	def Name(self, value):
		if isinstance(value, go.GoClass):
			_poly.fasta_Fasta_Name_Set(self.handle, value.handle)
		else:
			_poly.fasta_Fasta_Name_Set(self.handle, value)
	@property
	def Sequence(self):
		return _poly.fasta_Fasta_Sequence_Get(self.handle)
	@Sequence.setter
	def Sequence(self, value):
		if isinstance(value, go.GoClass):
			_poly.fasta_Fasta_Sequence_Set(self.handle, value.handle)
		else:
			_poly.fasta_Fasta_Sequence_Set(self.handle, value)

# Python type for struct fasta.Parser
class Parser(go.GoClass):
	"""Parser is a flexible parser that provides ample\ncontrol over reading fasta-formatted sequences.\nIt is initialized with NewParser.\n"""
	def __init__(self, *args, **kwargs):
		"""
		handle=A Go-side object is always initialized with an explicit handle=arg
		otherwise parameters can be unnamed in order of field names or named fields
		in which case a new Go object is constructed first
		"""
		if len(kwargs) == 1 and 'handle' in kwargs:
			self.handle = kwargs['handle']
			_poly.IncRef(self.handle)
		elif len(args) == 1 and isinstance(args[0], go.GoClass):
			self.handle = args[0].handle
			_poly.IncRef(self.handle)
		else:
			self.handle = _poly.fasta_Parser_CTor()
			_poly.IncRef(self.handle)
	def __del__(self):
		_poly.DecRef(self.handle)
	def __str__(self):
		pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
		sv = 'fasta.Parser{'
		first = True
		for v in pr:
			if callable(v[1]):
				continue
			if first:
				first = False
			else:
				sv += ', '
			sv += v[0] + '=' + str(v[1])
		return sv + '}'
	def __repr__(self):
		pr = [(p, getattr(self, p)) for p in dir(self) if not p.startswith('__')]
		sv = 'fasta.Parser ( '
		for v in pr:
			if not callable(v[1]):
				sv += v[0] + '=' + str(v[1]) + ', '
		return sv + ')'
	def ParseAll(self):
		"""ParseAll() []object, str
		
		ParseAll parses all sequences in underlying reader only returning non-EOF errors.
		It returns all valid fasta sequences up to error if encountered.
		"""
		return Slice_fasta_Fasta(handle=_poly.fasta_Parser_ParseAll(self.handle))
	def ParseN(self, maxSequences):
		"""ParseN(int maxSequences) []object fastas, str err
		
		ParseN parses up to maxSequences fasta sequences from the Parser's underlying reader.
		ParseN does not return EOF if encountered.
		If an non-EOF error is encountered it returns it and all correctly parsed sequences up to then.
		"""
		return Slice_fasta_Fasta(handle=_poly.fasta_Parser_ParseN(self.handle, maxSequences))
	def Reset(self, r, goRun=False):
		"""Reset(object r) 
		
		Reset discards all data in buffer and resets state.
		"""
		_poly.fasta_Parser_Reset(self.handle, r.handle, goRun)


# ---- Slices ---


# ---- Maps ---


# ---- Constructors ---
def NewParser(r, maxLineSize):
	"""NewParser(object r, int maxLineSize) object
	
	NewParser returns a Parser that uses r as the source
	from which to parse fasta formatted sequences.
	"""
	return Parser(handle=_poly.fasta_NewParser(r.handle, maxLineSize))


# ---- Functions ---
def Build(fastas):
	"""Build([]object fastas) []int, str
	
	Build converts a Fastas array into a byte array to be written to a file.
	"""
	return go.Slice_byte(handle=_poly.fasta_Build(fastas.handle))
def Parse(r):
	"""Parse(object r) []object, str"""
	return Slice_fasta_Fasta(handle=_poly.fasta_Parse(r.handle))
def Read(path):
	"""Read(str path) []object, str"""
	return Slice_fasta_Fasta(handle=_poly.fasta_Read(path))
def ReadGz(path):
	"""ReadGz(str path) []object, str"""
	return Slice_fasta_Fasta(handle=_poly.fasta_ReadGz(path))
def Write(fastas, path):
	"""Write([]object fastas, str path) str
	
	Write writes a fasta array to a file.
	"""
	return _poly.fasta_Write(fastas.handle, path)


