/*
 *	$Id$
 */

/*
 * !! Notice !!
 * Don't provide any methods modifying ml_model_t and ml_logs_t states
 * unless these are logicalized in advance.
 */
 
#ifndef  __ML_TERM_H__
#define  __ML_TERM_H__


#include  <kiklib/kik_def.h>	/* HAVE_PTHREAD/USE_WIN32API */

#include  "ml_pty.h"
#include  "ml_vt100_parser.h"
#include  "ml_screen.h"


typedef struct ml_term
{
	/*
	 * private
	 */
	ml_pty_ptr_t  pty ;
	ml_pty_event_listener_t *  pty_listener ; /* pool until pty opened. */
	
	ml_vt100_parser_t *  parser ;
	ml_screen_t *  screen ;

	/*
	 * private
	 */
	ml_vertical_mode_t  vertical_mode ;
	ml_bidi_mode_t  bidi_mode ;
	char *  bidi_separators ;
	char *  icon_path ;
	char *  uri ;

	int8_t  use_ctl ;
	int8_t  use_dynamic_comb ;
	int8_t  use_ot_layout ;

	int8_t  use_local_echo ;
	int8_t  is_attached ;
#ifdef  OPEN_PTY_ASYNC
	int8_t	return_special_pid ;
#endif

	void *  user_data ;

} ml_term_t ;


/* XXX */
extern void (*ml_term_pty_closed_event)( ml_term_t *) ;

#define  ml_term_init()  ml_vt100_parser_init()

void  ml_term_final(void) ;

ml_term_t *  ml_term_new( const char *  term_type , u_int  cols , u_int  rows ,
	u_int  tab_size , u_int  log_size , ml_char_encoding_t  encoding ,
	int  is_auto_encoding , int  use_auto_detect ,
	int  logging_vt_seq , ml_unicode_policy_t  policy ,
	u_int  col_size_a , int  use_char_combining , int  use_multi_col_char , int  use_ctl ,
	ml_bidi_mode_t  bidi_mode , const char *  bidi_separators ,
	int  use_dynamic_comb , ml_bs_mode_t  bs_mode ,
	ml_vertical_mode_t  vertical_mode , int  use_local_echo ,
	const char *  win_name , const char *  icon_name , ml_alt_color_mode_t  alt_color_mode ,
	int  use_ot_layout) ;

int  ml_term_delete( ml_term_t *  term) ;

int  ml_term_zombie( ml_term_t *  term) ;

int  ml_term_open_pty( ml_term_t *  term , const char *  cmd_path , char ** argv , char **  env ,
	const char *  host , const char *  work_dir , const char *  pass ,
	const char *  pubkey , const char *  privkey , u_int  width_pix , u_int  height_pix) ;

int  ml_term_plug_pty( ml_term_t *  term , ml_pty_ptr_t  pty) ;

#define  ml_term_pty_is_opened( term)  ((term)->pty != NULL)

int  ml_term_attach( ml_term_t *  term , ml_xterm_event_listener_t *  xterm_listener ,
	ml_config_event_listener_t *  config_listener ,
	ml_screen_event_listener_t *  screen_listener ,
	ml_pty_event_listener_t *  pty_listner) ;

int  ml_term_detach( ml_term_t *  term) ;

#define  ml_term_is_attached( term)  ((term)->is_attached)

#define  ml_term_parse_vt100_sequence( term)  ml_parse_vt100_sequence( (term)->parser)

#define  ml_term_reset_pending_vt100_sequence( term) \
		ml_reset_pending_vt100_sequence( (term)->parser)

#define  ml_term_response_config( term , key , value , to_menu) \
		ml_response_config( (term)->pty , key , value , to_menu)

#ifdef  USE_LIBSSH2
#define  ml_term_scp( term , dst_path , src_path , path_encoding) \
		ml_pty_ssh_scp( (term)->pty , ml_term_get_encoding( term) , \
			path_encoding , dst_path , src_path , 1)
