#include "generator.h"
#include "piresourcesstorage.h"


PIString initName(const PIString & n) {
	return PIFile::fileInfo(n).baseName().replaceAll(".", "_").replaceAll("/", "_")
							.replaceAll(":", "_").replaceAll("-", "_");
}


bool generate(const PIString & init_name, PIFile & file, const PIVector<ParserSection> & files) {
	if (!file.isOpened()) return false;
	PIString fcname = initName(file.path());
	PIString icname = "_PIRC_" + fcname + "_Initializer_";
	PIString dataname = "_pirc_" + fcname + "_data_";
	PIString descname = "_pirc_" + fcname + "_desc_";
	PIString funcname = "_pirc_" + init_name + "_init_";
	PIVector<PIResourcesStorage::__RCEntry> fv;
	piForeachC (ParserSection & s, files) {
		piForeachC (ParserEntry & p, s.files) {
			PIFile f;
			if (!f.open(p.path, PIIODevice::ReadOnly)) continue;
			//piCout << "gen" << p.name << p.alias << p.path;
			fv << PIResourcesStorage::__RCEntry(s.name, p.name, p.alias, p.path);
		}
	}
	if (fv.isEmpty()) return false;
	file << "#include \"piresourcesstorage.h\"\n\nstatic const uchar " << dataname << "[] = {\n";
	bool first = true;
	int rcnt = -1;
	llong curoff = 0, curfile = 0;
	piForeach (PIResourcesStorage::__RCEntry & e, fv) {
		e.offset = curoff;
		PIFile f;
		f.open(e.file, PIIODevice::ReadOnly);
		PIByteArray readed;
		curfile = 0;
		while (!f.isEnd()) {
			readed = f.read(4096);
			curfile += readed.size_s();
			for (int i = 0; i < readed.size_s(); ++i) {
				if (!first)
					file << ',';
				first = false;
				if (++rcnt >= 32) {
					file << '\n';
					rcnt = 0;
				}
				file << int(readed[i]);
			}
		}
		e.size = curfile;
		curoff += curfile;
	}
	file << "\n};\n";
	PIByteArray dba;
	dba << fv;
	file << "\nstatic const uchar " << descname << "[] = {\n";
	first = true;
	rcnt = -1;
	for (int i = 0; i < dba.size_s(); ++i) {
		if (!first)
			file << ',';
		first = false;
		if (++rcnt >= 32) {
			file << '\n';
			rcnt = 0;
		}
		file << int(dba[i]);
	}
	file << "\n};\n";

	file << "\nvoid " << funcname << "() {\n";
	file << "\tPIResourcesStorage::instance()->registerSection(" << dataname << ", " << descname << ", sizeof(" << descname << "));\n";
	file << "}\n";

	file << "\nclass " << icname << " {\n";
	file << "public:\n\t" << icname << "() {\n";
	file << "\t\t" << funcname << "();\n";
	file << "\t}\n";
	file << "} _pirc_" << fcname << "_initializer_;\n";
	return true;
}

