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

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

static char LineBuffer[MAXCOLUM+1] ;  /*  Line buffer		*/
static int  TextLength ;	      /*  Length of text line	*/
static int  LimitLine ;		      /*  Load limit line	*/
static int  CurrentLine ;	      /*  current line number	*/
static int  CurrentColum ;	      /*  current colum number	*/
static char *CurrentPoint ;	      /*  current point		*/
static char *BufferPointer ;	      /*  Line buffer pointer	*/

static void StoreString() ;
static void SpaceToTab() ;
extern int  SaveCutBuffer() ;
/************************************************************************/
/*  Marge text file into text buffer					*/
/************************************************************************/

extern int MargeTextFile( fname,line,size )
char *fname ;
int  line,size ;
{
	FILE  *fp ;
	register int  cc,res=0 ;

	LimitLine    = line + size ;
	CurrentLine  = line ;
	CurrentColum = 0 ;
	CurrentPoint = (char *)&TextBuffer[line][0] ;

	if (( fp = fopen( fname,"r" )) == NULL )  return ( -2 ) ;

	while ((( cc = getc( fp )) != EOF ) && ( res == 0 )) {
		switch ( cc ) {
			case '\t': res = TabToSpace() ;	     break ;
			case '\n': res = ReturnCode() ;	     break ;
			default	 : res = ReadOneChar( cc ) ; break ;
		}
	}
	fclose ( fp ) ;
	if ( res == ERROR )  return ( -1 ) ;

	if ( CurrentColum > 0 ) {
		for ( ; CurrentColum < MAXCOLUM ; CurrentColum++ ) *CurrentPoint++ = ' ' ;
		CurrentLine++ ;
	}
	return ( CurrentLine-line ) ;
}

/************************************************************************/
/*  Load text file into text buffer					*/
/************************************************************************/

extern int LoadTextFile( fname )
char  *fname ;
{
	FILE  *fp ;
	register int  cc,res=0 ;

	LimitLine    = MAXLINE ;
	CurrentLine  = 0 ;
	CurrentColum = 0 ;
	CurrentPoint = (char *)TextBuffer ;

	if (( fp = fopen( fname,"r" )) != NULL ) {
		while ((( cc = getc( fp )) != EOF ) && ( res == 0 )) {
			switch ( cc ) {
				case '\t': res = TabToSpace() ;		break ;
				case '\n': res = ReturnCode() ;		break ;
				default	 : res = ReadOneChar( cc ) ;	break ;
			}
		}
		fclose ( fp ) ;
		if ( res == ERROR )  return ( ERROR ) ;
	}
	for ( ; CurrentColum < MAXCOLUM ; CurrentColum++ ) {
		*CurrentPoint++ = ' ' ;
	}
	return ( CurrentLine ) ;
}

/************************************************************************/
/*  Change TAB code to Space code					*/
/************************************************************************/

static int TabToSpace()
{
	do {
		*CurrentPoint++ = ' ' ;
	} while ( ++CurrentColum % 8 ) ;

	if ( CurrentColum == MAXCOLUM ) {
		CurrentColum = 0 ;
		if ( ++CurrentLine == LimitLine )  return ( ERROR ) ;
	}
	return ( COMPLETE ) ;
}

/************************************************************************/
/*  Process of Carriage return code					*/
/************************************************************************/

static int ReturnCode()
{
	for ( ; CurrentColum < MAXCOLUM ; CurrentColum++ ) {
		*CurrentPoint++ = ' ' ;
	}
	CurrentColum = 0 ;
	if ( ++CurrentLine == LimitLine )  return ( ERROR ) ;
	return ( COMPLETE ) ;
}

/************************************************************************/
/*  Read one character							*/
/************************************************************************/

static int ReadOneChar( cc )
int  cc ;
{
	if ( 0x20 <= cc ) {
		if ( ++CurrentColum == MAXCOLUM ) {
			*CurrentPoint++ = ' ' ;
			CurrentColum	= 1 ;
			if ( ++CurrentLine == LimitLine )  return ( ERROR ) ;
		}
		*CurrentPoint++ = cc ;
	}
	return ( COMPLETE ) ;
}

/************************************************************************/
/*  Save text buffer into file						*/
/************************************************************************/

