# Copyright (c) 2004 by Intevation GmbH
# Authors:
# Nina Hüffmeyer <nhueffme@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

__version__ = "$Revision: 1.6 $"
# $Source: /thubanrepository/thuban/Extensions/ogr/ogrstart.py,v $
# $Id: ogrstart.py,v 1.6 2005/04/28 09:39:58 jan Exp $

# Needed wx-toolkit classes
from wxPython.wx import wxFileDialog, wxOPEN, wxMULTIPLE, wxID_OK

# We need os.path
import os

# use _() already now for all strings that may later be translated
from Thuban import _

from Thuban.Model.layer import Layer

# Import ogr related classes
from Extensions.ogr import ogrshapes, ogrdialog
from Extensions.ogr.ogrdialog import ChooseOGRDBTableDialog

from Thuban.UI.menu import Menu
from Thuban.UI.mainwindow import _has_dbconnections, _has_gdal_support

def open_with_ogr(context):
    '''Open a file supported by ogr.
    '''
    canvas = context.mainwindow.canvas
    map = canvas.Map()

    # Get the file to be opened
    dlg = wxFileDialog(canvas, _("Select a data file"),
                           context.application.Path("data"), "",
                           _("Shapefiles (*.shp)") + "|*.shp|" +
                           _("GML files (*.gml)") + "|*.gml|" +
                           _("MapInfo files (*.tab)") + "|*.tab|" +
                           _("DGN files (*.dgn)") + "|*.dgn|" +
                           _("CSV files (*.csv)") + "|*.csv|" +
                           _("All Files (*.*)") + "|*.*|",
                           wxOPEN | wxMULTIPLE)

    if dlg.ShowModal() == wxID_OK:
        filenames = dlg.GetPaths()
        for filename in filenames:
            title = os.path.splitext(os.path.basename(filename))[0]
            has_layers = map.HasLayers()
            layerDlg = ogrdialog.ChooseLayer(canvas, filename)
            if layerDlg.ShowModal() == wxID_OK:
                layername = layerDlg.GetLayer()
                try:
                    session = context.application.Session()
                    store = OpenFileShapestore(context.mainwindow, session,
                                               filename, layername)
                    session.AddShapeStore(store)
                except:
                    # the layer couldn't be opened
                    context.mainwindow.RunMessageBox(_("Add Layer"),
                                _("Can't open the file '%s'.") % filename)
                else:
                    if store is not None:
                        layer = Layer(title, store)
                        map.AddLayer(layer)
                        if not has_layers:
                            # if we're adding a layer to an empty map, fit the
                            # new map to the window
                            canvas.FitMapToWindow()
                    context.application.SetPath("data",filename)
        dlg.Destroy()

def select_file_format(context):
    ''' Display all available supported formats.
    '''

    canvas = context.mainwindow.canvas
    file = None
    map = canvas.Map()

    session = context.application.Session()

    dlg = ogrdialog.ChooseFileFormat(canvas, session)

    if dlg.ShowModal() == wxID_OK:
        pass
    dlg.Destroy()

def open_db(context):
    ''' Open a table in a database as a layer.
    '''

    canvas = context.mainwindow.canvas
    map = canvas.Map()

    session = context.application.Session()
    dlg = ChooseOGRDBTableDialog(canvas, session)

    if dlg.ShowModal() == wxID_OK:
        dbconn, connString, dbtable, id_column = dlg.GetTable()
        try:
            store = OpenDBShapestore(session, dbconn, dbtable, id_column,
                                            None)
            session.AddShapeStore(store)

            layer = Layer(dbtable, store)

            has_layers = map.HasLayers()
            map.AddLayer(layer)
            if not has_layers:
                canvas.FitMapToWindow()
        except:
            # Some error occured while initializing the layer
            context.mainwindow.RunMessageBox(_("Add Layer from database"),
                               _("Can't open the database table '%s'")
                               % dbtable)
    dlg.Destroy()

