 /*      
 *          Copyright (C) 2001 RasSimTech Ltd. 
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 */


//   $Revision: 1.0.1 $  $Date: 2001/03/31 00:00:00 $

#define S_FUNCTION_NAME AVDSPlaybackSetupBlock
#define S_FUNCTION_LEVEL 2


#include <afxwin.h>         // MFC core and standard components
#include <fstream>	// ofstream
#include <iomanip>	//setw
#include <sys/stat.h>	//chmod
#include <io.h>	//chmod
using namespace std;

#include "simstruc.h"

#include "Simulink2PlaybackDefs.h"

#define SAMPLE_TIME 0.0


///////////////////////////////////////////////////////////////////////////////////////
////////////////////////////   PARAMETER DEFINITIONS      //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

enum enParameters {
					paramConfigurationFileName,
					paramDataFileNameBase,
					paramNumberVehicles,
					paramTotalParameters};

#define PARAM_CONFIGURATION_FILE_NAME(S) ssGetSFcnParam(S,paramConfigurationFileName)
#define PARAM_DATA_FILE_NAME_BASE(S) ssGetSFcnParam(S,paramDataFileNameBase)
#define PARAM_NUMBER_VEHICLES(S) ssGetSFcnParam(S,paramNumberVehicles)
 



////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////   INPUT/OUTPUT DEFINITIONS   //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

// NOT USING INPUTS OR OUTPUTS
enum enInputs {	
				inTotalInputs };

enum enOutputs { 
				outTotalOutputs };


extern "C"
{
	void mdlStart(SimStruct *S);
	void mdlInitializeSizes(SimStruct *S);
	void mdlInitializeSampleTimes(SimStruct *S);
	void mdlInitializeConditions(SimStruct *S);
	void mdlOutputs(SimStruct *S, int_T tid);
	void mdlUpdate(SimStruct *S, int_T tid);
	void mdlTerminate(SimStruct *S);
	void mdlCheckParameters(SimStruct *S);
}


/*====================*
 * S-function methods *
 *====================*/

#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
	/* Function: mdlCheckParameters =============================================
	 * Abstract:
	 *    Validate our parameters to verify they are okay.
	*/
	static void mdlCheckParameters(SimStruct *S)
	{
      /* Check 1st parameter: Playback Configuration File Name */
      {
          if (!mxIsChar(PARAM_CONFIGURATION_FILE_NAME(S)) != 1) 
		  {
              ssSetErrorStatus(S,"1st parameter to the AVDSPlaybackSetupBlock must be the "
                               "Playback Configuration File Name.");
              return;
          }
      }
      /* Check 2nd parameter: Base File Name  */
      {
          if (!mxIsChar(PARAM_DATA_FILE_NAME_BASE(S)) != 1) 
		  {
              ssSetErrorStatus(S,"2nd parameter to the AVDSPlaybackSetupBlock must be the "
                               "Base File Name for the data file.");
              return;
          }
      }
      /* Check 3rd parameter: number of vehicles */
      {
          if (!mxIsDouble(PARAM_NUMBER_VEHICLES(S)) || mxGetNumberOfElements(PARAM_NUMBER_VEHICLES(S)) != 1) 
		  {
              ssSetErrorStatus(S,"3rd parameter to the AVDSPlaybackSetupBlock must be the "
                               "number of vehicles to include in the .ply.ini file");
              return;
          }
      }
	}
#endif /* MDL_CHECK_PARAMETERS */


 
/* Function: mdlInitializeSizes ===============================================
 * Abstract:
 *    The sizes information is used by Simulink to determine the S-function
 *    block's characteristics (number of inputs, outputs, states, etc.).
 */
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, paramTotalParameters);  /* Number of expected parameters */

	ssSetNumContStates(S, 0);	// number continuous
    ssSetNumDiscStates(S, 0);	// number discrete states

    if (!ssSetNumInputPorts(S, 1)) 
	{
		return;
	}

    ssSetInputPortWidth(S, 0, 1);
    ssSetInputPortDirectFeedThrough(S, 0, 1);	//not optional in R12

    if (!ssSetNumOutputPorts(S, 1))
	{
		return;
	}
    ssSetOutputPortWidth(S, 0, 1);


    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);

    /* Take care when specifying exception free code - see sfuntmpl.doc */
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}


#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ========================================
 * Abstract:
 *    Initialize both continuous states to zero.
 */
static void mdlInitializeConditions(SimStruct *S)
{
}

/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    Specifiy that we inherit our sample time from the driving block.
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
}

