==JZcmd==
##Note: stm is a script variable which is filled by the stateMgen conversion control routine which calls this script.
##stm is type of org.vishia.stateMGen.StateMGen$GenStateMachine. See the maybe written report file of data structure
##given by command line arg checkdata:result/data_StatemSrc.html (data_StatemSrc.dst.html).


##!checkJZcmd = "result/check_States.genC.txt";
##!checkXml = <:><&currdir>/check_States.genC.xml<.>;

Filepath outfile = &sOutfile; ##sOutfile is defined in the java calling environment: path to the out file which is
  written by <+>...<.+>

String stateMethodSuffix = stm.zbnfSrc.variables.StateMethodSuffix;

Class classStateComposite = org.vishia.states.StateComposite;   ##used for instanceof check
Class classStateCompositeFlat = org.vishia.states.StateCompositeFlat;   ##used for instanceof check
Class classStateParallel = org.vishia.states.StateParallel;  ##used for instanceof check




main(){
    <+><:s>
:::://This file is generated from StateMGen.java 
::::<.+>
  for(includeline:stm.zbnfSrc.includeLines) 
  { <+>
::::#include <&includeline><.+>
  }
    <+>  
::::    
::::#include "<&outfile.name()>.h"  //include the generated header file.
::::
:::://all entry-prototypes:<.+>
  for(state: stm.listStates)
  {
    <+>
::::void entry_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>);<.+>
  }
    <+>
::::<.+>  
  for(state: stm.listStates)
  { <+>
::::void exit_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>);<.+>
  }
    <+>
::::
::::<.+>
  for(state: stm.listStates)
  { Obj zsrcState = state.auxInfo().zsrcState; 
    if(state ?instanceof classStateParallel) {
      <+>
::::::    
::::::    
:::::://genStateM: stateParallel    
::::::static void entry_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ //genStateM: entry StateParallel. 
::::::  <&stm.zbnfSrc.variables.StateInstance>.state<&state.rootState.stateId> =
  k<&state.stateId>_<&stm.zbnfSrc.variables.StateSubStruct>;
::::::  #ifdef __DEBUG_entryprintf_States_Fwc__
::::::    printf(" entry <&state.stateId>; parallel\n");
::::::  #endif
::::::}
::::::
::::::
::::::INLINE_Fwc void exit_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ //genStateM: it is a parallelState , it is its own rootstate: <&state.rootState.stateId> 
::::::  //<&stm.zbnfSrc.variables.StateInstance>.state<&state.stateId> = 0;  //if a parallel state has a history, set
  bit and preserve state nr
::::::  #ifdef __DEBUG_entryprintf_States_Fwc__
::::::    printf("   exit <&state.stateId>;\n");
::::::  #endif
::::::}
::::::
::::::
::::::INLINE_Fwc int trans_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ //genStateM: parallelState
::::::  //TODO transitions
::::::  return 0;
::::::}
::::::
::::::
::::::<.+>
    } else {  //normal, non parallel, composite or simple:
      <+>
::::::    
::::::    
::::::    
::::::static void entry_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ //genStateM: entry StateComposite or StateSimple. <.+>
      if(state.rootState) { ##check whether it is not null. It is null on a parallel state or the stateTop.             
                                             
        <+>
::::::::  <&stm.zbnfSrc.variables.StateInstance>.state<&state.rootState.stateId> =
  k<&state.stateId>_<&stm.zbnfSrc.variables.StateSubStruct>;<.+>
      }
      if(state.auxInfo().timeCondition) { 
        <+>
::::::::  <&stm.zbnfSrc.variables.StateInstance>.timer<&state.rootState.stateId> = <&state.auxInfo().timeCondition>;<.+>
   
      } //timeCondition
      <+>
::::::  <&state.auxInfo().zsrcState.entry.code>
::::::  #ifdef __DEBUG_entryprintf_States_Fwc__
::::::    printf(" entry <&state.stateId>;\n");
::::::  #endif
::::::}
::::::
::::::INLINE_Fwc void exit_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ 
::::::  #ifdef __DEBUG_entryprintf_States_Fwc__
::::::    printf("   exit <&state.stateId>;\n");
::::::  #endif<.+>
      if(zsrcState.hasHistory) {
        <+>
::::::::  //It is a composite state with a history state. Mark the state number with the inactive bit:
::::::::  <&stm.zbnfSrc.variables.StateInstance>.state<&state.stateId> |= 0x80000000; <.+>
      } elsif(state.aParallelStates) {                       
        <+>
::::::::  //It is a composite state without a history state. Set the state number to zero.
::::::::  <&stm.zbnfSrc.variables.StateInstance>.state<&stateComposite.stateId> = 0; <.+>
      }
      <+>
::::::  <&state.auxInfo().zsrcState.exit.code>
::::::}
::::::<.+>

      <+>
