# -*- 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 Variables class which creates the <variable>,
<scalar> and <property> markups.

This module contains the following classes and function:
- Variables
- VariablesTestCase
"""

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


import unittest


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


from Common import *
import Toolbox


#-------------------------------------------------------------------------------
# class Variables : creates <variable>, <scalar> and <property> markups.
#-------------------------------------------------------------------------------


class Variables:
    """
    This class creates <variable>, <scalar> and <property> markups.
    Each new markup has a 'name' and a 'label' attribute.
    Each new markup has <listing_printing status='on'>, 
    <postprocessing_recording status='on'> and several
    <probe_recording name="XX"> (if any <probe> exists) as child markups.
    """
    def __init__(self, case):
        """
        Constructor.
        """
        self.case = case


    def defaultInitialValues(self):
        """
        Return in a dictionnary which contains default values.
        """
        default = {}
        #Initial values for thermal scalar: 20°C air at atmospheric pressure.
        default['temperature_celsius'] = 20.0
        default['temperature_kelvin'] = 293.15
        default['enthalpy'] = 297413.
    
        #Initial values for properties: 20°C air at atmospheric pressure.
        default['density'] = 1.17862
        default['molecular_viscosity'] = 1.83e-05
        default['diffusion_coefficient'] = 1.83e-05
        default['specific_heat'] = 1017.24
        default['thermal_conductivity'] = 0.02495

        return default


    def setOutputControl(self, variable):
        """
        Update the output markups <probe_recording name="XX">,
        <postprocessing_recording status='on'> and
        <listing_printing status='on'> for the new 'variable' markup.
        """
        analysis_ctrl = self.case.xmlGetNode('analysis_control')
        node_output   = analysis_ctrl.xmlInitNode('output')
        for node in node_output.xmlGetNodeList('probe', 'name'):
            num = node['name']
            variable.xmlInitChildNode('probe_recording', name=num)

##        variable.xmlInitChildNode('listing_printing', status='on')
##        variable.xmlInitChildNode('postprocessing_recording', status='on')


    def updateLabel(self, vv):
        """
        """
        if not vv['label']:
            vv['label'] = Toolbox.dicoLabel(vv['name'])


    def setNewVariable(self, node, tag):
        """
        Input a new <variable name="my_variable" label="ma_variable">
        in the xmldoc.
        """
        if not node.xmlGetNode('variable', name=tag):
            v1 = node.xmlInitNode('variable', name=tag)
            self.setOutputControl(v1)
            self.updateLabel(v1)


    def setNewThermalScalar(self, node, tag, zone):
        """
        Input a child node
        <scalar name="my_variable" label="ma_variable" type="thermal">
        to the argument node. Initial values are for air at
        atmospheric pressure.
        """
        if not node.xmlGetNode('scalar', type='thermal', name=tag):
            s1 = node.xmlInitNode('scalar', type='thermal', name=tag)
            s1.xmlInitChildNode('initial_value', zone=zone)
            if tag == "temperature_celsius":
                s1.xmlSetData('initial_value', self.defaultInitialValues()[tag])
            elif tag == "temperature_kelvin":
                s1.xmlSetData('initial_value', self.defaultInitialValues()[tag])
            elif tag == "enthalpy":
                s1.xmlSetData('initial_value', self.defaultInitialValues()[tag])
            else:
                print "Error in setNewThermalScalar:"
                print "the given tag is %s" % (tag)
                exit(0)

            s1.xmlSetData('min_value', SMGRAND)
            s1.xmlSetData('max_value', SPGRAND)

            self.setOutputControl(s1)
            self.updateLabel(s1)


    def setNewUserScalar(self, node, tag):
        """
        Input a new <scalar label="ma_variable" type="user">
        in the xmldoc.
        """
        if not node.xmlGetNodeList('scalar', type="user", label=tag):
            s1 = node.xmlInitNode('scalar', type="user", label=tag)
            self.setOutputControl(s1)
            self.updateLabel(s1)
        else:
            s1 = node.xmlGetNode('scalar', type="user", label=tag)

        return s1


    def setNewModelScalar(self, node, tag):
        """
        Input a new <scalar label="ma_variable" type="model">
        in the xmldoc.
        """
        if not node.xmlGetNodeList('scalar', type="model", name=tag, label=tag):
            s1 = node.xmlInitNode('scalar', type="model", name=tag, label=tag)
            self.setOutputControl(s1)
            self.updateLabel(s1)
        else:
            s1 = node.xmlGetNode('scalar', type="model", name=tag, label=tag )

        return s1


    def deleteAllModelScalars(self, node):
        """
        Input a new <scalar label="ma_variable" type="model">
        in the xmldoc.
        """
        nodeList = node.xmlGetNodeList('scalar')
        if nodeList != None:
            for node in nodeList :
                node.xmlRemoveNode()


    def setWeightMatrixComponents(self, event=None):
        """
        Input a new <scalar label="ma_variable" type="user">
        in the xmldoc.
        """
        node_np = self.case.xmlInitNode('numerical_parameters')
        node_ipucou = node_np.xmlInitNode('velocity_pressure_coupling')

        node_Tx = node_ipucou.xmlInitNode('property', name='weight_matrix_X')
        node_Ty = node_ipucou.xmlInitNode('property', name='weight_matrix_Y')
        node_Tz = node_ipucou.xmlInitNode('property', name='weight_matrix_Z')

        for (node, val) in [(node_Tx, 'weight_matrix_X'),
                            (node_Ty, 'weight_matrix_Y'),
                            (node_Tz, 'weight_matrix_Z')]:
            self.setOutputControl(node)
            if not node['label']: node['label'] = Toolbox.dicoLabel(val)

    def deleteAllModelProperties(self, modelNode):
        """
        Input a new <scalar label="ma_variable" type="model">
        in the xmldoc.
        """
        nodeList = modelNode.xmlGetNodeList('property')
        if nodeList != None:
            for node in nodeList :
                node.xmlRemoveNode()
    

    def setNewProperty(self, node, tag):
        """
        Input a new <property name="my_property" label="ma_propriete">
        in the xmldoc.
        """
        if not node.xmlGetNode('property', name=tag):
            p1 = node.xmlInitNode('property', name=tag)
            self.setOutputControl(p1)
            try :
                self.updateLabel(p1)
            except:
                pass
            if not p1['label']: p1['label'] = tag

    def setNewFluidProperty(self, node, tag, label=None):
        """
        Input a new <property name="my_property" label="ma_propriete", choice="constant">
        in the xmldoc.
        """
        if not node.xmlGetNode('property', name=tag):
            p1 = node.xmlInitNode('property', name=tag, choice='constant')
##            if tag == "density":
##                value = self.defaultInitialValues()[tag]
##            elif tag == "molecular_viscosity" or tag == "diffusion_coefficient":
##                value = self.defaultInitialValues()[tag]
##            elif tag == "specific_heat":
##                value = self.defaultInitialValues()[tag]
##            elif tag == "thermal_conductivity":
##                value = self.defaultInitialValues()[tag]
##            else:
##                print "Error in setNewFluidProperty:"
##                print "the given tag is %s" % (tag)
##                exit(0)

##            p1.xmlSetData('initial_value', value)
            self.setOutputControl(p1)
            p1.xmlInitChildNode('listing_printing')['status'] = "off"
            p1.xmlInitChildNode('postprocessing_recording')['status'] = "off"

            if label:
                p1['label'] = label
            else:
                self.updateLabel(p1)

        else:
            p1 = node.xmlGetNode('property', name=tag)

        return p1


#-------------------------------------------------------------------------------
# Class Model
#-------------------------------------------------------------------------------


class Model:
    """
    This class verifies int and float values mathematically
    """
##    def __init__(self, case):
##        """
##        Constructor.
##        """
##        self.case = case


    def isList(self, liste):
        """This method verifies that list is not empty"""
        if type(liste) != list: 
            msg = "There is an error : " + string.join(liste) + " is not a list\n"
            raise ValueError, msg
        return True


    def isInt(self, ival):
        """This method verifies that ival is a int value > 0"""
        if type(ival) != int: 
            msg = "There is an error : this value :" + str(ival) + " is not an integer\n"
            raise ValueError, msg
        return True

    def isPositiveInt(self, ival):
        """This method verifies that ival is a int value > or = 0"""
        if self.isInt(ival):
            if ival < 0: 
                msg = "There is an error : this value :" + str(ival) + " must not be negative\n"
                raise ValueError, msg
        return True

    def isStrictPositiveInt(self, ival):
        """This method verifies that ival is a int value > 0"""
        if self.isInt(ival):
            if ival <= 0: 
                msg = "There is an error : this value :" + str(ival) + "\n"\
                      "must not be neither negative neither 0\n"
                raise ValueError, msg
        return True
        

    def isIntBetween(self, ival,  imin, imax):
        """This method verifies that ival is in imin and imax"""
        if self.isInt(ival):
            if ival < imin or ival > imax: 
                msg = "There is an error : this value :" + str(ival) + "\n"\
                      "must be between " + str(imin) + "and" + str(imax) + "\n"
                raise ValueError, msg
        return True


    def isIntInList(self, ival, list):
        """This method verifies that ival is in list"""
        if self.isInt(ival) and self.isList(list):
            if ival not in list:
                msg = "There is an error : this value :" + str(ival) + "\n"\
                      "is not in list " + list + "\n"
                raise ValueError, msg
        return True

    def isFloat(self, val):
        """This method verifies that val is a float value > 0"""
        if type(val) != float and type(val) != int: 
            msg = "There is an error : this value :" + str(val) + " is not a float value\n"
            raise ValueError, msg
        return True


    def isPositiveFloat(self, val):
        """This method verifies that val is a float value > or = 0"""
        if self.isFloat(val):
            if val < 0: 
                msg = "There is an error : this value :" + str(val) + " must not be negative\n"
                raise ValueError, msg
        return True


    def isStrictPositiveFloat(self, val):
        """This method verifies that val is a float value > 0"""
        if self.isFloat(val):
            if val <= 0: 
                msg = "There is an error : this value :" + str(val) + "\n"\
                      "must not be neither negative neither 0\n"
                raise ValueError, msg
        return True


    def isFloatBetween(self, val,  min, max):
        """This method verifies that val is in min and max"""
        if self.isFloat(val):
            if val < min or val > max: 
                msg = "There is an error : this value :" + str(val) + "\n"\
                      "must be between " + str(min)+ "and" + str(max) + "\n"
                raise ValueError, msg
        return True


    def isFloatInList(self, val, list):
        """This method verifies that val is in list"""
        if self.isFloat(val):
            if val not in list:
                msg = "There is an error : this value :" + str(val) + "\n"\
                      "is not in list " + str(list) + "\n"
                raise ValueError, msg
        return True


    def isFloatInList(self, val, list):
        """This method verifies that val is in list"""
        if self.isFloat(val) and self.isList(list):
            if val not in list:
                msg = "There is an error : this value :" + str(val) + "\n"\
                      "is not in list " + str(list) + "\n"
                raise ValueError, msg
        return True


