/* UI_FILE - a generic STDIO like output stream.
   Copyright (C) 1999-2013 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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; either version 3 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "ui-file.h"
#include "tui/tui-file.h"
#include "tui/tui-io.h"

#include "tui.h"

#include "gdb_string.h"

/* A ``struct ui_file'' that is compatible with all the legacy
   code.  */

/* new */
enum streamtype
{
  afile,
  astring
};

/* new */
struct tui_stream
{
  int *ts_magic;
  enum streamtype ts_streamtype;
  FILE *ts_filestream;
  char *ts_strbuf;
  int ts_buflen;
};

static ui_file_flush_ftype tui_file_flush;
extern ui_file_fputs_ftype tui_file_fputs;
static ui_file_isatty_ftype tui_file_isatty;
static ui_file_rewind_ftype tui_file_rewind;
static ui_file_put_ftype tui_file_put;
static ui_file_delete_ftype tui_file_delete;
static struct ui_file *tui_file_new (void);
static int tui_file_magic;

static struct ui_file *
tui_file_new (void)
{
  struct tui_stream *tui = XMALLOC (struct tui_stream);
  struct ui_file *file = ui_file_new ();

  set_ui_file_data (file, tui, tui_file_delete);
  set_ui_file_flush (file, tui_file_flush);
  set_ui_file_fputs (file, tui_file_fputs);
  set_ui_file_isatty (file, tui_file_isatty);
  set_ui_file_rewind (file, tui_file_rewind);
  set_ui_file_put (file, tui_file_put);
  tui->ts_magic = &tui_file_magic;
  return file;
}

static void
tui_file_delete (struct ui_file *file)
{
  struct tui_stream *tmpstream = ui_file_data (file);

  if (tmpstream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_delete: bad magic number"));
  if ((tmpstream->ts_streamtype == astring) 
      && (tmpstream->ts_strbuf != NULL))
    {
      xfree (tmpstream->ts_strbuf);
    }
  xfree (tmpstream);
}

struct ui_file *
tui_fileopen (FILE *stream)
{
  struct ui_file *file = tui_file_new ();
  struct tui_stream *tmpstream = ui_file_data (file);

  tmpstream->ts_streamtype = afile;
  tmpstream->ts_filestream = stream;
  tmpstream->ts_strbuf = NULL;
  tmpstream->ts_buflen = 0;
  return file;
}

struct ui_file *
tui_sfileopen (int n)
{
  struct ui_file *file = tui_file_new ();
  struct tui_stream *tmpstream = ui_file_data (file);

  tmpstream->ts_streamtype = astring;
  tmpstream->ts_filestream = NULL;
  if (n > 0)
    {
      tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
      tmpstream->ts_strbuf[0] = '\0';
    }
  else
    /* Do not allocate the buffer now.  The first time something is
       printed one will be allocated by tui_file_adjust_strbuf().  */
    tmpstream->ts_strbuf = NULL;
  tmpstream->ts_buflen = n;
  return file;
}

static int
tui_file_isatty (struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_isatty: bad magic number"));
  if (stream->ts_streamtype == afile)
    return (isatty (fileno (stream->ts_filestream)));
  else
    return 0;
}

static void
tui_file_rewind (struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_rewind: bad magic number"));
  stream->ts_strbuf[0] = '\0';
}

static void
tui_file_put (struct ui_file *file,
	      ui_file_put_method_ftype *write,
	      void *dest)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_put: bad magic number"));
  if (stream->ts_streamtype == astring)
    write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
}

/* All TUI I/O sent to the *_filtered and *_unfiltered functions
   eventually ends up here.  The fputs_unfiltered_hook is primarily
   used by GUIs to collect all output and send it to the GUI, instead
   of the controlling terminal.  Only output to gdb_stdout and
   gdb_stderr are sent to the hook.  Everything else is sent on to
   fputs to allow file I/O to be handled appropriately.  */

/* FIXME: Should be broken up and moved to a TUI specific file.  */

void
tui_file_fputs (const char *linebuffer, struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_streamtype == astring)
    {
      tui_file_adjust_strbuf (strlen (linebuffer), file);
      strcat (stream->ts_strbuf, linebuffer);
    }
  else
    {
      tui_puts (linebuffer);
    }
}

char *
tui_file_get_strbuf (struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_get_strbuf: bad magic number"));
  return (stream->ts_strbuf);
}

/* Adjust the length of the buffer by the amount necessary to
   accomodate appending a string of length N to the buffer
   contents.  */
void
tui_file_adjust_strbuf (int n, struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);
  int non_null_chars;

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_adjust_strbuf: bad magic number"));

  if (stream->ts_streamtype != astring)
    return;

  if (stream->ts_strbuf)
    {
      /* There is already a buffer allocated.  */
      non_null_chars = strlen (stream->ts_strbuf);

      if (n > (stream->ts_buflen - non_null_chars - 1))
	{
	  stream->ts_buflen = n + non_null_chars + 1;
	  stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
	}
    }
  else
    /* No buffer yet, so allocate one of the desired size.  */
    stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
}

static void
tui_file_flush (struct ui_file *file)
{
  struct tui_stream *stream = ui_file_data (file);

  if (stream->ts_magic != &tui_file_magic)
    internal_error (__FILE__, __LINE__,
		    _("tui_file_flush: bad magic number"));

  switch (stream->ts_streamtype)
    {
    case astring:
      break;
    case afile:
      fflush (stream->ts_filestream);
      break;
    }
}
