// mINI.cpp
// ````````

#include "mINI.h"

// Read entire file into std::string
bool file_get_contents(std::wstring filepath, std::string& result) {	
	FILE* f = 0;
	long flen;
		
	_wfopen_s(&f, filepath.c_str(), L"rb");
	if (!f) return false;

		// Get length
		fseek(f, 0, SEEK_END);
		flen = ftell(f);
		fseek(f, 0, SEEK_SET);

		// Read into new buffer
		char* cBuff = new char[flen+1];
		memset(cBuff, 0, flen+1);
		fread(cBuff, 1, flen, f);
	fclose(f);

	result.assign(cBuff);
	delete[] cBuff;
	return true;
}

// Overwrite a file with the specified contents
bool file_put_contents(std::wstring filepath, std::string& data) {
	FILE* f = 0;
	_wfopen_s(&f, filepath.c_str(), L"wb");
	if (!f) return false;

		fwrite(data.c_str(), 1, data.length(), f);
	fclose(f);

	return true;
}

// Write an INI structure to file
void ini_write(std::wstring filepath, ini_t& data) {
	std::string text;
	
	for (ini_t::iterator i = data.begin(), e = data.end(); i != e; i++) {
		text += "[" + i->first + "]\r\n";
		for (
			std::map<std::string,std::string>::iterator
			j = i->second.begin(), k = i->second.end(); j != k; j++
		) {
			text += j->first + "=" + j->second + "\r\n";
		}
		text += "\r\n";
	}

	file_put_contents(filepath, text);
}

// Parse an INI file structure
ini_t ini_read(std::wstring filepath) {
	ini_t ret;
	std::string sbuf;
	file_get_contents(filepath, sbuf);

	long fpo = 0, fpn = 0;
	std::string sCurSection = "";
	do {
		fpn = sbuf.find("\n", fpo+1);
		if (fpn != sbuf.npos) fpn++;
		std::string sLine = sbuf.substr(fpo, fpn-fpo);

		// Strip \r
		long rp; while ((rp = sLine.find("\r")) != sLine.npos) sLine.erase(rp, rp+1);
		
		// Process each line
		if (sLine.length() > 1 && sLine.at(0) != '#') {
			if (sLine.at(0) == '[') {
				// Section, find ]
				long ebp = sLine.find("]", 1);
				if (ebp != sLine.npos) {
					sCurSection = sLine.substr(1, ebp-1);
					ret[sCurSection];
				}

			} else {
				// Key/value, find =
				long eqp = sLine.find("=");
				if (eqp != sLine.npos) {
					ret[sCurSection][sLine.substr(0, eqp)] = sLine.substr(eqp+1);
				}
			}			
		}

		fpo = fpn;
	} while (fpo != sbuf.npos);

	return ret;
}
