
from ouf import ByteChunk

def print_table(table):
	for row in table:
		line = "{!r:>15}" * len(row)
		print line.format(*row)

def print_head(ouf_file):
	names  = ["Table offset", "?", "First code used", "Last code used", "Length of table", "Book ID" ]
	names += ["?"] * (len(ouf_file.head) - len(names))
	for (k, (name, value)) in enumerate(zip(names, ouf_file.head)):
		print "{: >3} {: <20} {!r}".format(k, name, value)

def find_mp3_data(ouf_file):
	mp3_data = []

	_, block_start = ouf_file.offsets
	print "start of body at {!r}".format(ByteChunk(block_start).fill(4))

	for (i, (offset, length, end)) in enumerate(ouf_file.table):
		try:
			prefix = "{:> 4}/{:> 4}: ".format(i, len(ouf_file.table))

			if int(offset) == int(length) == int(end) == 0:
				print prefix + "row empty, skipping"
				continue

			if not (int(offset) > 0 and int(length) > 0 and int(end) == 1):
				e = ""
				while e not in ['y', 'n']:
					e = raw_input(prefix + "row {!r} {!r} {!r}; ".format(offset, length, end) + "skip? (y/n) ")
			
				if e == 'y':
					continue

			while True:
				while ouf_file[block_start] == "\x00":
					block_start += 1

				b1 = ByteChunk(ouf_file[block_start-4:block_start])
				b2 = ByteChunk(ouf_file[block_start:block_start+4])

				if int(b1) == 0 and int(b2) > 0:
					print prefix + "start autoaccepted; {!r} | {!r} at {!r}".format(b1, b2, ByteChunk(block_start).fill(4))
					break

				e = ""
				while e not in ['s', 'i', 'a']:
					e = raw_input(prefix + "found {!r} | {!r}; (s)earch and skip zeros, (i)nput manually or (a)ccept? (s/i/a) ".format(b1, b2))

				if e == "a":
					break
				if e == "s":
					block_start = ouf_file.raw.find("\x00\x00\x00\x00", block_start)
				if e == "i":
					block_start = int(raw_input(prefix + "position {!r}; beginn of block? 0x".format(ByteChunk(block_start).fill(4))), 16)
					break

			block_end = block_start + int(length)
			while True:
				b1 = ByteChunk(ouf_file[block_end-4:block_end])
				b2 = ByteChunk(ouf_file[block_end:block_end+4])

				if int(b2) == 0:
					print prefix + "end autoaccepted;   {!r} | {!r} at {!r}".format(b1, b2, ByteChunk(block_end).fill(4))
					break

				e = ""
				while e not in ['s', 'i', 'a']:
					e = raw_input(prefix + "end; found {!r} | {!r}; (s)earch zeros, (i)nput manually or (a)ccept? (s/i/a) ".format(b1, b2))

				if e == "a":
					break	
				if e == "s":
					block_end = ouf_file.raw.find("\x00\x00\x00\x00", block_end)
				if e == "i":
					block_start = int(raw_input(prefix + "position {!r}; end of block? 0x".format(ByteChunk(block_start).fill(4))), 16)
					break

			mp3_data.append((i, ByteChunk(block_start).fill(4), ByteChunk(block_end).fill(4), int(length) == block_end - block_start))
			block_start = block_end
		except IndexError:
			print ""
			print "Index out of range; aborting..."
			break
		except KeyboardInterrupt:
			print ""
			print "aborting..."
			break

	return mp3_data

def extract_mp3_data(ouf_file, mp3_positions, name = "extracted_{:>04}.mp3"):
	for (i, start, end, _) in mp3_positions:
		fh = open(name.format(i), 'w')
		fh.write(ouf_file[int(start):int(end)])
		fh.close()

