/*****************************
File:      RemoteServer.h
Language:   C++ (header)
Project:    H3DNetworkingUtils
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is H3DNetworkingUtils v1.0.

The Initial Developer of the Original Code is CSIRO.
Portions created by the Initial Developer are Copyright (C) 1009 CSIRO. All Rights Reserved.
Contributor(s):
    Chris Gunn  <Chris.Gunn@csiro.au> <ChrisJGunn@gmail.com>
***************************/

/// \file RemoteServer.h
/// \brief Header file for RemoteServer, an abstract base class for H3D communications servers.

#ifndef RemoteServer_H
#define RemoteServer_H

//
// <field "INPUT_OUTPUT" "listeningPort" "SFInt32" "9876">
// <field "INPUT_OUTPUT" "open"           "SFBool" "FALSE">

#include "H3DNetworkingUtils/RemoteConnection.h"

// This next line is needed because H3DAPI.dll instantiates this template but this class does not see the header with 
// the instantiation in it. So without the line, this class would instantiate an identical one and there would
// be a multiply defined symbol in the link stage.
template struct __declspec(dllimport) H3D::AutoUpdate <H3D::SFBool>;

namespace H3DNetworkingUtils {
   
/// \class RemoteServer
/// The RemoteServer class starts a Remote server using a TCP port.
/// It starts listening on the given port for a connection from a
/// remote client, then continues with the base class's behaviour, using a
/// newly allocate dport for communications.
/// When open is changed from false to true, the listening port is monitored
/// for a connection from a client.
/// When it is changed from true to false, the connection is closed.
/// At present, only one remote connection is handled.  \n
/// <b>Examples:</b>
///   - <a href="../../examples/RemoteSFTestServer.x3d">RemoteMFTestServer.x3d</a>
///   - <a href="../../examples/RemoteSFTestClient.x3d">RemoteMFTestClient.x3d</a>

class H3D_NETWORKING_UTILS_DLL_SPEC RemoteServer : public RemoteConnection {
public:

   class OpenHandler;
   
   /// Constructor
   RemoteServer(  H3D::Inst<H3D::SFInt32> _listeningPort = 0,
                  H3D::Inst<OpenHandler>  _open = 0);

   /// Destructor
   virtual ~RemoteServer();
   
  /// The X3D database
  static H3D::H3DNodeDatabase database;

  /// Handles opening of communications
  class H3D_NETWORKING_UTILS_DLL_SPEC OpenHandler : public H3D::AutoUpdate < H3D::SFBool > {
  public:
     OpenHandler() {value = false;}
     virtual void setValue(bool const & val, int id = 0);
    virtual void update();
  };

  // Public fields

  /// The port on which the server will listen for connections \n
  /// access type: inputOutput \n
  /// basic type: SFInt32 \n
  /// default value: 9876
  auto_ptr<H3D::SFInt32> listeningPort;

  /// When this turns true, the server will listen for connections \n
  /// access type: inputOutput \n
  /// basic type: SFBool \n
  /// default value: FALSE
  auto_ptr<OpenHandler>      open;

  virtual void initialize();


protected:

  virtual void startServer(int port_number) = 0;
  // Supplied by sub-classes.

  virtual bool doClosedActions();
  // Do any actions that are required while the connection is closed.
  // The return value tells the receive loop whether top break out of the
  // loop.
  // This class returns true, to tell the receive loop to break out when
  // the connection is closed, so that the thread can be used for listening for
  // a new connection.


private:

};

}

#endif
