// [io-guts.cpp]
// -------------------------------------------------------------------------------------------- //
// input/output tech subroutines
// -------------------------------------------------------------------------------------------- //

#define _CRT_SECURE_NO_DEPRECATE
#include "io-guts.h"

#include <stdio.h>
#include <string.h>
#include <sstream>

// --- including for directory operations
#ifdef _WIN32
#include <direct.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#include <errno.h>


// -------------------------------------------------------------------------------------------- //
// * Implementation *
// -------------------------------------------------------------------------------------------- //

// * append index * //
// -------------------------------------------------------------------------------------------- //
const std::string scm::append_index(
	const std::string& name, const int index)
{
	std::ostringstream sidx;
	sidx << index;

	const int ext_pos = name.find_last_of(".");
	std::string app_name = name;
	if (ext_pos == std::string::npos)
		app_name.append(sidx.str());
	else
		app_name.insert(ext_pos, sidx.str());

	return app_name;
}
// -------------------------------------------------------------------------------------------- //

// * create dir * //
// -------------------------------------------------------------------------------------------- //
bool scm::create_dir(const std::string& path)
{
	// empty path is OK	[local DIR]
	if (path.empty()) return true;

	char *c_path;
	c_path = new char[path.length() + 1];
	strcpy(c_path, path.c_str());

	int status;
	char *ptr = c_path + 1;		// not empty string
	while (*ptr != '\0')
	{
		if (*ptr == '/')
		{
			*ptr = '\0';
#ifdef _WIN32
			status = _mkdir(c_path);
#else
			status = mkdir(c_path, S_IRWXU);	// add group?: S_IRWXG
#endif
			if (!((status == 0) ||
				((status == -1) && (errno == EEXIST))))
			{
				delete[] c_path;
				return false;
			}

			*ptr = '/';
		}
		ptr++;
	}


#ifdef _WIN32
	status = _mkdir(c_path);
#else
	status = mkdir(c_path, S_IRWXU);	// add group?: S_IRWXG
#endif

	delete[] c_path;

	return ((status == 0) ||
		((status == -1) && (errno == EEXIST)));
}
// -------------------------------------------------------------------------------------------- //

// * getline * //
// -------------------------------------------------------------------------------------------- //
char* scm::getline(char** buf, int* size, FILE* ptr)
{
	const int c_min_size = 512;

	if (*size < c_min_size) {
		if (*size > 0) delete[](*buf);

		*size = c_min_size;
		*buf = new char[*size];
	}

	if (fgets(&(*buf)[0], *size, ptr) == NULL) return NULL;
	int bidx = strlen(*buf);

	while (!feof(ptr) && ((*buf)[bidx - 1] != '\n'))
	{
		// --- reading more ...

		// --- allocating additional memory
		*size += c_min_size;
		char *hbuf = new char[*size];
		strcpy(hbuf, *buf);

		// --- pointing buf to new memory
		delete[](*buf);
		*buf = hbuf;

		// --- reading & removing termination character
		if (fgets(&(*buf)[bidx], *size - bidx, ptr) == NULL) {
			if (!feof(ptr)) return NULL;
		}
		bidx = strlen(*buf);
	}

	return *buf;
}
// -------------------------------------------------------------------------------------------- //

// * convert to string * //
// -------------------------------------------------------------------------------------------- //
std::string scm::convert_to_string(const int value)
{
	std::ostringstream stream;
	stream << value;
	return stream.str();
}

std::string scm::convert_to_string(const double value)
{
	std::ostringstream stream;
	stream << value;
	return stream.str();
}
// -------------------------------------------------------------------------------------------- //