#else
#define  ml_term_scp( term , dst_path , src_path , path_encoding)  (0)
#endif

#define  ml_term_change_encoding( term , encoding) \
		ml_vt100_parser_change_encoding( (term)->parser , encoding)

#define  ml_term_get_encoding( term)  ml_vt100_parser_get_encoding( (term)->parser)

#define  ml_term_set_use_ctl( term , flag)  ((term)->use_ctl = (flag))

#define  ml_term_is_using_ctl( term)  ((term)->use_ctl)

#define  ml_term_set_bidi_mode( term , mode)  ((term)->bidi_mode = (mode))

#define  ml_term_get_bidi_mode( term)  ((term)->bidi_mode)

void  ml_term_set_use_ot_layout( ml_term_t *  term , int  flag) ;

#define  ml_term_is_using_ot_layout( term)  ((term)->use_ot_layout)

#define  ml_term_set_vertical_mode( term , mode)  ((term)->vertical_mode = (mode))

#define  ml_term_get_vertical_mode( term)  ((term)->vertical_mode)

#define  ml_term_set_use_dynamic_comb( term , use)  ((term)->use_dynamic_comb = (use))

#define  ml_term_is_using_dynamic_comb( term)  ((term)->use_dynamic_comb)

#define  ml_term_convert_to( term , dst , len , _parser) \
		ml_vt100_parser_convert_to( (term)->parser , dst , len , _parser)

#define  ml_term_init_encoding_parser( term)  ml_init_encoding_parser( (term)->parser)

#define  ml_term_init_encoding_conv( term)  ml_init_encoding_conv( (term)->parser)

int  ml_term_get_master_fd( ml_term_t *  term) ;

int  ml_term_get_slave_fd( ml_term_t *  term) ;

char *  ml_term_get_slave_name( ml_term_t *  term) ;

pid_t  ml_term_get_child_pid( ml_term_t *  term) ;

size_t  ml_term_write( ml_term_t *  term , u_char *  buf , size_t  len) ;

#define  ml_term_write_modified_key( term , key , modcode) \
	(term)->pty ? ml_vt100_parser_write_modified_key( (term)->parser , key , modcode) : 0

#define  ml_term_write_special_key( term , key , modcode , is_numlock) \
	(term)->pty ? \
		ml_vt100_parser_write_special_key( (term)->parser , key , modcode , is_numlock) : 0

/* Must be called in visual context. */
#define  ml_term_write_loopback( term , buf , len) \
	ml_vt100_parser_write_loopback( (term)->parser , buf , len)

/* Must be called in visual context. */
#define  ml_term_show_message( term , msg)  ml_vt100_parser_show_message( (term)->parser , msg)

#if  defined(__ANDROID__) || defined(__APPLE__)
/* Must be called in visual context. */
#define  ml_term_preedit( term , buf , len)  ml_vt100_parser_preedit( (term)->parser , buf , len)
#endif

int  ml_term_resize( ml_term_t *  term , u_int  cols , u_int  rows ,
	u_int  width_pix , u_int  height_pix) ;

#define  ml_term_cursor_col( term)  ml_screen_cursor_col( (term)->screen)

#define  ml_term_cursor_char_index( term)  ml_screen_cursor_char_index( (term)->screen)

#define  ml_term_cursor_row( term)  ml_screen_cursor_row( (term)->screen)

#define  ml_term_cursor_row_in_screen( term)  ml_screen_cursor_row_in_screen( (term)->screen)

int  ml_term_unhighlight_cursor( ml_term_t *  term , int  revert_visual) ;

#define  ml_term_get_cols( term)  ml_screen_get_cols( (term)->screen)

#define  ml_term_get_rows( term)  ml_screen_get_rows( (term)->screen)

#define  ml_term_get_logical_cols( term)  ml_screen_get_logical_cols( (term)->screen)

#define  ml_term_get_logical_rows( term)  ml_screen_get_logical_rows( (term)->screen)