#define MDL_START  /* Change to #undef to remove function */
#if defined(MDL_START) 
  /* Function: mdlStart =======================================================
   * Abstract:
   *    This function is called once at start of model execution. If you
   *    have states that should be initialized once, this is the place
   *    to do it.
   */
static void mdlStart(SimStruct *S)
{
	char caConfigurationFileName[256];
	mxGetString(PARAM_CONFIGURATION_FILE_NAME(S),caConfigurationFileName,256);


	ofstream* ofsOutToFile;
	ofsOutToFile = new ofstream(caConfigurationFileName,ios::out);
	//ofsOutToFile = new ofstream(caConfigurationFileName,ios::out,ios_base::ate );

#ifndef STEVETEST
	*ofsOutToFile << "[Block 1]" << endl;
	*ofsOutToFile << "Block Label=Network Block" << endl << endl;
	*ofsOutToFile << "[Block 2]" << endl;
	*ofsOutToFile << "Block Label=Display Charts" << endl;
	*ofsOutToFile << "Gallery:1=9109505" << endl;
	*ofsOutToFile << "Line Width:1=2" << endl;
	*ofsOutToFile << "Line Style:1=38469632" << endl;
	*ofsOutToFile << "Marker Shape:1=9109504" << endl;
	*ofsOutToFile << "Marker Size:1=3" << endl;
	*ofsOutToFile << "Marker Step:1=1" << endl;
	*ofsOutToFile << "Grid:1=9109505" << endl;
	*ofsOutToFile << "Title:1=(Right-Click in Chart Area for Menu)" << endl;
	*ofsOutToFile << "Chart3D:1=0" << endl;
	*ofsOutToFile << "Legend Visible:1=-1" << endl;
	*ofsOutToFile << "Legend Docked:1=256" << endl;
	*ofsOutToFile << "Y Axis Autoscale:1=0" << endl;
	*ofsOutToFile << "Y Axis Maximum:1=800" << endl;
	*ofsOutToFile << "Y Axis Minimum:1=-150" << endl;
	*ofsOutToFile << "Chart Refresh Rate=5" << endl;
	*ofsOutToFile << "X Increment=5" << endl;
	*ofsOutToFile << "Number of Charts=1" << endl << endl;
	*ofsOutToFile << "[Block 3]" << endl;
	*ofsOutToFile << "Block Label=AVDS Playback Block" << endl;

	char caDataFileNameBase[256];
	mxGetString(PARAM_DATA_FILE_NAME_BASE(S),caDataFileNameBase,256);
	int iNumberVehicles = (int)*mxGetPr(PARAM_NUMBER_VEHICLES(S));

	for (int iCount=0;iCount<iNumberVehicles;iCount++)
	{
		CString cstrDataFileName;
		cstrDataFileName.Format("%s%0.2d.dat",caDataFileNameBase,iCount+1);

		*ofsOutToFile << "Entity:" << (iCount+1) << ":DataFile=" << cstrDataFileName << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Time Type=Elapsed" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:time=1:1" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:x=1:2" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:y=1:3" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:z=1:4" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:xrot=1:5" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:yrot=1:6" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:zrot=1:7" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:craftmask=1:8" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:crafttype=1:9" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:eng=1:10" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:alpha=1:11" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:beta=1:12" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:G=1:13" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:V=1:14" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:M=1:15" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc01=1:16" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc02=1:17" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc03=1:18" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc04=1:19" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc05=1:20" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc06=1:21" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc07=1:22" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc08=1:23" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc09=1:24" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc10=1:25" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc11=1:26" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc12=1:27" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc13=1:28" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc14=1:29" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:sfc15=1:30" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:select=1:31" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:launch=1:32" << endl;
		*ofsOutToFile << "Entity:" << (iCount+1) << ":Dyn:explode=1:33" << endl;
	}	//for (int iCount=0;iCount<iNumberVehicles;iCount++)
	ofsOutToFile->close();
	delete ofsOutToFile;
#endif	//#ifdef STEVETEST
}
#endif /*  MDL_START */


/* Function: mdlTerminate =====================================================
 * Abstract:
 *    No termination needed, but we are required to have this routine.
 */
static void mdlTerminate(SimStruct *S)
{
}



/* Function: mdlOutputs =======================================================
 * Abstract:
 *      y = Cx + Du 
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
}



#define MDL_UPDATE
/* Function: mdlUpdate ======================================================
 * Abstract:
 *      xdot = Ax + Bu
 */
static void mdlUpdate(SimStruct *S, int_T tid)
{
}



#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif


