/*******************************************************************************/
/*			      Tiny Text Editor				       */
/*									       */
/*	   for	German and French  version				       */
/*									       */
/*	   Programmed by Y.Nishida   [ Nov.18, 1991 ]  version 1.00	       */
/*	   Programmed by N.Okajima   [ Jan.17, 1992 ]  version 1.50	       */
/*******************************************************************************/

#include    <stdio.h>
#include    <strings.h>
#include    <jstrings.h>
#include    <ctype.h>
#include    "console.h"
#include    "editor.h"

static int  SaveLine  ;			  /* Currennt Line  Save Area */
static int  SaveColum ;			  /* Currennt Colum Save Area */

static int  range_flg = 0 ;		  /* Range Flag */
static int  range_left	;		  /* Range Left	 Point */
static int  range_right ;		  /* Range Right Point */

static int  StartPoint ;		  /* Extent Start Point */
static int  EndPoint   ;		  /* Extent End	  Point */

static int  end_line ;			  /* Search End line */
static int  switch_flg = -1 ;		  /* Replase or Search flag */

static int  next_flg = 0 ;		  /* Next Replase or Search flag */
static char SaveOption[10] ;		  /* Option Save Area */

static char search_word[MAXCOLUM+1] ;	  /* Search Word Buffer */
static int  search_length = 0 ;		  /* Search Word Length Area */

static char replace_word[MAXCOLUM+1] ;	  /* Replace Word Buffer */
static int  replace_length = 0 ;	  /* Replace Word Length Area */

static char DoFlags[0x37] = {
	0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,
	0,1,1,1,1,0,0,1,1,0,1,0,0,0,1,1,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,1,0,0,0,0
} ;

static void ReplaceAll() ;
static void DisplayRANGE() ;
static void DisplayEXTENT() ;
static void ClearMSG() ;
static void WordRevers() ;
static void SetExtent() ;

/************************************************************************/
/*  Start string search							*/
/************************************************************************/

extern int SearchString()
{
	switch_flg = 0 ;

	if ( next_flg == 0 ) {
		PutStr( "\033[7m" ) ;
		PutStr( "\033[1;1H\033[KFind:" ) ;
		if (( search_length = InputString( 5,0 )) > 0 ) {
			strcpy( search_word,StringBuffer ) ;
			PutStr( "\033[1;1H\033[Koption:" ) ;
			InputString( 7,0 ) ;
			strcpy( SaveOption,StringBuffer ) ;
		}
		PutStr( "\033[27m" ) ;
	}

	if ( search_length > 0 ) {
		switch ( StringBuffer[0] ) {
			case 'b':
			case 'B':
				end_line = 0 ;
				break ;
			case 'f':
			case 'F':
				end_line = MaximumLine ;
				break ;
			case 't':
			case 'T':
				CurrentLine  = 0 ;
				CurrentColum = 0 ;
				end_line = MaximumLine ;
				break;
			case 'e':
			case 'E':
				CurrentLine  = MaximumLine ;
				CurrentColum = 0 ;
				end_line = 0 ;
				break;
			case 'x':
			case 'X':
				if ( next_flg == 0 ) {
					SetExtent() ;
					CurrentLine  = StartPoint ;
					CurrentColum = 0 ;
					end_line = EndPoint ;
				}
				break ;
			default:
				end_line = MaximumLine ;
				if ( isdigit( StringBuffer[0] )) {
					end_line = atoi( StringBuffer ) - 1 ;
					if ( end_line < 0 ) {
						end_line = 0 ;
					}
					else if ( end_line > MaximumLine ) {
						end_line = MaximumLine ;
					}
				}
				break ;
		}

		if ( StringBuffer[1] == 'R' || StringBuffer[1] == 'r' )
			range_flg = 1 ;

	}

	if(CurrentLine < end_line)	 SearchForward() ;
	else if (CurrentLine > end_line) SearchBack() ;

	if ( range_flg == 1 ) range_flg = 0 ;
	if ( next_flg == 1 )  next_flg = 0 ;

	PutStr( "\033[1;1H\033[K" ) ;
	sprintf( Information+6,"%05d  COL:%03d",CurrentLine+1,CurrentColum+1 ) ;
	Information[20] = ' ' ;
	PrintMessage( Information ) ;
	Locate( CursorPosX,CursorPosY ) ;
	return ( InputChar() ) ;
}


/************************************************************************/
/*  Replace string							*/
/************************************************************************/

