# -*- coding: iso-8859-1 -*-
from __future__ import division # 1/2 == .5 (par defaut, 1/2 == 0)

#    WxGeometrie
#    Dynamic geometry, graph plotter, and more for french mathematic teachers.
#    Copyright (C) 2005-2007  Nicolas Pourcelot
#
#    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#version unicode

    #try: 
    #    import psyco; 
    #    psyco.profile() 
    #except: 
    #    pass
  


import sys
import param
import os
import optparse

def gerer_arguments():
    u"""On récupère les options éventuelles passées au programme.
    
    -a ou --all : essaie de détecter tous les modules possibles pour les intégrer au démarrage
    ex: python wxgeometrie.pyw --all monfichier1.geo monfichier2.geo
    
    -p ou --param ou --parametres : modifier le contenu du module 'param'. Les parametres sont séparés par des points-virgules.
    ex: python wxgeometrie.pyw --param version='0.1';tolerance=0.01 monfichier1.geo monfichier2.geo
    
    -d ou --defaut : ne pas charger les préférences"""
    
    parametres_additionnels = {}
    
    parser = optparse.OptionParser(prog = "WxGeometrie", usage = "usage: %prog [options] fichiers",  version = "%prog " + param.version)
    parser.add_option("-a", "--all", action = "store_true", help="detecter tous les modules presents et les integrer au demarrage")
    parser.add_option("-d", "--defaut", action = "store_true", help="utiliser les parametres par defaut, sans tenir compte des preferences")
    parser.add_option("-b", "--debug", action = "store_true", help="afficher les eventuels messages d'erreurs lors de l'execution")
    parser.add_option("--nodebug", action = "store_true", help="ne pas afficher les messages d'erreurs lors de l'execution")
    parser.add_option("-w", "--warning", action = "store_true", help="afficher les eventuels avertissements lors de l'execution")
    parser.add_option("--nowarning", action = "store_true", help="ne pas afficher les avertissements lors de l'execution")
    parser.add_option("-p", "--parametres", help="modifier les parametres. ex: wxgeometrie -p 'tolerance=0.001;version=\"1.0\"'")
    parser.add_option("-r", "--recompile", action = "store_true", help="supprimer recursivement tous les fichiers .pyc, pour obliger python a recompiler tous les fichiers sources au demarrage.")
    
# parser.set_defaults()
    
    (options, args) = parser.parse_args()
    
    if options.defaut:
        param.charger_preferences = False
        
    if options.all:
        liste_modules = []
        rep_modules = os.path.join(os.getcwdu(), "modules") # ./modules
        # Par convention, les noms des modules ne contiennent que des lettres minuscules
        for entree in os.listdir(rep_modules):
            if entree.isalpha() and entree.islower() and os.path.isdir(os.path.join(rep_modules, entree)):
                liste_modules.append(entree)
        parametres_additionnels["modules"] = tuple(liste_modules)
    
    if options.debug:
        parametres_additionnels["debug"] = True
            
    if options.nodebug:
        parametres_additionnels["debug"] = False    
            
    if options.warning:
        parametres_additionnels["warning"] = True
            
    if options.nowarning:
        parametres_additionnels["warning"] = False    
            
    if options.parametres:
        for parametre in options.parametres.split(";"):
            try:
                nom, valeur = parametre.split("=", 1)
                parametres_additionnels[nom] = eval(valeur) # pas sensass question sécurité... :-( (?)
            except Exception:
                #raise
                print "Erreur: Parametre incorrect :", parametre
                print sys.exc_info()[0].__name__, ": ", sys.exc_info()[1]           
    
    if options.recompile:
        for root, dirs, files in os.walk(os.getcwdu()):
            for file in files:
                if file.endswith(".pyc"):
                    os.remove(os.path.join(root,file))
    
    arguments = []
    
    # Sous les Unix-like, les espaces dans les noms de fichiers sont mal gérés par python semble-t-il.
    # Par exemple, "mon fichier.geo" est coupé en "mon" et "fichier.geo"
    complet = True
    for arg in args:
        if complet:
            arguments.append(arg)
        else:
            arguments[-1] += " " + arg
        complet = arg.endswith(".geo") or arg.endswith(".geoz")
        
    for nom in parametres_additionnels:
        if not hasattr(param, nom):
            print u"Attention: Paramêtre inconnu : " + nom
        
    return parametres_additionnels, arguments


