# Copyright (C) 2004 by Intevation GmbH
# -*- coding:iso-8859-15 -*-
# Authors:
# Jan Schüngel <jschuengel@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

"""
This modul extend Thuban with the possibility to handle
UMN MapServer mapfiles.
"""

__version__ = "$Revision: 2864 $"
# $Source$
# $Id: mf_export.py 2864 2008-08-08 23:39:11Z elachuni $


# ###################################
#
# import necessary modules
#
# ###################################

import os

# mapscript
import mapscript
from mapscript import mapObj

# wxPython support
from wx import FileDialog, MessageDialog, OK, ID_OK, SAVE, OVERWRITE_PROMPT

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

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

# needed to add the new menu
from Thuban.UI.mainwindow import main_menu

# import Map Object for the Mapfile
from mapfile import MF_Map, MF_Symbol

# ###################################
#
# Mainpart of the Extension
#
# ###################################

def tbproj_to_map(tb_map, map):
    """
    set the projection from thuban to the mapscript
    """
    # TODO: epsg code support
    # epsg will convert to parameters at the moment
    tb_proj = tb_map.GetProjection()
    if tb_proj:
        map.set_projection(tb_proj)
    
def tblayer_to_map(tb_map, map):
    """
    added all layers which are displayed in thuban to the mapscript
    if the are new, else use the associated mapobjects.
    All other layers will be removed
    """
    tb_layers = tb_map.Layers()
    oldindex = map.get_layerorder()
    indexlist = []
    for layer in tb_layers:
        map.add_thubanlayer(layer)
        layind = layer.extension_umn_layerobj.get_index()
        indexlist.append(layind)
    bigint = 0
    for rmnr in oldindex:
        if rmnr > bigint:
            bigint = rmnr
    removelist = []
    for rnr in range(0, bigint+1, 1):
        if rnr not in indexlist:
            removelist.append(rnr)
    
    for i in range(len(removelist), 0, -1):
        map.remove_layer(removelist[i-1])

    map.set_layerorder(tuple(indexlist))

def thuban_to_map(tb_context, map):
    """
    add all context from thuban to the mapscript
    """
    # get the thuban map
    tb_map = tb_context.mainwindow.canvas.Map()
    # set the title
    map.set_name(tb_map.Title())
    # set the projection
    tbproj_to_map(tb_map, map)
    # set the extent
    tb_bbox = tb_context.mainwindow.canvas.VisibleExtent()
    # Size must be set before, because mapscript checks it
    # when extent is set
    map.set_extent(tb_bbox)
    tblayer_to_map(tb_map, map)

def add_circle_symbol(map):
    """
    Added a circle object like the one shown in thuban
    """
    if map.get_symbolset().get_symbol(2):
        return
    else:
        new_symbol = MF_Symbol()
        new_symbol.set_name("circle")
        new_symbol.set_type(mapscript.MS_SYMBOL_ELLIPSE)
        new_symbol.set_filled(False)
        map.get_symbolset().add_symbol(new_symbol)
        new_symbol = MF_Symbol()
        new_symbol.set_name("circle_filled")
        new_symbol.set_type(mapscript.MS_SYMBOL_ELLIPSE)
        new_symbol.set_filled(True)
        map.get_symbolset().add_symbol(new_symbol)

def write_creatorcomment(path,file):
    """
    Added a short comment to the created map file to show
    that the file is generated automatic
    """
    thuban_umn_comment = "# \n" + \
             "# Map file generated by Thuban (umn_mapserver Extension) \n" + \
             "# \n \n"
    datafile = os.path.join(path,file)
    
    in_file = open(datafile,"r")
    text_in_file = in_file.read()
    in_file.close()
    
    out_file = open(datafile,"w")
    out_file.write(thuban_umn_comment)
    out_file.write(text_in_file) # text in Datei schreiben
    out_file.close()    # Datei schliessen

def export_mapfile(context):
    """
    Exports an existing mapobj and set all stuff from thuban to
    the mapobj
    """
    theMap = context.mainwindow.canvas.Map().extension_umn_mapobj
    width, height = theMap.get_size() 
    if width <= 0 or height <= 0:
        dlg = MessageDialog (context.mainwindow,
                 "You must set the map size before exporting", "Warning", OK)
        dlg.ShowModal()
        return
    dlg = FileDialog(context.mainwindow, "Save file as...", ".", "", 
                       "UMN MapServer Mapfiles (*.map)|*.map|"     \
                       "All files (*.*)|*.*",
                       SAVE |OVERWRITE_PROMPT)
    if dlg.ShowModal() == ID_OK:
        path = dlg.GetDirectory()
        file = dlg.GetFilename()
        dlg.Destroy()
    else:
        return

    #add symbol
    add_circle_symbol(theMap)
    
    # set all thuban context to the mapobj
    thuban_to_map(context, theMap)

    # shapepath vom mapfile
    theMap.set_shapepath("")

    # save the map with the integrated mapscript saver
    theMap.save_map(os.path.join(path,file))
    
    # this funktion will write a commend to the generated mapfile
    # that shows that the file is generated by thuban
    write_creatorcomment(path,file)

 
# check if an mapobj exists, to control the menuitem is available or not
def _has_umn_mapobj(context):
    """Return true if a umn_mapobj exists"""
    return hasattr(context.mainwindow.canvas.Map(), "extension_umn_mapobj")
 
# ###################################
#
# Hook in MapServer Extension into Thuban
#
# ###################################

# register the new command
registry.Add(Command("export_new_mapfile", _("Export mapfile"), \
                     export_mapfile,  helptext = _("Create a new mapfile"), \
                     sensitive = _has_umn_mapobj))

# find the extensions menu (create it anew if not found)
experimental_menu = main_menu.FindOrInsertMenu("experimental", \
                                              _("Experimenta&l"))
# find the extension menu and add a new submenu if found
mapserver_menu = experimental_menu.FindOrInsertMenu("mapserver", \
                                                   _("&MapServer"))

# finally add the new entry to the extensions menu
mapserver_menu.InsertItem("export_new_mapfile", after="edit_mapfile")