extern int ReplaceString()
{

	if ( next_flg == 0 ) {
		PutStr( "\033[7m" ) ;
		PutStr( "\033[1;1H\033[KReplace From:" ) ;
		if (( search_length = InputString( 13,0 )) > 0 ) {
			strcpy( search_word,StringBuffer ) ;

			PutStr( "\033[1;1H\033[KReplace   To:" ) ;
			if (( replace_length = InputString( 13,0 )) > 0 ) {
				strcpy( replace_word,StringBuffer ) ;

				PutStr( "\033[1;1H\033[Koption:" ) ;
				InputString( 7,0 ) ;
				strcpy( SaveOption,StringBuffer ) ;
			}
		}
		PutStr( "\033[27m" ) ;
	}

	if ( search_length > 0 && replace_length > 0 ) {
		switch ( StringBuffer[0] ) {
			case 'a':
			case 'A':
				switch_flg = 3 ;
				CurrentLine  =	0 ;
				CurrentColum =	0 ;
				end_line = MaximumLine ;
				break ;
			case 'p':
			case 'P':
				switch_flg = 1 ;
				CurrentLine  =	0 ;
				CurrentColum =	0 ;
				end_line = MaximumLine ;
				break ;
			case 'x':
			case 'X':
				switch_flg = 1 ;
				if ( next_flg == 0 ) {
					SetExtent() ;
				}
				CurrentColum =	0 ;
				if ( StartPoint > EndPoint ) {
					CurrentLine  = EndPoint ;
					end_line     = StartPoint ;
				}
				else {
					CurrentLine  = StartPoint ;
					end_line     = EndPoint ;
				}
				break ;
			case 'y':
			case 'Y':
				switch_flg = 3 ;
				SetExtent() ;
				CurrentColum =	0 ;
				if ( StartPoint > EndPoint ) {
					CurrentLine  = EndPoint ;
					end_line     = StartPoint ;
				}
				else {
					CurrentLine  = StartPoint ;
					end_line     = EndPoint ;
				}
				break ;
			default:
				switch_flg = 1 ;
				end_line = MaximumLine ;
				if ( isdigit( StringBuffer[0] )) {
					end_line = atoi( StringBuffer ) - 1 ;
					if ( end_line < 0 ) {
						end_line = 0 ;
					}
					else if ( end_line > MaximumLine ) {
						end_line = MaximumLine ;
					}
				}
				break ;
		}
		if ( StringBuffer[1] == 'R' || StringBuffer[1] == 'r' )
			range_flg = 1 ;
	}

	SearchForward() ;
	if ( range_flg == 1 ) range_flg = 0 ;
	if ( next_flg == 1 )  next_flg = 0 ;

	PutStr( "\033[1;1H\033[K" ) ;
	sprintf( Information+6,"%05d  COL:%03d",CurrentLine+1,CurrentColum+1 ) ;
	Information[20] = ' ' ;
	PrintMessage( Information ) ;
	Locate( CursorPosX,CursorPosY ) ;
	return ( InputChar() ) ;
}

/************************************************************************/
/*  Range Set								*/
/************************************************************************/

extern int RangeSet()
{
	int  code,work,flag = 0 ;

	DisplayRANGE() ;
	code = InputChar();

	while ( flag != 2 ) {
		switch ( code ) {
			case 0x104:
			case 0x105:
			case 0x113:
			case 0x118:
				 code = (*CommandProcess[code-0x100])(code) ;
				 break;
			case 0x10d:
				 if ( flag == 0 )      range_left  = CurrentColum ;
				 else if ( flag == 1 ) range_right = CurrentColum ;
				 flag++ ;
				 code = InputChar() ;
				 break ;
			default	  :
			     code = InputChar() ;
		}
		if ( flag == 2 && range_left > range_right ) {
			work	    = range_left  ;
			range_left  = range_right ;
			range_right = work ;
		}
	}

	PutStr( "\033[1;1H\033[K" ) ;
	sprintf( Information+6,"%05d  COL:%03d",CurrentLine+1,CurrentColum+1 ) ;
	Information[20] = ' ' ;
	PrintMessage( Information ) ;

	Locate( CursorPosX,CursorPosY ) ;
	ClearMSG() ;
	return ( code ) ;

}

/************************************************************************/
/*  Next string Search & string Replace					*/
/************************************************************************/

extern int NextSearchReplace()
{
	next_flg = 1 ;

	switch ( switch_flg ) {
		case 0:
			  strcpy ( StringBuffer,SaveOption ) ;
			  if ( StringBuffer[0] == 'T' || StringBuffer[0] == 't' )
				  StringBuffer[0] = 'F' ;
			  if ( StringBuffer[0] == 'E' || StringBuffer[0] == 'e' )
				  StringBuffer[0] = 'B' ;
			  return ( 0x121 ) ;	      /* SearchString()	  */
			  break ;
		case 1:
			  strcpy ( StringBuffer,SaveOption ) ;
			  if ( StringBuffer[0] == 'Y' || StringBuffer[0] == 'y' )
				  StringBuffer[0] = 'X' ;
			  if ( StringBuffer[0] != 'A' || StringBuffer[0] != 'a' )
					return ( 0x133 ) ;    /*  ReplaseString() */
			  break ;
	}

	next_flg = 0 ;
	return ( InputChar() ) ;
}

