#!/usr/bin/python
# -*- coding: utf-8 -*-
# A native Python implementation of the SWORD Project Bible Reader
# This code has been modified by DarkRanger <http://darkranger.no-ip.org/>
# To obtain the original source code, go to https://github.com/kcarnold/pysword

import os, sys, re
import struct, zlib
import Books
appdir = os.path.abspath(os.path.dirname(sys.argv[0])).decode(sys.getfilesystemencoding())
os.chdir(appdir)
modules_path = os.path.join(appdir, u"modules", u"texts", u"ztext")

class ZModule(object):
    def __init__(self, module):
        self.module = module
        self.files = {
            'ot': self.get_files('ot'),
            'nt': self.get_files('nt')
            }
   
    def get_files(self, testament):
        '''Given a testament ('ot' or 'nt'), returns a tuple of files
        (verse_to_buf, buf_to_loc, text)
        '''
        base = os.path.join(modules_path, self.module)
        v2b_name, b2l_name, text_name = [os.path.join(base, '%s.bz%s' % (testament, code))
                                         for code in ('v', 's', 'z')]
        return [open(name, 'rb') for name in (v2b_name, b2l_name, text_name)]

    def text_for_index(self, testament, index):
        '''Get the text for a given index.'''
        verse_to_buf, buf_to_loc, text = self.files[testament]

        # Read the verse record.
        verse_to_buf.seek(10*index)
        buf_num, verse_start, verse_len = struct.unpack('<IIH', verse_to_buf.read(10))
       
        uncompressed_text = self.uncompressed_text(testament, buf_num)
        return uncompressed_text[verse_start:verse_start+verse_len]

    def uncompressed_text(self, testament, buf_num):
        verse_to_buf, buf_to_loc, text = self.files[testament]

        # Determine where the compressed data starts and ends.
        buf_to_loc.seek(buf_num*12)
        offset, size, uc_size = struct.unpack('<III', buf_to_loc.read(12))

        # Get the compressed data.
        text.seek(offset)
        compressed_data = text.read(size)
        return zlib.decompress(compressed_data)

    def text_for_ref(self, book, chapter, verse):
        '''Get the text for a given reference'''
        chapter, verse = int(chapter), int(verse)
        testament, idx = Books.ref_to_index(book, chapter, verse)
        if idx:
            return self.text_for_index(testament, idx)
        else:
            return None

    def all_verses_in_testament(self, testament):
        books = Books.testaments[testament]
        for book in books:
            for verse in self.all_verses_in_book(book):
                yield verse

    def all_verses_in_book(self, book):
        if not isinstance(book, Books.Book): book = Books.find_book(book)
        for chapter, verses in enumerate(book.chapter_lengths):
            chapter = chapter + 1
            for verse in range(verses):
                verse = verse+1
                yield (book, chapter, verse,
                       self.text_for_index(book.testament,
                                           book.get_index_for_ref(chapter, verse)))

def result(mod_name, book, chapter, verse):
    module = ZModule(mod_name)
    tag = module.text_for_ref(book, chapter, verse)
    if tag:
        return re.sub("<.*?>", "", tag)
    else:
        return None
