/*
** 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com> --- December 1997
 */

/*
 * MultiFiles.h --- class to store multiple files by directory
 */

#ifndef MULTIFILES_H
#define MULTIFILES_H

#include "TextBinary.h"

#include "CPStr.h"
#include <vector>

#ifdef _MSC_VER
	using namespace std;
#endif

class CvsArgs;

/// Used internally
class FileEntry
{
public:
	FileEntry();
	FileEntry(const char* filename, const UFSSpec* macspec = 0L, const char* currRevision = 0L);
	FileEntry(const FileEntry& entry);

	FileEntry& operator=(const FileEntry& entry);

protected:
	CStr file;
	CStr currRev;
	UFSSpec spec;

friend class MultiFilesEntry;
friend class MultiFiles;
};

/// Used internally
class MultiFilesEntry
{
public:
	MultiFilesEntry();
	MultiFilesEntry(const char* path);
	MultiFilesEntry(const MultiFilesEntry& entries);

	MultiFilesEntry& operator=(const MultiFilesEntry& entries);

	void setdir(const char* newdir);
	void add(const char* file, const UFSSpec* spec = 0L, const char* currRevision = 0L);
	
	bool get(int index, CStr& path, CStr& fileName, CStr& currRev) const;

	/// Get the number of files in the current dir
	int NumFiles(void) const { return files.size(); }

	/// Get the current directory
	const char* getdir() const { return dir; }

	/// Fill up the arguments with all the files
	const char* add(CvsArgs& args) const;

protected:
	CStr dir;
	std::vector<FileEntry> files;

friend class MultiFiles;
};

/// Store multiple files by directory
class MultiFiles
{
public:
	MultiFiles();

	void newdir(const char* dir);
	void newfile(const char* file, const UFSSpec* spec = 0L, const char* currRevision = 0L);

	typedef std::vector<MultiFilesEntry>::const_iterator const_iterator;
	
	const_iterator begin() const { return dirs.begin(); }
	const_iterator end() const { return dirs.end(); }

	bool getdir(int index, CStr& path) const;

	int NumDirs(void) const { return dirs.size(); }
	int TotalNumFiles(void) const;

	void reset();

	bool Normalize();
	
protected:
	std::vector<MultiFilesEntry> dirs;
};

/// A pair of MultiFiles::const_iterator and index allowing to identify the FileEntry
class MultiFilesEntryIndex
{
public:
	MultiFilesEntryIndex(int index, MultiFiles::const_iterator mfi)
		: m_index(index), m_mfi(mfi)
	{
	}

	int GetIndex() const { return m_index; }
	MultiFiles::const_iterator GetIterator() const { return m_mfi; }

private:
	int m_index;
	MultiFiles::const_iterator m_mfi;
};

#endif /* MULTIFILES_H */
