#include <resourceIo.h>
#include <string.h>

resIoList::resIoList()
{
    riolist.setAutoDelete(true);
}

resIoList::~resIoList()
{
    riolist.clear();
}

const char* resIoList::checkQueued(const char *url,  QNPInstance *q)
{
    resourceIo *i;
    for (i = riolist.first(); i != 0; i = riolist.next())
        if ( strcmp(url, i->url)  == 0 )  {
            return ( i->fetchState == resourceIo::READY ) ? i->localFilename : NULL; 
        }
    // did not return-->we need to queue the request.
    resourceIo *rio;
    rio = new resourceIo;
    rio->localFilename = NULL;
    rio->fetchState = resourceIo::IN_PROGRESS;
    rio->url = strdup(url);
    riolist.append( rio );
    qDebug("creating new resource for %s", url);
    q->getURL(url);
    return NULL;
}

bool resIoList::updateList(const char*url, const char*filename)
{
    // return true if updated, false otherwise. Tells us whether this URL was
    // requested via httpFetch, as are Textures and Audio clips, or via 
    // browser navigation, like wrl's and anchors. Need to know this because VRML
    // goes thru the parser (loadCB), while textures and audio clips do not.
    
    resourceIo *i;
    for (i = riolist.first(); i != 0; i = riolist.next())
        if ( strcmp(url, i->url) == 0 )  {
            i->localFilename = strdup(filename);
            qDebug("updated %s with localfile %s", url, filename);
            // don't change the state here from IN_PROGRESS, since we learn the file name
            // while it is still streaming
            return true;
        }
    qDebug("failed to update %s", url );
    return false;
}

bool resIoList::updateState(const char*url, int State)
{
    // return true if updated, false otherwise. Tells us whether this URL was
    // requested via httpFetch, as are Textures and Audio clips, or via 
    // browser navigation, like wrl's and anchors. Need to know this because VRML
    // goes thru the parser (loadCB), while textures and audio clips do not.
    
    resourceIo *i;
    for (i = riolist.first(); i != 0; i = riolist.next())
        if ( strcmp(url, i->url) == 0 )  {
            i->fetchState = State;
            qDebug("set %s fetchState to %d, READY = %d, IN+PROGRESS = %d", url ,
                            State, resourceIo::READY, resourceIo::IN_PROGRESS);
            return true;
        }
    return false;
}

void resIoList::setClient(const char* url, VrmlNode *ptr)
{
    resourceIo *i;
    for (i = riolist.first(); i != 0; i = riolist.next())
        if ( strcmp(url, i->url) == 0 )  {
            std::list<VrmlNode*>::iterator n;
            for (n = i->clientList.begin(); n != i->clientList.end(); ++n)
                if ((*n) == ptr) return;
           (i->clientList).push_front( ptr );
            qDebug("added client for url %s", url);
            return;
        }
    qDebug("resourceIo; have a client but no matching requestor; url = %s", url);
}

void resIoList::notify(const char* url)
{
    resourceIo *i;
    for (i = riolist.first(); i != 0; i = riolist.next())
        if ( strcmp(url, i->url) == 0 )  {
            std::list<VrmlNode*>::iterator n;
            for (n = i->clientList.begin(); n != i->clientList.end(); ++n)
               if ( *n ) (*n)->setModified(); 
        }
}


