/*
 * Copyright (C) 1996-2011 Daniel Waggoner and Tao Zha
 *
 * This 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 3 of the License, or
 * (at your option) any later version.
 *
 * It 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.
 *
 * If you did not received a copy of the GNU General Public License
 * with this software, see <http://www.gnu.org/licenses/>.
 */

#include "dw_switch.h"

#ifdef __cplusplus
extern "C"
{
#endif

/*
   Routines for reading/writing Markov state variable specifications, states, 
   transition matrices parameters and transition matrices from a TStateModel
   structure.
*/
TMarkovStateVariable* ReadMarkovSpecification(FILE *f, char *filename);
int WriteMarkovSpecification(FILE *f, char *filename, TStateModel *model);
int ReadTransitionMatrixParameters(FILE *f, char *filename, char *header, TStateModel *model);
int WriteTransitionMatrixParameters(FILE *f, char *filename, char *header, TStateModel *model);
int ReadBaseTransitionMatrices_t(int t, FILE *f, char *filename, char *header, TStateModel *model);
#define ReadBaseTransitionMatrices(f,filename,header,model) ReadBaseTransitionMatrices_t(0,f,filename,header,model)
int WriteGrandTransitionMatrix_t(int t, FILE *f, char *filename, char *header, TStateModel *model);
int WriteBaseTransitionMatrices_t(int t, FILE *f, char *filename, char *header, TStateModel *model);
#define WriteGrandTransitionMatrix(f,filename,header,model) WriteGrandTransitionMatrix_t(0,f,filename,header,model)
#define WriteBaseTransitionMatrices(f,filename,header,model) WriteBaseTransitionMatrices_t(0,f,filename,header,model)
int ReadStates(FILE *f, char *filename, char *header, TStateModel *model);
int WriteStates(FILE *f, char *filename, char *header, TStateModel *model);
int ReadTheta(FILE *f, char *filename, char *header, TStateModel *model);
int WriteTheta(FILE *f, char *filename, char *header, TStateModel *model);
int ReadFreeParameters(FILE *f, char *filename, TStateModel *model);
int WriteFreeParameters(FILE *f, char *filename, TStateModel *model);

/*
   Flat Files
*/
int ReadBaseTransitionMatricesFlat_t(int t, FILE *f, char *filename, TStateModel *model);
#define ReadBaseTransitionMatricesFlat(f,filename,model) ReadBaseTransitionMatricesFlat_t(0,f,filename,model)
int WriteBaseTransitionMatricesFlat_t(int t, FILE *f, char *filename, TStateModel *model, char *fmt);
#define WriteBaseTransitionMatricesFlat(f,filename,model,fmt) WriteBaseTransitionMatricesFlat_t(0,f,filename,model,fmt)
int sv_ReadBaseTransitionMatricesFlat_t(int t, FILE *f_in, TMarkovStateVariable *sv, TStateModel *model);
int sv_WriteBaseTransitionMatricesFlat(FILE *f_out, TMarkovStateVariable* sv, char *fmt);
int WriteBaseTransitionMatricesFlat_Headers(FILE *f, TStateModel *model);
int sv_WriteBaseTransitionMatricesFlat_Headers(FILE *f_out, TMarkovStateVariable* sv, char *idstring);

/*
   Metropolis-Hastings routines
*/
int Read_metropolis_theta(FILE *f, char *filename, char *header, struct TMetropolis_theta_tag *metropolis);
int Write_metropolis_theta(FILE *f, char *filename, char *header, struct TMetropolis_theta_tag *metropolis);
TMatrix dw_ReadPosteriorDraws(FILE *f_in, char *filename, char *tag, int nparameters);
int dw_ReadPosteriorDraw(FILE *f_in, TStateModel *model);

/*
   Base routines for recursively reading/writing Markov state variable 
   specifications, transition matrices parameters and transition matrices
   from a TMarkovStateVariable structure.
*/
TMarkovStateVariable* sv_ReadMarkovSpecification(FILE *f_in, char *idstring);
int sv_WriteMarkovSpecification(FILE *f_out, TMarkovStateVariable *sv, char *idstring);      
int sv_ReadTransitionMatrixParameters(FILE *f_in, TMarkovStateVariable *sv, char *header);       
int sv_WriteTransitionMatrixParameters(FILE *f_out, TMarkovStateVariable *sv, char *header); 
int sv_ReadBaseTransitionMatrices_t(int t, FILE *f_in, char *header, char *idstring, TMarkovStateVariable* sv, TStateModel *model);
int sv_WriteBaseTransitionMatrices(FILE *f, TMarkovStateVariable *sv, char *header, char *idstring);


//======   Read flat markov state variable specification from file. ======//
TMarkovStateVariable* CreateMarkovStateVariable_Simple(FILE *f_in, char *idstring);
TMarkovStateVariable* CreateMarkovStateVariable_File(FILE *f, char *filename);

int ReadDSGEControllingVariables(int *not_time_varying, int **n_coef, int **cum_total_coef, int*** idx_coef,
				 int **n_var, int **cum_total_var, int ***idx_var, FILE *f_in, TMarkovStateVariable *sv);


//====== TRestricted io routines ======//
#include "dw_dirichlet_restrictions.h"
TDirichletRestrictions* ReadSpecification_dirichlet_restrictions(FILE *f_in, char *trailer, int nstates);
int WriteSpecification_dirichlet_restrictions(FILE *f_out, TMarkovStateVariable *sv, char *trailer);


//====== Utility routines ======//
#define SWITCHIO_LINE_ID_NOT_FOUND  1
#define SWITCHIO_ERROR_READING_DATA 2
#define SWITCHIO_FILE_ERROR         3
void ReadError(char *idformat, char *trailer, int error);
int SetFilePosition(FILE *f_in, char *format, char *str);
int ReadInteger(FILE *f_in, char *idformat, char *trailer, int *i);
int ReadMatrix(FILE *f_in, char *idformat, char *trailer, TMatrix X);
int ReadVector(FILE *f_in, char *idformat, char *trailer, TVector v);
int ReadIntArray(FILE *f_in, char *idformat, char *trailer, void *X);
char* CreateIntegerString(char *format, char *str, int k);
  
#ifdef __cplusplus
}
#endif
