# -*- coding: iso-8859-1 -*-
#
#-------------------------------------------------------------------------------
#                    Code_Saturne version 1.3
#                    ------------------------
#
#
#     This file is part of the Code_Saturne User Interface, element of the
#     Code_Saturne CFD tool.
#
#     Copyright (C) 1998-2007 EDF S.A., France
#
#     contact: saturne-support@edf.fr
#
#     The Code_Saturne User Interface 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.
#
#     The Code_Saturne User Interface 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 the Code_Saturne Kernel; if not, write to the
#     Free Software Foundation, Inc.,
#     51 Franklin St, Fifth Floor,
#     Boston, MA  02110-1301  USA
#
#-------------------------------------------------------------------------------

"""
This module defines the differents possible outputs : listings, for ensights
chronologic and historic files .... captors .... used variables ...

This module defines the following classes:
- NumericalParamGlobalModel
- NumericalParamGlobalView
- PageText

"""

#-------------------------------------------------------------------------------
# Library modules import
#-------------------------------------------------------------------------------


from xml.dom.minidom import parse
import Tix, unittest
from Tkconstants import *


#-------------------------------------------------------------------------------
# Application modules import
#-------------------------------------------------------------------------------


from Base.Common import *
import Base.Toolbox as Tool
import Base.Dialog as Dialog
import Base.TkPage as TkPage
#from Base.XMLmodel import XMLmodel
from Base.XMLvariables import Variables



#-------------------------------------------------------------------------------
# NumericalParamGlobal model class
#-------------------------------------------------------------------------------


class NumericalParamGlobalModel:
    """
    Manage the input/output markups in the xml doc about Turbulence
    """

    def __init__(self, case):
        """
        Xml node declaration and supplementary default value settings.
        """
        self.case = case
        self.node_np = self.case.xmlInitNode('numerical_parameters')
        
        self.node_ivisse = self.node_np.xmlInitNode('gradient_transpose')
        self.node_relaxp = self.node_np.xmlInitNode('pressure_relaxation')
        self.node_extrag = self.node_np.xmlInitNode('wall_pressure_extrapolation')
        self.node_ipucou = self.node_np.xmlInitNode('velocity_pressure_coupling')
        self.node_imrgra = self.node_np.xmlInitNode('gradient_reconstruction')

  
    def defaultValues(self, event=None):
        """
        default values
        """
        self.default = {}
        self.default['gradient_transpose'] = 'on'
        self.default['pressure_relaxation'] = 1.
        self.default['velocity_pressure_coupling'] ='off'	
        self.default['wall_pressure_extrapolation'] = '0'
        self.default['gradient_reconstruction'] = 0
        return self.default


    def mGetGradTransp(self, event=None):
        """
        get IVISSE value
        """
        value = self.node_ivisse['status']
        if not value:
            value = self.defaultValues()['gradient_transpose']
            self.mSetGradTransp(value)
        return value


    def mGetVelPressCoupl(self, event=None):
        """
        get IPUCOU value
        """
        value = self.node_ipucou['status']
        if not value:
            value = self.defaultValues()['velocity_pressure_coupling']
            self.mSetVelPressCoupl(value)
        return value


    def mGetWallPrExtrap(self, event=None):
        """
        get EXTRAG value
        """
        value = self.node_np.xmlGetString('wall_pressure_extrapolation')
        if not value:
            value = self.defaultValues()['wall_pressure_extrapolation']
            self.mSetWallPrExtrap(value)
        return value 


    def mGetPressRelax(self, event=None):
        """
        get RELAXP value
        """
        value = self.node_np.xmlGetDouble('pressure_relaxation')
        if not value:
            value = self.defaultValues()['pressure_relaxation']
            self.mSetPressRelax(value)
        return value


    def mGetGradReconst(self, event=None):
        """
        get IMRGRA value
        """
        value = self.node_imrgra['choice']
        if not value:
            value = self.defaultValues()['gradient_reconstruction']
            self.mSetGradReconst(value)
        return value


    def mSetGradTransp(self, value):
        self.node_ivisse['status'] = value


    def mSetPressRelax(self, value):
        self.node_np.xmlSetData('pressure_relaxation', value)


    def mSetVelPressCoupl(self, value):
        self.node_ipucou['status'] = value
        if value== 'on': Variables(self.case).setWeightMatrixComponents()


    def mSetWallPrExtrap(self, value):
        self.node_np.xmlSetData('wall_pressure_extrapolation', value)


    def mSetGradReconst(self,  value):
        self.node_imrgra['choice'] = value


