//  FILE_IO.C
//  File input/output functions
//  © 2021 Peter J. Meyer

#include "iss.h"

#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

//  input_filepath[] got from read_command_line().
/*-----------------------*/
void set_up_filenames(void)
{
strcpy(output_filepath,input_filepath);
strcpy(strrchr(output_filepath,'.'),".OUT");

strcpy(map_filepath,input_filepath);
strcpy(strrchr(map_filepath,'.'),".MAP");

#if SAVE_MEASUREMENTS
strcpy(measurements_filepath,input_filepath);
strcpy(strrchr(measurements_filepath,'.'),".MEA");
#endif

#if CHECK_ADMISSABILITY
_strdate(temp2);    
expired = ( atoi(&temp2[6]) );   
//  Version 1.93 expires on 2001-01-01.
//  'expired' used in DSTARTUP.C and in MEAS.C.
#endif
}

/*----------------------------------*/
void check_if_output_file_exists(void)
{
int ch;
FILE *of;

if ( file_exists(output_filepath) )
    {
    if ( memcmp(output_filepath,"ISING",5) != 0 
      && memcmp(output_filepath,"POTTS",5) != 0 
      && memcmp(output_filepath,"BONDPERC",8) != 0
      && memcmp(output_filepath,"SITEPERC",8) != 0 
      && memcmp(output_filepath,"SW",2) != 0
      && memcmp(output_filepath,"WO",2) != 0 )
        {
        printf("\nOutput file %s already exists.",output_filepath);
        printf("\nOverwrite existing file? (Y|N) ");
        ch = getche();
        printf("\n");
        if ( ! ( ch == 'Y' || ch == 'y' ) )
            exit(0);
        }
    }

while  ( !open_file(output_filepath,"wt",&of) )  
    //  If file exists then this truncates it.
    {
    printf("\n\aCannot open output file %s.",output_filepath);
    printf("\nPerhaps this file is already open?  Retry or quit? (R|Q) ");
    ch = getche();
    if ( ch == 'Q' || ch == 'q' ) 
        exit(1);
    printf("\n");
    }

fclose(of);
}

//  Returns true if file opened successfully, false otherwise.
/*-------------------------*/
int open_file(char *filename, 
              char *mode,               //  e.g. "rt", "wt"
              FILE **file)
{
*file = fopen(filename,mode);
return ( *file != NULL );
}

/*---------------------------*/
int read_line(FILE *input_file)     
{
char *ptr;

//  fgets() reads at most sizeof(line)-1 bytes
//  and keeps the final LINEFEED if found.
if ( fgets(line,sizeof(line),input_file) == NULL )
    return ( false );

if ( ( ptr = strchr(line,LINEFEED) ) != NULL )
    *ptr = 0;		//  Remove final line feed

remove_outer_spaces(line);
_strlwr(line);

return ( true );
}

/*---------------------------*/
int file_exists(char *filepath)
{
FILE *f;

f = fopen(filepath,"rt");   
if ( f == NULL )
    return ( false );

fclose(f);
return ( true );
}

#if false

//  Not used.

//  Save measurements to .MEA file.
//  Low-level file I/O is used.
/*-----------------------*/
int save_measurements(void)
{
int fh;
int nmc=NUM_MAGNETIZATION_COMPONENTS;
int niec=NUM_INTERNAL_ENERGY_COMPONENTS;
int nac=NUM_AUTOCORRELATION_COMPONENTS;
int measurements_bytes_written;

if ( ( fh = _open(measurements_filepath,_O_WRONLY|_O_CREAT|_O_TRUNC,
                                        _S_IREAD|_S_IWRITE ) ) == -1 )   
    display_file_error_message("open (for writing)",
        "measurements",measurements_filepath);
    //  Does not return.  

_write(fh,&num_time_slices,sizeof(int));
_write(fh,&internal_energy_measured,sizeof(int));
_write(fh,&second_moment_measured,sizeof(int));
_write(fh,&model_is_q_state_potts,sizeof(int));
_write(fh,&q,sizeof(int));
_write(fh,&nmc,sizeof(int));
_write(fh,&niec,sizeof(int));
_write(fh,&nac,sizeof(int));
_write(fh,&num_spins,sizeof(int));

measurements_bytes_written = 9*sizeof(int);

_write(fh,&num_samples,sizeof(double));
_write(fh,&temperature,sizeof(double));

measurements_bytes_written += sizeof(double);

if ( ( measurements_bytes_written += _write(fh,&magnetization[0][0],
       sizeof(double)*(num_time_slices+1)*NUM_MAGNETIZATION_COMPONENTS)) == -1 )
    display_file_error_message("write measurements to",
        "measurements",measurements_filepath);

if ( internal_energy_measured )
    if ( ( measurements_bytes_written += _write(fh,&internal_energy[0][0],
         sizeof(double)*(num_time_slices+1)*NUM_INTERNAL_ENERGY_COMPONENTS)) == -1 )
        display_file_error_message("write measurements to",
            "measurements",measurements_filepath);

if ( second_moment_measured && model_is_q_state_potts )
    if ( ( measurements_bytes_written += _write(fh,&potts_magnetization_squares[0][0],
         sizeof(double)*(num_time_slices+1)*(q+1))) == -1 )
        display_file_error_message("write measurements to",
            "measurements",measurements_filepath);

if ( autocorrelation_measured )
    if ( ( measurements_bytes_written += _write(fh,&autocorrelation[0][0],
         sizeof(double)*(num_time_slices+1)*NUM_AUTOCORRELATION_COMPONENTS)) == -1 )
        display_file_error_message("write measurements to",
            "measurements",measurements_filepath);


_close( fh );

return ( measurements_bytes_written );
}

#endif