extern int SaveTextFile( fname,line,count )
char *fname ;
int  line,count ;
{
	FILE *fp ;
	int  cc,res ;

	if (( fp = fopen( fname,"w" )) == NULL )  return ( ERROR ) ;

	for ( ; count>0 ; line++,count-- ) {
		BufferPointer = LineBuffer ;
		CurrentPoint  = (char *)&TextBuffer[line][0] ;
		CurrentColum  = 0 ;
		TextLength    = GetLineLength( CurrentPoint+MAXCOLUM ) ;

		while ( CurrentColum < TextLength ) {
			cc = *CurrentPoint++ ;
			switch ( cc ) {
				case '\"':
				case '\'':
					StoreString( cc ) ;
					break ;
				default:
					*BufferPointer++ = (char)cc ;
					CurrentColum++ ;
					break ;
			}
		}
		if ( line != MaximumLine ) *BufferPointer++ = '\n' ;
		*BufferPointer = '\0' ;
		fputs( LineBuffer,fp ) ;
	}
	res = ferror( fp ) ;
	fclose( fp ) ;
	return ( res ) ;
}

/************************************************************************/
/*  Save Cut buffer into file						*/
/************************************************************************/

extern int SaveCutBuffer( fname,count )
char *fname ;
int  count ;
{
	FILE *fp ;
	int  cc,res, line=0;

	if (( fp = fopen( fname,"w" )) == NULL )  return ( ERROR ) ;

	for ( ; count>0 ; line++,count-- ) {
		BufferPointer = LineBuffer ;
		CurrentPoint  = (char *)&CutBuffer[line][0] ;
		CurrentColum  = 0 ;
		TextLength    = GetLineLength( CurrentPoint+MAXCOLUM ) ;

		while ( CurrentColum < TextLength ) {
			cc = *CurrentPoint++ ;
			switch ( cc ) {
				case ' ':
					SpaceToTab() ;
					break ;
				case '\"':
				case '\'':
					StoreString( cc ) ;
					break ;
				default:
					*BufferPointer++ = (char)cc ;
					CurrentColum++ ;
					break ;
			}
		}
		if ( line != MaximumLine ) *BufferPointer++ = '\n' ;
		*BufferPointer = '\0' ;
		fputs( LineBuffer,fp ) ;
	}
	res = ferror( fp ) ;
	fclose( fp ) ;
	return ( res ) ;
}
/************************************************************************/
/*  Store string literal						*/
/************************************************************************/

static void StoreString( terminator )
int  terminator ;
{
	register int  cc ;

	*BufferPointer++ = terminator ;
	CurrentColum++ ;

	while ( CurrentColum < TextLength ) {
		CurrentColum++ ;
		cc = *CurrentPoint++ ;
		*BufferPointer++ = cc ;
		if ( cc == '\\' && CurrentColum < TextLength ) {
			CurrentColum++ ;
			*BufferPointer++ = *CurrentPoint++ ;
		}
		if ( cc == terminator ) break ;
	}
}

/************************************************************************/
/*  Change space code to TAB code					*/
/************************************************************************/

static void SpaceToTab()
{
	int  tab,cur,len ;

	len = GetSpaceLength() ;
	cur = CurrentColum + len ;
	if ( len > 1 ) {
		for ( tab=(CurrentColum+8)&~7 ; tab<=cur ; tab+=8 ) {
			CurrentColum	 = tab ;
			*BufferPointer++ = '\t' ;
		}
	}
	for ( ; CurrentColum<cur ; CurrentColum++ ) {
		*BufferPointer++ = ' ' ;
	}
}

/************************************************************************/
/*  Check length of space code						*/
/************************************************************************/

static int GetSpaceLength()
{
	register int  len=1 ;

	while ( *CurrentPoint++ == ' ' )  len++ ;
	CurrentPoint-- ;
	return ( len ) ;
}

/************************************************************************/
/*  Check length of text line						*/
/************************************************************************/

extern int GetLineLength( txtptr )
char  *txtptr ;
{
	register int  len=MAXCOLUM ;

	while ( *--txtptr == ' ' ) {
		if ( --len == 0 ) break ;
	}
	return ( len ) ;
}

/************************************************************************/
/*  Write Text File							*/
/************************************************************************/

extern int WriteText( fname,line,count )
char *fname ;
int  line,count ;
{
	FILE *fp ;
	char *txtptr ;
	int  length ;

	if (( fp = fopen( fname,"w" )) == NULL ) return ( ERROR ) ;
	fprintf( fp,"%d\n",count ) ;

	while ( count-- > 0 ) {
		txtptr = (char *)&TextBuffer[line][0] ;
		length = GetLineLength( txtptr+MAXCOLUM ) ;
		if ( length ) {
			fwrite( txtptr,sizeof(char),length,fp ) ;
		}
		if ( line++ != MaximumLine ) {
			fputc( '\n',fp ) ;
		}
	}
	fclose( fp ) ;
	return ( COMPLETE ) ;
}
