#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004  Donald N. Allingham
#
# 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 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
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# $Id$

#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import os
from gettext import gettext as _

#-------------------------------------------------------------------------
#
# GNOME modules
#
#-------------------------------------------------------------------------
import gtk
import gtk.glade
import gobject
import gnome

#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
import Utils
import const
import QuestionDialog
import Plugins
import GrampsBSDDB
import GrampsXMLDB
import GrampsGEDDB
import GrampsGconfKeys

#-------------------------------------------------------------------------
#
# DbPrompter
#
#-------------------------------------------------------------------------
class DbPrompter:
    """Make sure a database is opened"""
    
    def __init__(self,parent,want_new,parent_window=None):
        self.parent = parent
        self.parent_window = parent_window
        opendb = gtk.glade.XML(const.gladeFile, "opendb","gramps")
        top = opendb.get_widget('opendb')
        if parent_window:
            top.set_transient_for(parent_window)
        title = opendb.get_widget('title')

        Utils.set_titles(top,title,_('Open a database'))

        new = opendb.get_widget("new")
        new.set_active(want_new)

        while 1:
            top.show()
            response = top.run()
            top.hide()
            if response == gtk.RESPONSE_OK:
                if new.get_active():
                    prompter = NewNativeDbPrompter(self.parent,self.parent_window)
                else:
                    prompter = ExistingDbPrompter(self.parent,self.parent_window)
                
                if prompter.chooser():
                    break
            elif response == gtk.RESPONSE_CANCEL:
                break
            elif response == gtk.RESPONSE_HELP:
                try:
                    gnome.help_display('gramps-manual','choose-db-start')
                except gobject.GError,msg:
                    QuestionDialog.ErrorDialog(_('Help not available'),msg)

        top.destroy()
        if response == gtk.RESPONSE_CANCEL:
            gtk.main_quit()

#-------------------------------------------------------------------------
#
# ExistingDbPrompter
#
#-------------------------------------------------------------------------
class ExistingDbPrompter:
    """
    This class allows to open an existing database. 
    
    Any data format is allowed. The available formats are obtained
    from the plugins. If the selected format is non-native (non-grdb)
    then the call is made to set up a new native grdb database. 
    
    """
    
    def __init__(self,parent,parent_window=None):
        self.parent = parent
        self.parent_window = parent_window

    def chooser(self):
        """
        Select the new file. 
        Return 1 when selection is made and 0 otherwise.
        """
        choose = gtk.FileChooserDialog(_('GRAMPS: Open database'),
                                           self.parent_window,
                                           gtk.FILE_CHOOSER_ACTION_OPEN,
                                           (gtk.STOCK_CANCEL,
                                            gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN,
                                            gtk.RESPONSE_OK))
        choose.set_local_only(gtk.FALSE)
        # Always add automatic (macth all files) filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('Automatic'))
        mime_filter.add_pattern('*')
        choose.add_filter(mime_filter)
        
        # Always add native format filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('GRAMPS databases'))
        mime_filter.add_mime_type(const.app_gramps)
        choose.add_filter(mime_filter)

        # Always add native format filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('GRAMPS XML databases'))
        mime_filter.add_mime_type(const.app_gramps_xml)
        choose.add_filter(mime_filter)

        # Always add native format filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('GEDCOM files'))
        mime_filter.add_mime_type(const.app_gedcom)
        choose.add_filter(mime_filter)

        # Add more data type selections if opening existing db
        for (importData,mime_filter,mime_type,native_format) in Plugins._imports:
            if not native_format:
                choose.add_filter(mime_filter)
        
        # Suggested folder: try last open file, last import, last export, 
        # then home.
        default_dir = os.path.split(GrampsGconfKeys.get_lastfile())[0] + os.path.sep
        if len(default_dir)<=1:
            default_dir = GrampsGconfKeys.get_last_import_dir()
        if len(default_dir)<=1:
            default_dir = GrampsGconfKeys.get_last_export_dir()
        if len(default_dir)<=1:
            default_dir = '~/'

        choose.set_current_folder(default_dir)
        response = choose.run()
        if response == gtk.RESPONSE_OK:
            filename = choose.get_filename()
            filetype = gnome.vfs.get_mime_type(filename)

            (the_path,the_file) = os.path.split(filename)
            GrampsGconfKeys.save_last_import_dir(the_path)

            if filetype == const.app_gramps:
                choose.destroy()
                self.parent.db = GrampsBSDDB.GrampsBSDDB()
                msgxml = gtk.glade.XML(const.gladeFile, "load_message","gramps")
                msg_top = msgxml.get_widget('load_message')
                self.parent.read_file(filename)
                msg_top.destroy()
                return True
            elif filetype == const.app_gramps_xml:
                choose.destroy()
                self.parent.db = GrampsXMLDB.GrampsXMLDB()
                self.parent.read_file(filename)
                return True
            elif filetype == const.app_gedcom:
                choose.destroy()
                self.parent.db = GrampsGEDDB.GrampsGEDDB()
                self.parent.read_file(filename)
                return True

            # The above native formats did not work, so we need to 
            # look up the importer for this format
            # and create an empty native database to import data in
            for (importData,mime_filter,mime_type,native_format) in Plugins._imports:
                if filetype == mime_type or the_file == mime_type:
                    choose.destroy()
                    QuestionDialog.OkDialog( _("Opening non-native format"), 
                                _("New gramps database has to be set up "
                                  "when opening non-native formats. The "
                                  "following dialog will let you select "
                                  "the new database."),
                                self.parent_window)
                    prompter = NewNativeDbPrompter(self.parent,self.parent_window)
                    if prompter.chooser():
                        importData(self.parent.db,filename)
                        self.parent.import_tool_callback()
                        return True
                    else:
                        return False
            QuestionDialog.ErrorDialog( _("Could not open file: %s") % filename,
                        _('The type "%s" is not in the list of known file types') % filetype )
        choose.destroy()
        return False

