/* dynState.c */

#include "dynState.h"
#include <stdio.h>


/*
 * Exit on null pointer exception.
 */
void exitOnFatalNullPointerException() {
  puts("exitOnFatalNullPointerException");
  exit();
}



/*
 * Allocate memory and initialize state with name etc.
 * *stateName       - pointer to char array representing the name of the state
 *
 * return Value:      pointer to new state or NULL, respectively
 */
State *newState(char *stateName) {
  State *state = (State *)malloc(sizeof(State));

  if (state == NULL) {
    exitOnFatalNullPointerException();
  }
  state->name = (char *)malloc(sizeof(strlen(stateName) + 1) * sizeof(char));
  if (stateName == NULL) {
    exitOnFatalNullPointerException();
  }
  strcpy(state->name, stateName);
  state->nofStates = 0;
  state->arr = NULL;
}



/*
 * Free previously allocated memory.
 * *state           - pointer to state
 */
void deleteState(State *state) {
  free(state->name);
  free(state->arr);
  free(state);
}



/*
 * Connect the fromState with the toState. Direction is from .. to.
 * If connections are made to several states, connections are numbered
 * starting with 0.
 * *fromState       - pointer to state from where to start when traversing
 * *toState         - pointer to state to where to arrive when traversing
 */
void connectStates(State *fromState, State *toState) {
  if (fromState->nofStates == 0) {
    fromState->arr = (State **)malloc(sizeof(State *));
  }
  else {
    fromState->arr =
      (State **)realloc(fromState->arr, sizeof(State *) * fromState->nofStates);
  }

  if (fromState->arr == NULL) {
    exitOnFatalNullPointerException();
  }
  *(fromState->arr + fromState->nofStates) = toState;

  fromState->nofStates++;
}



/*
 * Print the name of the state.
 * *state           - pointer to state
 */
void printStateName(State *state) {
  printf("%s\n", state->name);
}



/*
 * Print the name of the state between stars.
 * *state           - pointer to state
 */
void printStateNameBetweenStars(State *state) {
  printf("*%s*\n", state->name);
}



/*
 * Visit several states starting from firstState proceeding to next state
 * according the steering array stateIndicesArray. In arriving at a state
 * (except firstState), the action is performed which *outFctPtr is poining
 * to. Repeat for all array indices.
 * *firstState      - pointer to state where to start visiting (traversing)
 *                    from
 * *stateIndicesArray - array containing indices. Each index steers which
 *                    connection in a state to choose next. Order (and index)
 *                    of connections are determined when connecting states.
 * arrSize          - size of the array stateIndicesArray
 * (*outFctPtr)()   - pointer to function to (output) action when visiting
 *                    a state
 */
void visitStates(State *firstState, int *stateIndicesArr, int arrSize, void (*outFctPtr)()) {
  int i;
  State *nextState;

  nextState = firstState;
  for (i = 0; i < arrSize; ++i) {
    nextState = nextState->arr[stateIndicesArr[i]];
    (* outFctPtr)(nextState);
  }
}
