/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/


#define LIBRARY
#define S_FILE_LIBRARY

#include	<stdlib.h>
#include	<fcntl.h>
#ifdef VA2
#include	<varargs.h>
#else
#include	<stdarg.h>
#endif
#include	<errno.h>

#include	"memory_debug.h"
#include	"utils.h"
#include	"stream.h"
#include	"task.h"

extern SEM stream_lock;

int s_close_terminal();
int s_write_terminal();
int s_read_terminal();
int s_vprintf_terminal();
int s_vprintf_cr_terminal();
int s_flush_terminal();
int s_vscanf_terminal();

extern STREAM * s_error_stream();
extern int s_error();
extern void _s_open(STREAM * s,int mode);

S_TABLE s_terminal_table = {
    'e',
    0,
    s_error_stream,
    s_close_terminal,
    s_write_terminal,
    s_read_terminal,
    s_flush_terminal,
    s_error,
    s_error_stream,
    s_error,
};



STREAM *
s_open_terminal(int (*prompt)())
{
STREAM * ret;
	ret = d_alloc(sizeof(S_TERMINAL),137);
	ret->h.tbl = &s_terminal_table;
	ret->terminal.inp = s_stdin;
	ret->terminal.out = s_stdout;
	ret->terminal.prompt = prompt;
	_s_open(ret,O_RDWR);
	(*prompt)(ret);
	return ret;
}

int
s_close_terminal(STREAM * s)
{
extern int s_close_file(STREAM * s);

	s_close_file(s->terminal.out);
	s_close_file(s->terminal.inp);
	return 0;
}

int
s_write_terminal(STREAM * s,void * data,int len)
{
	return s_write(s->terminal.out,data,len);
}

int
s_read_terminal(STREAM * s,void * data,int len)
{
int ret,p,q;
char * dp;

	ret = s_read(s->terminal.inp,data,len);
	if ( ret < 0 ) {
		return ret;
	}
	dp = data;
	q = 0;
	for ( p = 0 ; p < ret ; p ++ )
		if ( dp[p] == '\n' ) {
			(s->terminal.prompt)(s,q);
			q = 0;
		}
		else	q ++;
	return ret;
}
/*
int
s_vprintf_terminal(STREAM * s,char * string)
{	
	return (*s->terminal.out->h.tbl->vprintf)(s->terminal.out,string);
}

int
s_vprintf_cr_terminal(STREAM * s,char * string)
{
	return (*s->terminal.out->h.tbl->vprintf_cr)(s->terminal.out,string);
}
*/
int
s_flush_terminal(STREAM * s)
{
	return s_flush(s->terminal.out);
}

int
s_set_prompt(STREAM * s,int (*prompt)())
{
	if ( s->h.tbl != &s_terminal_table )
		return -1;
	s->terminal.prompt = prompt;
	return 0;
}
