// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <OB/CORBA.h>
#include <OB/Util.h>

#include <Receiver_impl.h>

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#ifdef HAVE_TERMIO_H
#   include <termio.h>
#else
#   ifndef HAVE_TERMIOS_H
#       error Neither termio.h nor termios.h is available!
#   endif
#   include <termios.h>
#endif
#include <sys/ioctl.h>

#ifdef HAVE_TERMIO_H
static struct termio TerminalSettings;
#else
static struct termios TerminalSettings;
#endif

extern "C"
{

static void
ResetTerm(int sig)
{
    //
    // Reset terminal
    //
#ifdef HAVE_TERMIO_H
    ioctl(STDIN_FILENO, TCSETA, &TerminalSettings);
#else
    ioctl(STDIN_FILENO, TCSETS, &TerminalSettings);
#endif

    //
    // Send signal again
    //
    signal(sig, SIG_DFL);
    kill(getpid(), sig);
}

}

int
main(int argc, char* argv[], char*[])
{
    //
    // Get host and port
    //
    char host[1024];
    char port[256];
    cout << "Host name? " << flush;
    cin >> host;
    cout << "Port number? " << flush;
    cin >> port;

    CORBA_UShort portNum = atoi(port);

    cout << "Using object `Chat-Server' from host `" << host
	 << "' on port " << portNum << "..." << endl;

    char c;
    cin.read(&c, 1);

    //
    // Set terminal mode
    //
#ifdef HAVE_TERMIO_H
    struct termio ctl;
    ioctl(STDIN_FILENO, TCGETA, &TerminalSettings);
    ioctl(STDIN_FILENO, TCGETA, &ctl);
#else
    struct termios ctl;
    ioctl(STDIN_FILENO, TCGETS, &TerminalSettings);
    ioctl(STDIN_FILENO, TCGETS, &ctl);
#endif
    ctl.c_lflag &= ~(ICANON | ECHO);
    ctl.c_cc[VMIN] = 1;
    ctl.c_cc[VTIME] = 0;
#ifdef HAVE_TERMIO_H
    ioctl(STDIN_FILENO, TCSETA, &ctl);
#else
    ioctl(STDIN_FILENO, TCSETS, &ctl);
#endif

    //
    // Set signal handler
    //
    signal(SIGHUP, ResetTerm);
    signal(SIGINT, ResetTerm);
    signal(SIGTERM, ResetTerm);
    signal(SIGQUIT, ResetTerm);

    int status;

    try
    {
	//
	// Create ORB and BOA
	//
	CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
	CORBA_BOA_var boa = orb -> BOA_init(argc, argv);
	
	//
	// Set the concurrency model
	//
	orb -> conc_model(CORBA_ORB::ConcModelReactive);
	boa -> conc_model(CORBA_BOA::ConcModelReactive);
	
	//
	// Get "server" object
	//
	CORBA_Object_var obj =
	    orb -> get_inet_object(host, portNum, "Chat-Server");
	assert(!CORBA_is_nil(obj));
	
	Broadcaster_var server = Broadcaster::_narrow(obj);
	assert(!CORBA_is_nil(server));
	
	//
	// Initialize the servers so that incoming requests are
	// handled from this point on
	//
	boa -> init_servers();
	
	//
	// Create client object
	//
	Receiver_var client = new Receiver_impl(server);
	
	//
	// Run implementation
	//
	boa -> impl_is_ready(CORBA_ImplementationDef::_nil());

	status = 0;
    }
    catch(CORBA_SystemException& ex)
    {
	OBPrintException(ex);
	status = 1;
    }

    //
    // Reset terminal
    //
#ifdef HAVE_TERMIO_H
    ioctl(STDIN_FILENO, TCSETA, &TerminalSettings);
#else
    ioctl(STDIN_FILENO, TCSETS, &TerminalSettings);
#endif

    return status;
}
