# Export dia finite state machines into C state machines
#
# Copyright (c) 2012, Tomas Pospisek <tpo_deb@sourcepole.ch>
#
#   This program 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.
#
#   This program 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 this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


import dia
import uml_stm_export

class CDiagramRenderer(uml_stm_export.SimpleSTM):
    CODE_PREAMBLE = '''
// Machine generated file - do not edit!!!
// Generated by uml_stm_c_export.py script for Dia


void configure_statemachine( State_machine_t* stm )
{
    // STATES: 'state', 'action'
    //
'''
    TRANSITIONS_PREAMBLE = '''
    // TRANSITIONS: 'src state', 'trigger', 'target state'
    //
'''
    CODE_POSTAMBLE = '''
}
'''

    def __init__(self):
        uml_stm_export.SimpleSTM.__init__(self)
        self.filename = ""

    def begin_render (self, data, filename):
        self.filename = filename
        uml_stm_export.SimpleSTM.parse(self, data)
                   
    def end_render(self) :
        f = open(self.filename, "w")
        f.write(self.CODE_PREAMBLE)

        initial_state = None
        for transition in self.transitions:
            # specialcase initial transition -> create initial state
            if(transition.source == "INITIAL_STATE"):
                initial_state = self.states[transition.target]
                f.write("    add_initial_state( stm, %s, %s );\n" %
                    (initial_state.name, initial_state.doaction))

        for key in self.states.keys():
            state = self.states[key]
            # initial_state has already been output
            # TODO: the fact that state can be None looks like a bug to me
            if(state != None and state.name != initial_state.name):
                f.write("    add_state( stm, %s, %s );\n" %
                                                       (state.name, state.doaction))
                # (state.name, state.iaction, state.oaction, state.doaction)

        f.write(self.TRANSITIONS_PREAMBLE)

        for transition in self.transitions:
            # specialcase UNIVERSAL - this is a transition that's valid for all states
            if(transition.source == "INITIAL_STATE"):
                continue # skip the initial state transition
            f.write("    add_transition( stm, %s, %s, %s );\n" %
                (transition.source, transition.trigger, transition.target ))
            #   (transition.source, transition.trigger, transition.target, transition.action))

        f.write(self.CODE_POSTAMBLE)

        f.close()
        self.states = {}
        self.transitions = []

# dia-python keeps a reference to the renderer class and uses it on demand
dia.register_export("State Machine Cstma Dump", "c", CDiagramRenderer())
