/*
    This file is part of libtermui.

    libtermui 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.

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

    Copyright 2006, Alexandre Becoulet <alexandre.becoulet@free.fr>

*/

#ifdef CONFIG_LIBTERMUI_FILEIO
#include <stdio.h>
#endif

#ifdef CONFIG_LIBTERMUI_SSL
#include <openssl/ssl.h>
#endif

#ifdef CONFIG_LIBTERMUI_TERMIOS
# include <termios.h>
#endif

#ifdef CONFIG_LIBTERMUI_LIBSSH
# include <libssh/libssh.h>
#endif

#ifndef TERMUI_TERMIO_H_
#define TERMUI_TERMIO_H_

struct termui_term_s;

#define TERMUI_TERMIO_FCN_GETSIZE(f)	\
  termui_err_t f(struct termui_term_s *tm, termui_cursor_pos_t *x, termui_cursor_pos_t *y)

#define TERMUI_TERMIO_FCN_GETTYPE(f)	\
  const char * f(struct termui_term_s *tm)

#define TERMUI_TERMIO_FCN_WRITE(f)	\
  void f(struct termui_term_s *tm, const void *data, termui_size_t size)

#define TERMUI_TERMIO_FCN_READ(f)	\
  int_fast16_t f(struct termui_term_s *tm)

#define TERMUI_TERMIO_FCN_POLLFD(f)	\
  int32_t f(struct termui_term_s *tm)

#define TERMUI_TERMIO_FCN_CLEANUP(f)	\
  void f(struct termui_term_s *tm)

/** This function returns terminal size or error if not able to determine */
typedef TERMUI_TERMIO_FCN_GETSIZE(termui_termio_getsize_t);

/** This function returns terminal type name or NULL if not able to determine */
typedef TERMUI_TERMIO_FCN_GETTYPE(termui_termio_gettype_t);

/** This function write some characters to terminal */
typedef TERMUI_TERMIO_FCN_WRITE(termui_termio_write_t);

/** This function reads one character from terminal or EOT on error */
typedef TERMUI_TERMIO_FCN_READ(termui_termio_read_t);

/** This function return a pollable file descriptor */
typedef TERMUI_TERMIO_FCN_POLLFD(termui_termio_pollfd_t);

/** This function cleanup terminal termio object */
typedef TERMUI_TERMIO_FCN_CLEANUP(termui_termio_cleanup_t);

#ifdef CONFIG_LIBTERMUI_FILEIO
/** @this initializes a terminal termio object for raw io on a @tt FILE stream */
termui_err_t
termui_file_io_init(struct termui_term_s *tm, FILE *file, const char *term_type);

/** @internal */
struct termui_term_fileio_s
{
  FILE *stream;
};
#endif

#ifdef CONFIG_LIBTERMUI_RAWFD
/** @this initializes a terminal termio object for raw io on a file descriptor */
termui_err_t
termui_rawfd_io_init(struct termui_term_s *tm, int32_t fd_in, int32_t fd_out, const char *term_type);

/** @internal */
struct termui_term_rawfd_s
{
  int32_t	fd_in;
  int32_t	fd_out;
};
#endif

#ifdef CONFIG_LIBTERMUI_TERMIOS
/** @this initializes a terminal termio object for use with a UNIX tty
    file descriptor */
termui_err_t
termui_tty_io_init(struct termui_term_s *tm, int32_t fd_in, int32_t fd_out);

/** @internal */
struct termui_term_tty_s
{
  int32_t		fd_in;
  int32_t		fd_out;
  struct termios	old_tio;  
};
#endif

#ifdef CONFIG_LIBTERMUI_TELNET

# ifdef CONFIG_LIBTERMUI_SOCKET
/** @this initializes a terminal termio object for use as a telnet
    termio on given socket */
termui_err_t
termui_telnet_io_init(struct termui_term_s *tm, int32_t socket);
# endif

# ifdef CONFIG_LIBTERMUI_SSL
/** @this initializes a terminal termio object for use as a telnet
    termio over given SSL object */
termui_err_t
termui_telnet_ssl_io_init(struct termui_term_s *tm, SSL *ssl);
# endif

/** @internal */
struct termui_term_telnet_s
{
  termui_cursor_pos_t	width, height;
  union {
# ifdef CONFIG_LIBTERMUI_SOCKET
    int32_t		soc;
# endif
# ifdef CONFIG_LIBTERMUI_SSL
    SSL			*ssl;
# endif
  }			tr;
# if defined(CONFIG_LIBTERMUI_SSL) && defined(CONFIG_LIBTERMUI_SOCKET)
  termui_termio_read_t	*raw_read;
  termui_termio_write_t	*raw_write;
# endif
};
#endif

# ifdef CONFIG_LIBTERMUI_LIBSSH
termui_err_t
termui_libssh_io_init(struct termui_term_s *tm,
		      ssh_session s, ssh_channel c);

struct termui_term_libssh_s
{
  termui_cursor_pos_t	width, height;
  ssh_session session;
  ssh_channel channel;
};
#endif

/** @this cleanups a terminal termio object */
#define termui_termio_cleanup(tm)  (tm)->s_cleanup(tm);

#endif

