#ifndef __PDACFILE__
#define __PDACFILE__

#include <algorithm>

#include "PDAC"

namespace PDAC
{

template <class T>
class Container
{
protected:

	static void deleteItem( pair< string, T* > item ) { if( item.second ) delete item.second; }

public:

	Container() {}
	~Container() { for_each ( _content.begin(), _content.end(), deleteItem ); _content.clear(); }

	const map< string, T * > &content() const { return _content; }

	void clear() { for_each ( _content.begin(), _content.end(), deleteItem ); _content.clear(); }

	virtual void load() = 0;
	virtual void create( const T &item) = 0;
	virtual void update( const string &name, const T &item) = 0;
	virtual void remove( const string &name) = 0;

protected:

	virtual void updateCreate(const string &name, const T& item, bool isUpdate) = 0;

	map< string, T * > _content;

};

//******************************************************************************
typedef map< string, Dev* > MapDevices;
typedef Container< Dev > DevicesContainer;

class DevicesFile : public DevicesContainer
{

public:

	static DevicesFile *instance();
	~DevicesFile() {}

	void load();
	void create(const Dev &dev);
	void update(const string &name, const Dev &dev);
	void remove(const string &name);

	class const_iterator: std::iterator< std::bidirectional_iterator_tag, const DevConst*>
	{
		public:
			const DevConst* operator*() { return (*cur).second; }
			bool operator!=(const const_iterator& i) const { return cur!=i.cur; }
			const const_iterator& operator++(){ ++cur; return (*this); }

		private:
			MapDevices::const_iterator cur;

			friend class DevicesFile;
			const_iterator(MapDevices::const_iterator _cur):cur(_cur) {} // private constructor for begin, end
	};

	const_iterator begin() const { return const_iterator(content().begin()); }
	const_iterator end() const { return const_iterator(content().end()); }

protected:

	DevicesFile(): DevicesContainer() {}
	void updateCreate(const string &name, const Dev &dev, bool isUpdate);

	static DevicesFile *_instance;

};

//******************************************************************************
typedef map< string, Rule* > MapRules;
typedef Container<Rule> RulesContainer;

class RulesFile: public RulesContainer
{
public:
	static RulesFile *instance();
	~RulesFile() {}

	void load();
	void create( const Rule &rule);
	void update( const string &name, const Rule &rule);
	void remove( const string &name);

protected:

	RulesFile(): RulesContainer() {}
	void updateCreate(const string &name,
					  const Rule &rule, bool isUpdate);

	static RulesFile *_instance;
};

} /* namespace PDAC */

#endif /* __PDACFILE__ */
