// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1994
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        connect.h
// 
// Purpose:     
// 
// Created:     28 Jun 95   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// 
// </file> 
#ifndef hg_dispatch_connect_h
#define hg_dispatch_connect_h

#include <hyperg/utils/inetaddr.h>
#include <hyperg/utils/inetsocket.h>

class ConnectArgs ;
class ConnectRequest ;
class ConnectRequests ; // some helpful container used by Connecter only

class Connectable {
public:
   virtual void connected (const ConnectArgs& /*as a kind of a reference number*/, 
                           const INETSocketPtr&) = 0 ;
   virtual void connectError (const ConnectArgs& /*as above*/) = 0 ;
} ;


class ConnectArgs {
public:
   ConnectArgs() ;
   ConnectArgs (const ConnectArgs&) ;

   ConnectArgs& operator = (const ConnectArgs&) ;

   const INETAddress& address() const { return address_; }
   long refno() const { return refno_; }
   long timeout() const { return timeout_; }

   ConnectArgs& address (const INETAddress& a) { address_=a; return *this; }
   ConnectArgs& refno (long r) { refno_=r; return *this; }
   ConnectArgs& timeout (long t) { timeout_=t; return *this; }

private: 
   INETAddress address_ ;
   long refno_ ;
   long timeout_ ;
} ;
inline ConnectArgs :: ConnectArgs()
: address_(),
  refno_(-1),
  timeout_(0) {}
inline ConnectArgs& ConnectArgs :: operator = (const ConnectArgs& ca) {
   address_ = ca.address_ ;
   refno_ = ca.refno_ ;
   timeout_ = ca.timeout_ ;
   return *this ;
}
inline ConnectArgs :: ConnectArgs (const ConnectArgs& ca) {
   operator = (ca) ;
}


class Connecter {
public:
   boolean beginRequest (Connectable*, const ConnectArgs&) ;

   // terminate the request with refno (default all pending requests)
   boolean endRequest (const Connectable*, long refno=-1) ;

   static Connecter& instance() ;

private:
   friend class ConnectRequest ; // calling this -->
   void rem_requ_(const ConnectRequest*) ;

   Connecter() ;
   Connecter (const Connecter&) {}
   ~Connecter() {} // should live forever

   Connecter& operator = (const Connecter&) { return *this; }

private:
   ConnectRequests* requests_ ;

   static Connecter* instance_ ;
} ;


#endif
