#!/usr/bin/env /usr/bin/ecell3-python

# $Id: eri2eml.in,v 1.3 2004/09/14 06:44:39 tishida Exp $
# Eri to Eml converter

import sys
import string
import re
import os
import time
import getopt
import types

from ecell.eml import *

#def convertFQEN2SystemID( aFQEN ):
#    aPathToSystem = aFQEN.split( ':' )[0]
#    aSystemSimpleID = aFQEN.split( ':' )[1]
#
#    if ( aPathToSystem == '/' ):
#        aSystemID = '/' +aSystemSimpleID
#    else:
#        asystemID = aPathToSystem + '/' +aSystemSimpleID
#    return aSystemID


def appendUnderScore( aString ):
    if ( re.match( r'^[0-9]', aString ) != None ):
        return '_' + aString
    else:
        return aString

def replaceProhibitLetter( aString ):
    replacedString = re.sub( r'[-+.,!]', '_', aString)
    return appendUnderScore( replacedString )


if __name__ == '__main__':


    def usage():
        aProgramName = os.path.basename( sys.argv[0] )

        print '''
%s -- conver eri to eml (for E-Cell SE version 1 user)

Usage:
       %s [-h] [-f] [-o outfile] infile

Options:
       -h or --help    : Print this message.
       -f or --force   : Force overwrite even if outfile already exists.
       -o or --outfile=: specify output file name. '-' means stdout.
       
''' % ( aProgramName, aProgramName )


    # commandline processing
    try:
        opts, args = getopt.getopt( sys.argv[1:], "hfo:",
                                    ["help","force","outfile="] )
    except getopt.GetoptError:
        usage()
        sys.exit( 1 )


    anEmlFileName = None
    aForceFlag = 0

    for anOption, anArg in opts:
        if anOption in ( "-h", '--help' ):
            usage()
            sys.exit( 0 )

        if anOption in ( "-f", '--force' ):
            aForceFlag = 1

        if anOption in ( "-o", "--outfile" ):
            anEmlFileName = anArg

    if len( args ) == 0:
        sys.stderr.write("No input File.\n")
        usage()
        sys.exit( 1 )

    anEriFileName = args[0]


    anEriFile = open( anEriFileName )
    anEriData = anEriFile.readlines()
    anEriFile.close()

    aBaseName = os.path.basename( anEriFileName )
    aBaseName, anExt = os.path.splitext( aBaseName )

    if anEmlFileName == None:
        if anExt == '.eri':
            anExt = '.eml'
        else:
            anExt += '.eml'

        anEmlFileName = aBaseName + anExt


#    if anEriFileName == '-':
#        anEmlFile = sys.stdout
#    else:
#        if os.path.isfile( anEmlFileName ) and aForceFlag == 0:
#            sys.stderr.write("Output file %s exists. Use -f to overwrite.\n"
#                             % anEmlFileName )
#            sys.exit( 1 )

#        anEmlFile = open( anEmlFileName, 'w' )
#
#    aBuffer = '''
## created by eri2eml program
## from file: %s, date: %s
##
#''' % ( anEriFileName, time.asctime( time.localtime() ) )
#
#    try:
#


    # eri2eml main   
    anEriStrings = []
    for anEriLineData in anEriData:
        anEriLineWord = anEriLineData.split('\t')
        anEriStrings.append(anEriLineWord)

    anEml = Eml()

    anEml.createStepper( 'FixedODE1Stepper', 'SRM_01')

    aSystemFullID='System::/'
    anEml.createEntity( 'System', aSystemFullID )
    anEml.setEntityProperty( aSystemFullID, 'StepperID', ['SRM_01'] )
    anEml.setEntityProperty( aSystemFullID, 'Name', ['Root System'] )

    for anEriLine in anEriStrings:
        if ( anEriLine[0] == 'SYSTEM' ):
#           aSystemID = replaceProhibitLetter( anEriLine[2] )
#           print aSystemID
            aSystemFullID = 'System:' +anEriLine[2]                
            anEml.createEntity( 'System', aSystemFullID )
            anEml.setEntityProperty( aSystemFullID, 'StepperID', ['SRM_01'] )
            anEml.setEntityProperty( aSystemFullID, 'Name', anEriLine[3:4] )
            
        elif ( anEriLine[0] == 'SUBSTANCE' ):
            aSystemID = replaceProhibitLetter( anEriLine[2] )