#-------------------------------------------------------------------------------
# MODEL test case
#-------------------------------------------------------------------------------


class ModelTestCase(unittest.TestCase):
    """
    """
##    def setUp(self):
##        """This method is executed before all "check" methods."""
##        from Base.XMLengine import Case
####        self.case = Case(None)
##
##    def tearDown(self):
##        """This method is executed after all "check" methods."""
##        del self.case


    def checkIsInt(self):
        """ Check whether the Model class could be verify value is integer """
        ival = 3
        xval = 5.2
        assert Model().isInt(ival),'Should be an integer value'


    def checkIsPositiveInt(self):
        """Check whether the Model class could be verify value is a int value > or = 0"""
        ival = 3
        assert Model().isPositiveInt(ival) == True,\
        'Should be a positive integer value'


    def checkIsStrictPositiveInt(self):
        """Check whether the Model class could be verify value is a int value > or = 0"""
        ival = 3
        assert Model().isStrictPositiveInt(ival) == True,\
        'Should be a strict positive integer value'


    def checkIsIntbetween(self):
        """Check whether the Model class could be verify value is between min-max"""
        ival = 3
        imin = 1
        imax = 10
        assert Model().isIntBetween(ival, imin, imax) == True,\
        'Could not verify value is between min and max integer values'


    def checkIsIntInList(self):
        """Check whether the Model class could be verify value is in list"""
        ival = 3
        list = ['toto', 3.4, 3, "machin"]
