//<copyright>
//
// Copyright (c) 1995
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
//
//</copyright>

//<file>
//
// Name:        urlserver.C
//
// Purpose:     server for fetching texture images and inline scenes from the Web
//
// Created:     29 Nov 1995   Michael Pichler
//
// Changed:     30 Nov 1995   Michael Pichler
//
// $Id: urlserver.C,v 1.1 1995/12/20 15:53:42 mpichler Exp $
//
//</file>


#include "urlserver.h"
#include "httpreader.h"

#include "scene3d.h"

#include <hyperg/WWW/HTParse.h>
#include <hyperg/utils/str.h>

#undef DEBUG
/* also defined by HTParse.h */
#include <hyperg/hyperg/verbose.h>

#include <iostream.h>


/***** URLRequest *****/

class URLRequest
{
  public:
    URLRequest (
      const char* url, const char* docurl,
      const QvWWWInline* in_line,
      void*  // reserved for texture images
    )
    {
      url_ = url;
      docurl_ = docurl;
      inline_ = in_line;
    }


    RString url_;
    RString docurl_;
    const QvWWWInline* inline_;
    //  texture_;
};  // URLReqeust



/***** URLReader *****/


static const char* const appname = "VRweb/1.1";  // User-Agent for URL request


class URLReader: public HTTPReader
{
  public:
    URLReader (URLRequest* req)  // must not be nil
    : HTTPReader (req->url_, req->docurl_, appname)
    {
      inline_ = req->inline_;
    }

// TODO: callbacks for "real" work

    // HTTPReader
    void success (const char*);
    void failure ();

    const QvWWWInline* inline_;
    //  texture_;
};  // URLReader


void URLReader::success (const char* filename)
{
  cerr << "TODO: read data from file filename (via callback) and delete the file" << endl;
  delete this;
}


void URLReader::failure ()
{
  cerr << "connection interrupted or something else" << endl;
  delete this;
}



/***** URLServer *****/


URLServer::URLServer (Scene3D* scene)
{
  scene_ = scene;
  reqtextures_ = 0;

  pendinginlinereq_ = 0;
  pendingtexturereq_ = 0;
}


URLServer::~URLServer ()
{
  DEBUGNL ("~URLServer");

  clearAllRequests ();

  DEBUGNL ("~URLServer finished");
}


void URLServer::clearAllRequests ()
{
  DEBUGNL ("URLServer::clearAllRequests");

  delete pendinginlinereq_;
  pendinginlinereq_ = 0;

  delete pendingtexturereq_;
  pendingtexturereq_ = 0;

  URLRequest* req;
  for (req = (URLRequest*) inlinerequests_.first ();  req;
       req = (URLRequest*) inlinerequests_.next ())
  { delete req;
  }
  inlinerequests_.clear ();  // clear list of VRML inline requests

  for (req = (URLRequest*) texturerequests_.first ();  req;
       req = (URLRequest*) texturerequests_.next ())
  { delete req;
  }
  texturerequests_.clear ();  // clear list of VRML inline requests

  reqtextures_ = 0;

  DEBUGNL ("URLServer::clearAllRequests finished");
}


// appendInlineRequest
// put a request for a VRML inline;
// handleRequests must be called when requests should be carried out

void URLServer::appendInlineRequest (
  QvWWWInline* node,
  const char* url,
  const char* docurl
)
{
  DEBUGNL ("appending request for VRML inline");

  URLRequest* req = new URLRequest (url, docurl, node, NULL);
  inlinerequests_.put (req);

} // appendInlineRequest


// appendTextureRequest
// put a request for a texture image;
// handleRequests must be called when requests should be carried out

// void URLServer::appendTextureRequest (
// )
// {
// TODO
// } // appendTextureRequest


// handleRequests
// hanldes the next request unless another one is pending
// texturesalso determines whether texture requests are handled too
// when a request is finished, the procedure will be called again
// until all requests are handled

void URLServer::handleRequests (int texturesalso)
{
  reqtextures_ |= texturesalso;  // is reset in clearAllRequests

  // only one at a time (may handle multiple connections)
  if (pendinginlinereq_ || pendingtexturereq_)
  { DEBUGNL ("URLServer::handleRequests: another request currently pending");
    return;
  }

  URLRequest* req;

  while (req = (URLRequest*) inlinerequests_.first ())
  { // handle next request (if one succeeds exit loop)
    DEBUGNL ("URLServer: handling VRML inline request");

    URLReader* reader = new URLReader (req);
    inlinerequests_.removeFirst ();

    if (reader->error ())  // invalid URL or no connection
      delete reader;  // forget this request, try next one
    else  // TODO: feedback!!! (via callbacks)
      return;  // handle requests one by one
  }

  if (!reqtextures_)
  { DEBUGNL ("URLServer::handleRequests: no more inlines; textures not required");
    return;
  }

  req = (URLRequest*) texturerequests_.first ();
  if (req)
  {
    DEBUGNL ("URLServer: handling texture request");
cerr << "TODO" << endl;
    
    return;
  }

  DEBUGNL ("URLServer::handleRequests: nothing more to handle");

} // handleRequests
