//
// Copyright 2005 The Android Open Source Project
//
// Our collection of devices.
//

// For compilers that support precompilation, include "wx/wx.h".
#include "wx/wxprec.h"

// Otherwise, include all standard headers
#ifndef WX_PRECOMP
# include "wx/wx.h"
#endif
//#include "wx/image.h"   // needed for Windows build


#include "PhoneCollection.h"
#include "PhoneData.h"
#include "MyApp.h"

#include <utils.h>

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <assert.h>

using namespace android;

/*static*/ PhoneCollection* PhoneCollection::mpInstance = NULL;

/*static*/ const char* PhoneCollection::kLayoutFile = "layout.xml";


/*
 * (Re-)scan the specified directory for phones.  We register a hit if we can
 * see a file called "<directory>/layout.xml".
 */
void PhoneCollection::ScanForPhones(const char* directory)
{
    /*
     * Scan through the directory and find everything that looks like it
     * might hold phone data.
     */
    StringArray strArr;

#ifdef BEFORE_ASSET
    DIR* dirp;
    struct dirent* entp;

    dirp = opendir(directory);
    if (dirp == NULL) {
        char buf[512];
        fprintf(stderr, "ERROR: unable to scan directory '%s' for phone data\n",
            directory);
        fprintf(stderr, "Current dir is %s\n", getcwd(buf, sizeof(buf)));
        return;
    }

    while (1) {
        wxString dirName;
        wxString fileName;

        entp = readdir(dirp);
        if (entp == NULL)
            break;              // done with scan
        dirName = directory;
        dirName += '/';
        dirName += entp->d_name;
        fileName = dirName;
        fileName += '/';
        fileName += kLayoutFile;

        if (access(fileName, R_OK) == 0) {
            strArr.push_back(dirName);
            //printf("--- examining '%s'\n", (const char*) fileName);
        }
    }
    closedir(dirp);
#else
    android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager();
    android::AssetDir* pDir;
    int i, count;

    pDir = pAssetMgr->openDir("");
    assert(pDir != NULL);
    count = pDir->getFileCount();

    for (i = 0; i < count; i++) {
        android::String8 layoutPath;

        if (pDir->getFileType(i) != kFileTypeDirectory)
            continue;

        layoutPath = pDir->getFileName(i);
        layoutPath.appendPath(kLayoutFile);

        if (pAssetMgr->getFileType(layoutPath.string()) == kFileTypeRegular) {
            strArr.push_back(pDir->getFileName(i).string());
            printf("--- examining '%s'\n", layoutPath.string());
        }
    }

    delete pDir;
#endif

    if (strArr.size() == 0) {
        fprintf(stderr, "ERROR: no phone data found in '%s'\n", directory);
        return;
    }

    /*
     * Found some candidates.  If they parse successfully, add them to
     * our list.
     *
     * We sort them first, because it's nice when everybody's user
     * interface looks the same.  Note we're sorting the directory name,
     * so it's possible to define a sort order in the filesystem that
     * doesn't require messing up the phone's title string.
     */
    mPhoneList.clear();
    strArr.sort(StringArray::cmpAscendingAlpha);

    for (int i = 0; i < strArr.size(); i++) {
        PhoneData tmpPhone;

        if (!tmpPhone.Create(strArr.getEntry(i))) {
            fprintf(stderr, "Sim: Abandoning phone '%s'\n", strArr.getEntry(i));
            //strArr.erase(i);
            //i--;
        } else {
            if (GetPhoneData(tmpPhone.GetName()) != NULL) {
                fprintf(stderr, "Sim: ERROR: duplicate name '%s' in '%s'\n",
                    tmpPhone.GetName(), strArr.getEntry(i));
            } else {
                mPhoneList.push_back(tmpPhone);
            }
        }
    }
}


/*
 * Return the Nth member of the phone data array.  (Replace w/Vector.)
 */
PhoneData* PhoneCollection::GetPhoneData(int idx)
{
    typedef List<PhoneData>::iterator Iter;

    for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) {
        if (idx == 0)
            return &(*ii);
        --idx;
    }
    return NULL;
}

/*
 * Return the entry whose phone data name matches "name".
 */
PhoneData* PhoneCollection::GetPhoneData(const char* name)
{
    typedef List<PhoneData>::iterator Iter;

    for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) {
        if (strcasecmp((*ii).GetName(), name) == 0)
            return &(*ii);
    }
    return NULL;
}

