/*  DS
 *  Copyright (C) Joakim Kolsjö and Anders Asplund 2005
 *	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.
 *
 *  This program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
 */ 
 
#include "read_file.h"
#include <fstream>

using namespace std;

#ifdef WIN32
	#include <windows.h>
#else
	#include <dirent.h>
#endif

namespace DS
{
#ifndef NOFILE
	ReadFile::ReadFile(const char* pDir)
	{
		m_directory = pDir;
	}

	void ReadFile::Init()
	{
		ParseDir(m_directory.c_str());
	}
	
	void ReadFile::Read(const char* pFile)
	{
#ifdef FILE_USAGE_LOG
		ofstream usage("fileusage.txt", ios::out|ios::app);
		usage << pFile << endl;
		usage.close();
#endif
		
		static char* fn = "[ReadFile::Read]";
		string file = m_directory + (string)"/" + pFile;
		FILE* pF = fopen(file.c_str(), "rb");
		if(!pF)
			throw Exception(fn, (string)"Failed to open file " + file + ".");	
		
		if(m_MemFiles[pFile])
			throw Exception(fn, (string)"File already loaded(" + pFile + ").");	
		
		// Read data
		fseek(pF, 0, SEEK_END);
		long size = ftell(pF);
		fseek(pF, 0, SEEK_SET);
		char* pData = new char[size];
		fread(pData, size, 1, pF);			
		MemFile* pMemFile = new MemFile(pData, size);
		fclose(pF);

		m_MemFiles[pFile] = pMemFile;
	}
	
#ifdef unix
	void ReadFile::ParseDir(const char* pDirectory)
	{
		static char* fn = "[ReadFile::ParseDir]";
		DIR *pDirent = opendir(pDirectory);
		if(pDirent)
		{			
			rewinddir(pDirent);
			dirent *pDirItem;
	
			while((pDirItem = readdir(pDirent)))
			{
				string item = pDirItem->d_name;
				if(item != "." && item != "..")
				{
					DIR* pTempDir = opendir(((string) pDirectory + "/" + item).c_str());
					if(pTempDir) { // Checking d_type does not work on some linux systems
						closedir(pTempDir);
						ParseDir(((string) pDirectory + "/" + item).c_str());
					}
					else {
						string file = ((string)pDirectory + "/" + item);
						file = file.substr(m_directory.size()+1, file.size()-m_directory.size()-1);
						m_FileNames.push_back(file.c_str());
					}
				}			
			}
			closedir(pDirent);
		}
		else
			throw Exception(fn, (string)"Failed to open " + pDirectory + ".");
	}
#endif

#ifdef WIN32
	void ReadFile::ParseDir(const char* pDirectory)
	{
		static char* fn = "[ReadFile::ParseDir]";
		WIN32_FIND_DATA fileData;
		string str_dir = pDirectory;
		HANDLE directory = FindFirstFile((str_dir+(string)"/*").c_str(), &fileData);

		if(directory != INVALID_HANDLE_VALUE)
		{
			for(;;)
			{ 
				string item = fileData.cFileName;
				if(item != "." && item != "..")
				{
					if(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
						ParseDir(((string)pDirectory + "/" + item).c_str());
					else {
						string file = ((string)pDirectory + "/" + item);
						file = file.substr(m_directory.size()+1, file.size()-m_directory.size()-1);
						m_FileNames.push_back(file.c_str());
					}
				}
				
				if(!FindNextFile(directory, &fileData))
					if(GetLastError() == ERROR_NO_MORE_FILES)
						break;
			}
			FindClose(directory);
		}
		else
			throw Exception(fn, (string)"Failed to open " + pDirectory + ".");
	}
#endif	
#endif
}