##        list = ['toto', 3.4, "machin"]
        assert Model().isIntInList(ival, list) == True,\
        'Could not verify value is in list '


    def checkIsFloat(self):
        """ Check whether the Model class could be verify value is float """
        ival = 3
        xval = 5.2
        assert Model().isFloat(xval) == True,'Should be a float value'


    def checkIsPositiveFloat(self):
        """Check whether the Model class could be verify value is a float value > or = 0"""
        val = 3.5
        assert Model().isPositiveFloat(val) == True,\
        'Should be a positive float value'


    def checkIsStrictPositiveFloat(self):
        """Check whether the Model class could be verify value is a float value > or = 0"""
        val = 3.5
        assert Model().isStrictPositiveFloat(val) == True,\
        'Should be a strict positive float value'


    def checkIsFloatbetween(self):
        """Check whether the Model class could be verify value is between min-max"""
        val = 3.5
        min = 1.0
        max = 10.0
        assert Model().isFloatBetween(val, min, max) == True,\
        'Could not verify value is between min and max float values'


    def checkIsFloatInList(self):
        """Check whether the Model class could be verify value is in list"""
        val = 3.4
        list = ['toto', 3.4, 3, "machin"]
##        list = ['toto', 3, "machin"]
        assert Model().isFloatInList(val, list) ==True ,\
        'Could not verify value is in list '


    def checkIsList(self):
        """Check whether the Model class could be verify value is not empty"""
        list = ['toto', 3.4, 3, "machin"]
##        list = ('toto', 3.4, 3, "machin")
        assert Model().isList(list) == True,\
        'Should be a list '

def suite1():
    testSuite = unittest.makeSuite(ModelTestCase, "check")
    return testSuite

