/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWREMOTE_SOCKETPROVIDER_H
#define __IWREMOTE_SOCKETPROVIDER_H

#include <iwremote/callprovider.h>
#include <net/socketset.h>
#include <net/sslcertmanager.h>
#include <net/udpconnection.h>
#include <net/tcpconnection.h>
#include <boost/intrusive_ptr.hpp>
#include <iwremote/socketremoteconnection.h>

namespace iwear
{
    namespace net
    {
/**
 * This class is a CallProvider for Socket based communication (IP Sockets,
 * maybe Unix sockets later or in a seperate class, dunno how to handle them in
 * contrast to usual IP sockets)
 */
class SocketProvider : public CallProvider
{
friend class SocketRemoteConnection;
private:
protected:
    /**
     * This set contains all the SocketRemoteConnections we have created.
     */

    TCPConnection master_tcp4;
    TCPConnection master_tcp6;

    UDPConnection master_udp4;
    UDPConnection master_udp6;

    /**
     * Thats a socketset of all the open connections and setup sockets we have.
     */
    SocketSet socks;

    /**
     * The certification manager we use if ssl connections are requested.
     */
    SSLCertManager* sslcert;

    float accept_timeout;

    float check_timeout;
    
    float connect_timeout;
    
    float idle_accept_timeout;
    
    float recv_timeout;
    
    float send_timeout;
    unsigned int max_queue_wait;

    void check_connections( void );

    void check_for_incoming( void );
    void check_existing( void );

    void register_connection( SocketRemoteConnectionPtr );
    void deregister_connection( SocketRemoteConnectionPtr );
//    void check_preallocated( void );
public:
    SocketProvider( CallManager* );
    virtual ~SocketProvider();

    void _debug_add_connection( RemoteConnectionPtr );

//    RPCStream& get_callrpcstream( uint32_t callid, RemoteObject& );
//    RPCStream& get_retrpcstream( uint32_t callid, RemoteObject& );

PH1 virtual void connected( RemoteConnectionPtr );

PH1 virtual void disconnected( RemoteConnectionPtr );

//    void search_object( RPCStream& );

    /**
     * Check for a stream thats destination is the system and return it. If
     * after the timeout for this callprovider (e.g. listening on socket) no
     * stream could be found, it returns NULL.
     */
    pair<RPCStream*,RemoteConnectionPtr> get_system_stream( double timeout );

    virtual void _debug_print_state( void );

    virtual RemoteConnectionPtr get_connection( HostConnector& );
};

}
}
#endif
