#-----------------------------------------------------------------------------
# Name:        odexml.py
# Purpose:     Read and write model files in xml format
#
# Author:      Flavio Codeco Coelho
#
# Created:     2006/06/30
# RCS-ID:      $Id: odexml.py $ 
# Copyright:   (c) 2006
# Licence:     GPL
# New field:   Whatever
#-----------------------------------------------------------------------------
from xml.dom import minidom, Node
import __version__ as V
import wxversion
wxversion.select('2.6')
import wx, sys, os
from numpy import array

class Model:
    def __init__(self):
        self.model = minidom.Document()
        self.model.appendChild(self.model.createComment("Model Builder %s - model definition file"%V.version))
        self.body = self.model.createElement('body')
        self.model.appendChild(self.body)
        #output = self.model.createElement('output')
        #self.model.appendChild(output)
        self.modict = {}
        self.path = None
    def Create(self,**kwargs):
        """
        Creates all the elements and append to the 'body' section.
        Takes a dictionary or keyword elements as input.
        """
        eqlist = kwargs.pop('equations').split('\n')
        parlist = kwargs.pop('parameters').split('\n')
        #creating model name
        modelname = self.model.createElement('modelname')
        modelname.appendChild(self.model.createTextNode(kwargs.pop('modelname').strip()))
        self.body.appendChild(modelname)
        #creating equations
        for n,e in enumerate(eqlist):
            equation = self.model.createElement('equation')
            self.body.appendChild(equation)
            equation.setAttribute('number',str(n))
            equation.appendChild(self.model.createTextNode(e.strip()))
        #creating parameters
        for n,p in enumerate(parlist):
            parameter = self.model.createElement('parameter')
            self.body.appendChild(parameter)
            parameter.setAttribute('number',str(n))
            parameter.appendChild(self.model.createTextNode(p.strip()))
        # Creating others
        for k,v in kwargs.items():
            Key = self.model.createElement(k)
            self.body.appendChild(Key)
            Key.appendChild(self.model.createTextNode(str(v).strip()))
    def addResults(self,results):
        """
        appends results matrix to the xml file.
        """
        pass
    def saveFile(self,filename):
        """
        Saves the generated XML to disk.
        """
        os.chdir(self.path)
        #if os.path.exists(filename):
        #    os.unlink(filename)
        f = open(filename,'w')
        f.write(self.model.toprettyxml())
        f.close()
        print "saved file", filename, "at",self.path
        
    def readFile(self,filename):
        """
        read a model from an xml document.
        """
##        try:
        doc = minidom.parse(filename)
        print 'Done parsing'
        if self.Verify(doc):
            self.model = doc
            self.readFromDom()
            return 0
        else:
            print 'This is not a model file'
            return 1
##        except:
##            print 'There was a problem parsing the model file.',
##            print sys.exc_info()
##            return 2
            
    def readFromDom(self):
        """
        Prepares self.modict
        from the data contained in the 
        dom object.
        """
        equations = ''
        parameters = ''
        for child in self.model.getElementsByTagName('body')[0].childNodes:
            if child.nodeType == Node.ELEMENT_NODE:
                #print child.tagName
                if child.tagName == 'equation':
                    for node in child.childNodes:
                        equations += node.data.strip() +'\n'
                elif child.tagName == 'parameter':
                    for node in child.childNodes:
                        parameters += node.data.strip() +'\n'
                else:
                    for node in child.childNodes:
                        self.modict[child.tagName.encode('ascii','ignore')] = node.data.strip().encode('ascii','ignore')
            else: pass 
        self.modict['equations'] = equations[:-1]
        self.modict['parameters'] = parameters[:-1]
    
    def Verify(self,doc):
        """
        Check if the xml file was generated by modelbuilder
        """
        for child in doc.childNodes:
            if child.nodeType == Node.COMMENT_NODE:
                if child.data.startswith('Model Builder'):
                    if V.version not in child.data:
                        print 'this model was generated in a different version of Model Builder.'
                        return 2
                    else:
                        print 'verify ok!'
                        return 1
                else: 
                    print 'not a Model Builder file!!'
                    return 0
                

if __name__ == '__main__':
    m = Model() # add a call to run your script here
    m.Create(**{'modelname':'teste','equations':'x+y\nz+x','parameters':'1\n2\n3'})
    m.saveFile('modelo.xml')
    m.readFile('modelo.xml')
    print m.model.toprettyxml()
    print m.modict
