import stext;
import sexec;
import ecore;
import sgraph;
import base;

//TODO Workaround for error in Typesystem
String name(Declaration this) : this.metaType.getProperty("name").toString();
String name(Vertex this) : this.metaType.getProperty("name").toString();
String name(EObject this): this.metaType.getProperty("name").toString();

String name(Expression this):
	"/*Name of "+this+"*/";
String name(FeatureCall this):
	feature.name();
String name(ElementReferenceExpression this):
	reference.name();

ExecutionFlow getExecutionFlow(InterfaceScope this) : ((ExecutionFlow)this.eContainer);

String scName(Expression statement) : ((ExecutionFlow)statement.eRootContainer).name ;

List[EventDefinition] declaredEvents(ExecutionFlow flow) : flow.scopes.declarations.typeSelect(EventDefinition);
List[TimeEvent] declaredTimerEvents(ExecutionFlow flow) : flow.scopes.declarations.typeSelect(TimeEvent);
List[VariableDefinition] declaredVariables(ExecutionFlow flow) : flow.scopes.declarations.typeSelect(VariableDefinition);

String test(ecore::ENamedElement obj) :  "";
String StName(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toFirstUpper();// + "Statemachine";
String STNAME(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toUpperCase() + "STATEMACHINE";
String StNameEv(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toFirstUpper();// + "Statemachine_ev";
String StNameCy(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toFirstUpper();// + "Statemachine_cy";

String DRName(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toFirstUpper() + "DataRepository";
String DRNAME(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toUpperCase() + "DATAREPOSITORY";

String EvName(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toFirstUpper() + "Event";
String EVNAME(Object this) : ((ExecutionFlow)((EObject)this).eRootContainer).name.toUpperCase() + "EVENT";

cached String functionName(Step step) : 
	(step.isEffect()) ? step.actionFunctionName() : (
	(step.isReactionCheck()) ? step.checkFunctionName() : (
	(step.isEntryAction()) ? step.entryActionFunctionName() : ( 
	(step.isExitAction()) ? step.exitActionFunctionName() : (
	(step.isEnterSequence()) ? step.enterSequenceFunctionName() : ( 
	(step.isExitSequence()) ? step.exitSequenceFunctionName() : 	
	" !! unknown function type !!" )))));


String actionFunctionName(Step this) : "actions_" + this.reaction().state().simpleName + "_" + this.reaction().name; 
String checkFunctionName(Step this) : "condition_" + this.reaction().state().simpleName + "_" + this.reaction().name; 
String entryActionFunctionName(Step this) : "entryActions_" + this.state().simpleName; 
String exitActionFunctionName(Step this) : "exitActions_" + this.state().simpleName; 
String enterSequenceFunctionName(Step this) : "_enterSequence_" + this.state().simpleName; 
String exitSequenceFunctionName(Step this) : "_exitSequence_" + this.state().simpleName; 

boolean isEffect(Step step) : (! Check.isInstance(step)) && Reaction.isInstance(step.eContainer) ;
boolean isReactionCheck(Step step) : Reaction.isInstance(step.eContainer) && Check.isInstance(step);
boolean isEntryAction(Step step) : ExecutionState.isInstance(step.eContainer) && step.state().entryAction == step;
boolean isExitAction(Step step) : ExecutionState.isInstance(step.eContainer) && step.state().exitAction == step;
boolean isEnterSequence(Step step) : ExecutionState.isInstance(step.eContainer) && step.state().enterSequence == step;
boolean isExitSequence(Step step) : ExecutionState.isInstance(step.eContainer) && step.state().exitSequence == step;
  
Reaction reaction(Step this) : (Reaction) this.eContainer ;
ExecutionState state(Reaction this) : (ExecutionState) eContainer;
ExecutionState state(Step this) : (ExecutionState) eContainer;

String interfaceName(InterfaceScope this) : ((this.name == null) ? "_if" : "_if_" + this.name);
String interfaceClassName(InterfaceScope this) : "If" + ((this.name == null)?"":this.name.toFirstUpper());
String interfaceObjectName(InterfaceScope this) : "interface" + ((this.name == null)?"":this.name.toFirstUpper());

String getEventEnumName(EventDefinition this) : "ev_" + this.name.toFirstLower();
String getEventEnumName(TimeEvent this) : "ev_" + this.name.toFirstLower();

String getBoolTrue() : "bool_true";
String getBoolFalse() : "bool_false";

