# -*- coding: iso-8859-1 -*-
#-------------------------------------------------------------------------------
#Copyright (C) 2002 - 2006, EDF/R&D/MFEE
#-------------------------------------------------------------------------------


"""
This module manages the differents possible outputs :
- listing printing
- post-processing and relationship with the FVM library
- monitoring points

This module defines the following classes:
- OutputControlModel
"""


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


import string, sys
from types import FloatType
from xml.dom.minidom import parse
import Tix
from Tkconstants import *

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

import Base.XMLmodel as XMLmodel

#-------------------------------------------------------------------------------
# Model class
#-------------------------------------------------------------------------------


class OutputControlModel:
    """
    Class for Variables and Scalar model initialization.
    """
    def __init__(self, case):
        """
        Constructor
        """
        self.case = case
        node_control  = self.case.xmlGetNode('analysis_control')
        self.node_out = node_control.xmlInitNode('output')
        self.dicoName = {}


    def defaultInitialValues(self):
        """
        Return in a dictionnary which contains default values.
        """
        default = {}
        default['listing_printing_frequency'] = 1
        default['postprocessing_frequency'] = -1
        default['probe_recording_frequency'] = 1
        default['postprocessing_options'] = "binary"
        default['postprocessing_format'] = "EnSight"
        default['fluid_domain'] = "on"
        default['domain_boundary'] = "off"
        default['syrthes_boundary'] = "on"

        return default


    def setListingFrequency(self, freq):
        self.node_out.xmlSetData('listing_printing_frequency', freq)


    def getListingFrequency(self):
        f = self.node_out.xmlGetInt('listing_printing_frequency')
        if not f:
            f = self.defaultInitialValues()['listing_printing_frequency']
            self.setListingFrequency(f)
        return f


    def setPostprocessingFrequency(self, freq):
        self.node_out.xmlSetData('postprocessing_frequency', freq)


    def getPostprocessingFrequency(self):
        f = self.node_out.xmlGetInt('postprocessing_frequency')
        if not f:
            f = self.defaultInitialValues()['postprocessing_frequency']
            self.setPostprocessingFrequency(f)
        return f


    def getFluidDomainPostProStatus(self):
        nod = self.node_out.xmlGetNode('fluid_domain', 'status')
        if not nod: 
            status = self.defaultInitialValues()['fluid_domain']
            self.setFluidDomainPostProStatus(status)
        else:
            status = nod['status']
        return status


    def setFluidDomainPostProStatus(self, status):
        node = self.node_out.xmlInitNode('fluid_domain', 'status')
        node['status'] = status


    def getDomainBoundaryPostProStatus(self):
        nod = self.node_out.xmlGetNode('domain_boundary', 'status')
        if not nod:
            status = self.defaultInitialValues()['domain_boundary']
            self.setDomainBoundaryPostProStatus(status)
        else:
            status = nod['status']
        return status


    def setDomainBoundaryPostProStatus(self, status):
        node = self.node_out.xmlInitNode('domain_boundary', 'status')
        node['status'] = status


    def getSyrthesBoundaryPostProStatus(self):
        nod = self.node_out.xmlGetNode('syrthes_boundary', 'status')
        if not nod: 
            status = self.defaultInitialValues()['syrthes_boundary']
            self.setSyrthesBoundaryPostProStatus(status)
        else:
            status = nod['status']
        return status


    def setSyrthesBoundaryPostProStatus(self, status):
        node = self.node_out.xmlInitNode('syrthes_boundary', 'status')
        node['status'] = status


    def getPostProFormat(self):
        node = self.node_out.xmlGetNode('postprocessing_format', 'choice')
        if not node:
            choice = self.defaultInitialValues()['postprocessing_format']
            self.setPostProFormat(choice)
        else:
            choice = node['choice']
        return choice


    def setPostProFormat(self, choice):
        node = self.node_out.xmlInitNode('postprocessing_format', 'choice')
        node['choice'] = choice


    def getPostProOptionsFormat(self):
        node = self.node_out.xmlGetNode('postprocessing_options', 'choice')
        if not node:
            line = self.defaultInitialValues()['postprocessing_options']
            self.setPostProOptionsFormat(line)
        else:
            line = node['choice']
        return line 


    def setPostProOptionsFormat(self, line):
        n = self.node_out.xmlInitNode('postprocessing_options', 'choice')
        n['choice'] = line


    def setMonitoringPointFrequency(self, freq):
        self.node_out.xmlSetData('probe_recording_frequency', freq)


    def getMonitoringPointFrequency(self):
        f = self.node_out.xmlGetInt('probe_recording_frequency')
        if not f:
            f = self.defaultInitialValues()['probe_recording_frequency']
            self.setMonitoringPointFrequency(f)
        return f


    def addMonitoringPoint(self, x=0.0, y=0.0, z=0.0):
        """
        Input a new monitoring point definition.
        """
        status="on"
        num = 1
        while (str(num)) in self.dicoName.keys(): num = num+1
        num = str(num)
        probe_num = 'item' + num
        self.dicoName[num] = probe_num
        
        node = self.node_out.xmlInitNode('probe', name=num, status=status)
        node.xmlSetData('probe_x', x)
        node.xmlSetData('probe_y', y)
        node.xmlSetData('probe_z', z)

        # we put probes on all variables, scalars and properties
        #
        for node in XMLmodel.XMLmodel(self.case).getAllVarScalProper(): 
            node.xmlInitNode('probe_recording', name=num)

        return int(num)


    def replaceMonitoringPointCoordinates(self, name=None, x=0.0, y=0.0, z=0.0):
        """
        Change the localization of a probe
        """
        if not name:
            print "replaceMonitoringPointCoordinates : pas de nom au point de monitoring"
            sys.exit(1)

        node = self.node_out.xmlGetNode('probe', name=name)
        node.xmlSetData('probe_x', x)
        node.xmlSetData('probe_y', y)
        node.xmlSetData('probe_z', z)

    def __deleteMonitoringPoint(self, n):
        node = self.node_out.xmlGetNode('probe', name=n)
        if node:
            node.xmlRemoveNode()
            self.case.xmlRemoveChild('probe_recording', name=n)
            del self.dicoName[n]


    def deleteMonitoringPointsList(self, nameList):
        """
        Destroy the definition of a monitoring points list
        """
        if not nameList: return
        for n in nameList:
            self.__deleteMonitoringPoint(n)

        # compactage du numero des points de monitorings
        listprob, dicocoord = [], {}
        for node in self.node_out.xmlGetNodeList('probe'):
            listprob.append(node['name'])
            dicocoord[node['name']] = (node.xmlGetDouble('probe_x'),
                                       node.xmlGetDouble('probe_y'),
                                       node.xmlGetDouble('probe_z'))
        listprob.sort()
        for n in range(len(listprob)):
            # si l'indice de rangement ne correspond pas à un point de monitoring ...
            if str(n+1) not in listprob:
                # alors on fait un décalage sur tous les points de monitoring suivants
                for num in range(n, len(listprob)):
                    for node in self.node_out.xmlGetNodeList('probe'):
                        if node['name'] == listprob[n]:
                            node['name'] = str(n+1)
                            prob = listprob[n]
                            node.xmlSetData('probe_x',dicocoord[prob][0])
                            node.xmlSetData('probe_y',dicocoord[prob][1])
                            node.xmlSetData('probe_z',dicocoord[prob][2])
                     
                    for node in self.case.xmlGetNodeList('probe_recording'):
                        if node['name'] == listprob[n]:
                            node['name'] = str(n+1)
                    listprob[n] = n+1

        #on réinitialise le dico pour le remplir avec les valeurs compactées
        self.dicoName = {}
        for n in range(len(listprob)):
            self.dicoName[str(n+1)] = 'item'+str(listprob[n])


    def getMonitoringPointInfo(self):
        """
        """
        X = []
        Y = []
        Z = []
        N = []
        for probe in self.node_out.xmlGetNodeList('probe'):
            X.append(probe.xmlGetDouble('probe_x'))
            Y.append(probe.xmlGetDouble('probe_y'))
            Z.append(probe.xmlGetDouble('probe_z'))
            num = probe['name']
            N.append(num)
            probe_num = 'item' + num
            self.dicoName[num] = probe_num

        return N, X, Y, Z

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


syntax highlighted by Code2HTML, v. 0.9.1