// utf-8

/*	Copyright  (c)	Günter Woigk  2002-2003
  					mailto:kio@little-bat.de

	This file is free software

 	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.  

 	Permission to use, copy, modify, distribute, and sell this software and
 	its documentation for any purpose is hereby granted without fee, 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 the copyright holder not be used
 	in advertising or publicity pertaining to distribution of the software
 	without specific, written prior permission. The copyright holder makes no
 	representations about the suitability of this software for any purpose.
 	It is provided "as is" without express or implied warranty.

 	THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 	INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 	EVENT SHALL THE COPYRIGHT HOLDER 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.
*/



//	***!*** man console_codes



#ifndef _stream_h_
#define _stream_h_

#include <fcntl.h>
#include "kio/kio.h"
#include "unix/file_utilities.h"
#include "ustring/sstring.h"



typedef int VT_Color;
enum
{		VT_normal = 0,

		VT_black,
		VT_red,
		VT_green,
		VT_yellow,
		VT_blue,
		VT_magenta,
		VT_cyan,
		VT_white,

		VT_dark=0,
		VT_bright=16,

		VT_bold=32,
		VT_inverse=64,
		VT_underline=128
};


extern String		VT_Bold			( cString& );
extern String		VT_Inverse		( cString& );
extern String		VT_Underline	( cString& );
extern String		VT_FGColor 		( cString& s, VT_Color c );
extern String		VT_BGColor 		( cString& s, VT_Color c );
extern String		VT_Attr 		( cString& s, VT_Color fg, VT_Color bg=VT_normal );




class Stream
{

	int				fd;				// unix file descriptor
	String			path;			// open() path
	s_type			type;			// stream type

	bool			openout;		// open state flags
	bool			openin;

	UCS4Char		linebreak;		// dflt: system default
	CharEncoding	conversion;		// tty: character set conversion. dflt: utf-8

	long			timeoutin;		// timeout for blocking input [ms]	dflt: 0=for ever
	long			timeoutout;		// timeout for blocking output [ms]	dflt: 0=for ever

	bool			getstoptabs;	// shall get() stop on 'tab' in addition to cr,lf,ff,eof	dflt: no
	bool			getstopctls;	// shall get() stop on any ctl code? (tty: no editor!)		dflt: no
	bool			getstorectls;	// shall get() store the final ctl code? (or drop it)		dflt: no

//	OSErr			error;			// last i/o error
	String			bufferin;		// backchar() and not yet read input data (not for file, tty)

	void			_init			( cString& );
	UCS4Char		TTYGetString	( String& string, long& idx );

public:
					~Stream			( );
					Stream			( );							// a dummy stream, no input or output
					Stream			( int fd, cString& path );		// assign stream to stdin/stdout/stderr
					Stream			( cString& path, int flags );	// rw= O_RDWR|O_CREAT;  r=O_RDONLY;  w=O_WRONLY|O_CREAT|O_TRUNC
					Stream			( const Stream& );				// prohibit
	void			operator=		( const Stream& );				// prohibit


// set/get data members:
	int				GetFD			( )				{ return fd; }
	cString&		GetPath			( )				{ return path; }
	s_type			GetType			( )				{ return type; }
	bool			IsTTY			( )				{ return type==s_tty; }

	bool			IsOpenIn		( )				{ return openin; }
	bool			IsOpenOut		( )				{ return openout; }

	UCS4Char		GetLinebreak	( )				{ return linebreak; }
	void			SetLinebreak	( UCS4Char c )	{ XXTRAP(c>0x1f); linebreak = c; }
	void			SetLinebreak	( UTF8Char c )	{ XXTRAP(!c||*c>0x1f); SetLinebreak(*c); }

	CharEncoding	GetConversion	( )				{ return conversion; }
	void			SetConversion	(CharEncoding n){ conversion = n; }

	long			GetTimeoutIn	( )				{ return timeoutin; }	// read(), get(), input()
	long			GetTimeoutOut	( )				{ return timeoutout; }	// write(), put() et.al.
	void			SetTimeoutIn	( long msecs )	{ XXTRAP(msecs<0); timeoutin=msecs; }
	void			SetTimeoutOut	( long msecs )	{ XXTRAP(msecs<0); timeoutout=msecs; }
	void			ClearTimeoutIn	( )				{ timeoutin=0; }
	void			ClearTimeoutOut	( )				{ timeoutout=0; }