#            print aSystemID
            aSystemFullID = 'Variable:' +aSystemID
            anEriChunk = anEriLine[4].split()
            anEml.createEntity( 'Variable', aSystemFullID )
#            anEml.setEntityProperty( aSystemFullID, anEriChunk[0], anEriChunk[1:] )
            anEml.setEntityProperty( aSystemFullID, 'Value', anEriChunk[1:] )
#            print anEriLine[3:4]
            anEml.setEntityProperty( aSystemFullID, 'Name', anEriLine[3:4] )
        
        elif ( anEriLine[0] == 'REACTOR' ):
            aSystemID = replaceProhibitLetter( anEriLine[2] )
            aSystemFullID = 'Process:' +aSystemID
            if ( anEriLine[1] == 'ConstantParameterReactor' ): # set Volume of the System.
                aSystemID = anEriLine[2].split(':')[0]
#                if ( aSystemID == '/ENVIRONMENT'):
#                    aSystemFullID = 'System::/'    # /ENVIRONMENT set as the RootSystem
#                else:
#                    aSystemFullID = convertSystemID2SystemFullID( aSystemID )

                aVariableFullID = 'Variable:' + aSystemID + ':SIZE' # Volume is set as Variable(SIZE)
                anEml.createEntity( 'Variable', aVariableFullID )
                
                anEriChunk = anEriLine[4].split()
                anEml.setEntityProperty( aVariableFullID, 'Value', anEriChunk[1:] )
                
            else:                                              # set other parameters
                anEml.createEntity( anEriLine[1], aSystemFullID )
                anEml.setEntityProperty( aSystemFullID, 'Name', anEriLine[3:4] )

                # create VariableReferenceList from Eri data
                aVariableReferenceList = []
                aSubstrateNumber = 0
                aProductNumber = 0
                aCatalystNumber = 0
                anEffectorNumber =0
        
                for anEriChunk in anEriLine[4:]:
                    anEriChunkElement = anEriChunk.split()
                    if ( anEriChunkElement[0] == 'Substrate' ):
                        aSubstrateList = []
                        aSubstrateList.append( 'S' + str(aSubstrateNumber) )
                        aSubstrateNumber = aSubstrateNumber + 1
                        aSubstrateID = replaceProhibitLetter( anEriChunkElement[1] )
                        aSubstrateList.append( 'Variable:' + aSubstrateID )
                        aSubstrateList.append( str(-1 * int(anEriChunkElement[2])) )
                        aVariableReferenceList.append( aSubstrateList )
                    elif ( anEriChunkElement[0] == 'Product' ):
                        aProductList = []
                        aProductList.append( 'P' + str(aProductNumber) )
                        aProductNumber = aProductNumber + 1
                        aProductID = replaceProhibitLetter( anEriChunkElement[1] )
                        aProductList.append( 'Variable:' + aProductID )
                        aProductList.append( str(1 * int(anEriChunkElement[2])) )
                        aVariableReferenceList.append( aProductList )

                    elif ( anEriChunkElement[0] == 'Catalyst' ):
                        aCatalystList = []
                        aCatalystList.append( 'C' + str(aCatalystNumber) )
                        aCatalystNumber = aCatalystNumber + 1
                        aCatalystID =replaceProhibitLetter( anEriChunkElement[1] ) 
                        aCatalystList.append( 'Variable:' + aCatalystID )
                        aCatalystList.append( '0' )
                        aVariableReferenceList.append( aCatalystList )

                    elif ( anEriChunkElement[0] == 'Effector' ):
                        anEffectorList = []
                        anEffectorList.append( 'E' + str(anEffectorNumber) )
                        anEffectorNumber = anEffectorNumber + 1
                        anEffectorID = replaceProhibitLetter( anEriChunkElement[1] )
                        anEffectorList.append( 'Variable:' + anEffectorID )
                        anEffectorList.append( '0' )
                        aVariableReferenceList.append( anEffectorList )

                    else:
                        aPropertyID = replaceProhibitLetter( anEriChunkElement[0] )
                        anEml.setEntityProperty( aSystemFullID, aPropertyID, anEriChunkElement[1:] )

                # set VariableReferenceList
                anEml.setEntityProperty( aSystemFullID, 'VariableReferenceList', aVariableReferenceList )
    else: 
        pass



    anEml.save( anEmlFileName )
#        aString = anEml.asString()

#        print aString


