#!/usr/bin/env python
# -*- mode: python; coding: koi8-r; -*-

import fb2wrap


class FictionBook2:

    _fb = None

    def __init__(self, filename):

        self._fb = fb2wrap.new_FB2Content(filename)
        if self._fb == 'NULL':
            raise IOError, 'Cannot parse fb2 file: ' + filename

        self.text = fb2wrap.FB2Content_text_get(self._fb)
        self.description = fb2wrap.FB2Content_description_get(self._fb)
        self.author = fb2wrap.FB2Content_author_get(self._fb)
        self.name = fb2wrap.FB2Content_name_get(self._fb)
        self.cover_href = fb2wrap.FB2Content_cover_href_get(self._fb)

## /* types of bookmark */
## #define BOOKMARK_TYPE 0
## #define LINK_TYPE 10
## #define NOTE_TYPE 11
## #define IMAGE_TYPE 20
## #define STRONG_TYPE 30
## #define EMPHASIS_TYPE 31
## #define NAMED_STYLE_TYPE 32

        bookmarks = []
        styles = []
        i = 0
        while 1:
            bm = fb2wrap.FB2Content_get_mark(self._fb, i)
            status, offset, length, type = bm
            if status < 0: break
            #print offset, length, type
            if type == 0: # BOOKMARK_TYPE
                bookmarks.append((offset, length))

            elif type == 30: # STRONG_TYPE
                styles.append((offset, length, 'strong'))
            elif type == 31: # EMPHASIS_TYPE
                styles.append((offset, length, 'emphasis'))

            i += 1
        self.bookmarks = bookmarks
        self.styles = styles

        links = []
        i = 0
        while 1:
            lnk = fb2wrap.FB2Content_get_link(self._fb, i)
            status, start, end, link_start, link_end, type = lnk
            if status < 0: break
            if type == 10: # LINK_TYPE
                links.append((start, end, link_start, link_end, 'link_type'))
            elif type == 11: # NOTE_TYPE
                links.append((start, end, link_start, link_end, 'note_type'))
            i += 1
        self.links = links

        genres = []
        i = 0
        while 1:
            g = fb2wrap.FB2Content_get_genre(self._fb, i)
            if not g: break
            genres.append(g)
            i += 1
        self.genres = genres

        binaries = []
        i = 0
        while 1:
            bin_data = fb2wrap.FB2Content_get_binary_data(self._fb, i)
            if not bin_data: break
            bin_id = fb2wrap.FB2Content_get_binary_id(self._fb, i)
            bin_ct = fb2wrap.FB2Content_get_binary_content_type(self._fb, i)
            bin_offset = fb2wrap.FB2Content_get_binary_offset(self._fb, i)
            #if bin_offset >= 0:
            binaries.append((bin_id, bin_ct, bin_data, bin_offset))
            i += 1
        self.binaries = binaries


    def __del__(self):
        fb2wrap.delete_FB2Content(self._fb)


    def __getattr__(self, name):
        if not self._fb:
            raise IOError, 'fb2wrap is undefine'

        if name == 'text':
            return fb2wrap.FB2Content_text_get(self._fb)

        if name == 'description':
            return fb2wrap.FB2Content_description_get(self._fb)

        if name == 'author':
            return fb2wrap.FB2Content_author_get(self._fb)

        if name == 'name':
            return fb2wrap.FB2Content_name_get(self._fb)


#define BOOKMARK_TYPE 0
#define LINK_TYPE 1
#define IMAGE_TYPE 2
#define STRONG_TYPE 3
#define EMPHASIS_TYPE 4
#define NAMED_STYLE_TYPE 5

        if name == 'bookmarks':
            bookmarks = []
            i = 0
            while 1:
                bm = fb2wrap.FB2Content_get_mark(self._fb, i)
                status, offset, length, type = bm
                if status < 0: break
                if type == 0: # BOOKMARK_TYPE
                    bookmarks.append((offset, length))
                i += 1
            return bookmarks

        if name == 'links':
            links = []
            i = 0
            while 1:
                lnk = fb2wrap.FB2Content_get_link(self._fb, i)
                status, start, end, link_start, link_end, type = lnk
                if status < 0: break
                if type == 1: # LINK_TYPE
                    links.append((start, end, link_start, link_end))
                i += 1
            return links



        if name == 'genres':
            genres = []
            i = 0
            while 1:
                g = fb2wrap.FB2Content_get_genre(self._fb, i)
                if not g: break
                genres.append(g)
                i += 1
            return genres

        if name == 'binaries':
            binaries = []
            i = 0
            while 1:

##                 bin = fb2wrap.FB2Content_get_binary(self._fb, i)
##                 status, content, id, content_type = bin
##                 if status < 0: break
##                 binaries.append((id, content_type, content))

                bin_data = fb2wrap.FB2Content_get_binary_data(self._fb, i)
                if not bin_data: break
                bin_id = fb2wrap.FB2Content_get_binary_id(self._fb, i)
                bin_ct = fb2wrap.FB2Content_get_binary_content_type(self._fb, i)
                bin_offset = fb2wrap.FB2Content_get_binary_offset(self._fb, i)
                binaries.append((bin_id, bin_ct, bin_data, bin_offset))

                i += 1

            return binaries

        raise AttributeError, name


if __name__ == '__main__':
    import sys
    if len(sys.argv) != 2:
        sys.exit('usage: %s file' % sys.argv[0])

    fb = FictionBook2(sys.argv[1])

##     print fb
##     print fb.categories
##     print fb.author
##     print fb.name
##     text = fb.text
##     for i in fb.bookmarks:
##         print i, text[i[0]:i[0]+i[1]]
##     print fb.description

##     import base64
##     for bin in fb.binaries:
##         print bin[0], bin[1], bin[3]
        #print '-'*80
        #print bin[2]
        #print '-'*80
        #data=base64.decodestring(bin[2])
        #open(bin[0], 'w').write(data)

    for link in fb.links:
        print link


