/*plantCompiler.h
*Written By: Kris Eggert
*Creation Date: 5/7/09
*Last Revisions: 5/13/09
*
*
*NOTES:
* COMMENTS ARE SIMPLE DESCRIPTIONS TO
* BE UPDATED AT A LATER DATE
*/


#include "pns.h"
#include "petriNetSerializer.h"
#include "matrix.h"



////////////////////////////////////////////////////////////////////////
//Function: compileProcessArray
//
//Purpose: Generate the code for all plant processes
//
////////////////////////////////////////////////////////////////////////

void compileProcessArray(process **pnsArray, int nbrElements);



////////////////////////////////////////////////////////////////////////
//Function: compileSinglePlant
//
//Purpose: Generate the code for a single plant petrinet
//
////////////////////////////////////////////////////////////////////////

void compileSinglePlant(pns *pnsPlant, FILE* plantFile, char *includes);



//Adds a heading to the specified file
void createFileHeading(FILE* plantFilem, char *fileName);


//At this point, this function simply ends the main function
void finalizeFile(FILE* plantFile);


//Outpus the declarations/initializations of
//Two arrays of goto labels (stored as void * values)
//One array is for the place labels
//The other is for the transition labels
void createLblArrays(pns *pnsPlant, FILE *plantFile);


//Outputs the declarations/initializations of signal 
//related variables to the plantFile
//Also initializes supervisor pid to 1st command line argument
void createSignalVars(FILE* plantFile);


//Initializes Mutex Locks
void initMutexLocks(FILE* plantFile);

//Generates the c code to create the pns
//Outputs the generated code to the specified file
//Uses petrNetSerializer to generate pns code 
void createPNSCode(pns *pnsPlant, FILE* plantFile);

//Generate the main function signature
void createMain(FILE* plantFile);


//Generate the include statements
void createIncludes(FILE* plantFile, char *includes);

//Retrieve the includes statements from the file
void retrieveIncludes(FILE* plantFile, text *includes);



//Creates Global Variables
void createGlobals(FILE* plantFile);


//Creates the code to unbuffer stdin, stdout
void unbufferIO(FILE* plantFile);


//Creates the initial goto statement
//based on the initial marking
//Currently only one token is supported!
//If more than one detected, the first place occurrence is used
void genInitialStart(pns *pnsPlant, FILE* plantFile);

//Generates and outputs the code for each place label
//to the specified file
//i.e.
//      //Code for place 1
//      P0:
//      printf("This is PLACE 1!");
//      goto T0;
void genPlaceCode(pns *pnsPlant, FILE* plantFile);



//Retrieves the code associated with the passed place number (pnum)
//Outputs the code to the specified plantFile
//
//The code is retrieved using the text *segment member of the
//the pns struct.
void retrievePlaceCode(pns *pnsPlant, FILE* plantFile, int pnum);



//Create the goto transition statement at the end of the current
//place number (pnum) code
//
//Currently this function only supports a place outputting to only
//one transition. The code allows for this functionallity to later be
//added.
void createGotoTrans(pns *pnsPlant, FILE* plantFile, int pnum);




//Generates and outputs the code for each transition label
//to the specified file
//i.e.
//     //Code for Transition 0
//     T0:
//        ...TRANSITION ALGORITHM...
//
void genTransitionCode(pns *pnsPlant, FILE* plantFile);

//Generates all functions except main
void generateFunctions(pns* pnsPlant, FILE* plantFile);

//Generates and outputs the code for the following function:
            
//   int isEnabled(pns *pn, int tnum, int *___currentMarking)
//          
//    This function returns 1 (true) if the transition (tnum) is enabled
//    or 0 (false) if it is not
void genEnabledFunction(pns* pnsPlant,FILE* plantFile);


//Generates and outputs the code for the following function:
            
//    void handleSigUsr1(int signalNbr, siginfo_t* info, void *voidptr)
//          
//    Is the signal handler for the SIGUSR1 signal. Sets the ___FIRE_FLAG
//    to 1 if permission is given from supervisor to fire
void genHandlerFunction(FILE* plantFile);




//Generates and outputs the code for the following function:
            
//    void waitForPermission(sigset_t *___sMskPtr,pid_t ___pidSup,
//                           union sigval *____sValPtr);

//          
//    This function is the algorithm that causes the transition
//    to signal the supervisor and wait for permission from 
//    the supervisor to fire
void genSigWaitFunction(FILE* plantFile);



//Generates and outputs the code for the following function:
            
//    void waitForPermission(int ___lblNbr, int ___transNbr);

//          
//    This function is the algorithm that causes the transition
//    to signal the supervisor and wait for permission from 
//    the supervisor to fire
//    THIS DEFINITION OF FUNCTION FOR USE WITH UNNAMED PIPES
void genPipesWaitFunction(FILE* plantFile);



//Generates and outputs the code for the following function:
            
//    void updatePns(pns *___pnsPtr,int ___cTnum);

//          
//    This function correctly updates the current marking on the petri net.
//    This function should be called by a transition (___cTnum is the current
//    transition nbr)
void genUpdateFunction(FILE * plantFile);



//Generates and outputs the code for the following function:
            
//    int gotoCurrentMark(pns *___pnsPtr, int *currentMarking);

//          
//    This function returns an integer that indicates the place number
//    to begin at based on the current marking.
void genGotoCurrentMark(FILE *plantFile);


//Generates and outputs the code for the following function:
            
//   void initResArray();

//    This function returns intializes all values of reservations array to 0



void genInitResArray(FILE* plantFile);

//Generates and outputs the code for the following function:
            
//   int retrieveReservation();

//Returns the first available reservation id
void genRetrieveRes(FILE* plantFile);

//Outputs the function prototypes to plantFile
void genFunctionPrototype(FILE* plantFile);
