/*
	BinMaker program
	Copyright 2007 Jonathan Wilson
	Portions lifted from BinOpener copyright 2007 booto (temptemp91 at hotmail dot com)

	This file is part of binmaker.

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	binmaker is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
#include <stdio.h>
#include "manifestitem.h"

ManifestFile::ManifestFile()
{
	Header.version = 0x50100;
	Header.filesignature = 0x3bbb08d3;
	Header.manifestsignature = 0xC4D3AC23;
	Header.binsize = 4;
	Header.maxstreamsize = 0;
	Header.maxrelosize = 0;
	Header.maximpsize = 0;
	Header.includenamessize = 0;
	Header.extraentriessize = 0;
	Header.streamnamessize = 0;
	Header.sourcenamessize = 0;
	StreamPos = 0;
	SourcePos = 0;
	ExtraEntryPos = 0;
}

void ManifestFile::Save(const char *filebase)
{
	int x = strlen(filebase) + 1;
	char *manifest = new char[x+9];
	char *bin = new char[x+4];
	char *imp = new char[x+4];
	char *relo = new char[x+5];
	strcpy(manifest,filebase);
	strcat(manifest,".manifest");
	strcpy(bin,filebase);
	strcat(bin,".bin");
	strcpy(imp,filebase);
	strcat(imp,".imp");
	strcpy(relo,filebase);
	strcat(relo,".relo");
	Header.itemcount = Items.size();
	for (unsigned int i = 0;i < Items.size();i++)
	{
		Items[i]->calcsize(this);
	}
	for (unsigned int i = 0;i < Includes.size();i++)
	{
		Header.includenamessize += 2;
		Header.includenamessize += strlen(Includes[i]->name);
	}
	Manifest = fopen(manifest,"wb");
	Relo = fopen(relo,"wb");
	Bin = fopen(bin,"wb");
	Imp = fopen(imp,"wb");
	Streams = new char[Header.streamnamessize];
	Sources = new char[Header.sourcenamessize];
	ExtraEntries = new ExtraEntry[Header.extraentriessize/sizeof(ExtraEntry)];
	if (binsize)
	{
		Header.binsize = binsize;
	}
	if (maxstreamsize)
	{
		Header.maxstreamsize = maxstreamsize;
	}
	if (maxrelosize)
	{
		Header.maxrelosize = maxrelosize;
	}
	if (maximpsize)
	{
		Header.maximpsize = maximpsize;
	}
	fwrite(&Header,sizeof(Header),1,Manifest);
	fwrite(&Header.filesignature,4,1,Relo);
	fwrite(&Header.filesignature,4,1,Bin);
	fwrite(&Header.filesignature,4,1,Imp);
	for (unsigned int i = 0;i < Items.size();i++)
	{
		Items[i]->save(this);
	}
	char *incs = new char[Header.includenamessize];
	char *t = incs;
	for (unsigned int i = 0;i < Includes.size();i++)
	{
		t[0] = Includes[i]->type;
		t++;
		strcpy(t,Includes[i]->name);
		t += strlen(Includes[i]->name);
		t++;
	}
	fwrite(ExtraEntries,Header.extraentriessize,1,Manifest);
	fwrite(incs,Header.includenamessize,1,Manifest);
	fwrite(Streams,Header.streamnamessize,1,Manifest);
	fwrite(Sources,Header.sourcenamessize,1,Manifest);
}

void ManifestFile::AddInclude(const char *filename,unsigned char type)
{
	Include *i = new Include;
	Includes.push_back(i);
	i->name = _strdup(filename);
	i->type = type;
}