#define  ml_term_get_log_size( term)  ml_screen_get_log_size( (term)->screen)

#define  ml_term_change_log_size( term , log_size) \
		ml_screen_change_log_size( (term)->screen , log_size)

#define  ml_term_unlimit_log_size( term)  ml_screen_unlimit_log_size( (term)->screen)

#define  ml_term_log_size_is_unlimited( term)  ml_screen_log_size_is_unlimited( (term)->screen)

#define  ml_term_get_num_of_logged_lines( term)  ml_screen_get_num_of_logged_lines( (term)->screen)

#define  ml_term_convert_scr_row_to_abs( term , row) \
		ml_screen_convert_scr_row_to_abs( (term)->screen , row)

#define  ml_term_get_line( term , row)  ml_screen_get_line( term->screen , row)

#define  ml_term_get_line_in_screen( term , row) \
		ml_screen_get_line_in_screen( (term)->screen , row)

#define  ml_term_get_cursor_line( term)  ml_screen_get_cursor_line( (term)->screen)

#define  ml_term_is_cursor_visible( term)  ml_screen_is_cursor_visible( (term)->screen)

#if  0
int  ml_term_set_modified_region( ml_term_t *  term ,
	int  beg_char_index , int  beg_row , u_int  nchars , u_int  nrows) ;

int  ml_term_set_modified_region_in_screen( ml_term_t *  term ,
	int  beg_char_index , int  beg_row , u_int  nchars , u_int  nrows) ;
#endif

int  ml_term_set_modified_lines( ml_term_t *  term , int  beg , int  end) ;

int  ml_term_set_modified_lines_in_screen( ml_term_t *  term , int  beg , int  end) ;

int  ml_term_set_modified_all_lines_in_screen( ml_term_t *  term) ;

int  ml_term_updated_all( ml_term_t *  term) ;

int  ml_term_update_special_visual( ml_term_t *  term) ;

#define  ml_term_logical_visual_is_reversible( term) \
		ml_screen_logical_visual_is_reversible( (term)->screen)

#define  ml_term_is_backscrolling( term)  ml_screen_is_backscrolling( (term)->screen)

int  ml_term_enter_backscroll_mode( ml_term_t *  term) ;

#define  ml_term_exit_backscroll_mode( term)  ml_exit_backscroll_mode( (term)->screen)

#define  ml_term_backscroll_to( term , row)  ml_screen_backscroll_to( (term)->screen , row)

#define  ml_term_backscroll_upward( term , size) \
		ml_screen_backscroll_upward( (term)->screen , size)

#define  ml_term_backscroll_downward( term , size) \
		ml_screen_backscroll_downward( (term)->screen , size)

#define  ml_term_reverse_color( term , beg_char_index , beg_row , \
		end_char_index , end_row , is_rect) \
		ml_screen_reverse_color( (term)->screen , beg_char_index , beg_row , \
			end_char_index , end_row , is_rect)

#define  ml_term_restore_color( term , beg_char_index , beg_row , \
		end_char_index , end_row , is_rect) \
		ml_screen_restore_color( (term)->screen , beg_char_index , beg_row , \
			end_char_index , end_row , is_rect)

#define  ml_term_copy_region( term , chars , num_of_chars , beg_char_index , beg_row , \
		end_char_index , end_row , is_rect) \
		ml_screen_copy_region( (term)->screen , chars , num_of_chars , \
			beg_char_index , beg_row , end_char_index , end_row , is_rect)

#define  ml_term_get_region_size( term , beg_char_index , beg_row , \
		end_char_index , end_row , is_rect) \
		ml_screen_get_region_size( (term)->screen , beg_char_index , beg_row , \
			end_char_index , end_row , is_rect)

#define  ml_term_get_line_region( term , beg_row , end_char_index , end_row , base_row) \
		ml_screen_get_line_region( (term)->screen , beg_row , end_char_index , \
			end_row , base_row)

