/*  $Id: inputsource_file.cpp,v 1.5 2003/09/08 14:08:45 grumbel Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library 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
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
**
*/

#include "Core/precomp.h"

#include <API/Core/IOData/inputsource_file.h>

CL_InputSource_File::CL_InputSource_File(const std::string &_filename)
{
	filename = _filename;
	filehandle = NULL;
	open();
}

CL_InputSource_File::CL_InputSource_File(const CL_InputSource_File *source)
{
	filename = source->filename;
	filehandle = NULL;

	open();
	fseek(filehandle, ftell(source->filehandle), SEEK_SET);
}

CL_InputSource_File::~CL_InputSource_File()
{
	close();
}

int CL_InputSource_File::read(void *data, int size)
{
	return fread(data, 1, size, filehandle);
}

void CL_InputSource_File::open()
{
	if (filehandle != NULL) return;

#ifndef WIN32 // hate win32 non posix conform
	if (filename[0] == '!')
	{
		filehandle = popen(std::string(filename, 1).c_str(), "rb");
		if (filehandle == NULL)
		{
			throw CL_Error("Could not open pipe: " + std::string(filename,1));
		}
		filesize = 99999999;
	}
	else
#endif
	{
		filehandle = fopen(filename.c_str(), "rb");
		if (filehandle == NULL)
		{
			throw CL_Error("Could not open file: " + filename);
		}
		fseek(filehandle, 0, SEEK_END);
		filesize = ftell(filehandle);
		fseek(filehandle, 0, SEEK_SET);
	}
//	cl_assert(filehandle != NULL);
}

void CL_InputSource_File::close()
{
	if (filehandle == NULL) return;
	fclose(filehandle);

	filehandle = NULL;
}

CL_InputSource *CL_InputSource_File::clone() const
{
	return new CL_InputSource_File(this);
}

int CL_InputSource_File::tell() const
{
	return ftell(filehandle);
}

void CL_InputSource_File::seek(int pos, SeekEnum seek_type)
{
	switch (seek_type)
	{
		case seek_cur:
			fseek(filehandle, pos, SEEK_CUR);
			break;

		case seek_set:
			fseek(filehandle, pos, SEEK_SET);
			break;

		case seek_end:
			fseek(filehandle, pos, SEEK_END);
			break;
	}
}

int CL_InputSource_File::size() const
{
	return filesize;
}

void CL_InputSource_File::push_position()
{
	int a = ftell(filehandle);

	stack.push(a);
}

void CL_InputSource_File::pop_position()
{
	int a = stack.top();
	stack.pop();

	fseek(filehandle, a, SEEK_SET);
}
