#include "unpile.h"
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
#include "lprintf.h"
#define nsprintf lprintf
#include "lib.h"
#define DMID 24
#include "debug.h"
#include <string.h>
#include <stdlib.h>

int wild_find(char *wild, char *names[], int max, int *size);


int unpile(char *infile, char *dest)
{
	return unpile2(infile,dest,false,true);
}
int unpile_binary(char *infile, char *dest)
{
	return unpile2(infile,dest,true,true);
}

int unpile2(char *infile, char *dest, int is_binary, int make_original)
{
	char bf[BFSZ];
	if (!unpile3(infile,dest,is_binary,true)) return false;
	if (!make_original) return true;
	nsprintf(bf,BFSZ-1,"%s/Original/",dest);
	lib_create_dir(bf,0700);
	nsprintf(bf,BFSZ-1,"%s/Original",dest);
	return unpile3(infile,bf,is_binary,true);
}



int unpile3(char *infile, char *dest, int is_binary, int replace)
{
	FILE *fout;
	FILE *f;
	/*int nerr;*/
	char *s;
	char bf[200];
	char *s1,*s2;
	char afile[1000];
	char outfile[1000];
	int len;
	char *upto;
	int rlen;
	int sz;
	char *whole;
	char *mode;
	int r = true;
	if (is_binary) mode="wb";
	else mode="w";
	whole = NULL;
	sz = 0;
	lib_create_dir(dest,0700);
	fout = fopen(infile,"rb");
	if (fout==NULL) {
		printf("Unpile %s. Failed to read it\n",infile);
		perror(infile);
		return false;
	}
	for (;;) {
		if (fread(bf,1,80,fout)<80) {
			break; /* Matt's Change */
			/*return r;*/
		}
		s = mystrtok(bf," ",&upto); if (s==NULL) {r=false;break;}
		ncpy(afile,s,999);
		s = mystrtok(NULL," ",&upto); if (s==NULL) {r=false;break;}
		nsprintf(outfile,999,"%s/%s",dest,afile);
		if (strchr(afile,'/'))
			lib_create_dir(outfile,0700);
		len = atoi(s);
		if (sz<len) {
			if (whole!=NULL) free(whole);
			whole = malloc(len+1);
			sz = len;
		}
		if (whole==NULL) {r=false;break;}
		fread(whole,1,len,fout);	
		/*nerr=0;*/
		/*printf("Writing %s\n",outfile);*/
		if (!replace && lib_exists(outfile)) continue;
		f = fopen(outfile,mode);
		if (f==NULL) {
			printf("unpile %s. Failed to write to [%s]\n",infile,outfile);
			perror(outfile); 
			continue;
		}
		if (is_binary) {
			rlen=(int)fwrite(whole,1,len,f);
			if (rlen<len) r = false;
		}
		else {
#ifdef WIN32
			s1 = whole;
			for (;(s1-whole)<len;) {
				s2 = strchr(s1,'\n');
				if (s2==NULL) break;
				*s2 = 0;
				fprintf(f,"%s\n",s1);
				s1 = s2 + 1;
			}
			len = len - (int)(s1-whole);
			if ((int) fwrite(s1,1,len,f)<len) r = false;
#else
			rlen=fwrite(whole,1,len,f);
			if (rlen<len) r = false;
			/*if (fwrite(whole,1,len,f)<len) r = FALSE;*/
#endif
		}
		if (fclose(f)!=0) r = false;;
	}
 	fclose(fout);
	if (whole!=NULL) free(whole);
	return r;

}

#define MAX_PILE 1000
int pile_add_file(FILE *f, char *fname, char *afile, int is_binary);

int pile_files(char *fname, char *names[], char *anames[], int n, int is_binary)
{
	FILE *f;
	int i;

	if (is_binary)
		f=fopen(fname,"wb");
	else
		f=fopen(fname,"w");
	if (!f) return false;
	for(i=0;i<n;i++) {
		pile_add_file(f,names[i],anames[i],is_binary);
	}
	fclose(f);
	return true;
}

int pile(char *fname, char *wild, int is_binary)
/*
!is_binary not implemented.
*/
{
	char *names[MAX_PILE];
	char *anames[MAX_PILE];
	int n;
	int size;
	int i;

	n=wild_find(wild,names,MAX_PILE-1,&size);
	for(i=0;i<n;i++) {
		anames[i]=lib_file_name_only(names[i]);
	}
	pile_files(fname,names,anames,n,is_binary);
	for(i=0;i<n;i++) {
		free(names[i]);
	}
	return true;
}

int pile_add_file(FILE *f, char *fname, char *afile, int is_binary)
{
	FILE *f2;
	int sz;
	char *bf;
	/*char *afile;*/
	int r;
	int z;
	char bf2[BFSZ];

	if (is_binary) {
		f2=fopen(fname,"rb");
		if (!f2) return false;
		sz=lib_file_osize(f2);
		if (sz<=0) {
			fclose(f2);
			return false;
		}
		bf=malloc(sz);
		z=0;
		while(!feof(f2)) {
			r=(int)fread(bf2,1,BFSZ-1,f2);
			if (r<=0) break;
			memcpy(bf+z,bf2,r);
			z+=r;
		}
		fclose(f2);

		/*afile=lib_file_name(fname);*/ /* Don't save the full path. */
		nsprintf(bf2,79,"%s %d",afile,z);
		fwrite(bf2,1,80,f);
		fwrite(bf,1,z,f);
		free(bf);
		return true;

	}
	else {
		return false;
	}

	
}