::::::
::::::
::::::INLINE_Fwc int trans_<&state.stateId><&stateMethodSuffix>(<:subtext:stateMethodArguments>)
::::::{ int trans = 0;
::::::  //genStateM: check all conditions of transitions, return on transition with != 0<.+>    
        if(zsrcState.hasHistory || state.aParallelstates) { 
        <+>
::::::::  //xxx trans =
  switchStates_<&state.stateId><&stm.zbnfSrc.variables.StateSubStruct>(<&stm.zbnfSrc.callingArgs>);<.+>     
        }
        Obj stateOwn = state;
        do {  //for own state and all enclosing states
          if(state.aTransitions) {
            for(trans: state.aTransitions) {
              if(trans.zsrcTrans.cond) { 
                <+>  
::::::::::::::::  if(<&trans.zsrcTrans.cond>) {<.+>
                call genTransitionFire(trans = trans);
                <+>
::::::::::::::::  }
::::::::::::::::  else <.+>
              } elsif(trans.zsrcTrans.time) {             
                <+>
::::::::::::::::  if(<&stm.zbnfSrc.variables.StateInstance>.timer<&state.rootState.stateId> <0) {<.+>
                call genTransitionFire(trans = trans);
                <+>
::::::::::::::::  }
::::::::::::::::  else <.+>
              }
            } ##for(state.transitions)           
          } else {                                      
            <+>
::::::::::::  //genStateM: no transitions.<.+>
          }//if state.aTransitions
          
          if(state.transJoins) {
            for(trans: state.transJoins) {                  
              <+>
::::::::::::::  //StateMGen: join transition
::::::::::::::  if(<.+>
              if(trans.zsrcTrans.cond) {                  
::::::::::::::::<+><&trans.zsrcTrans.cond> <.+>
              } else {  
::::::::::::::::<+>true <.+>
              }
              for(joinState: trans.joinStates) {          
::::::::::::::::<+>&& <&stm.zbnfSrc.variables.StateInstance>.state<&joinState.rootState.stateId> <:s>
::::::::::::::::== k<&joinState.auxInfo().zsrcState.stateName>_<&stm.zbnfSrc.variables.StateSubStruct> <.+>
              }  
::::::::::::::::<+>) {<.+>
              call genTransitionFire(trans = trans);
              <+>
::::::::::::::  }
::::::::::::::  else <.+>
            } ##for(state.transitions)           
          }//if state.transJoins
          
          state = state.enclState;  //all transitions of StateCompositeFlat
          if(state ?instanceof classStateComposite || state ?instanceof classStateParallel) {
            state = null;
          } else {                                      
            <+>
::::::::::::  //genStateM: transitions of enclosing state: <&state.stateId><.+>
          }
        } while(state);  
        <+>
::::::::  { //StateMGen: action in state. No transition switched.
::::::::    <&stateOwn.auxInfo().zsrcState.instate.code>
::::::::  }
::::::::  return trans;                           
::::::::}
::::::::
::::::::
::::::::<.+>
    }##NOT stateParallel
  }##for all states


    <+>
:::://This method should be called in any step time. It decrements all timer which are set.
:::://
::::void stepStateTimer_<&stm.zbnfSrc.variables.StateSubStruct>( <:subtext:stateMethodArguments> )
::::{<.+>
      for(rootState: stm.rootStates) {
        Obj srcState = rootState.auxInfo();
        if(srcState.hasTimer) { 
          String timer = <:><&stm.zbnfSrc.variables.StateInstance>.timer<&rootState.stateId><.>;
          <+>
        ::::  if(<&timer> >=0) { 
        ::::    <&timer> -=1; 
        ::::  }<.+>        
      } }
    <+>
::::
::::}
::::
::::
::::
::::
::::
:::://Note: html-anchor is regarded from text2Html to produce an anchor for hyperlink.

::::int stepStates_<&stm.zbnfSrc.variables.StateSubStruct>( <:subtext:stateMethodArguments> )
  //html-anchor="stepStates"<.+>
    call switchStatesMethodBody(stateComposite = stm.stateTop, recurs =1);
  <+>
::::<.+>
  
  
} ##main






sub stateMethodArguments()
{ 
  for(arg:stm.zbnfSrc.statefnargs) { <:><&arg><:hasNext>, <.hasNext><.>; }
}



sub genTransitionFire(Obj trans) 
{
   for(exitState:trans.exitStates) {           <+>
                            ::::::    exit_<&exitState.stateId><&stateMethodSuffix>(<&stm.zbnfSrc.callingArgs>);<.+>  
   }                                           <+>  
                            ::::::    <:if:trans.zsrcTrans><&trans.zsrcTrans.code><.if><.+>
   for(entryState:trans.entryStates) {         <+>
                            ::::::    entry_<&entryState.stateId><&stateMethodSuffix>(<&stm.zbnfSrc.callingArgs>);<.+>  
   }                                           <+>    
                            ::::::    trans = mTransit_States_Fwc; <.+>
}



 

sub switchStatesMethodBody(Obj stateComposite, Num recurs = 0)
{                                           <+>
                            ::::::{ int trans = 0;                //set to true if transition has fired.<.+>
  call switchStates(stateComposite = stateComposite, recurs =0);
                            <+>
                            ::::::  return trans;
                            ::::::}<.+>
}
  

