// inputhandler.cpp,v 1.16 2001/03/26 21:16:52 coryan Exp


#include "inputhandler.h"
#include "errorlog.h"
#include "debug.h"
#include "Event_Comm_i.h"
#include "supplier.h"
#include "tao/ORB_Core.h"

InputHandler::InputHandler ()
  : supplier_ (0),
  shutdown_(SEM_EMPTY, "SHUTDOWN SEM")
{
  // No-Op.
}

InputHandler::~InputHandler (void)
{
  DPRINTF("InputHandler::~InputHandler\n");
    // Make sure to cleanup the STDIN handler.
}

int
InputHandler::close (void)
{
  DPRINTF("closing down Supplier::InputHandler\n");
  
  // Make sure to cleanup the STDIN handler.
  return this->remove_stdin_handler (
       TAO_ORB_Core_instance ()->reactor (),
       TAO_ORB_Core_instance ()->thr_mgr ());
}

int
InputHandler::initialize (Supplier *supplier)
{
  supplier_ = supplier;
  // Register our <Input_Handler> to handle STDIN events, which will
  // trigger the <handle_input> method to process these events.

  if (this->register_stdin_handler
      (this,
       TAO_ORB_Core_instance ()->reactor (),
       TAO_ORB_Core_instance ()->thr_mgr ()) == -1) {
	   ErrorLog::logError("register_stdin_handler");
	   return -1;
  }

  return 0;
}

// Frame input events and notify <Consumers>.

int
InputHandler::handle_input (ACE_HANDLE)
{
  char buf[BUFSIZ];

  // Read up to BUFSIZ worth of data from ACE_HANDLE h.

  if (ACE_OS::fgets (buf,
		     sizeof buf - 1,
                     stdin) == 0)
    {
      DPRINTF("shutting down InputHandler\n");
      return 0;
    }
  else
    {
      size_t n = ACE_OS::strlen (buf);

      // Null terminate the buffer, replacing the '\n' with '\0'.
      if (buf[n - 1] == '\n')
	buf[n - 1] = '\0';
      else
	buf[n] = '\0';
      DPRINTF("queuing for event %s\n", buf);
    }


  ACE_ASSERT (supplier_ != 0);
  
  // Use the notifier to notify Consumers.
  ACE_TRY_NEW_ENV
  {
	  CORBA::Any any;

	  Event_Comm::Event event;
	  
	  if (ACE_OS::strncmp (buf, "quit", 4) == 0) {
		  // Tell the main event loop to shutdown.
		  this->sendShutdown ();
		  return -1;
	  }
	  
	  // Pass the buf over in the tag field.
	  event.tag_ = ACE_OS::strdup (buf);
	  
	  // This is where the "any" value goes or the object
	  // reference...  event.value_ = ...
	  
	  any <<= event;
	  
	  // Forward <Event> to all <Consumers>.
	  supplier_->queue_event (any);

	  
   ACE_TRY_CHECK;
   }
   ACE_CATCHANY
   {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Unexpected Error\n");
   }
   ACE_ENDTRY;

  return 0;
}

void InputHandler::sendShutdown(void)
{
	shutdown_.set();
}