	void			ResetGetStops	( )				{ getstoptabs=0; getstopctls=0; }
	void			SetGetStopTabs	( )				{ getstoptabs=1; getstopctls=0; }
	void			SetGetStopCtls	( )				{ getstoptabs=0; getstopctls=1; }
	bool			IsGetStopTabs	( )				{ return getstoptabs; }
	bool			IsGetStopCtls	( )				{ return getstopctls; }

	bool			IsGetStoreCtls	( )				{ return getstorectls; }
	void			SetGetStoreCtls	( bool f=1)		{ getstorectls=f; }
	void			ClearGetStoreCtls ( )			{ getstorectls=0; }

//	OSErr			GetError		( )				{ return error; }
//	void			ClearError		( )				{ error = noerror; }

// io buffers:
	void			DiscardInput	( );			// discard all pending in data
	void			DiscardOutput	( );			// discard all not-yet-written out data
	void			SyncOutput		( );			// enforce and wait for write completion
	bool			IsInAvail		( );
	bool			IsOutFree		( );
	bool			IsOutPending	( );
	ssize_t			GetInAvail		( );
	ssize_t			GetOutFree		( );
	ssize_t			GetOutPending	( );
// file:
	ssize_t			GetFileLength	( );
	void			SetFileLength	( ssize_t );
	ssize_t			GetPosition		( );
	void			SetPosition		( ssize_t );
	void			Append			( );
	void			Clear			( );
// tty:
	void			GetPosition		( uint& row, uint& col );
	void			SetPosition		( uint  row, uint  col );
	void 			SavePosition	( );
	void 			RestorePosition	( );
	void			GetWindowSize	( uint& rows, uint& cols );
	void			SetWindowSize	( uint  rows, uint  cols );
	void 			Cls 			( );
	void 			Locate 			( uint row, uint col )		{ SetPosition(row,col); }
	void 			HLocate 		( uint col );
	void 			VLocate 		( uint row );
	void 			CursorLeft 		( );
	void 			CursorRight 	( );
	void 			CursorUp 		( );
	void 			CursorDown 		( );
	void 			CursorLeft 		( uint n );
	void 			CursorRight 	( uint n );
	void 			CursorUp 		( uint n );
	void 			CursorDown 		( uint n );
	void 			NL 				( );
	void 			Tab 			( );
	void 			Bell 			( );
	void			ClearLeft		( );
	void			ClearRight		( );
	void			ClearLine		( );
	void			ClearUp			( );
	void			ClearDown		( );
	void			ClearScreen		( );

	void			ClearAttr		( );
	void			SetBold			( bool f = on );
	void			SetInverse		( bool f = on );
	void			SetUnderline	( bool f = on );
	void			SetFGColor		( VT_Color );
	void			SetBGColor		( VT_Color );
	void			SetAttr 		( VT_Color fg, VT_Color bg=VT_normal );

// ***** INPUT / OUTPUT *****

// binary mode: no conversion, no echo:
	ssize_t			Write			( const void*, ssize_t );	// returns bytes written
	ssize_t			Read			( void*,       ssize_t );	// returns bytes read

// text mode:
	void			PutbackChar		( UCS4Char );
	void			PutbackChar		( UTF8Char );
	void			PutbackString	( cString& );

	void			PutChar			( UCS4Char );
	void			PutChar			( UTF8Char );
	UCS4Char		GetChar			( );						// ***TODO*** non-blocking!
	String			GetCharString	( );						// ***TODO*** non-blocking!

	void			PutString		( cString& );
	String			GetString		( );						// tty: echo, line editor
	String			Input			( Var& history, long editcol=0 );	

	void			PutNL			( )				{ PutChar(linebreak); }
	void			PutTab			( )				{ PutChar('\t'); }
	void			PutSpace		( )				{ PutChar(' '); }
	void			PutSpaces		( uint n )		{ PutString(SpaceString(n)); }
};




#endif