sub switchStates(Obj stateComposite, Num recurs = 0)
{ if(stateComposite.aSubstates && stateComposite.aSubstates.length()>0) {
    //only if it has aSubstates:            <+>
                            ::::::<:@2*recurs>  int ctSwitchState = 10;     //prevent too many transitions - a endless
                              loop
                            ::::::<:@2*recurs>  do { 
                            ::::::<:@2*recurs>    trans &= ~mTransit_States_Fwc;
                            ::::<:@2*recurs>   
                              switch(<&stm.zbnfSrc.variables.StateInstance>.state<&stateComposite.stateId>) {
                            ::::<:@2*recurs>               //if the state was entried newly without define an inner
                              state, then the statedefault will be entered now.
                            ::::<:@2*recurs>               //Note that the default state cannot be entered on entry
                              action because it is unknown in that time
                            ::::<:@2*recurs>               //whether there will be an entry to a designated state.
                            ::::<:@2*recurs>      case 0:
                              entry_<&stateComposite.stateDefault><&stateMethodSuffix>(<&stm.zbnfSrc.callingArgs>);
                              //without break, do trans:
                            ::::<:@2*recurs>      //switch to the current state:<.+>
    call switchCaseState(stateComposite = stateComposite, recurs = recurs+2);
                            <+>
                            ::::::<:@2*recurs>    } //switch    
                            ::::::<:@2*recurs>  } while((trans & mTransit_States_Fwc)    //continue checking transitions
                              if one of the has fired, it is run to completion.
                            ::::::<:@2*recurs>      &&
                              <&stm.zbnfSrc.variables.StateInstance>.state<&stateComposite.stateId> !=0  //don't
                              continue if the composite is inactive now.
                            ::::::<:@2*recurs>      && --ctSwitchState >0);     //don't execute too may loops, only a
                              safety check. <.+>
  }                                         <+>
                            ::::::<:@2*recurs>  //
                            ::::::<:@2*recurs>  //for all parallel states: switch only if this state is the active one
                              still. Regard a leave of the state from any substate.<.+> 
##  for(state : stateComposite.aParallelstates) {
##                                            <+>
##                                      :::::: 
  if(<&stm.zbnfSrc.variables.StateInstance>.state<&state.rootState.stateId> ==
  k<&stateComposite.stateId>_State<&stateMethodSuffix>)  
##                                  ::::::::::  { switch_<&state.stateId><&stm.zbnfSrc.variables.StateSubStruct>(
  <&stm.zbnfSrc.callingArgs> ); }<.+>
##  }                                       
}






sub switchCaseState(Obj stateComposite, Num recurs = 0)
{
  for(state : stateComposite.aSubstates) {
    Obj zsrcState = state.auxInfo().zsrcState; 
    if(state ?instanceof classStateComposite) { ##zsrcState.hasHistory || zsrcState.parallelParentState) {  
      //an innner switch-case:                                           <+>
                            ::::::::::<:@2*recurs>  case k<&state.stateId>_State<&stateMethodSuffix>: { <.+>
      call switchStates(stateComposite = state, recurs = recurs+1);      <+>
                            ::::::::::<:@2*recurs>  } break; //composite state<.+>
    } elsif(state ?instanceof classStateCompositeFlat) {
      //it has not an own case!
      call switchCaseState(stateComposite = state, recurs = recurs);   //all case of composite:     
    } elsif(state ?instanceof classStateParallel) {                     <+>
                            ::::::::::<:@2*recurs>  case k<&state.stateId>_State<&stateMethodSuffix>: {<.+>
      for(stateParallel: state.aParallelstates) {           <+>
                            ::::::::::<:@2*recurs>     { //genStateM: Parallel state switch<.+>
        call switchStates(stateComposite = stateParallel, recurs = recurs+3);
                            <+>
                            ::::::::::<:@2*recurs>     }<.+>
      }
                            <+>
                            ::::::::::<:@2*recurs>    trans |=
                              trans_<&state.stateId><&stateMethodSuffix>(<&stm.zbnfSrc.callingArgs>); 
                            ::::::::::<:@2*recurs>  } break; <.+>      
    } else { //StateSimple                                    <+>
                            ::::::::::<:@2*recurs>  case k<&state.stateId>_State<&stateMethodSuffix>: trans |=
                              trans_<&state.stateId><&stateMethodSuffix>(<&stm.zbnfSrc.callingArgs>); break;<.+>      
    }
  }
  ##for(state : stateComposite.aParallelstates) {
  ##                                                                        <+>
  ##                                                  ::::::::::<:@2*recurs>    //parallelState state<&state.stateId>
  ##                                                  ::::::::::<:@2*recurs>   
    switch_<&state.stateId><&stm.zbnfSrc.variables.StateSubStruct>( <&stm.zsrdFile.callingArgs> )<.+>
  ##  //call switchStates(stateComposite = state, recurs = recurs+1);
  ##}
}