##def gerer_arguments_old():
##    u"""On récupère les options éventuelles passées au programme.
##    
##    -a ou --all : essaie de détecter tous les modules possibles pour les intégrer au démarrage
##    ex: python wxgeometrie.pyw --all monfichier1.geo monfichier2.geo
##    
##    -p ou --param ou --parametres : modifier le contenu du module 'param'. Les parametres sont séparés par des points-virgules.
##    ex: python wxgeometrie.pyw --param version='0.1';tolerance=0.01 monfichier1.geo monfichier2.geo
##    
##    -d ou --defaut : ne pas charger les préférences"""
##
##    arguments = []
##    
##    print sys.argv
##
##    i = 0
##    while i < len(sys.argv):
##        if sys.argv[i] in ("-a", "--all"):
##            liste_modules = []
##            rep_modules = os.path.join(os.getcwdu(), "modules") # ./modules
##            # Par convention, les noms des modules ne contiennent que des lettres minuscules
##            for entree in os.listdir(rep_modules):
##                if entree.isalpha() and entree.islower() and os.path.isdir(os.path.join(rep_modules, entree)):
##                    liste_modules.append(entree)
##            param.modules = tuple(liste_modules)
##                    
##        elif sys.argv[i] in ("-d", "--defaut"):
##            param.charger_preferences = False
##        elif sys.argv[i] in ("-p", "--param", "--parametres"):
##            i += 1
##            parametres = sys.argv[i].split(";")
##            for parametre in parametres:
##                try:
##                    nom, valeur = parametre.split("=", 1)
##                    setattr(param, nom, eval(valeur)) # pas sensass question sécurité... :-( (?)
##                except Exception:
##                    #raise
##                    print "Parametre incorrect :", parametre
##                    print sys.exc_info()[0].__name__, ": ", sys.exc_info()[1]           
##        else:
##            arguments.append(sys.argv[i])
##        i += 1
##    return arguments


# à faire avant d'importer API et LIB
parametres_additionnels, arguments = gerer_arguments()
    
print parametres_additionnels, arguments

import API
from LIB import *

if param.charger_psyco is not False:
    try:
        import psyco
        if param.charger_psyco is True:
            psyco.full()
        else:
            psyco.profile()
    except ImportError:
        pass


def initialiser():
    param.EMPLACEMENT = os.getcwdu()
    app = wx.PySimpleApp()
    path = path2(param.emplacements["preferences"] + "/parametres.xml")
    try:
        if param.charger_preferences and os.path.exists(path):
            # on charge les préférences de l'utilisateur depuis parametres.xml
            a_verifier = {}
            a_verifier.update([(dico, getattr(param, dico)) for dico in param.a_mettre_a_jour])
            API.actualiser_module(param, path)
            # certains paramètres peuvent avoir besoin d'une mise à jour (en cas de changement de version de wxgéométrie par exemple)
            # cela concerne en particulier les dictionnaires, qui peuvent gagner de nouvelles clés.
            for dictionnaire in param.a_mettre_a_jour:
                for key in a_verifier[dictionnaire].keys():
                    getattr(param, dictionnaire).setdefault(key, a_verifier[dictionnaire][key])
        else:
            API.actualiser_module(param, None)
    except:
        print_error()
    
    param.__dict__.update(parametres_additionnels)
#    for key in parametres_additionnels:
#        setattr(param, key, parametres_additionnels[key])
    
    app.SetAppName(u"WxGéométrie")
    #~ print "Test 2.5"
    import GUI
    #~ print "Test 3"
    if param.debug:
        app.RedirectStdio(None)     # redirection vers une fenetre de messages
        
        print "Initialisation:", parametres_additionnels, arguments

    elif param.enregistrer_messages:
        filename = path2(param.emplacements["log"] + u"/messages.log")
        try:
            open(filename, "w").close() # on purge le fichier de log
            app.RedirectStdio(filename)
        except IOError:
            print_error()
            param.enregistrer_messages = param.historique_log = False

    #~ print "Test 4"
    app.SetOutputWindowAttributes(title = u"WxGéométrie - messages.")
    if param.erreurs_initialisation:
        print param.erreurs_initialisation

    try:
        frame = GUI.WxGeometrie(app)
        try:
            if arguments:
                for arg in arguments:
                    frame.onglets.ouvrir(arg) # ouvre le fichier passé en paramètre
                #fichier = arguments[1]
                #fgeo, message = ouvrir_fichierGEO(fichier)
                #module = frame.onglets.onglet(fgeo.module)
                #if module is not None:
                #    module._ouvrir(fgeo)
                #    frame.onglets.changer_onglet(module)

        except:
            print_error() # affiche l'erreur interceptée, à titre informatif
            print(arg)
    except:
        app.RestoreStdio()
        raise
    #~ print "test3"
    frame.Show(True)
    #~ print "test"
    app.MainLoop()
