/**
 *
 */

/* WIN32 stuff */
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

// TODO: reference additional headers your program requires here
#include <process.h>
#include <strsafe.h>
#include <shlwapi.h>
#include <io.h>

#include <atlbase.h>

#include "tools.h"

void _addpath ( TCHAR * path )
{
	TCHAR * pv;
	size_t	pv_len,var_size;
	errno_t res;

	/* Determine the length of the current path. */
	_tgetenv_s ( &var_size, NULL, 0, TEXT("PATH") );
	pv_len = var_size + _tcslen ( path ) + 2;

	/* Allocate memory for the path string from the environment
	   plus the added path. */
	pv = (TCHAR *) malloc ( pv_len * sizeof(TCHAR) );
	if ( pv == NULL )
	{
		perror ( "Failed to allocate memory for path" );
		exit ( -1 );
	}

	/* Get the variable. */
	res = _tgetenv_s ( &var_size, pv, pv_len, TEXT("PATH") );
	if ( res != 0 )
	{
		perror ( "Cannot read environment variable PATH" );
		exit ( -1 );
	}

	/* Add the new path string. */
	var_size = _tcslen ( pv );
	StringCbCat ( pv, pv_len*sizeof(TCHAR), TEXT(";") );
	var_size = _tcslen ( pv );
	StringCbCat ( pv, pv_len*sizeof(TCHAR), path );
	var_size = _tcslen ( pv );

	/* Put the modified string back to the environment of this
	   process. */
	res = _tputenv_s( TEXT("PATH"), pv );
	if ( res != 0 )
	{
		perror ( "Cannot store new PATH" );
		exit ( -1 );
	}
}

TCHAR * _tstrtrim ( TCHAR * str )
{
   TCHAR * os = str;
   TCHAR * oe = str + _tcslen ( str ) - 1;

   while ( _istspace ( *os )) os++;
   while ( _istspace ( *oe )) oe--;
   *++oe = 0;

   return os;
}

errno_t replace_in_scenario (
	const TCHAR * sce_name,
	const TCHAR * new_name,
	const TCHAR * section,
	const TCHAR ** patterns,
	int num_patterns,
	const TCHAR * replacement
	)
{
	TCHAR   tline[MAX_LINE];
	TCHAR   trml[MAX_LINE];
    TCHAR   tmp_name[MAX_PATH];
	FILE *  tmp_stream;
	FILE *  sce_stream;
	errno_t res;

	/* Create filename of the temporary scenario. */
	_ttmpnam_s ( tmp_name );

    /* Open the temporary file for writting. */
    res = _tfopen_s ( &tmp_stream, tmp_name, TEXT("w") );
	if ( res != 0 )
	{
		perror ( "Cannot create temporary file" );
		return res;
	}

    /* Open the scenario file for reading */
    res = _tfopen_s ( &sce_stream, sce_name, TEXT("r") );
    if ( res != 0 )
	{
		perror ( "Cannot open scenario for reading" );
		return res;
	}

    /* Copy the scenario file to the temporary location line by line,
       changing the lines containing some of strings in `patterns`
	   to `replacement`, but only in section name `section`. */

    bool is_sct = false;
    bool is_upd = false;

	while ( !feof ( sce_stream ))
	{
        /* Read a single line from the scenario file. */
        if ( _fgetts ( tline, MAX_LINE, sce_stream ) == NULL )
		{
			/* Error reading from source file. */
			if ( !feof ( sce_stream )) perror ( "Error reading scenario" );
			break;
		}

		/* Is the `tline` empty? */
		StringCbCopy ( trml, MAX_LINE*sizeof(TCHAR), tline );
        TCHAR * ttrml = _tstrtrim ( trml );
        if ( _tcslen ( ttrml ) == 0 ) continue;

        /* Check the beginning of the specified section. */
        if ( !is_sct )
		{
            is_sct = ( _tcsstr ( tline, section ) != NULL );
		}
		else
		{
			/* We are inside the section, try to replace the text
			   that should be replaced. */
			bool is_pat = false;
			for (int i=0;i<num_patterns;i++)
			{
				is_pat = ( _tcsstr ( tline, patterns[i] ) != NULL );
				if ( is_pat ) break;
			}
            if ( is_pat )
			{
                _sntprintf_s ( tline, MAX_LINE, MAX_LINE-2, TEXT("%s\n"), replacement );
                is_upd = true;
			}
		}
        _fputts ( tline, tmp_stream );
	}

    /* Construct the section if none is present. */
    if ( ! is_sct )
	{
        _ftprintf ( tmp_stream, TEXT("%s\n"), section );
	}

    /* If the replacement string was not found in the scenario file,
	   inject it. */
    if ( ! is_upd )
	{
        _ftprintf ( tmp_stream, TEXT("%s\n"), replacement );
	}

    fclose ( tmp_stream );
    fclose ( sce_stream );

    /* Do not rewrite the original scenario file, but move the temporary
       file to the same directory under a new name that has been
	   specified as a parameter. */
    if ( ! _taccess ( new_name, 00 ))
	{
		/* File exists, delete it. */
        DeleteFile ( new_name );
	}
    MoveFile ( tmp_name, new_name );

	return 0;
}

errno_t replace_stoptime (
	const TCHAR * net_path,
	const TCHAR * stoptime
	)
{
	TCHAR   tline[MAX_LINE];
    TCHAR   tmp_name[MAX_PATH];
    TCHAR   run_name[MAX_EXE_PATH];
	FILE *  tmp_stream;
	FILE *  run_stream;
	errno_t res;
	int     line_no;

	/* Create filename of the temporary file with replaced stoptime. */
	_ttmpnam_s ( tmp_name );

    /* Open the temporary file for writting. */
    res = _tfopen_s ( &tmp_stream, tmp_name, TEXT("w") );
	if ( res != 0 )
	{
		perror ( "Cannot create temporary file" );
		return res;
	}

	/* Create the name of the time file. */
	StringCbCopy ( run_name, MAX_EXE_PATH, net_path );
	StringCbCat  ( run_name, MAX_EXE_PATH, TEXT("\\AIMSUN\\RunTime") );

	/* Open the time file for reading */
    res = _tfopen_s ( &run_stream, run_name, TEXT("r") );
    if ( res != 0 )
	{
		perror ( "Cannot open scenario for reading" );
		return res;
	}

    /* Copy the time file to the temporary location line by line,
       changing the third line containing stop time. */
	line_no = 0;
	while ( !feof ( run_stream ))
	{
        /* Read a single line from the scenario file. */
        if ( _fgetts ( tline, MAX_LINE, run_stream ) == NULL )
		{
			/* Error reading from source file. */
			if ( !feof ( run_stream )) perror ( "Error reading scenario" );
			break;
		}

		/* Increase the line counter. */
		line_no++;

		/* Replace the third line. */
		if ( line_no == 3 )
		{
			_sntprintf_s ( tline, MAX_LINE, MAX_LINE-2, TEXT("%s\n"), stoptime );
		}

        _fputts ( tline, tmp_stream );
	}

    fclose ( tmp_stream );
    fclose ( run_stream );

    /* Rewrite the original RunTime file. */
    if ( ! _taccess ( run_name, 00 ))
	{
		/* File exists, delete it. */
        DeleteFile ( run_name );
	}
    MoveFile ( tmp_name, run_name );

	return 0;

}

int _search_index ( const int *list, int numElements, int value )
{
	int i;
	for ( i = 0 ; i < numElements ; i++ )
	{
		if ( *list == value ) break;
		list++;
	}
	if ( i >= numElements ) i = -1;
	return i;

}
