#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include "cFile.h"

#include "cStack.cpp"

////////////////////////////////////////////////////////////////
cFile::cFile(){
	FileName = NULL;
	File = NULL;
}

cFile::~cFile(){
	Close();
	if(FileName) delete [] FileName;
}
///////////////////////// Open , Close ////////////////////////
bool cFile::Open(char *Mode){
	if(FileName){
		File = fopen(FileName, Mode);
		if(File) return true;
	}
	return false;
}

bool cFile::Open(char *nFileName, char *Mode){
	Close();
	SetFileName(nFileName);
	File = fopen(FileName, Mode);
	if(File) return true;
	return false;
}

void cFile::Close(){
	if(File) fclose(File);
}

FILE *cFile::GetFile(){
	return File;
}
/////////////////////////////// Seek //////////////////////////
bool cFile::Seek(int Offset, int Origin){
	if(fseek(File, Offset, Origin)) return false;
	return true;
}

bool cFile::SkipSpace(){
	int Char;

	do{
		Char = Getc();
		if(Char == EOF) return false;
	} while(isspace(Char) || Char == '\n');
	Ungetc(Char);
	return true;
}

bool cFile::FindChar(char c){
	int Char;
	do{
		Char = Getc();
		if(Char == EOF) return false;
	} while(Char != c);
	Ungetc(c);
	return true;
}

//////////////////////////////////////////////////////////////
int cFile::Read(void *Dest, int Size, int Block){
	return fread(Dest, Size, Block, File);
}

int cFile::Write(void *Src, int Size, int Block){
	return fwrite(Src, Size, Block, File);
}


int cFile::WriteSpace(int Count){
	while(Count --){
		if(Putc(0) == EOF) return EOF;
	}
	return Count;
}
///////////////////// Gets, Puts  //////////////////////////////
char *cFile::Gets(char *String, int n){
	return fgets(String, n, File);
}

int cFile::Puts(char *String){
	return fputs(String, File);
}
int cFile::Printf(char *Format, ...){
   va_list argptr;
   int Count;

   va_start(argptr, Format);
   Count = vfprintf(File, Format, argptr);
   va_end(argptr);

   return Count;
}

///////////////////////// For Text File
bool cFile::GetString(char *String, int n){
	if(fgets(String, n, File)) return true;
	return false;
}
int cFile::Getc(){
	return getc(File);
}
int cFile::Ungetc(int Char){
	return ungetc(Char, File);
}

int cFile::Putc(int c){
	return putc(c, File);
}
/////////////////////////////////// File Position & Stack Management
void cFile::ClearPosStack(){
	PosStack.Clear();
}
bool cFile::PushPos(){
	fpos_t Pos;
	if(fgetpos(File, &Pos)) return false;
	PosStack.Push(Pos);
	return true;
}

bool cFile::PopPos(){
	fpos_t Pos;
	PosStack.Pop(Pos);
	if(fsetpos(File, &Pos)) return false;
	return true;
}
void cFile::DelTop(){
	fpos_t Pos;
	PosStack.Pop(Pos);
}

////////////////////////// Set File Name ///////////////////////
void cFile::SetFileName(char *nFileName){
	if(FileName) delete [] FileName;
	FileName = new char [strlen(nFileName) + 1];
	strcpy(FileName, nFileName);
}