#-------------------------------------------------------------------------------
# Main class
#-------------------------------------------------------------------------------


class NumericalParamGlobalView(TkPage.Page):
    """
    Class to open Turbulence Page.
    """
    def _pageControl(self):
        """
        Xml node declaration and supplementary default value settings.
        """
        self.model = NumericalParamGlobalModel(self.case)


    def _tkControlVariables(self):
        """
        Tkinter variables declaration.
        """
        self.ivisse = Tix.StringVar()
        self.relaxp = Tix.DoubleVar()
        self.ipucou = Tix.StringVar()
        self.extrag = Tix.StringVar()
        self.imrgra = Tix.StringVar()

    def setIVISSE(self, event=None):
        self.model.mSetGradTransp(self.ivisse.get())


    def setIPUCOU(self, event=None):
        value = self.ipucou.get()
        self.model.mSetVelPressCoupl(value)


    def setEXTRAG(self, event=None):
        self.model.mSetWallPrExtrap(self.extrag.get())


    def setRELAXP(self, event=None):
        self.stbar.busy()
        val1 = 1e-15
        val2 = 1 + val1
        if self.check2.isBetween(self.e2, self.relaxp, val1, val2):
            self.model.mSetPressRelax(self.relaxp.get()) 
        self.stbar.idle()


    def setIMRGRA(self, event=None):
        self.model.mSetGradReconst(self.imrgra.get())

    def _createWidgets(self):
        """
        Create the Page layout.
        """
        t = PageText()

        w1 = Tix.LabelFrame(self.myPage, bd=2, label=t.GLOBPARAM_TITLE, relief=FLAT)
        w1.label.config(font=fT)
        w1.pack(side=TOP, fill=BOTH, pady = 10)

        self.c = [0]*3
        self.l = [0]*3
        self.s = [0]*3
        padyy  = 15
        
        for (i, txt, var, command, kword) in 	\
                [(0, t.IVISSE, self.ivisse, self.setIVISSE, 'IVISSE'),
                (2, t.IPUCOU, self.ipucou, self.setIPUCOU, 'IPUCOU')]:

            self.l[i] = Tix.Label(w1.frame, text=txt)
            self.l[i].grid(row=i, column=0, pady=padyy, sticky=W)
            self.c[i] = Tix.Checkbutton(w1.frame, onvalue='on', offvalue='off',
                                  variable=var, command=command)
            self.c[i].grid(row=i, column=1, pady=padyy, sticky=E)
            self.balloon.bind_widget(self.l[i], balloonmsg=t.KEYWORD+kword)
            self.balloon.bind_widget(self.c[i], balloonmsg=t.KEYWORD+kword)
            self.s[i] = Tix.Frame(w1.frame, height=2, bd=2, relief=SUNKEN)
            self.s[i].grid(row=i+1, column=0, columnspan=2,pady=padyy, sticky=W+E)


        self.l1 = Tix.Label(w1.frame, text=t.EXTRAG)
        self.l1.grid(row=4, column=0, padx=5, pady=padyy, sticky=W)
        self.o1 = Tix.OptionMenu(w1.frame)
        self.o1.menubutton.config(width=10, bd=2, relief=RAISED)
        self.o1.grid(row=4, column=1, padx=1, pady=padyy, sticky=E)
        self.o1.add_command('0', label=t.NEUMANN1)
