# -*- coding: UTF-8 -*-
# vim: fdm=marker

__revision__ = '$Id$'

# Copyright (c) 2005-2009 Piotr Ożarowski
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

# You may use and distribute this software under the terms of the
# GNU General Public License, version 2 or later

import os
from gi.repository import Gtk
import gutils
import glob
import shutil
import version
import math
from xml.dom import minidom
import logging
from plugins.export import Base
from gettext import gettext as _

log = logging.getLogger("Griffith")


class ExportPlugin(Base):
    name = 'HTML'
    description = _('Plugin exports data using templates')
    author = 'Piotr Ożarowski'
    email = 'piotr@griffith.cc'
    version = '4.0'

    # ==[ configuration - default values ]==========={{{
    settings = {
        'sorting': 'movies_title',
        'sorting2': 'ASC',
        'export_dir': '',
        'template': 2,
        'title': _("Griffith's movies list"),
        'style': 0,
        'custom_style': False,
        'custom_style_file': None,
        'split_num': 50,  # split into x files/pages
        'split_by': 1,  # 0==files, 1==movies
        'poster_convert': False,  # dont convert
        'poster_height': 200,
        'poster_width': 150,
        'poster_mode': 'RGB',  # RGB == color, L == black and white
        'poster_format': 'jpeg'
        }
    fields = {
        'movies_cast': False,
        'movies_classification': False,
        'movies_country': True,
        'movies_genre': True,
        'movies_director': True,
        'movies_image': True,
        'movies_o_site': True,
        'movies_site': True,
        'movies_trailer': True,
        'movies_loaned': False,
        'movies_media_num': True,
        'movies_number': True,
        'movies_o_title': True,
        'movies_plot': False,
        'movies_rating': True,
        'movies_runtime': True,
        'movies_studio': False,
        'movies_seen': True,
        'movies_title': True,
        'movies_year': True,
        'movies_notes': False,
        'movies_screenplay': False,
        'movies_cameraman': False,
        'movies_width': False,
        'movies_height': False,
        'movies_barcode': False,
        #        'movies_region'         : False,
        #        'movies_layers'         : False,
        #        'movies_condition'      : False,
        #        'movies_color'          : False,
        #        'movies_volume_id'      : False,
        #        'movies_collection_id'  : False,
        'media_name': True,
        'collections_name': True,
        'volumes_name': True,
        # 'acodecs_name'          : True,
        'vcodecs_name': True,
        }

    fields_as_columns = {
        'movies_cast': 'cast',
        'movies_classification': 'classification',
        'movies_country': 'country',
        'movies_genre': 'genre',
        'movies_director': 'director',
        'movies_image': 'poster_md5',
        'movies_o_site': 'o_site',
        'movies_site': 'site',
        'movies_trailer': 'trailer',
        'movies_loaned': 'loaned',
        'movies_media_num': 'media_num',
        'movies_number': 'number',
        'movies_o_title': 'o_title',
        'movies_plot': 'plot',
        'movies_rating': 'rating',
        'movies_runtime': 'runtime',
        'movies_studio': 'studio',
        'movies_seen': 'seen',
        'movies_title': 'title',
        'movies_year': 'year',
        'movies_notes': 'notes',
        'movies_screenplay': 'screenplay',
        'movies_cameraman': 'cameraman',
        'movies_width': 'width',
        'movies_height': 'height',
        'movies_barcode': 'barcode',
        #        'movies_region'         : 'region',
        #        'movies_layers'         : 'layers',
        #        'movies_condition'      : 'condition',
        #        'movies_color'          : 'color',
        #        'movies_volume_id'      : 'volume_id',
        #        'movies_collection_id'  : 'collection_id',
        'media_name': 'name',
        'collections_name': 'name',
        'volumes_name': 'name',
        # 'acodecs_name'          : 'name',
        'vcodecs_name': 'name',
        }

    names = {
        _('Cast'): 'movies_cast',
        _('Classification'): 'movies_classification',
        _('Country'): 'movies_country',
        _('Director'): 'movies_director',
        _('Genre'): 'movies_genre',
        _('Image'): 'movies_image',
        _('Official site'): 'movies_o_site',
        _('Site'): 'movies_site',
        _('Trailer'): 'movies_trailer',
        _('Loaned'): 'movies_loaned',
        _('Discs'): 'movies_media_num',
        _('Number'): 'movies_number',
        _('Original Title'): 'movies_o_title',
        _('Plot'): 'movies_plot',
        _('Rating'): 'movies_rating',
        _('Runtime'): 'movies_runtime',
        _('Studio'): 'movies_studio',
        _('Seen it'): 'movies_seen',
        _('Title'): 'movies_title',
        _('Year'): 'movies_year',
        _('Notes'): 'movies_notes',
        _('Screenplay'): 'movies_screenplay',
        _('Cameraman'): 'movies_cameraman',
        _('Width'): 'movies_width',
        _('Height'): 'movies_height',
        _('Barcode'): 'movies_barcode',
        #        _('Region')         : 'movies_region',
        #        _('Layers')         : 'movies_layers',
        #        _('Condition')      : 'movies_condition',
        #        _('Color')          : 'movies_color',
        #        _('Volume')         : 'movies_volume_id',
        #        _('Collection')     : 'movies_collection_id',
        _('Media'): 'media_name',
        _('Collection'): 'collections_name',
        _('Volume'): 'volumes_name',
        # _('Audio codecs')   : 'acodecs_name',
        _('Video codec'): 'vcodecs_name',
        }

    # }}}

    def initialize(self):  #{{{
        self.fields_to_export = []
        for field in ExportPlugin.fields:
            if field == 'movies_image':
                self.fields_to_export.append('movies.poster_md5')
            else:
                pos = field.find('_')
                self.fields_to_export.append("%s.%s" % (field[:pos], field[pos+1:]))

        self.widgets = {}
        self.style_list = {}
        self.templates = self.make_template_list()
        # glade
        gf = os.path.join(self.locations['glade'], 'exporthtml.ui')
        self.load_configuration()
        self.define_widgets(gf)
        self.fill_widgets()
        return True
    #}}}

    def load_configuration(self):  # {{{
        # persist config
        if self.config is not None:
            config = self.settings
            for name, value in list(config.items()):
                try:
                    tmp = self.config.get(name, value, section='export-html')
                    if isinstance(value, bool):
                        config[name] = bool(int(tmp))
                    elif isinstance(value, int):
                        config[name] = int(tmp)
                    else:
                        config[name] = tmp
                except:
                    pass
            selected_fields = self.config.get('selected_fields', '', section='export-html')
            if selected_fields:
                for name in self.fields:
                    self.fields[name] = False
                selected_fields = selected_fields.split(',')
                for selected_field in selected_fields:
                    if selected_field in self.fields:
                        self.fields[selected_field] = True
    # }}}

    def run(self):
        pass

    def get_node_value_by_language(self, parent, name, language='en'):  # {{{
        nodes = parent.getElementsByTagName(name)
        for node in nodes:
            if node.parentNode != parent:
                continue
            elif node.attributes.get('xml:lang') is not None:
                if node.attributes.get('xml:lang').value == language:
                    return node.firstChild.nodeValue
            else:    # set default value in case node has no xml:lang attribute
                value = node.firstChild.nodeValue
        return value
    # }}}

    def make_template_list(self):  # {{{
        language = 'en'
        if 'LANG' in os.environ:
            language = os.environ['LANG'][:2]
        templates = {}
        j = 0  # number of templates
        dirName = os.path.join(self.locations['share'], 'export_templates')
        items = os.listdir(dirName)
        items.sort()
        for i in items:
            fileName = os.path.join(dirName, i)
            if not os.path.islink(fileName) and os.path.isdir(fileName):
                # clear previous data
                doc = None
                styles = {}
                tpl_name = None
                tpl_author = None
                tpl_email = None
                tpl_version = None
                tpl_ext = None
                tpl_desc = None
                try:
                    doc = minidom.parse(os.path.join(fileName, 'config.xml'))
                except:
                    log.info(
                        "Can't parse configuration file for template: %s" % fileName)
                    continue
                for template in doc.getElementsByTagName('template'):
                    tpl_name = self.get_node_value_by_language(
                        template, 'name', language)
                    tpl_author = template.getElementsByTagName('author')[
                        0].firstChild.nodeValue
                    tpl_email = template.getElementsByTagName('email')[
                        0].firstChild.nodeValue
                    tpl_version = template.getElementsByTagName('version')[
                        0].firstChild.nodeValue
                    tpl_ext = template.getElementsByTagName('extension')[
                        0].firstChild.nodeValue
                    tpl_desc = self.get_node_value_by_language(
                        template, 'description', language)
                    k = 0  # number of styles
                    try:
                        styles_list = template.getElementsByTagName('styles')[
                            0].getElementsByTagName('style')
                        for style in styles_list:
                            tpl_style_name = self.get_node_value_by_language(
                                style, 'name', language)
                            tpl_style_file = style.getElementsByTagName('file')[
                                0].firstChild.nodeValue
                            # get preview if available
                            try:
                                tpl_style_preview = \
                                style.getElementsByTagName('preview')[
                                    0].firstChild.nodeValue
                            except:
                                tpl_style_preview = None
                            styles[k] = {
                                'name': tpl_style_name,
                                'file': tpl_style_file,
                                'preview': tpl_style_preview
                                }
                            k = k + 1
                    except:
                        styles = None
                if tpl_name == '':
                    continue
                templates[j] = {
                    'dir': i,
                    'name': tpl_name,
                    'author': tpl_author,
                    'email': tpl_email,
                    'version': tpl_version,
                    'ext': tpl_ext,
                    'desc': tpl_desc,
                    'styles': styles
                    }
                j = j + 1
        return templates

    # }}}

    # ==[ widgets ]=================================={{{
    def define_widgets(self, glade_file):
        get = lambda x: builder.get_object(x)
        builder = Gtk.Builder()
        builder.set_translation_domain("griffith")
        builder.add_from_file(glade_file)
        self.widgets = {
            'window': get('w_eh'),
            'fcw': get('fcw'),
            'box_include_1': get('box_include_1'),
            'box_include_2': get('box_include_2'),
            'box_include_3': get('box_include_3'),
            'sb_split_num': get('sb_split_num'),
            'rb_split_files': get('rb_split_files'),
            'rb_split_movies': get('rb_split_movies'),
            'entry_header': get('entry_header'),
            'cb_custom_style': get('cb_custom_style'),
            'cb_reverse': get('cb_reverse'),
            'combo_style': get('combo_style'),
            'combo_sortby': get('combo_sortby'),
            'combo_theme': get('combo_theme'),
            'fcb_custom_style_file': get('fcb_custom_style_file'),
            'l_tpl_author': get('l_tpl_author'),
            'l_tpl_email': get('l_tpl_email'),
            'l_tpl_version': get('l_tpl_version'),
            'l_tpl_desc': get('l_tpl_desc'),
            'image_preview': get('image_preview'),
            'vb_posters': get('vb_posters'),
            'sb_height': get('sb_height'),
            'sb_width': get('sb_width'),
            'cb_black': get('cb_black'),
            'combo_format': get('combo_format'),
            'cb_convert': get('cb_convert'),
            }

        # define handlers for general events
        builder.connect_signals({
            'on_export_button_clicked': self.export_data,
            'on_rb_split_files_toggled': self.on_rb_split_files_toggled,
            'on_rb_split_movies_toggled': self.on_rb_split_movies_toggled,
            'on_cancel_button_clicked': self.on_quit,
            'on_cb_data_toggled': self.on_cb_data_toggled,
            'on_cb_custom_style_toggled': self.on_cb_custom_style_toggled,
            'on_fcb_custom_style_file_activated':
                self.on_fcb_custom_style_file_activated,
            'on_combo_style_changed': self.on_combo_style_changed,
            'on_combo_theme_changed': self.on_combo_theme_changed,
            'on_cb_convert_toggled': self.on_cb_convert_toggled,
            })

    def fill_widgets(self):
        # themes
        for i in self.templates:
            self.widgets['combo_theme'].insert_text(i,
                                                    self.templates[i]['name'])

        # sortby combo
        keys = list(self.names.keys())
        keys.sort()
        j = 0
        pos_o_title = 0
        for i in keys:
            self.widgets['combo_sortby'].append_text(i)
            if self.names[i] == self.settings['sorting']:
                pos_o_title = j
            j += 1
        self.widgets['combo_sortby'].set_wrap_width(3)

        # include data
        j = 0
        k = math.ceil(len(self.names) / float(3))
        for i in keys:
            j = j + 1
            field = self.names[i]
            self.widgets['cb_' + field] = Gtk.CheckButton(i)
            self.widgets['cb_' + field].set_name("cb_%s" % field)
            self.widgets['cb_' + field].connect('toggled',
                                                self.on_cb_data_toggled)
            self.widgets['cb_' + field].set_active(self.fields[field])
            if j <= k:
                self.widgets['box_include_1'].add(self.widgets["cb_%s" % field])
            elif j <= 2 * k:
                self.widgets['box_include_2'].add(self.widgets["cb_%s" % field])
            else:
                self.widgets['box_include_3'].add(self.widgets["cb_%s" % field])
        self.widgets['box_include_1'].show_all()
        self.widgets['box_include_2'].show_all()
        self.widgets['box_include_3'].show_all()

        # set defaults --------------------------------
        self.widgets['entry_header'].set_text(self.settings['title'])
        self.widgets['combo_sortby'].set_active(pos_o_title)
        if self.settings['sorting2'] == 'DESC':
            self.widgets['cb_reverse'].set_active(True)
        else:
            self.widgets['cb_reverse'].set_active(False)
        # template and theme
        style = self.settings[
            'style']  # save it temporary because change of the template set it 0
        self.widgets['combo_theme'].set_active(self.settings['template'])
        self.widgets['combo_style'].set_active(style)
        self.widgets['cb_custom_style'].set_active(
            self.settings['custom_style'])
        if self.settings['custom_style_file']:
            self.widgets['fcb_custom_style_file'].set_filename(
                self.settings['custom_style_file'])
        # spliting
        self.widgets['sb_split_num'].set_value(self.settings['split_num'])
        if self.settings['split_by'] == 0:
            self.widgets['rb_split_files'].set_active(True)
        else:
            self.widgets['rb_split_movies'].set_active(True)
        # posters
        self.widgets['combo_format'].set_active(0)
        if self.settings['poster_format'] == 'PNG':
            self.widgets['combo_format'].set_active(1)
        elif self.settings['poster_format'] == 'GIF':
            self.widgets['combo_format'].set_active(2)
        if self.settings['poster_convert'] and self.settings[
            'poster_convert'] == True:
            self.widgets['cb_convert'].set_active(True)
            self.widgets['vb_posters'].set_sensitive(True)
        else:
            self.widgets['cb_convert'].set_active(False)
            self.widgets['vb_posters'].set_sensitive(False)
        self.widgets['sb_height'].set_value(self.settings['poster_height'])
        self.widgets['sb_width'].set_value(self.settings['poster_width'])
        if self.settings['poster_mode'] == 'L':
            self.widgets['cb_black'].set_active(True)
        # destination dir
        if self.settings['export_dir']:
            self.widgets['fcw'].set_current_folder(self.settings['export_dir'])
    #}}}

    #==[ callbacks ]================================{{{
    # buttons:
    def on_quit(self, widget=None):
        self.widgets['window'].destroy()

    # data tab -------------------------------------#{{{
    def on_rb_split_files_toggled(self, widget):
        self.settings['split_by'] = 0    # files

    def on_rb_split_movies_toggled(self, widget):
        self.settings['split_by'] = 1    # movies

    # export frame
    def on_cb_data_toggled(self, widget):
        self.fields[gutils.after(widget.get_name(), 'cb_')] = (
            widget.get_active())

    # posters frame
    def on_cb_convert_toggled(self, widget):
        active = widget.get_active()
        self.settings['poster_convert'] = active
        if not active:
            self.widgets['vb_posters'].set_sensitive(False)
        else:
            self.widgets['vb_posters'].set_sensitive(True)
    #}}}

    # template tab ---------------------------------#{{{
    def on_combo_theme_changed(self, widget):
        old_id = self.settings['template']
        tpl_id = widget.get_active()
        self.settings['template'] = tpl_id
        # fill authors data
        self.widgets['l_tpl_author'].set_markup("<i>%s</i>" % self.templates[tpl_id]['author'])
        self.widgets['l_tpl_email'].set_markup("<i>%s</i>" % self.templates[tpl_id]['email'])
        self.widgets['l_tpl_email'].set_selectable(True)
        self.widgets['l_tpl_version'].set_markup("<i>%s</i>" % self.templates[tpl_id]['version'])
        self.widgets['l_tpl_desc'].set_markup("<i>%s</i>" % self.templates[tpl_id]['desc'])
        # remove old style list
        self.widgets['combo_style'].get_model().clear()
        # ... and add new
        if self.templates[tpl_id]['styles'] is not None:
            for i in self.templates[tpl_id]['styles']:
                self.widgets['combo_style'].insert_text(i, self.templates[tpl_id]['styles'][i]['name'])    # template name
            self.widgets['combo_style'].set_active(0)
        else:
            self.settings['style'] = None
            self.widgets['image_preview'].set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR)

    def on_combo_style_changed(self, widget):
        self.settings['style'] = widget.get_active()
        self.widgets['cb_custom_style'].set_active(False)
        preview_file = None

        tpl_id = self.settings['template']
        template_dir = os.path.join(self.locations['share'], 'export_templates',
                                    self.templates[tpl_id]['dir'])
        if self.settings['style'] > -1:
            preview_file = self.templates[
                self.settings['template']]['styles'][self.settings['style']]['preview']
        if preview_file is not None:
            preview_file = os.path.join(template_dir, preview_file)
        if preview_file is not None and not os.path.isfile(preview_file):
            # try default preview image
            preview_file = os.path.join(template_dir, 'preview.jpg')
            if not os.path.isfile(preview_file):
                preview_file = None
        if preview_file is not None:
            self.widgets['image_preview'].set_from_file(preview_file)
        else:
            self.widgets['image_preview'].set_from_stock(
                Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR)
        self.widgets['image_preview'].show()

    def on_cb_custom_style_toggled(self, widget):
        if widget.get_active():
            self.settings['custom_style'] = True
            self.widgets['image_preview'].hide()
        else:
            self.settings['custom_style'] = False
            self.widgets['image_preview'].show()

    def on_fcb_custom_style_file_activated(self, widget):
        self.settings['custom_style_file'] = widget.get_filename()
        self.widgets['cb_custom_style'].set_active(True)
    #}}} }}}

    def make_navigation(self, pages, current):#{{{
        if pages > 1:    # navigation needed
            tpl_id = self.settings['template']
            t = '<div class="navi">\n\t<p id="prev">'
            if current > 1:
                t += '<a href="./page_%s.%s">%s</a>' % \
                    (str(current-1), self.templates[tpl_id]['ext'],
                     _('previous'))
            else:    # first page
                t += _('previous')
            t += "</p>\n"
            for i in range(1, pages+1):
                if i == current:
                    t += '\t<p id="current">%s</p>\n' % str(i)
                else:
                    t += '\t<p><a href="./page_%s.%s">%s</a></p>\n' % \
                         (str(i), self.templates[tpl_id]['ext'], str(i))
            t += '\t<p id="next">'
            if pages > current:
                t += '<a href="./page_%s.%s">%s</a>' % \
                        (str(current+1), self.templates[tpl_id]['ext'], _('next'))
            else:    # last page
                t += _('next')
            t += "</p>\n</div>"
            return t
        else:
            return ''
    # }}}

    def fill_template(self, template, field, data='', title='', remove=False):    #{{{
        start = template.find(f'<@{field}>')
        end = template.find(f'</@{field}>', start+1)
        if start > -1 and end > -1:
            if remove:
                return template[:start] + template[end+4+len(field):]
            else:
                tmp = gutils.trim(template, f'<@{field}>', f'</@{field}>')
                tmp = tmp.replace("@DATA@", data)
                tmp = tmp.replace("@TITLE@", title)
                tmp = template[:start] + tmp + template[end+4+len(field):]
                if tmp.find(f'<@{field}>') != -1:
                    tmp = self.fill_template(tmp, field, data, title, remove)
                return tmp
        else:
            return template
    #}}}

    def select(self):    # {{{
        config = self.settings
        # sort order TODO: update self.search_conditions["sort_by"]
        tmp = config['sorting'].split('_')
        sort_column = "%s.%s" % (tmp[0], '_'.join(tmp[1:]))

        if config['sorting2'] == 'ASC':
            sort_column += ' ASC'
        else:
            sort_column += ' DESC'

        self.search_conditions["sort_by"] = (sort_column,)
        query = self.get_query()

        return query.execute()
    #}}}

    #==[ main function ]============================{{{
    def export_data(self, widget):
        """Main exporting function"""

        config = self.settings
        fields = self.fields
        tid = config['template']

        # get data from widgets
        self.settings['export_dir'] = self.widgets['fcw'].get_filename()
        self.settings['title'] = self.widgets['entry_header'].get_text()
        self.settings['sorting'] = self.names[
            self.widgets['combo_sortby'].get_active_text()]
        if self.widgets['cb_reverse'].get_active():
            self.settings['sorting2'] = 'DESC'
        else:
            self.settings['sorting2'] = 'ASC'
        self.settings['split_num'] = self.widgets[
            'sb_split_num'].get_value_as_int()
        self.settings['poster_height'] = self.widgets[
            'sb_height'].get_value_as_int()
        self.settings['poster_width'] = self.widgets[
            'sb_width'].get_value_as_int()
        if self.widgets['cb_black'].get_active():
            self.settings['poster_mode'] = 'L'
        else:
            self.settings['poster_mode'] = 'RGB'
        self.settings['poster_format'] = self.widgets[
            'combo_format'].get_active_text()

        # persist config
        if self.config is not None:
            for name, value in list(config.items()):
                self.config.set(name, value, section='export-html')
            selected_fields = ''
            for name, value in list(self.fields.items()):
                if value:
                    selected_fields = selected_fields + name + ','
            self.config.set('selected_fields', selected_fields,
                            section='export-html')
            self.config.save()

        # create directories
        if not config['export_dir']:
            log.info("Error: Folder name not set!")
            return 1

        if not os.path.isdir(config['export_dir']):
            try:
                os.mkdir(config['export_dir'])
            except:
                gutils.error(_("Can't create %s!") % config['export_dir'])
                return 2

        data_path = os.path.join(self.locations['share'], 'export_templates',
                                 self.templates[tid]['dir'], 'data')
        if os.path.isdir(data_path):
            try:
                gutils.copytree(data_path, config['export_dir'])
            except Exception as err:
                gutils.warning(str(err))

        if fields['movies_image']:
            # import modules needed later
            # modules are needed at least to convert griffith.png to nopic.(gif|jpeg|png)
            from PIL import Image
            # py2exe problem workaround:
            if os.name == 'nt' or os.name.startswith('win'): # win32, win64
                from PIL import PngImagePlugin
                from PIL import GifImagePlugin
                from PIL import JpegImagePlugin
                Image._initialized=2
            if not config['poster_convert']:
                config['poster_format'] = 'jpeg' # replace 'jpeg'

            posters_dir = os.path.join(config['export_dir'], 'posters')
            if os.path.isdir(posters_dir):
                if gutils.question(_("Directory %s already exists.\nDo you want to overwrite it?") % posters_dir, self.widgets['window']):
                    try:
                        shutil.rmtree(posters_dir)
                    except:
                        gutils.error(_("Can't remove %s!") % config['export_dir'])
                        return 3
                else:
                    return 4
            try:
                os.mkdir(posters_dir)
            except:
                gutils.error(_("Can't create %s!") % posters_dir)
                return 5

        if config['custom_style']:
            if (config['custom_style_file'] is not None
                    and os.path.isfile(config['custom_style_file'])):
                try:
                    shutil.copy(config['custom_style_file'],
                                config['export_dir'])
                except:
                    gutils.warning(_(f"Can't copy "
                                     f"{config['custom_style_file']}!"))
                    config['custom_style'] = False
                style = os.path.split(self.settings['custom_style_file'])[1]
            else:
                config['custom_style'] = False

        if config['style'] is not None and config['custom_style']==False:
            style = self.templates[tid]['styles'][config['style']]['file']
            style_path = os.path.join(
                self.locations['share'], 'export_templates',
                self.templates[tid]['dir'], style)
            try:
                shutil.copy(style_path,config['export_dir'])
            except:
                gutils.warning(_("Can't copy %s!")%style_path)

        # select exported movies
        exported_movies = self.select().fetchall()
        if self.settings['sorting'] in ('movies_title', 'movies_o_title'):
            # re-sorting movies case-insensitive and respect the current locale setting
            # if sorting by title or original title is selected
            import locale
            locale.setlocale(locale.LC_ALL,"")
            exported_movies.sort(
                key=lambda k: locale.strxfrm(
                    k[self.settings['sorting']] and
                    k[self.settings['sorting']].lower() or ''),
                reverse=self.settings['sorting2'] == 'DESC')
        number_of_exported_movies = len(exported_movies)

        if config['split_by'] == 1:    # split by number of movies per page
            self.entries_per_page = config['split_num']
        else:                # split by number of pagess
            if number_of_exported_movies < config['split_num']:
                self.entries_per_page = 1
            else:
                self.entries_per_page = int(number_of_exported_movies / config['split_num'])

        # calculate number of files to be created (pages)
        self.pages = int(math.ceil(float(number_of_exported_movies) / self.entries_per_page))

        template_dir = os.path.join(self.locations['share'], 'export_templates', self.templates[tid]['dir'])
        try:
            filename = 'page.tpl'
            tpl_header = open(os.path.join(template_dir,filename), "r").read()
        except:
            gutils.error(_("Can't open %s!")%filename)
            return False

        tpl_header = self.fill_template(tpl_header, 'header', config['title'])
        try:
            tpl_header = self.fill_template(tpl_header, 'style', style)
        except:
            pass
        tmp = (_('Document generated by Griffith v') + version.pversion +
               ' - Copyright (C) ' + version.pyear + ' ' + version.pauthor +
               ' - ' + _('Released Under the GNU/GPL License'))
        tmp = gutils.html_encode(tmp)
        tmp = tmp.replace('@', ' at ')    # prevent spam
        tpl_header = self.fill_template(tpl_header, 'copyright', tmp)
        tmp = None

        tpl_header = self.fill_template(tpl_header, 'pages', self.pages)

        # count exported fields
        rowspan = 0
        for i in fields:
            if fields[i] == True:
                rowspan = rowspan + 1
        rowspan = str(rowspan)
        tpl_header = self.fill_template(tpl_header, 'rowspan', rowspan)

        # split template
        tpl_tail = gutils.after(tpl_header, '<!-- /ITEMS -->')
        tpl_item = gutils.trim(tpl_header, '<!-- ITEMS -->','<!-- /ITEMS -->')
        tpl_header = gutils.before(tpl_header, '<!-- ITEMS -->')

        # fill header
        for j in self.names:
            if self.fields[self.names[j]] == True:
                tpl_header = self.fill_template(tpl_header, self.names[j], '', j)
            else:
                tpl_header = self.fill_template(tpl_header, self.names[j], remove=True)

        # check if line break needs conversion
        if tpl_header.upper().find('XHTML 1.0') > -1:
            linebreak_replacement = '<br />'
        else:
            linebreak_replacement = None

        item=1    # item's position on page (1 - first, ...)
        i = 1
        page=1    # page number
        for row in exported_movies:    # fill items {{{
            # check if new file has to be created
            if item==1:
                filename = os.path.join(
                    config['export_dir'], 'page_%s.' %
                                          page + self.templates[tid]['ext'])
                try:
                    exported_file = open(filename, 'w')
                except:
                    gutils.error(_("Can't create %s!")%filename)
                    return False
                tmp2 = tpl_header + ''
                exported_file.write(self.fill_template(tmp2, 'page', str(page)))
                tmp2 = None

            # ---------------------------------------------
            tmp = tpl_item + '' # a copy (not a reference!)
            tmp = self.fill_template(tmp, 'id', str(item))
            tmp = self.fill_template(tmp, 'item', str(i))
            for j in self.names:
                if self.fields[self.names[j]] == True:
                    if self.names[j] == 'movies_image':
                        if row['movies_poster_md5']:
                            #image = row['movies_poster_md5'] + '.' + config['poster_format'].lower()
                            image = "%d.%s" % (row['movies_number'],
                                               config['poster_format'].lower())
                            tmp = self.fill_template(tmp, self.names[j], image, j)
                        else:
                            tmp = self.fill_template(
                                tmp, self.names[j],
                                'nopic.' + config['poster_format'].lower(), j)
                    elif row[self.names[j]] is None:
                        tmp = self.fill_template(tmp, self.names[j], '', j)
                    elif row[self.names[j]] is True:
                        tmp = self.fill_template(tmp, self.names[j], _('Yes'), j)
                    elif row[self.names[j]] is False:
                        tmp = self.fill_template(tmp, self.names[j], _('No'), j)
                    else:
                        try:
                            data = str(row[self.names[j]])
                            if linebreak_replacement is not None:
                                data = data.replace('\r\n', linebreak_replacement)
                                data = data.replace('\n', linebreak_replacement)
                            tmp = self.fill_template(tmp, self.names[j], data, j)
                        except UnicodeDecodeError:
                            log.info("Unicode Decode Error occurred while decoding %s (movie number: %s)" % (self.names[j], row['movies_number']))
                            data = str(row[self.names[j]])
                            if linebreak_replacement is not None:
                                data = data.replace('\r\n', linebreak_replacement)
                                data = data.replace('\n', linebreak_replacement)
                            tmp = self.fill_template(tmp, self.names[j], data, j)
                        except Exception as ex:
                            log.info("Error occurred while decoding %s (movie number: %s)" % (self.names[j], row['movies_number']))
                else:
                    tmp = self.fill_template(tmp, self.names[j], remove=True)
                tmp = gutils.convert_entities(tmp)
            exported_file.write(tmp)
            tmp = None
            # ---------------------------------------------

            # copy poster
            if fields['movies_image']:

                if row['movies_poster_md5']:
                    image_file_src = gutils.get_image_fname(row['movies_poster_md5'], self.db)
                    image_file_dst = os.path.join(posters_dir, "%d.%s" % (row['movies_number'], config['poster_format'].lower()))
                    if not config['poster_convert']:    # copy file
                        try:
                            shutil.copy(image_file_src, image_file_dst)
                        except:
                            log.info("Can't copy %s", image_file_src)
                    else:    # convert posters
                        try:
                            im = Image.open(image_file_src, 'r').convert(config['poster_mode'])
                            im.thumbnail((config['poster_width'], config['poster_height']), Image.LANCZOS)
                            im.save(image_file_dst, config['poster_format'])
                        except:
                            log.info("Can't convert %s", image_file_src)

            # close file if last item
            if ((page-1)*self.entries_per_page)+item == number_of_exported_movies:
                tmp2 = tpl_tail + ''
                exported_file.write(self.fill_template(tmp2, 'navigation', self.make_navigation(self.pages, page)))
                exported_file.close()
                tmp2 = None

            # close file if last item in page
            elif item == self.entries_per_page:
                tmp2 = tpl_tail + ''
                exported_file.write(self.fill_template(tmp2, 'navigation', self.make_navigation(self.pages, page)))
                exported_file.close()
                page = page+1
                item=1
                tmp2 = None
            else:
                item=item+1
            i=i+1
        # }}}
        if fields['movies_image']:
            # convert/copy the griffith picture for movies without a poster
            image_file_src = os.path.join(self.locations['images'],
                                          'griffith.png')
            image_file_dst = os.path.join(posters_dir, 'nopic.'
                                          + config['poster_format'].lower())
            try:
                if config['poster_convert']:
                    im = Image.open(image_file_src, 'r').convert(config['poster_mode'])
                    im.thumbnail((config['poster_width'],
                                  config['poster_height']), Image.LANCZOS)
                else:
                    im = Image.open(image_file_src, 'r')
                im = im.convert("RGB")
                im.save(image_file_dst, config['poster_format'])
            except:
                log.info("Can't convert %s" % image_file_src)
        gutils.info(_("Document has been generated."), self.widgets['window'])
        self.on_quit()
    # }}}

