__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'

import os

from calibre.customize.conversion import OptionRecommendation, OutputFormatPlugin


class FB2Output(OutputFormatPlugin):

    name = 'FB2 Output'
    author = 'John Schember'
    file_type = 'fb2'
    commit_name = 'fb2_output'

    FB2_GENRES = [
        # Science Fiction & Fantasy
        'sf_history',  # Alternative history
        'sf_action',  # Action
        'sf_epic',  # Epic
        'sf_heroic',  # Heroic
        'sf_detective',  # Detective
        'sf_cyberpunk',  # Cyberpunk
        'sf_space',  # Space
        'sf_social',  # Social#philosophical
        'sf_horror',  # Horror & mystic
        'sf_humor',  # Humor
        'sf_fantasy',  # Fantasy
        'sf',  # Science Fiction
        # Detectives & Thrillers
        'det_classic',  # Classical detectives
        'det_police',  # Police Stories
        'det_action',  # Action
        'det_irony',  # Ironical detectives
        'det_history',  # Historical detectives
        'det_espionage',  # Espionage detectives
        'det_crime',  # Crime detectives
        'det_political',  # Political detectives
        'det_maniac',  # Maniacs
        'det_hard',  # Hard#boiled
        'thriller',  # Thrillers
        'detective',  # Detectives
        # Prose
        'prose_classic',  # Classics prose
        'prose_history',  # Historical prose
        'prose_contemporary',  # Contemporary prose
        'prose_counter',  # Counterculture
        'prose_rus_classic',  # Russial classics prose
        'prose_su_classics',  # Soviet classics prose
        # Romance
        'love_contemporary',  # Contemporary Romance
        'love_history',  # Historical Romance
        'love_detective',  # Detective Romance
        'love_short',  # Short Romance
        'love_erotica',  # Erotica
        # Adventure
        'adv_western',  # Western
        'adv_history',  # History
        'adv_indian',  # Indians
        'adv_maritime',  # Maritime Fiction
        'adv_geo',  # Travel & geography
        'adv_animal',  # Nature & animals
        'adventure',  # Other
        # Children's
        'child_tale',  # Fairy Tales
        'child_verse',  # Verses
        'child_prose',  # Prose
        'child_sf',  # Science Fiction
        'child_det',  # Detectives & Thrillers
        'child_adv',  # Adventures
        'child_education',  # Educational
        'children',  # Other
        # Poetry & Dramaturgy
        'poetry',  # Poetry
        'dramaturgy',  # Dramaturgy
        # Antique literature
        'antique_ant',  # Antique
        'antique_european',  # European
        'antique_russian',  # Old russian
        'antique_east',  # Old east
        'antique_myths',  # Myths. Legends. Epos
        'antique',  # Other
        # Scientific#educational
        'sci_history',  # History
        'sci_psychology',  # Psychology
        'sci_culture',  # Cultural science
        'sci_religion',  # Religious studies
        'sci_philosophy',  # Philosophy
        'sci_politics',  # Politics
        'sci_business',  # Business literature
        'sci_juris',  # Jurisprudence
        'sci_linguistic',  # Linguistics
        'sci_medicine',  # Medicine
        'sci_phys',  # Physics
        'sci_math',  # Mathematics
        'sci_chem',  # Chemistry
        'sci_biology',  # Biology
        'sci_tech',  # Technical
        'science',  # Other
        # Computers & Internet
        'comp_www',  # Internet
        'comp_programming',  # Programming
        'comp_hard',  # Hardware
        'comp_soft',  # Software
        'comp_db',  # Databases
        'comp_osnet',  # OS & Networking
        'computers',  # Other
        # Reference
        'ref_encyc',  # Encyclopedias
        'ref_dict',  # Dictionaries
        'ref_ref',  # Reference
        'ref_guide',  # Guidebooks
        'reference',  # Other
        # Nonfiction
        'nonf_biography',  # Biography & Memoirs
        'nonf_publicism',  # Publicism
        'nonf_criticism',  # Criticism
        'design',  # Art & design
        'nonfiction',  # Other
        # Religion & Inspiration
        'religion_rel',  # Religion
        'religion_esoterics',  # Esoterics
        'religion_self',  # Self#improvement
        'religion',  # Other
        # Humor
        'humor_anecdote',  # Anecdote (funny stories)
        'humor_prose',  # Prose
        'humor_verse',  # Verses
        'humor',  # Other
        # Home & Family
        'home_cooking',  # Cooking
        'home_pets',  # Pets
        'home_crafts',  # Hobbies & Crafts
        'home_entertain',  # Entertaining
        'home_health',  # Health
        'home_garden',  # Garden
        'home_diy',  # Do it yourself
        'home_sport',  # Sports
        'home_sex',  # Erotica & sex
        'home',  # Other
    ]
    ui_data = {
        'sectionize': {
            'toc': _('Section per entry in the ToC'),
            'files': _('Section per file'),
            'nothing': _('A single section')
        },
        'genres': FB2_GENRES,
    }

    options = {
        OptionRecommendation(name='sectionize',
            recommended_value='files', level=OptionRecommendation.LOW,
            choices=list(ui_data['sectionize']),
            help=_('Specify how sections are created:\n'
                ' * nothing: {nothing}\n'
                ' * files: {files}\n'
                ' * toc: {toc}\n'
                'If ToC based generation fails, adjust the "Structure detection" and/or "Table of Contents" settings '
                '(turn on "Force use of auto-generated Table of Contents").').format(**ui_data['sectionize'])
        ),
        OptionRecommendation(name='fb2_genre',
            recommended_value='antique', level=OptionRecommendation.LOW,
            choices=FB2_GENRES,
            help=(_('Genre for the book. Choices: %s\n\n See: ') % ', '.join(FB2_GENRES)
                ) + 'http://www.fictionbook.org/index.php/Eng:FictionBook_2.1_genres ' + _('for a complete list with descriptions.')),
    }

    def convert(self, oeb_book, output_path, input_plugin, opts, log):
        from calibre.ebooks.fb2.fb2ml import FB2MLizer
        from calibre.ebooks.oeb.transforms.jacket import linearize_jacket
        from calibre.ebooks.oeb.transforms.rasterize import SVGRasterizer, Unavailable

        try:
            rasterizer = SVGRasterizer()
            rasterizer(oeb_book, opts)
        except Unavailable:
            log.warn('SVG rasterizer unavailable, SVG will not be converted')

        linearize_jacket(oeb_book)

        fb2mlizer = FB2MLizer(log)
        fb2_content = fb2mlizer.extract_content(oeb_book, opts)

        close = False
        if not hasattr(output_path, 'write'):
            close = True
            if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '':
                os.makedirs(os.path.dirname(output_path))
            out_stream = open(output_path, 'wb')
        else:
            out_stream = output_path

        out_stream.seek(0)
        out_stream.truncate()
        out_stream.write(fb2_content.encode('utf-8', 'replace'))

        if close:
            out_stream.close()
