"""
Package pileup contains pileup parsers and writers.

The pileup format is a text-based bioinformatics format to summarize aligned
reads against a reference sequence. In comparison to simply getting a consensus
sequence from sequencing data, pileup files can contain more context about the
mutations in a sequencing run, which is especially useful when analyzing
plasmid sequencing data from Nanopore sequencing runs.

Pileup files are basically tsv files with 6 columns: Sequence Identifier, Position,
Reference Base, Read Count, Read Results, and Quality. An example from
wikipedia (https://en.wikipedia.org/wiki/Pileup_format) is shown below:

	```
	seq1 	272 	T 	24 	,.$.....,,.,.,...,,,.,..^+. 	<<<+;<<<<<<<<<<<=<;<;7<&
	seq1 	273 	T 	23 	,.....,,.,.,...,,,.,..A 	<<<;<<<<<<<<<3<=<<<;<<+
	seq1 	274 	T 	23 	,.$....,,.,.,...,,,.,... 	7<7;<;<<<<<<<<<=<;<;<<6
	seq1 	275 	A 	23 	,$....,,.,.,...,,,.,...^l. 	<+;9*<<<<<<<<<=<<:;<<<<
	seq1 	276 	G 	22 	...T,,.,.,...,,,.,.... 	33;+<<7=7<<7<&<<1;<<6<
	seq1 	277 	T 	22 	....,,.,.,.C.,,,.,..G. 	+7<;<<<<<<<&<=<<:;<<&<
	seq1 	278 	G 	23 	....,,.,.,...,,,.,....^k. 	%38*<<;<7<<7<=<<<;<<<<<
	seq1 	279 	C 	23 	A..T,,.,.,...,,,.,..... 	75&<<<<<<<<<=<<<9<<:<<<
	```

	1. Sequence Identifier: The sequence identifier of the reference sequence
	2. Position: Position of row in the reference sequence (indexed at 1)
	3. Reference Base: Base pair in reference sequence
	4. Read Count: Number of aligned reads to this particular base pair
	5. Read Results: The resultant alignments
	6. Quality: Phred quality scores associated with each base

This package provides a parser and writer for working with pileup files.

"""
# python wrapper for package github.com/bebop/poly/io/pileup 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 pileup
# and then refer to everything using pileup. prefix
# packages imported by this package listed below:




# ---- Types ---

