#include <piInstance.h>
#include <qPIWidget.h>
#include <qSystempi.h>
#include <OpenVrml/VrmlScene.h>
#include <OpenVrml/System.h>  // for defaultSystem
#include <resourceIo.h>
#include <ViewerQt.h>

static int loadCB( char *buf, int bufSize );

static piInstance *thePIinstance = 0;

static System piDefaultSystem;

piInstance::piInstance() : iv(0)
{
    qtSystem = new qSystem(this);
    qDebug("piInstance::piInstance()");
}

piInstance::~piInstance() 
{
    if (theSystem == qtSystem) theSystem = &piDefaultSystem;
    delete qtSystem;
    qDebug("piInstance::~piInstance()");
}

QNPWidget* piInstance::newWindow()
{
    iv = new qPIWidget;
    qtSystem->set_receiver( iv->receiver() );
    theSystem = qtSystem;
    qDebug("piInstance::newWindow()");
    return iv;
}

bool piInstance::newStreamCreated(QNPStream* qnps, StreamMode& smode)
{
    smode = AsFileOnly;
    qDebug("piInstance::newStreamCreated() for %s", qnps->url() );
    return TRUE;
}

void piInstance::streamAsFile(QNPStream* qnps, const char* fname)
{
    local_url = fname;
    resourceIoList->updateList( qnps->url(), fname );
    qDebug("piInstance::streamASFile(), fname = %s, qnps->url = %s",
                    fname, qnps->url() );
}

void piInstance::streamDestroyed( QNPStream * qnps)
{
    qDebug("piInstance::streamDestroyed()");
    // called when a stream is destroyed. At this point, the stream may be complete() and okay().
    // If it is not okay(), then an error has occurred. If it is okay(), but not complete(), then
    // the user has cancelled the transmission - do not give an error message in this case.

    piInstance *theInstance;
    theInstance = (piInstance*)qnps->instance();
    if (theInstance != 0 && qnps->complete() )
    {
        thePIinstance = theInstance;
        int fetchstate = ( qnps->okay() ) ? resourceIo::READY : resourceIo::NOT_AVAILABLE;
        if ( resourceIoList->updateState( qnps->url(), fetchstate) ) { // its a resource
            qDebug("notifying nodes interested in %s", qnps->url());
            resourceIoList->notify( qnps->url() );
            theInstance->iv->scene()->setModified( ); 
        }
        else { // its VRML
            thePIinstance->np_returned_file = (gzFile)gzopen(thePIinstance->local_url, "rb");
            theInstance->iv->scene()->loadFromFunction( loadCB, qnps->url());
        }
        thePIinstance = 0;
    }
}

static int loadCB( char *buf, int bufSize )
{
    qDebug("loadCB()");
    fflush(stdout); 
    int nread = 0;
    if (thePIinstance)
    {
        nread = gzread( thePIinstance->np_returned_file, buf, bufSize );
        if (nread == 0) gzclose(thePIinstance->np_returned_file);
        if (nread == -1) theSystem->error("loadCB: gzread error on %s\n", thePIinstance->local_url);
    }
    return nread;
}


