// -*- Mode: C++; tab-width: 4 -*-

// ======================================================================
// Copyright 1996 by Sam Rushing
// 
//                         All Rights Reserved
// 
// Permission to use, copy, modify, and distribute this software and
// its documentation for any purpose and without fee is hereby
// granted, provided that the above copyright notice appear in all
// copies and that both that copyright notice and this permission
// notice appear in supporting documentation, and that the name of Sam
// Rushing not be used in advertising or publicity pertaining to
// distribution of the software without specific, written prior
// permission.
// 
// SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
// NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
// ======================================================================

#ifndef ASYNCHAT_H
#define ASYNCHAT_H

#ifdef _WIN32
#pragma warning(disable: 4237)
#include <bstring.h>
#include <list.h>
#include <stack.h>
#else
#include <string>
#include <list>
#include <queue>
#endif

#include "asyncore.h"

// ===========================================================================
// producer and simple_producer
// ===========================================================================

class producer
{
public:
  virtual string* more (void) = 0;
};

class simple_producer : public producer
{
public:
  string data;

  simple_producer (const string& output_string) { data = output_string; }

  string* more (void) {
	string * slice = new string (data.substr (0,512));
	data.remove (0,512);
	return slice;
  }
};

// ===========================================================================
// async_chat
// ===========================================================================

class async_chat : public dispatcher
{
public:
  static const int ac_in_buffer_size;
  static const int ac_out_buffer_size;
  static const string null_terminator;

  string ac_in_buffer;
  string ac_out_buffer;
  string terminator;

  queue<list<producer*> > producer_fifo;

  virtual void	set_terminator			(const string & t);
  virtual string& get_terminator		(void);

  void			handle_read				(void);
  void			handle_write			(void);
  
  virtual void	collect_incoming_data	(const string& data) { };
  virtual void	found_terminator		(void) { };
  virtual void	send					(const string& data);
  virtual void	send					(producer* p);

  bool			readable				(void);
  bool			writable				(void);
  void			refill_buffer			(void);
  void			initiate_send			(void);
  void			close_when_done			(void)
  { producer_fifo.push ((producer *) 0); }

};

#endif // ASYNCHAT_H