def runTest():
    print "ModelTestCase"
    runner = unittest.TextTestRunner()
    runner.run(suite1())
##    runner.run(suite2())
        
#-------------------------------------------------------------------------------
# Variables test case
#-------------------------------------------------------------------------------


##class VariablesTestCase(unittest.TestCase):
##    """
##    """
##    def setUp(self):
##        """This method is executed before all "check" methods."""
##        import XMLengine
##        self.doc = XMLengine.XMLDocument("")
##        self.case = self.doc.parseString('<?xml version="1.0" ?>'\
##                                         '<Code_Saturne_GUI/>')
##        self.case.root().xmlAddChild('analysis_control')
##
##    def tearDown(self):
##        """This method is executed after all "check" methods."""
##        del self.case
##
##    def xmlNodeFromString(self, string):
##        """Private method to return a xml node from string"""
##        return self.doc.parseString(string).root()
##
##    def checkVariablesInstantiation(self):
##        """ Check whether the Variable class could be instantiated """
##        doc = None
##        doc = Variables(self.case)
##        assert doc != None, 'Could not instantiate Variables'
##
##    def checkSetOutputControl(self):
##        """ Check whether the <probe_recording name="XX">,
##        <postprocessing_recording status='on'> and
##        <listing_printing status='on'> markups could be set.  """
##        node = self.case.root().xmlAddChild('variable')
##        Variables(self.case).setOutputControl(node)
##        doc = '<variable/>'
##        assert node == self.xmlNodeFromString(doc),\
##            'Could not set the output control markups'
##
##    def checkSetNewVariable(self):
##        """ Check whether a new
##        <variable name="my_variable" label="ma_variable">
##        in the xmldoc could bet set.  """
##        root = self.case.root()
##        Variables(self.case).setNewVariable(root, 'pressure')
##        node = root.xmlGetChildNode('variable')
##        node['label'] = "toto"
##        doc = '<variable label="toto" name="pressure"/>'
##        assert  node == self.xmlNodeFromString(doc),\
##            'Could not set the variable markup'
##
##    def checkSetNewThermalScalar(self):
##        """ Check whether a new
##        <scalar name="my_variable" label="ma_variable" type="">
##        in the xmldoc could bet set.  """
##        root = self.case.root()
##        Variables(self.case).setNewThermalScalar(root, 'temperature_celsius', "0")
##        node = root.xmlGetChildNode('scalar')
##        node['label'] = "toto"
##        doc = '<scalar label="toto" name="temperature_celsius" type="thermal">'\
##                '<initial_value zone="0">20</initial_value>'\
##                '<min_value>-1e+12</min_value>'\
##                '<max_value>1e+12</max_value>'\
##              '</scalar>'
##        assert node == self.xmlNodeFromString(doc),\
##            'Could not set the thermal scalar markups'
##
##    def checkSetNewUserScalar(self):
##        """
##        Check whether a new <scalar label="ma_variable" type="user">
##        in the xmldoc could bet set.
##        """
##        root = self.case.root()
##        Variables(self.case).setNewUserScalar(root, 'scalar1')
##        node = root.xmlGetChildNode('scalar')
##        doc = '<scalar label="scalar1" type="user"/>'
##        assert node == self.xmlNodeFromString(doc),\
##           'Could not set the user scalar markups'
##
##    def checkSetNewProperty(self):
##        """
##        Check whether a new
##        <property name="my_property" label="ma_propriete">
##        in the xmldoc could bet set.
##        """
##        root = self.case.root()
##        Variables(self.case).setNewProperty(root, 'prop')
##        node = root.xmlGetChildNode('property')
##        truc = node.toString()
##        doc = '<property label="prop" name="prop"/>'
##        assert node == self.xmlNodeFromString(doc),\
##           'Could not set the property markups'
##
##    def checkSetNewFluidProperty(self):
##        """
##        Check whether a new
##        <property name="my_property" label="ma_propriete" choice="constant">
##        in the xmldoc could bet set.
##        """
##        root = self.case.root()
##        Variables(self.case).setNewFluidProperty(root, 'density')
##        node = root.xmlGetChildNode('property')
##        node['label'] = "toto"
##        doc = '<property choice="constant" label="toto" name="density">'\
##                '<listing_printing status="off"/>'\
##                '<postprocessing_recording status="off"/>'\
##                '</property>'
##        assert node == self.xmlNodeFromString(doc),\
##           'Could not set the fluid property markups'
##
##def suite():
##    testSuite = unittest.makeSuite(VariablesTestCase, "check")
##    return testSuite
##
##def runTest():
##    print "VariablesTestCase"
##    runner = unittest.TextTestRunner()
##    runner.run(suite())
##

#-------------------------------------------------------------------------------
# End of XMLvariables
#-------------------------------------------------------------------------------


syntax highlighted by Code2HTML, v. 0.9.1