/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Access a chunk of the asset hierarchy as if it were a single directory.
//
#ifndef __LIBS_ASSETDIR_H
#define __LIBS_ASSETDIR_H

#include <androidfw/misc.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <sys/types.h>

namespace android {

/*
 * This provides vector-style access to a directory.  We do this rather
 * than modeling opendir/readdir access because it's simpler and the
 * nature of the operation requires us to have all data on hand anyway.
 *
 * The list of files will be sorted in ascending order by ASCII value.
 *
 * The contents are populated by our friend, the AssetManager.
 */
class AssetDir {
public:
    AssetDir(void)
        : mFileInfo(NULL)
        {}
    virtual ~AssetDir(void) {
        delete mFileInfo;
    }

    /*
     * Vector-style access.
     */
    size_t getFileCount(void) { return mFileInfo->size(); }
    const String8& getFileName(int idx) {
        return mFileInfo->itemAt(idx).getFileName();
    }
    const String8& getSourceName(int idx) {
        return mFileInfo->itemAt(idx).getSourceName();
    }

    /*
     * Get the type of a file (usually regular or directory).
     */
    FileType getFileType(int idx) {
        return mFileInfo->itemAt(idx).getFileType();
    }

private:
    /* these operations are not implemented */
    AssetDir(const AssetDir& src);
    const AssetDir& operator=(const AssetDir& src);

    friend class AssetManager;
    friend class AssetManager2;

    /*
     * This holds information about files in the asset hierarchy.
     */
    class FileInfo {
    public:
        FileInfo(void) {}
        FileInfo(const String8& path)      // useful for e.g. svect.indexOf
            : mFileName(path), mFileType(kFileTypeUnknown)
            {}
        ~FileInfo(void) {}
        FileInfo(const FileInfo& src) {
            copyMembers(src);
        }
        const FileInfo& operator= (const FileInfo& src) {
            if (this != &src)
                copyMembers(src);
            return *this;
        }

        void copyMembers(const FileInfo& src) {
            mFileName = src.mFileName;
            mFileType = src.mFileType;
            mSourceName = src.mSourceName;
        }

        /* need this for SortedVector; must compare only on file name */
        bool operator< (const FileInfo& rhs) const {
            return mFileName < rhs.mFileName;
        }

        /* used by AssetManager */
        bool operator== (const FileInfo& rhs) const {
            return mFileName == rhs.mFileName;
        }

        void set(const String8& path, FileType type) {
            mFileName = path;
            mFileType = type;
        }

        const String8& getFileName(void) const { return mFileName; }
        void setFileName(const String8& path) { mFileName = path; }

        FileType getFileType(void) const { return mFileType; }
        void setFileType(FileType type) { mFileType = type; }

        const String8& getSourceName(void) const { return mSourceName; }
        void setSourceName(const String8& path) { mSourceName = path; }

        /*
         * Handy utility for finding an entry in a sorted vector of FileInfo.
         * Returns the index of the matching entry, or -1 if none found.
         */
        static int findEntry(const SortedVector<FileInfo>* pVector,
            const String8& fileName);

    private:
        String8    mFileName;      // filename only
        FileType    mFileType;      // regular, directory, etc

        String8    mSourceName;    // currently debug-only
    };

    /* AssetManager uses this to initialize us */
    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }

    SortedVector<FileInfo>* mFileInfo;
};

}; // namespace android

#endif // __LIBS_ASSETDIR_H