# Python type for slice []pileup.Pileup
class Slice_pileup_Pileup(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_pileup_Pileup_CTor()
			_poly.IncRef(self.handle)
			if len(args) > 0:
				if not isinstance(args[0], _collections_abc.Iterable):
					raise TypeError('Slice_pileup_Pileup.__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 = 'pileup.Slice_pileup_Pileup len: ' + str(len(self)) + ' handle: ' + str(self.handle) + ' ['
		if len(self) < 120:
			s += ', '.join(map(str, self)) + ']'
		return s
	def __repr__(self):
		return 'pileup.Slice_pileup_Pileup([' + ', '.join(map(str, self)) + '])'
	def __len__(self):
		return _poly.Slice_pileup_Pileup_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_pileup_Pileup_len(self.handle)
				return Slice_pileup_Pileup(handle=_poly.Slice_pileup_Pileup_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 Pileup(handle=_poly.Slice_pileup_Pileup_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_pileup_Pileup_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_pileup_Pileup.__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 = Pileup(handle=_poly.Slice_pileup_Pileup_elem(self.handle, self.index))
			self.index = self.index + 1
			return rv
		raise StopIteration
	def append(self, value):
		_poly.Slice_pileup_Pileup_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 pileup.Parser
class Parser(go.GoClass):
	"""Parser is a pileup parser.\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.pileup_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 = 'pileup.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 = 'pileup.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 pileup sequences up to error if encountered.
		"""
		return Slice_pileup_Pileup(handle=_poly.pileup_Parser_ParseAll(self.handle))
	def ParseN(self, maxRows):
		"""ParseN(int maxRows) []object pileups, str err
		
		ParseN parses up to maxRows pileup 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_pileup_Pileup(handle=_poly.pileup_Parser_ParseN(self.handle, maxRows))
	def ParseNext(self):
		"""ParseNext() object, str
		
		ParseNext parses the next pileup row in a pileup file.
		ParseNext returns an EOF if encountered.
		"""
		return Pileup(handle=_poly.pileup_Parser_ParseNext(self.handle))
	def Reset(self, r, goRun=False):
		"""Reset(object r) 
		
		Reset discards all data in buffer and resets state.
		"""
		_poly.pileup_Parser_Reset(self.handle, r.handle, goRun)

# Python type for struct pileup.Pileup
class Pileup(go.GoClass):
	"""Pileup struct is a single position in a pileup file. Pileup files \"pile\"\na bunch of separate bam/sam alignments into something more readable at a per\nbase pair level, so are only useful as a grouping.\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.pileup_Pileup_CTor()
			_poly.IncRef(self.handle)
			if  0 < len(args):
				self.Sequence = args[0]
			if "Sequence" in kwargs:
				self.Sequence = kwargs["Sequence"]
			if  1 < len(args):
				self.Position = args[1]
			if "Position" in kwargs:
				self.Position = kwargs["Position"]
			if  2 < len(args):
				self.ReferenceBase = args[2]
			if "ReferenceBase" in kwargs:
				self.ReferenceBase = kwargs["ReferenceBase"]
			if  3 < len(args):
				self.ReadCount = args[3]
			if "ReadCount" in kwargs:
				self.ReadCount = kwargs["ReadCount"]
			if  4 < len(args):
				self.ReadResults = args[4]
			if "ReadResults" in kwargs:
				self.ReadResults = kwargs["ReadResults"]
			if  5 < len(args):
				self.Quality = args[5]
			if "Quality" in kwargs:
				self.Quality = kwargs["Quality"]
	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 = 'pileup.Pileup{'
		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 = 'pileup.Pileup ( '
		for v in pr:
			if not callable(v[1]):
				sv += v[0] + '=' + str(v[1]) + ', '
		return sv + ')'
	@property
	def Sequence(self):
		return _poly.pileup_Pileup_Sequence_Get(self.handle)
	@Sequence.setter
	def Sequence(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_Sequence_Set(self.handle, value.handle)
		else:
			_poly.pileup_Pileup_Sequence_Set(self.handle, value)
	@property
	def Position(self):
		return _poly.pileup_Pileup_Position_Get(self.handle)
	@Position.setter
	def Position(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_Position_Set(self.handle, value.handle)
		else:
			_poly.pileup_Pileup_Position_Set(self.handle, value)
	@property
	def ReferenceBase(self):
		return _poly.pileup_Pileup_ReferenceBase_Get(self.handle)
	@ReferenceBase.setter
	def ReferenceBase(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_ReferenceBase_Set(self.handle, value.handle)
		else:
			_poly.pileup_Pileup_ReferenceBase_Set(self.handle, value)
	@property
	def ReadCount(self):
		return _poly.pileup_Pileup_ReadCount_Get(self.handle)
	@ReadCount.setter
	def ReadCount(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_ReadCount_Set(self.handle, value.handle)
		else:
			_poly.pileup_Pileup_ReadCount_Set(self.handle, value)
	@property
	def ReadResults(self):
		return go.Slice_string(handle=_poly.pileup_Pileup_ReadResults_Get(self.handle))
	@ReadResults.setter
	def ReadResults(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_ReadResults_Set(self.handle, value.handle)
		else:
			raise TypeError("supplied argument type {t} is not a go.GoClass".format(t=type(value)))
	@property
	def Quality(self):
		return _poly.pileup_Pileup_Quality_Get(self.handle)
	@Quality.setter
	def Quality(self, value):
		if isinstance(value, go.GoClass):
			_poly.pileup_Pileup_Quality_Set(self.handle, value.handle)
		else:
			_poly.pileup_Pileup_Quality_Set(self.handle, value)


# ---- Slices ---


# ---- Maps ---


# ---- Constructors ---
def NewParser(r, maxLineSize):
	"""NewParser(object r, int maxLineSize) object
	
	NewParser creates a parser from an io.Reader for pileup data.
	"""
	return Parser(handle=_poly.pileup_NewParser(r.handle, maxLineSize))


# ---- Functions ---
def Read(path):
	"""Read(str path) []object, str"""
	return Slice_pileup_Pileup(handle=_poly.pileup_Read(path))
def Write(pileups, path):
	"""Write([]object pileups, str path) str
	
	Write writes a pileup array to a file
	"""
	return _poly.pileup_Write(pileups.handle, path)
def WritePileups(pileups, w):
	"""WritePileups([]object pileups, object w) str
	
	WritePileups writes a pileup array to an io.Writer
	"""
	return _poly.pileup_WritePileups(pileups.handle, w.handle)
def Parse(r):
	"""Parse(object r) []object, str"""
	return Slice_pileup_Pileup(handle=_poly.pileup_Parse(r.handle))