# la valeur 0.5 est vérouillée
# self.o1.add_command('0.5', label=t.NEUMANN2)
        self.o1.add_command('1', label=t.EXTRAPOL)
        self.o1.config(variable=self.extrag, command=self.setEXTRAG)
        self.balloon.bind_widget(self.l1, balloonmsg=t.KEYWORD+'EXTRAG')
        self.balloon.bind_widget(self.o1, balloonmsg=t.KEYWORD+'EXTRAG')

        self.s2 = Tix.Frame(w1.frame, height=2, bd=2, relief=SUNKEN)
        self.s2.grid(row=5, column=0, columnspan=2,pady=padyy, sticky=W+E)

        self.l2 = Tix.Label(w1.frame, text=t.RELAXP)
        self.l2.grid(row=6, column=0, padx=5, pady=padyy, sticky=W)
        self.e2 = Tix.Entry(w1.frame, bd=2, width=6, textvariable=self.relaxp)
        self.e2.grid(row=6, column=1, padx=1, pady=padyy, sticky=E)
        self.e2.event_add("<<Event>>", "<Return>", "<Leave>", "<FocusOut>")
        self.e2.bind("<<Event>>", self.setRELAXP)
        self.balloon.bind_widget(self.l2, balloonmsg=t.KEYWORD+'RELAXP')
        self.balloon.bind_widget(self.e2, balloonmsg=t.KEYWORD+'RELAXP')
 
        self.s3 = Tix.Frame(w1.frame, height=2, bd=2, relief=SUNKEN)
        self.s3.grid(row=7, column=0, columnspan=2,pady=padyy, sticky=W+E)

        self.l3 = Tix.Label(w1.frame, text=t.IMRGRA)
        self.l3.grid(row=8, column=0, padx=5, pady=padyy, sticky=W)
        self.o3 = Tix.OptionMenu(w1.frame)
        self.o3.menubutton.config(width=22, bd=2, relief=RAISED)
        self.o3.grid(row=8, column=1, padx=1, pady=padyy, sticky=E)
        self.o3.add_command('0', label=t.RECONST97)
        self.o3.add_command('1', label=t.MC_CELVOI)
        self.o3.add_command('2', label=t.MC_SUPETCOMP)
        self.o3.add_command('3', label=t.MC_SUPETREST)
        self.o3.add_command('4', label=t.INI_MC)
        self.o3.config(variable=self.imrgra, command=self.setIMRGRA)
        self.balloon.bind_widget(self.l3, balloonmsg=t.KEYWORD+'IMRGRA')
        self.balloon.bind_widget(self.o3, balloonmsg=t.KEYWORD+'IMRGRA')


    def _initializeWidgets(self):
        """
        Extract resquested informations from XML document.
        This informations are used to initialize the widgets.
        For this page default values of all widgets are necessary
        included in the XML file.
        """
        t = PageText()

        if self.model.mGetGradTransp() == 'on':
            self.c[0].select()
        else:
            self.c[0].deselect()
        if self.model.mGetVelPressCoupl() == 'on':
            self.c[2].select()
        else:
            self.c[2].deselect()

        self.relaxp.set(self.model.mGetPressRelax())
        self.o1.config(value=self.model.mGetWallPrExtrap())
        self.o3.config(value=self.model.mGetGradReconst())


#-------------------------------------------------------------------------------
# Text and messages for this page
#-------------------------------------------------------------------------------


class PageText:
    """
    Storage of all texts and messages for this page.
    """
    def __init__(self):
        
        # 1) Texts
        #
        if Tool.GuiParam.lang == 'fr':
            self.GLOBPARAM_TITLE = "PARAMETRES GLOBAUX"
            self.KEYWORD	 = "Mot clé Code_Saturne: "
            self.IVISSE		 = "Prise en compte des termes sources\n" +\
                                "en gradient transposé\net divergence de vitesse"
            self.RELAXP		 = "Coefficient de relaxation de\nl'incrément de pression"
            self.IPUCOU		 = "Couplage Vitesse - Pression"
            self.EXTRAG		 = "Extrapolation du gradient de pression\nau bord"
            self.YES		 = "Oui"
            self.NO		 = "Non"
            self.NEUMANN1	 = "Neum. ordre 1"
            self.NEUMANN2	 = "Neum. ordre 2"
            self.EXTRAPOL	 = "Extrapolation"
            self.RECONST97	 = "Reconstruction 97"
            self.MC_CELVOI	 = "M.C. Cellules voisines"
            self.MC_SUPETCOMP	 = "M.C. Support étendu complet"
            self.MC_SUPETREST	 = "M.C. Support étendu restreint"
            self.INI_MC		 = "Initialisation M.C."
            self.IMRGRA		 = "Reconstruction des gradients"
        else:
            self.GLOBPARAM_TITLE = "GLOBAL PARAMETERS"
            self.KEYWORD	 = "Code_Saturne key word: "
            self.IVISSE		 = "Handling of transposed gradient\nand "  +\
                           "divergence source terms\nin momentum equation"
            self.RELAXP		 = "Relaxation of pressure increase"
            self.IPUCOU		 = "Velocity- Pressure Coupling"
            self.EXTRAG		 = "Extrapolation of pressure gradient\n"	+\
                           "on domain boundary"
            self.YES		 = "Yes"
            self.NO		 = "No"
            self.NEUMANN1	 = "Neum. order 1"
            self.NEUMANN2	 = "Neum. order 2"
            self.EXTRAPOL	 = "Extrapolation"
            self.IMRGRA		 = "Gradient reconstruction type"