#define  ml_term_get_word_region( term , beg_char_index , beg_row , end_char_index , end_row , \
		base_char_index , base_row) \
		ml_screen_get_word_region( (term)->screen , beg_char_index , beg_row , \
			end_char_index , end_row , base_char_index , base_row)

#define  ml_term_set_use_multi_col_char( term , flag) \
		ml_vt100_parser_set_use_multi_col_char( (term)->parser , flag)

#define  ml_term_is_using_multi_col_char( term) \
		ml_vt100_parser_is_using_multi_col_char((term)->parser)

#define  ml_term_get_mouse_report_mode( term) \
		ml_vt100_parser_get_mouse_report_mode((term)->parser)

#define  ml_term_want_focus_event( term)  ml_vt100_parser_want_focus_event((term)->parser)

#define  ml_term_set_alt_color_mode( term , mode) \
		ml_vt100_parser_set_alt_color_mode((term)->parser , mode)

#define  ml_term_get_alt_color_mode( term) \
		ml_vt100_parser_get_alt_color_mode((term)->parser)

int  ml_term_set_icon_path( ml_term_t *  term , const char *  path) ;

#define  ml_term_window_name( term)  ml_get_window_name((term)->parser)

#define  ml_term_icon_name( term)  ml_get_icon_name((term)->parser)

#define  ml_term_icon_path( term)  ((term)->icon_path)

#define  ml_term_get_uri( term)  ((term)->uri)

#define  ml_term_is_bracketed_paste_mode( term) \
		ml_vt100_parser_is_bracketed_paste_mode((term)->parser)

#define  ml_term_set_unicode_policy( term , policy) \
		ml_vt100_parser_set_unicode_policy((term)->parser , policy)

#define  ml_term_get_unicode_policy( term)  ml_vt100_parser_get_unicode_policy((term)->parser)

void  ml_term_set_bidi_separators( ml_term_t *  term , const char *  bidi_separators) ;

#define  ml_term_get_cmd_line( term)  ml_pty_get_cmd_line( (term)->pty)

#define  ml_term_start_config_menu( term , cmd_path , x , y , display) \
		ml_reset_pending_vt100_sequence( (term)->parser) ; \
		ml_start_config_menu( (term)->pty , cmd_path , x , y , display)

int  ml_term_get_config( ml_term_t *  term , ml_term_t *  output , char *  key ,
	int  to_menu , int *  flag) ;

int  ml_term_set_config( ml_term_t *  term , char *  key , char *  value) ;

#define  ml_term_exec_cmd( term , cmd)  ml_vt100_parser_exec_cmd( (term)->parser , cmd)

#define  ml_term_report_mouse_tracking( term , col , row , button , is_released , \
		key_state , button_state) \
		ml_vt100_parser_report_mouse_tracking( (term)->parser , col , row , \
			button , is_released , key_state , button_state)

#define  ml_term_search_init( term , match)  ml_screen_search_init( (term)->screen , match)

#define  ml_term_search_final( term)  ml_screen_search_final( (term)->screen)

#define  ml_term_search_reset_position( term)  ml_screen_search_reset_position( (term)->screen)

#define  ml_term_search_find( term , beg_char_index , beg_row , \
		end_char_index , end_row , regex , backward) \
		ml_screen_search_find( (term)->screen , beg_char_index , beg_row , \
			end_char_index , end_row , regex , backward)

#define  ml_term_blink( term , visible)  ml_screen_blink( (term)->screen , visible)

#define  ml_term_get_user_data( term , key)  ((term)->user_data)

#define  ml_term_set_user_data( term , key , val)  ((term)->user_data = (val))

#define  ml_term_select_drcs(term)  ml_vt100_parser_select_drcs((term)->parser)

#define  ml_term_write_content( term , fd , conv , clear_at_end) \
		ml_screen_write_content( term->screen , fd , conv , clear_at_end)


#endif