def open_OGRConnection(context):
    """Open a datasource with an OGRConnection string."""
    canvas = context.mainwindow.canvas
    map = canvas.Map()

    session = context.application.Session()
    dlg = ogrdialog.OGRConnectionDialog(canvas, session)

    if dlg.ShowModal() == wxID_OK:
        dsname = dlg.GetDatasourceName()

        layerDlg = ogrdialog.ChooseLayer(canvas, dsname)
        if layerDlg.ShowModal() == wxID_OK:
            layername = layerDlg.GetLayer()
            try:
                store = ogrshapes.OGRShapeStore(session, dsname, layername)
                session.AddShapeStore(store)
            except:
                # the layer couldn't be opened
                context.mainwindow.RunMessageBox(("Add Layer"),
                            ("Can't open the file '%s'.") % dsname)
            else:
                layer = Layer(dsname, store)
                has_layers = map.HasLayers()
                map.AddLayer(layer)
                if not has_layers:
                    # if we're adding a layer to an empty map, fit the
                    # new map to the window
                    canvas.FitMapToWindow()
    dlg.Destroy()

def OpenFileShapestore(mainwindow, session, filename, layername):
    """Open a datasource and add the required layer.
    """
    try:
        store = ogrshapes.OGRFileShapeStore(session, filename, layername)
        return store
    except:
        # Some error occured while initializing the layer
        mainwindow.RunMessageBox(_("Open datasource"),
                           _("Can't open the datasource '%s'")
                           % filename)
        return None

def OpenDBShapestore(session, dbconn, layername, id_column, geo_column):
    """Open a datasource and add the required layer.

    dbconn     - shold be a DBConnection
    layername  - the name of the table which should opened as layer
    id_column  - the column name which should be used as ID column
    geo_column - always None for ogr
    """
    try:
        filename = "PG: dbname=%s" %dbconn.dbname
        if dbconn.host is not "":
            filename = filename + " host=%s" % dbconn.host
        if dbconn.user is not "":
            filename = filename + " user=%s" % dbconn.user
        if dbconn.password is not "":
            filename = filename + " password=%s" % dbconn.password
        if dbconn.port is not "":
            filename = filename + " port=%s" % dbconn.port
        store = ogrshapes.OGRShapeStore(session, filename, layername,
                                        id_column = id_column)
        return store
    except:
        # Some error occured while initializing the layer
        context.mainwindow.RunMessageBox(_("Open datasource"),
                           _("Can't open the datasource '%s'")
                           % filename)

# Thuban has named commands which can be registered in the central
# instance registry.
from Thuban.UI.command import registry, Command

# The instance of the main menu of the Thuban application
# See Thuban/UI/menu.py for the API of the Menu class
from Thuban.UI.mainwindow import main_menu


# find the map menu (create a new if not found)
map_menu = main_menu.FindOrInsertMenu('map', _('Map'))
ogr_menu = Menu("ogr", _("Open layer via OGR"),[])

ogrsupport = ogrshapes.has_ogr_support()

# create new commands and register them
registry.Add(Command('open_ogr_files', 'Open an ogr-file', open_with_ogr,
                     sensitive = _has_gdal_support,
                     helptext = 'Open a file supported from ogr'))

#registry.Add(Command('select_file_format', 'Select a file format',
#                     select_file_format, 
#                     helptext = "Select a file format supported from ogr"))

registry.Add(Command('open_db', 'Open a layer from a database',
                     open_db,
                     sensitive = _has_dbconnections,
                     helptext = "Open a layer from a database, e.g. PostGIS"))

registry.Add(Command('open_OGRConnection',
                     ("Open a datasource with an OGRConnection string"),
                     open_OGRConnection,
                     sensitive = _has_gdal_support, helptext = 
                     "Open a datasource with an OGRConnection string"))

# finally bind the new command with an entry in the extensions menu
ogr_menu.InsertItem("open_ogr_files")
#ogr_menu.InsertItem('select_file_format')
ogr_menu.InsertItem('open_db')
ogr_menu.InsertItem('open_OGRConnection')

# Add ogr menu to map menu
map_menu.InsertItem(ogr_menu, after = "rasterlayer_add")