#	    self.RECONST97	 = "Reconstruction 97"
#	    self.MC_CELVOI	 = "M.C. Cellules voisines"
#	    self.MC_SUPETCOMP	 = "M.C. Support étendu complet"
#	    self.MC_SUPETREST	 = "M.C. Support étendu restreint"
#	    self.INI_MC		 = "Initialization M.C."
            self.RECONST97	 = "Iter. hand. of N.O."
            self.MC_CELVOI	 = "L.S. over neigh. cells"
            self.MC_SUPETCOMP	 = "L.S. over ext. cell neigh."
            self.MC_SUPETREST	 = "L.S. over part. ext. cell neigh."
            self.INI_MC		 = "L.S. Initialization"

        # 2) Messages
        #
        if Tool.GuiParam.lang == 'fr':
            self.MSG_ERR_VIT = "Votre fichier xml a été 'trafiqué'"
            self.MSG_HLIST   = "Cliquer le bouton droit pour "       +\
                               "le menu contextuel."
            self.MSG_POSITIV = "Cette valeur est forcément positive"
        else:
            self.MSG_ERR_VIT = "Your xmlfile has been corrupted"
            self.MSG_HLIST   = "Click right button for popup menu."
            self.MSG_POSITIV = "This value is obligatory positive"


#-------------------------------------------------------------------------------
# NumericalParamEquat test case
#-------------------------------------------------------------------------------


class NumericalParamGlobalTestCase(unittest.TestCase):
    """
    """
    def setUp(self):
        """
        This method is executed before all "check" methods.
        """
        from Base.XMLengine import Case
        from Base.XMLinitialize import XMLinit
        Tool.GuiParam.lang = 'en'
        self.case = Case(None)
        XMLinit(self.case)


    def tearDown(self):
        """
        This method is executed after all "check" methods.
        """
        del self.case


    def checkNumericalParamGlobalInstantiation(self):
        """
        Check whether the NumericalParamEquatModel class could be instantiated
        """
        model = None
        model = NumericalParamGlobalModel(self.case)
        assert model != None, 'Could not instantiate NumericalParamGlobalModel'


    def checkgetGradTransp(self):
        """
        Check whether the NumericalParamEquatModel class could get gradient transpose
        """
        model = None
        model = NumericalParamGlobalModel(self.case)
        resu = model.mGetGradTransp()
        test = 'on'
        assert resu == test, 'Could not get gradient transpose'


    def checkgetWallPrExtrap(self):
        """
        Check whether the NumericalParamEquatModel class could get 
        wall pressure extrapolation
        """
        model = None
        model = NumericalParamGlobalModel(self.case)
        resu = model.mGetWallPrExtrap()
        test  = '0'
        assert resu == test, 'Could not get wall pressure extrapolation'


    def checkgetGradReconst(self):
        """
        Check whether the NumericalParamEquatModel class could get 
        gradient reconstruction
        """
        model = None
        model = NumericalParamGlobalModel(self.case)
        resu = model.mGetGradReconst()
        test = 0
        assert resu == test, 'Could not get gradient reconstruction'


    def checksetWallPrExtrap(self):
        """
        Check whether the NumericalParamEquatModel class could set 
        wall pressure extrapolation
        """
        model = None
        model = NumericalParamGlobalModel(self.case)
        model.mSetWallPrExtrap(0.8)
        resu = model.node_np.toString()
        test  = '<numerical_parameters>'\
                    '<gradient_transpose/>'\
                    '<pressure_relaxation/>'\
                    '<wall_pressure_extrapolation>0.8</wall_pressure_extrapolation>'\
                    '<velocity_pressure_coupling/>'\
                    '<gradient_reconstruction/>'\
                '</numerical_parameters>'

        assert resu == test, 'Could not set wall pressure extrapolation'


def suite():
    testSuite = unittest.makeSuite(NumericalParamGlobalTestCase, "check")
    return testSuite


def runTest():
    runner = unittest.TextTestRunner()
    runner.run(suite())


#-------------------------------------------------------------------------------
# End
#-------------------------------------------------------------------------------


syntax highlighted by Code2HTML, v. 0.9.1