#-------------------------------------------------------------------------
#
# ImportDbPrompter
#
#-------------------------------------------------------------------------
class ImportDbPrompter:
    """
    This class allows to import a database. The data is imported into
    the currently opened database, so we don't have to worry about
    setting up the native database.
    
    Any data format is allowed. The available formats are obtained
    from the plugins. 
    
    """
    
    def __init__(self,parent,parent_window=None):
        self.parent = parent
        self.parent_window = parent_window

    def chooser(self):
        """
        Select the new file. 
        Return 1 when selection is made and 0 otherwise.
        """
        choose = gtk.FileChooserDialog(_('GRAMPS: Import database'),
                                           self.parent_window,
                                           gtk.FILE_CHOOSER_ACTION_OPEN,
                                           (gtk.STOCK_CANCEL,
                                            gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN,
                                            gtk.RESPONSE_OK))
        choose.set_local_only(gtk.FALSE)
        # Always add automatic (macth all files) filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('Automatic'))
        mime_filter.add_pattern('*')
        choose.add_filter(mime_filter)
        
#   FIXME: Uncomment when we have grdb importer
#        # Always add native format filter
#        mime_filter = gtk.FileFilter()
#        mime_filter.set_name(_('GRAMPS databases'))
#        mime_filter.add_mime_type(const.app_gramps)
#        choose.add_filter(mime_filter)

        # Add more data type selections if opening existing db
        for (importData,mime_filter,mime_type,native_format) in Plugins._imports:
            choose.add_filter(mime_filter)
        
        # Suggested folder: try last open file, import, then last export, 
        # then home.
        default_dir = GrampsGconfKeys.get_last_import_dir()
        if len(default_dir)<=1:
            default_dir = os.path.split(GrampsGconfKeys.get_lastfile())[0] + os.path.sep
        if len(default_dir)<=1:
            default_dir = GrampsGconfKeys.get_last_export_dir()
        if len(default_dir)<=1:
            default_dir = '~/'

        choose.set_current_folder(default_dir)
        response = choose.run()
        if response == gtk.RESPONSE_OK:
            filename = choose.get_filename()
            filetype = gnome.vfs.get_mime_type(filename)
#   FIXME: Uncomment when we have grdb importer
#
#            if filetype == 'application/x-gramps':
#                choose.destroy()
#                self.parent.read_file(filename)
#                return True

            (the_path,the_file) = os.path.split(filename)
            GrampsGconfKeys.save_last_import_dir(the_path)
            for (importData,mime_filter,mime_type,native_format) in Plugins._imports:
                if filetype == mime_type or the_file == mime_type:
                    choose.destroy()
                    importData(self.parent.db,filename)
                    self.parent.import_tool_callback()
                    return True
            QuestionDialog.ErrorDialog( _("Could not open file: %s") % filename,
                        _('The type "%s" is not in the list of known file types') % filetype )
        choose.destroy()
        return False

#-------------------------------------------------------------------------
#
# NewNativeDbPrompter
#
#-------------------------------------------------------------------------
class NewNativeDbPrompter:
    """
    This class allows to set up a new empty native (grdb) database.
    The filename is forced to have an '.grdb' extension. If not given,
    it is appended. 
    """
    
    def __init__(self,parent,parent_window=None):
        self.parent = parent
        self.parent_window = parent_window

    def chooser(self):
        """
        Select the new file. Suggest the Untitled_X.grdb name.
        Return 1 when selection is made and 0 otherwise.
        """
        choose = gtk.FileChooserDialog(_('GRAMPS: Create GRAMPS database'),
                                           self.parent_window,
                                           gtk.FILE_CHOOSER_ACTION_SAVE,
                                           (gtk.STOCK_CANCEL,
                                            gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN,
                                            gtk.RESPONSE_OK))
        self.parent.clear_database()

        # Always add automatic (macth all files) filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('Automatic'))
        mime_filter.add_pattern('*')
        choose.add_filter(mime_filter)
        
        # Always add native format filter
        mime_filter = gtk.FileFilter()
        mime_filter.set_name(_('GRAMPS databases'))
        mime_filter.add_mime_type(const.app_gramps)
        choose.add_filter(mime_filter)

        # Suggested folder: try last open file, import, then last export, 
        # then home.
        default_dir = os.path.split(GrampsGconfKeys.get_lastfile())[0] + os.path.sep
        if len(default_dir)<=1:
            default_dir = GrampsGconfKeys.get_last_import_dir()
        if len(default_dir)<=1:
            default_dir = GrampsGconfKeys.get_last_export_dir()
        if len(default_dir)<=1:
            default_dir = '~/'

        new_filename = Utils.get_new_filename('grdb',default_dir)
        
        choose.set_current_folder(default_dir)
        choose.set_current_name(os.path.split(new_filename)[1])

        while (True):
            response = choose.run()
            if response == gtk.RESPONSE_OK:
                filename = choose.get_filename()
                if filename == None:
                    continue
                if os.path.splitext(filename)[1] != ".grdb":
                    filename = filename + ".grdb"
                choose.destroy()
                self.parent.read_file(filename)
                return True
            else:
                choose.destroy()
                return False
        return False