/************************************************************************/
/*  Set Extent								*/
/************************************************************************/

static void SetExtent()
{
	int  code,flag = 0 ;

	PutStr( "\033[1;1H\033[K" ) ;
	DisplayEXTENT() ;
	Locate( CursorPosX,CursorPosY ) ;

	code = InputChar() ;

	while ( flag != 2 ) {
		if ( code >= 0x200 ) {
			code = GotoLine( code-0x200 ) ;
		}
		else if ( code >= 0x100 && DoFlags[code-0x100] == 1 ) {
			code = (*CommandProcess[code-0x100])(code) ;
		}
		else if ( code == 0x10d ) {
			if ( flag == 0 ){
				StartPoint = CurrentLine ;
				code = InputChar() ;
			}
			else if ( flag == 1 ) EndPoint	 = CurrentLine ;
			flag++ ;
		}
		else {
			code = InputChar() ;
		}
		if ( flag == 2 && StartPoint == EndPoint ) flag = 0 ;
	}
	ClearMSG();
}

/************************************************************************/
/*  Search Word From Forward						*/
/************************************************************************/

static int SearchForward()
{
	register int bottom,col,max,res ;

	bottom = MaximumLine - ( ScreenHeight - 2 ) ;
	if ( bottom < 0 ) bottom = 0 ;

	for(CurrentLine; CurrentLine <=	 end_line; CurrentLine++){

		if ( range_flg == 1 ) {
			col = range_left ;
			if ( range_left == range_right ) max = range_right ;
			else  max = range_right - ( search_length-1 ) ;
		}
		else {
			col = 0 ;
			max = ( GetLineLength(&TextBuffer[CurrentLine][MAXCOLUM]) ) - search_length ;
		}

		if ( next_flg == 1 && SaveLine == CurrentLine && SaveColum == CurrentColum )
			col=CurrentColum + search_length ;

		while( col <= max ){
			if((strncmp(&TextBuffer[CurrentLine][col],search_word,search_length)) == 0){
				CurrentColum = col ;
				CurrentHomeX = 0 ;
				CurrentHomeY = CurrentLine - ( ScreenHeight - 1 )/4 ;
				CursorPosX   = col ;
				CursorPosY   = CurrentLine + 1 - CurrentHomeY ;

				if ( CurrentHomeY < 0 ) {
					CurrentHomeY = 0 ;
					CursorPosY   = CurrentLine - CurrentHomeY + 1 ;
				}
				if ( CurrentHomeY >= bottom ) {
					CurrentHomeY = bottom ;
					CursorPosY   = CurrentLine - CurrentHomeY + 1 ;
				}
				if ( CurrentColum > ScreenWidth) {
					CurrentHomeX += (CurrentColum + 1 - ScreenWidth) + search_length ;
					CursorPosX   -= CurrentHomeX ;
				}

				DisplayAllScreen() ;

/***************Locate( CursorPosX,CursorPosY ) ;
				PutStr( "\033[?25l" ) ;
				PutStr( "\033[7m" ) ;
				write(1,&TextBuffer[CurrentLine][col],search_length) ;
				PutStr( "\033[27m" ) ;
				PutStr( "\033[?25h" ) ;*********************/

				if ( switch_flg == 1 ){
					res = Replace();
					if ( res == -1 ) return ;
					col+=replace_length-1 ;
				}
				else if ( switch_flg == 3 ) {
					ReplaceAll();
					col+=replace_length-1 ;
				}
				else{
					SaveLine  = CurrentLine	 ;
					SaveColum = CurrentColum ;
					return ;
				}
			}
			col++;
		}
	}

	CurrentHomeX = 0 ;
	CurrentHomeY = end_line - ( ScreenHeight - 2 ) ;
	CurrentColum = 0 ;
	CurrentLine  = end_line ;
	CursorPosX   = 0 ;
	if ( (ScreenHeight - 1) > end_line ) CursorPosY = end_line     + 1 ;
	else				     CursorPosY = ScreenHeight - 1 ;
	if( CurrentHomeY < 0 ) CurrentHomeY=0 ;

	DisplayAllScreen() ;
	Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*  Search Word From Back						*/
/************************************************************************/

static int SearchBack()
{
	register int top,bottom,col,max ;

	top    = ScreenHeight - 1 ;
	bottom = MaximumLine  - ( ScreenHeight - 2 ) ;
	if ( bottom < 0 )  bottom = 0 ;

	for(CurrentLine; CurrentLine >= end_line; CurrentLine--){

		if ( range_flg == 1 ) {
			col = range_left ;
			if ( range_left == range_right ) max = range_right ;
			else  max = range_right - ( search_length-1 ) ;
		}
		else {
			col = 0 ;
			max = ( GetLineLength(&TextBuffer[CurrentLine][MAXCOLUM]) ) - search_length ;
		}

		if ( next_flg == 1 && SaveLine == CurrentLine && SaveColum == CurrentColum )
			col=CurrentColum + search_length ;

		while( col <= max ){
			if((strncmp(&TextBuffer[CurrentLine][col],search_word,search_length)) == 0){
				CurrentHomeX = 0 ;
				CurrentHomeY = CurrentLine - ( ScreenHeight - 1 )/4 ;
				CurrentColum = col ;
				CursorPosX   = col ;
				CursorPosY   = CurrentLine + 1 - CurrentHomeY ;
				if ( CurrentHomeY <= top ) {
					CurrentHomeY = 0 ;
					CursorPosY   = CurrentLine - CurrentHomeY + 1 ;
				}
				if ( CurrentHomeY >= bottom ) {
					CurrentHomeY = bottom ;
					CursorPosY   = CurrentLine - CurrentHomeY + 1 ;
				}
				if ( CurrentColum > ScreenWidth) {
					CurrentHomeX += (CurrentColum + 1 - ScreenWidth) + search_length ;
					CursorPosX   -= CurrentHomeX ;
				}
				DisplayAllScreen() ;

				if ( switch_flg == 1 ) {
					Replace();
					col+=replace_length-1 ;
				}
				else if ( switch_flg == 3 ) {
					ReplaceAll();
					col+=replace_length-1 ;
				}
				else {
					SaveLine  = CurrentLine	 ;
					SaveColum = CurrentColum ;
					return ;
				}
			}
			col++;
		}
	}
	CurrentHomeX = 0 ;
	CurrentHomeY = end_line ;
	CurrentColum = 0 ;
	CurrentLine  = end_line ;
	CursorPosX   = 0 ;
	CursorPosY   = end_line - CurrentHomeY + 1 ;
	DisplayAllScreen() ;
	Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*  Replace string All							*/
/************************************************************************/

static void ReplaceAll()
{
	unchar *txtptr ;
	register int i;
	int    pnt ;
	char   cc=' ' ;

	txtptr = &TextBuffer[CurrentLine][CurrentColum] ;
	Locate( CursorPosX,CursorPosY ) ;

	DeleteMemory(txtptr,MAXCOLUM-CurrentColum,search_length) ;
	InsertMemory(txtptr,MAXCOLUM-CurrentColum,replace_length) ;
	for ( i=0; i<replace_length; i++) {
		*txtptr++ = replace_word[i] ;
	}
	write( 1,txtptr-replace_length,ScreenWidth-CursorPosX-1 ) ;

}

/************************************************************************/
/*  Replace								*/
/************************************************************************/

static int Replace()
{
	unchar *txtptr ;
	register int	cc,res,i;
	int    pnt ;
	char   c=' ' ;

	txtptr = &TextBuffer[CurrentLine][CurrentColum] ;

	PutStr( "\033[1;1H\033[K" ) ;
	PrintMessage( " Replace ? (Y/N)   Stop:S" ) ;
	Locate( CursorPosX,CursorPosY ) ;
	res = -1 ;
	while ( res == -1 ) {
		cc = InputChar() ;
		if ( cc == 'Y' || cc == 'y' ) {
			DeleteMemory(txtptr,MAXCOLUM-CurrentColum,search_length) ;
			InsertMemory(txtptr,MAXCOLUM-CurrentColum,replace_length) ;
			for ( i=0; i<replace_length; i++) {
				*txtptr++  = replace_word[i] ;
			}

			write( 1,txtptr-replace_length,ScreenWidth-CursorPosX-1 ) ;

			res = 0 ;
		}
		else if ( cc == 's' || cc == 'S' ) return ( -1 ) ;
		else  break ;
	}
	return ( 0 ) ;
}


/************************************************************************/
/*  Display "RANGE" into Information area				*/
/************************************************************************/

static void DisplayRANGE()
{
	strcpy( Information+27,"RANGE" ) ;
	Information[32]=' ' ;
	Locate(0,0) ;
	PrintMessage( Information ) ;
	Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*  Display "EXTENT" into Information area				*/
/************************************************************************/

static void DisplayEXTENT()
{
	strcpy( Information+27,"EXTNT" ) ;
	Information[32]=' ' ;
	Locate(0,0) ;
	PrintMessage( Information ) ;
	Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*  Clear MSSAGE into Information area					*/
/************************************************************************/

static void ClearMSG()
{
	strcpy( Information+27,"     " ) ;
	Information[32]=' ' ;
	Locate(0,0) ;
	PrintMessage( Information ) ;
	Locate( CursorPosX,CursorPosY ) ;
}

