OgreAndroidOgreADPArchive_h        
#ifndef __ADPArchive_H__
#define __ADPArchive_H__

#include <OgreArchive.h>
#include <OgreArchiveFactory.h>

namespace Ogre{

	/// Provides access to the top-level adp files
	class ADPSource
	{
	public:
		virtual DataStreamPtr getPackage(const String &name) = 0;
	};
	
	class ADPArchive : public Archive
	{
	private:
		struct ADPEntry{
			String name;
			size_t offset, length;
		};
		Ogre::list<ADPEntry>::type mEntries;
		Ogre::uint8 *mBuffer;
		size_t mBufferSize;
		ADPSource *mSource;
	public:
		ADPArchive(const String& name, const String& archType, ADPSource *source);
        ~ADPArchive();

        /// @copydoc Archive::isCaseSensitive
        bool isCaseSensitive(void) const;

        /// @copydoc Archive::load
        void load();
        /// @copydoc Archive::unload
        void unload();

        /// @copydoc Archive::open
        DataStreamPtr open(const String& filename, bool readOnly = true) const;

		/// @copydoc Archive::create
		DataStreamPtr create(const String& filename) const;

		/// @copydoc Archive::delete
		void remove(const String& filename) const;

		/// @copydoc Archive::list
        StringVectorPtr list(bool recursive = true, bool dirs = false);

        /// @copydoc Archive::listFileInfo
        FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);

        /// @copydoc Archive::find
        StringVectorPtr find(const String& pattern, bool recursive = true,
            bool dirs = false);

        /// @copydoc Archive::findFileInfo
        FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true,
            bool dirs = false);

        /// @copydoc Archive::exists
        bool exists(const String& filename);

		/// @copydoc Archive::getModifiedTime
		time_t getModifiedTime(const String& filename);
	};
	
	class ADPArchiveFactory : public ArchiveFactory
    {
	private:
		ADPSource *mSource;
    public:
		ADPArchiveFactory(ADPSource *source):mSource(source){}
        virtual ~ADPArchiveFactory() {}
        /// @copydoc FactoryObj::getType
        const String& getType(void) const;
        /// @copydoc FactoryObj::createInstance
        Archive *createInstance( const String& name ) 
        {
            return OGRE_NEW ADPArchive(name, "ADP", mSource);
        }
        /// @copydoc FactoryObj::destroyInstance
        void destroyInstance( Archive* arch) { OGRE_DELETE arch; }
    };
}

#endif