/*	TEXT 24, a graphical text editor for LCARS 24 */

/* This program is free software. You may redistribute and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License or
 * (at your option) any later version.
 *
 * Refer to the file C:\LCARS24\DATA\COPYING.TXT for details.
 */


#include "text24.h"

void AutoCorrect()
{
#define NUMCHECKS 179

	int x_holder, y_holder, p, i, start;
	char Replace;
	char OneWord[80];
	char Wrong[NUMCHECKS][16] = {
"fo", "ti","fi","ta","ture","si","sa","yiu",
"adn","teh","thier","ahve","i","i'd","i'll","i'm","i've","doen",
"acheive","acn","aslo","agian","almsot","alwasy","amke","awya","bakc",
"baout","acn","bcak","amkes","beacsue","befoer","beleive","cheif","claer",
"cna","coudl","doign","peopel","ehr","esle","eyt","bery","feild",
"fianlly","fidn","firts","follwo","foudn","freind","frmo","fwe",
"gerat","goign","gonig","gruop","grwo","haev","hda","hsa","hsi",
"hte","htere","htey","hting","htink","htis","hvae","idae",
"iades","ihs","htey","iwll","iwth","jsut","knwo","konw","konws",
"konws","levle","htey","liek","liekd","liev","littel","mkae","mkaes",
"moeny","mroe","htey","mysefl","nkow","nkows","nwe","nwo","oging",
"ohter","omre","onyl","optoin","nkow","otehr","otehr","otu","owrk",
"owrd","pf","perhpas","poeple","porblem","pwoer","questoin",
"rwite","seh","shoudl","smae","smoe","soem","sohw","soudn","soudns",
"exmaple","tjat","chagne","thsi","wiht","taht","tehy","seperate","tahn",
"tath","theri","thme","thne","tehn","tje","tkae","todya","veyr",
"waht","watn","wehn","whihc","whta","wief","wierd","wihch","wiht",
"wnat","wnats","wnated","woh","wohle","wokr","woudl","wriet","wrod",
"wtih","wya","yera","yeras","yuo","yuor","whixh","lief","vrey","tihs","thign",
"english","america","american","sunday","monday","tuesday",
"wednesday","thursday","friday","saturday"
};
	char Right[NUMCHECKS][16] = {
"of", "if","if","at","true","is","as","you",
"and","the","their","have","I","I'd","I'll","I'm","I've","done",
"achieve","can","also","again","almost","always","make","away","back",
"about","can","back","makes","because","before","believe","chief","clear",
"can","could","doing","people","her","else","yet","very","field",
"finally","find","first","follow","found","friend","from","few",
"great","going","going","group","grow","have","had","has","his",
"the","there","they","thing","think","this","have","idae",
"ideas","his","they","will","with","just","know","know","knows",
"knows","level","they","like","liked","live","little","make","makes",
"money","more","they","myself","know","knows","new","now","going",
"other","more","only","option","know","other","other","out","work",
"word","of","perhaps","people","problem","power","question",
"write","she","should","same","some","some","show","sound","sounds",
"example","that","change","this","with","that","they","separate","than",
"that","their","them","then","then","the","take","today","very",
"what","want","when","which","what","wife","weird","which","with",
"want","wants","wanted","who","whole","work","would","write","word",
"with","way","year","years","you","your","which","life","very","this","thing",
"English","America","American","Sunday","Monday","Tuesday",
"Wednesday","Thursday","Friday","Saturday"
};

	x_holder=x;
	y_holder=y;
	p=0;
	Replace=FALSE;

	if(x < AutoCorrectDone+1) { AutoCorrectDone=x; return; }
	if( x==1 ) { AutoCorrectDone=2; return; }
	if( y==0 && x==1) return;
/* 	if( y==0 && !isalpha(Ln[0][x-2]) ) return; */
	WordLeft();
	if( y==0 && x==1) {x=x_holder; return; }
	if(!isalpha(Ln[y][x-1])) ++x;
	start=x;

	do{
		t=Ln[y][x-1];
		OneWord[p]=t;
		x++;
		p++;
		if(p==1 && ispunct(t)) p=0;
		if(x >= x_holder-1 && ispunct(t)) break;
	} while (t != 32);

	OneWord[p-1]=(null);

	for(i=0; i < NUMCHECKS; ++i) {
		if(isupper(OneWord[0])) Wrong[i][0]=toupper(Wrong[i][0]);
		if(strcmp(OneWord,Wrong[i])==0) {
			Replace=TRUE;
			if(isupper(OneWord[0])) Right[i][0]=toupper(Right[i][0]);
			strcpy(OneWord,Right[i]);
			break;
		}
	}

	if(Replace==TRUE) {
		p=0;
		for(i=start; i < x_holder-1; ++i) {
			t=OneWord[p];
			if(t !=0 ) Ln[y][i-1] = (t);
			p++;
		}
		T24DisplayString();
	}

	x=x_holder;
	y=y_holder;
	AutoCorrectDone=x;
}

void SilentDel()
{
	int z;

	for( z=x-1; z < k; ++z) Ln[y][z]=Ln[y][z+1];
}
void SaveDictionary()
{
	long z;
	int i;
	unsigned short cr=13;
	unsigned short lf=10;
	unsigned short t;
	PACKFILE *Fp;
	char PersDictPath[80];

	strcpy(PersDictPath, LcarsPath);
	strcat(PersDictPath,"\\LC24APPS\\TEXT24\\PERSDICT.TXT");

	if ( ( Fp=pack_fopen(PersDictPath, "w") ) ==NULL ) {
		return;
	}

	z=0;
	i=0;
	t=32;
	do {
		if( z > EndPersonalDict-1) break;
		t=PersonalDictionary[z][i];
		if(  t==(null) ) {
			pack_putc( (cr), Fp);
			pack_putc( (lf), Fp);
			++z;
			i=0;
		} else {
			pack_putc( (t), Fp);
			++i;
		}
	}  while(1);
	pack_fclose( Fp );
}
void PostError(char *ErrorStr)
{
	rectfill(screen,1+12,42,MaxX-124,MaxY-42,BLACK);
	PutsScorpio(200,200,ORANGE,ErrorStr);
	T24ClearAllMessageBoxes();
	T24Box(BRICK, 8, "CANCEL","F8");
	T24Box(ORANGE, 12, "CLOSE","F12");
loopback:
	do {
		T24PutTime();
	} while(!keypressed());
	c=GetKey();
	switch( c )
	{
		case F8:
		case 27: rectfill(screen,1+12,42,MaxX-124,MaxY-42,BLACK);
			T24MessageBoxes();
			T24LowerMessageBoxes();
			T24RefreshAll();
			return;
		case F12: return;
		default: 	goto loopback;
	}
}
void LoadMainDictionary()
{
	long z;
	int i;
	int IndexFinder, PreviousIndexFinder;
	int t;
	PACKFILE *Fp;
	char MainDictPath[80];

	strcpy(MainDictPath, LcarsPath);
	strcat(MainDictPath,"\\LC24APPS\\TEXT24\\MAINDICT.TXT");


	for(z = 0; z < 110000; ++z) memset(Dictionary[z],0,30);

	if ( ( Fp=pack_fopen(MainDictPath, "r") ) == NULL ) {
		PostError("No dictionary file: MAINDICT.TXT" );
		DictionaryMissing=TRUE;
		return;
	}

	z=0;
	i=0;
	t=32;
	DictionaryIndex[0]=0;
	PreviousIndexFinder=65;
	do {
		if(pack_feof(Fp)) break;
		t=pack_getc(Fp);
			if( t==13 ) {
			IndexFinder=toupper(Dictionary[z][0]);
			if(IndexFinder != PreviousIndexFinder) {
				DictionaryIndex[IndexFinder-65]=z;
				PreviousIndexFinder=IndexFinder;
			}
			++z;
			i=0;
		}  else {
			Dictionary[z][i]=(t);
			if (t> 31) ++i;
			if( t < 32 ) Dictionary[z][i]=(null);
		}
	}  while(1);
	EndDict=z;
	DictionaryIndex[0]=0;
	DictionaryIndex[26]=EndDict;

	strcpy(Dictionary[z],"******");
	pack_fclose( Fp );
}
void LoadPersonalDictionary()
{
	long z;
	int i;
	unsigned short t;
	PACKFILE *Fp;
	char PersDictPath[80];

	strcpy(PersDictPath, LcarsPath);
	strcat(PersDictPath,"\\LC24APPS\\TEXT24\\PERSDICT.TXT");

	if ( ( Fp=pack_fopen(PersDictPath, "r") )==NULL ) {
		PostError("No personal-dictionary file: PERSDICT.TXT" );
		PersonalDictionaryMissing=TRUE;
		return;
	}

	z=0;
	i=0;
	t=32;
	do {
		if(pack_feof(Fp)) break;
		t=pack_getc(Fp);
			if( t==13 ) {
			 ++z;
			 i=0;
		}  else {
			PersonalDictionary[z][i]=(t);
			if (t> 31) ++i;
			if( t < 32 ) PersonalDictionary[z][i]=(null);
		}
	}  while(1);
	EndPersonalDict=z;
	strcpy(PersonalDictionary[z],"******");
	pack_fclose( Fp );
}
void AddToSkipList()
{
	char WordInFile[30];
	int a,b,j,n,z;

	a=x-1;
	b=a;
	while( isalpha(Ln[y][b]) != 0 || Ln[y][b]==39 ) {
		if(y>=EndText-Limit) return;
		++b;
	}
	--b;
	n=b-a;
	j=0;
	memset(WordInFile,0,30);
	for( z=a; z <= b; ++z) {
		t=Ln[y][z];
		WordInFile[j]=(t);
		if(j<29) ++j;		/* no words over 30 letters */
	}
	strcpy(SkipList[EndSkipList],WordInFile);
	++EndSkipList;
	strcpy(SkipList[EndSkipList],"******");
}
void AddToDictionary()
{
	char WordInFile[30];
	int a,b,j,n,z;

	if(PersonalDictionaryLoaded==0) LoadPersonalDictionary();

	a=x-1;
	b=a;
	while( isalpha(Ln[y][b]) != 0 || Ln[y][b]==39 ) {
		if(y>=EndText-Limit) return;
		++b;
	}
	--b;
	n=b-a;
	j=0;
	memset(WordInFile,0,30);
	for( z=a; z <= b; ++z) {
		t=Ln[y][z];
		WordInFile[j]=(t);
		if(j<29) ++j;	/* no words over 30 letters */
	}
	strcpy(PersonalDictionary[EndPersonalDict],WordInFile);
	++EndPersonalDict;
	strcpy(PersonalDictionary[EndPersonalDict],"******");
	PersonalDictionaryUpdated=1;
	rectfill(screen,380,13,540,39,LILAC);
	PutsLuna(380,20,BLACK,LILAC, "ADDED:");
	PutsLuna(422,20,BLACK,LILAC, WordInFile);
	WordRight();
}
int SearchSkipList(char *WordInFile)
{ /* returns 1 if word found, 0 if not */
	int p;
	char TargetWord[30];
	size_t Length;

	if(EndSkipList==0) return(0);

	Length=strlen(WordInFile)-1;
	memset(TargetWord, 0, 30);
	strcpy(TargetWord,WordInFile);

	p=0;
	do {
		if( p>= EndSkipList) {
			return(0);
		}
		if(memicmp(SkipList[p],TargetWord,Length) !=0) ++p;
			else return(1);
	} while(1);
}
int SearchPersonalDict(char *WordInFile)
{ /* returns 1 if word found, 0 if not */
	int p;
        size_t Length;
	char TargetWord[30];

	Length=strlen(WordInFile)-1;
	memset(TargetWord,0, 30);
	strcpy(TargetWord,WordInFile);

	if(SearchSkipList(WordInFile)==1) return(1);
	p=0;
	do {
		if( p>= EndPersonalDict) {
/*
rectfill(screen,380,13,540,39,BIGBLUE);
PutsLuna(390,20,BLACK,BIGBLUE, TargetWord);
*/
			return(0);
		}
		if(memicmp(PersonalDictionary[p],TargetWord,Length) !=0) {
			++p;
		} else {
/*
			rectfill(screen,230,13,370,39,ORANGE);
			PutsLuna(240,20,BLACK,ORANGE, TargetWord);
*/
			return(1);
		}
	} while(1);
}
int SpellCheck()
{
	char WordInFile[30];
	int a,b,i,j,n,z;
        size_t Length;
	int offset_holder=Offset;
	int EndText_holder=EndText;
	int ChapterStart, ChapterEnd; /* line nums of dictionary chapters a-z */
	int ChapterNum;
	char Checking;
	char trap=FALSE;

	if(DictionaryLoaded==0) LoadMainDictionary();
	if(PersonalDictionaryLoaded==0) LoadPersonalDictionary();

	if( DictionaryMissing==TRUE ) return(1);
	if( PersonalDictionaryMissing==TRUE ) return(1);
	DictionaryLoaded=1;
	PersonalDictionaryLoaded=1;
	submarine=TRUE;

	++EndText;
	do {
		if(y>=EndText) {
			EndText=y+1;
			submarine=FALSE;
			goto out;
		}
		while( isalpha(Ln[y][x])==0 && Ln[y][x] !=39) {
			if(y>=EndText) {
				EndText=y+1;
				submarine=FALSE;
				goto out;
			}
			if(CursorRight()) goto out;
		}
retry:
		/* capture a word */
		a=x-1;
		b=a;									  /* apostrophe: ASCII 39 */
		while( isalpha(Ln[y][b]) != 0 || Ln[y][b]==39 ) {
			if(y==EndText) {
				submarine=FALSE;
				goto out;
			}
			++b;
		}
		if(b-a >=30) {	/* word too long--flag the freak */
			if(x==1 && trap==FALSE) {
				trap=TRUE;
				goto retry;
			}
			trap=FALSE;
			sy=y+1-Offset;
			if( sy >=NumLns-1 ) JumpUp();
			submarine=FALSE;
			if(Offset != offset_holder) T24RefreshAll();
			EndText=EndText_holder;
			while( y > EndText) CursorUp();
			memset(Ln[EndText+1],0, LINELENGTH);
			MarkWord=1;
			return(2);
		}
/*		--b;
*/		n=b-a;
		j=0;
		memset(WordInFile,0,30);
		for( z=a; z <= b; ++z) {
			t=Ln[y][z];
			WordInFile[j]=(t);
			++j;

		}

/* No space at the end of a line? Pretend there is one! */
		if(t == 0) strcat(WordInFile, " ");

		Length=strlen(WordInFile)-1;

/* search for one word in appropriate chapter of main dictionary */

		Checking=1;
		t=WordInFile[0];
		ChapterNum=toupper(t)-65;

		ChapterStart=DictionaryIndex[ChapterNum];
		ChapterEnd=DictionaryIndex[ChapterNum+1];
		i=ChapterStart;

		do {
			if(i>ChapterEnd) {
				if(SearchPersonalDict(WordInFile)==0) {
					sy=y+1-Offset;
					if( sy >=NumLns-1 ) JumpUp();
					submarine=FALSE;
					if(Offset != offset_holder) T24RefreshAll();
					EndText=EndText_holder;
					while( y > EndText) CursorUp();
					memset(Ln[EndText+1],0,LINELENGTH);
					MarkWord=1;
					return(2);
				} else {
					WordRight();
					break;
				}
			}
if(strlen(Dictionary[i]) !=Length || memicmp(Dictionary[i],WordInFile,Length) !=0) ++i;
				else {
					WordRight();
					break;
				}

		} while(1);
/* end of search in chapter for one word */

	} while(y < EndText);

out:
	EndText=EndText_holder;
	submarine=FALSE;
	while( y >= EndText) {
		EndText = y+1;
		CursorUp();
	}
	memset(Ln[EndText+1],0,LINELENGTH);
	T24RefreshAll();
	return(0);
}
int Supertype() /* version that doesn't use RefreshLine() */
{
	char abbr[32];
	size_t z;
	int i=1;
	int py;
	int x_holder;
	int y_holder;
	int sy_holder;
	int OffsetHolder;
	int rx_holder;
	char a, b, a_holder, b_holder;
	char KillTrail=FALSE;
	int startingX=x;
	int startingY=y;
	int startingSY=sy;
	int StartingOffset=Offset;
	size_t len,len1,len2,j;
	int Result=0;
/*	char check[32]; */


	if(y >=EndText) EndText++;
	if(x >= 2 && Ln[y][x-2]==32) {
		do_again=TRUE;
		if(x > 67) {
			do_again=FALSE;
			return(Result);
		}
	}
	submarine=TRUE;
	memset(CapturedStr,0,LINELENGTH);

/* capture the abbreviation */

	memset(abbr,0,32);
	rx_holder=x;

	if(x+y > 1 ) {
		if(Ln[y][x-1]==32) CursorLeft();
		a=x;
		WordLeft();
		b=x;
	}

	a_holder=a;
	b_holder=b;
	x_holder=x;
	y_holder=y;
	sy_holder=sy;
	OffsetHolder=Offset;
	z=0;
	do  {
		t=Ln[y][x+z-1];
		if( UserCap==0 && z==0) abbr[z]=tolower(t);
			else abbr[z]=(t);
		++z;
	} while( isalnum(t) ); /* accept numerics in abbreviations */
	abbr[z-1]=(null);
	a=0;
	z=0;

	do	{
		i=1;
		i=memcmp (abbr, ShortKey[z], 2);
		if(i==0) {
			memcpy(CapturedStr, AbbrBuf[z], strlen(AbbrBuf[z]));
			a=2;
			b=0;
			goto bypass;
		}
		++z;
		if( z==AbbrEnd-1 ) a=2;
	} while(a==0);

	a=a_holder;
	b=b_holder;

/* repeat function: get the next word if no new abbr */

	if( do_again==TRUE ) {
		submarine=TRUE;
		x=capture_x;
		y=capture_y;
		WordRight();
		WordRight();
		j=x;
		WordLeft();
		if( j==1 ) j=strlen(Ln[y]);
		capture_x=x;
		capture_y=y;
		for( z=x-1; z< j; ++z ) CapturedStr[z-x]=Ln[y][z-1];
		CapturedStr[z-x]=(null);
		x=rx_holder;
		y=y_holder;
		sy=sy_holder;
		Offset=OffsetHolder;
		if( x_holder >=67 ) {
			Xreturn();
			strcpy(Ln[y],CapturedStr);
			strcat(Ln[y]," ");
			CursorEOL();
			Offset=OffsetHolder;
			AlignParagraph();
			do_again=FALSE;
			return(Result);
		}
		len=strlen(CapturedStr);
		if(x+len > 72) Xreturn();

		for(z=0; z<len; ++z) {
			c=CapturedStr[z];
			T24PutOneChar();
		}
		goto done;
	}

/* search backwards */

	submarine=TRUE;
	while( i != 0 && x+y > 1  ) {
		j=x;
		py=y;
		WordLeft();
		if(y < py) j=strlen(Ln[y]); /* enable grabbing from right */
		for( z=x-1; z< j; ++z ) {
			t=Ln[y][z-1];
			CapturedStr[z-x]=( t );
		}
		CapturedStr[z-x]=(null);
		i=memcmp (CapturedStr, abbr, a-b);
		capture_x=x;
		capture_y=y;
		if( y==0 && x==1) { /* return empty-handed */
			x=rx_holder;
			y=y_holder;
			sy=sy_holder;
			Offset=OffsetHolder;
			submarine=FALSE;
			Result=1;
			goto done;
		}
	}
/* Now, jump back to the abbr, bringing the goods */

	x=x_holder;
	y=y_holder;
	sy=sy_holder;
	Offset=OffsetHolder;
	submarine=FALSE;
	KillTrail=TRUE;
	if(i !=0 ) return(Result);
bypass:

	if(i==0 ) { 		/* if something was actually found */
		len1=strlen(abbr);
		len2=strlen(CapturedStr);

		if(memicmp( abbr, CapturedStr, len1-2 ) !=0 ) {
			x=startingX;
			y=startingY;
			sy=startingSY;
			Offset=StartingOffset;
			submarine=FALSE;
			return(Result);
		}

		if( x_holder >=67 ) {
			y=y_holder;
			sy=sy_holder;
			Offset=OffsetHolder;
			Xreturn();
			if(y >=EndText) EndText++;
			strcpy(Ln[y],CapturedStr);
			strcat(Ln[y]," ");
			CursorEOL();
			Offset=OffsetHolder;
			AlignParagraph();
			if(y >=EndText) EndText++;
			return(Result);
	}
		for(z=0; z< (a-b); ++z) DelKey();  	/* erase abbr  */
		for(z=0; z<strlen(CapturedStr); ++z) { /* put goodies */
			c=CapturedStr[z];
			T24PutOneChar();
		}
		while(KillTrail==TRUE) {
			t=Ln[y][x-2];
			if(isalnum(t)) KillTrail=FALSE;
			if( t=='-' ) KillTrail=FALSE;
			if(ispunct(t) && KillTrail==TRUE) Backspace();
			if( t==' ' ) Backspace();
		}
		c=32;
		T24PutOneChar();
	} else {
		x=startingX;
		y=startingY;
		sy=startingSY;
		Offset=StartingOffset;
	}

done:
	do_again=FALSE;
	submarine=FALSE;
	if(y < y_holder) {
		x=startingX;
		y=startingY;
		sy=startingSY;
		Offset=StartingOffset;
	}
	if(Offset != StartingOffset) T24RefreshAll();
	return(Result);
}
void DisplayFilename()
{
	rectfill(screen,StrLenScorpio(ProgramTitle)+66,1+12,548,39,LILAC);
	PutsLuna(StrLenScorpio(ProgramTitle)+66,20,BLACK,LILAC,MakeDisplayName(CurrentFile));
}
void Brackets2()
{
	NortheastElbow(MaxX-12-125,13,LILAC);
	rectfill(screen,12,13,MaxX-12-126,39,LILAC);
	SoutheastElbow(MaxX-12-125,MaxY-12,LILAC);
	rectfill(screen,12, MaxY-26-12, MaxX-12-126, MaxY-12, LILAC);
	min_old=70;
	T24PutTime();
		  strcpy(ProgramTitle,"TEXT 24");
	ColorTitle(ProgramTitle,LILAC);
}
void T24ClearAllMessageBoxes()
{
	rectfill(screen,MaxX-100-12, 65, MaxX-12, MaxY-48-6-12,BLACK);
}
void T24ClearUpperMessageBoxes()
{
	rectfill(screen,MaxX-100-16, 65, MaxX-12,416,BLACK);
	SpellBoxesDisplayed=FALSE;
}
void T24Box(int Hue, int Pos, char *Label1, char *Label2)
{
	int boxtop;

	boxtop=(39*Pos)+12+17;
	rectfill(screen,MaxX-100-12,boxtop,MaxX-12,boxtop+35,Hue);
	PutsLuna(MaxX-96-12,boxtop+4, BLACK,Hue, Label1);
	PutsLuna(MaxX-2-StrLenLuna(Label2)-12,boxtop+4,BLACK,Hue,Label2);
}
void T24ClearSpellBoxes()
{
	T24Box(BLACK, 7, "","");
	T24Box(BLACK, 8, "","");
	if(AutoCorrectOff==FALSE) T24Box(SEABLUE, 8, "AUTOSPELL OFF","F8");
		else T24Box(BRICK, 8, "AUTOSPELL ON","F8");
	SpellBoxesDisplayed=FALSE;
}
void T24MessageBoxes()
{	 /* position range: 1 to 10 */
	T24ClearUpperMessageBoxes();
	T24Box(PURPLE, 1, "SAVE (S)","F1");
	T24Box(LAVENDER, 2, "OPEN (O)","F2");
	T24Box(LAVENDER, 3, "NEW (N)","F3");
	T24Box(LAVENDER, 4, "SAVE AS","F4");
	T24Box(BRICK, 5, "WORD COUNT","F5");
	T24Box(BIGBLUE, 6, "COLOR (T)","F6");
	T24ClearSpellBoxes(); /* see above function */
	T24Box(BRICK, 9, "SPELL CHECK","F9");
}
void T24LowerMessageBoxes()
{
	T24Box(ORANGE, 10, "ALIGN","F10");
	T24Box(ORANGE, 11, "HELP","F11");
	T24Box(ORANGE, 12, "CLOSE","F12");
}
void T24Screen1()
{
	rectfill(screen,0,0,MaxX,MaxY,BLACK);
	Brackets2();
	T24MessageBoxes();
	T24LowerMessageBoxes();
	PutsLuna(160,567,BLACK,LILAC, "SELECT: SHIFT + ARROW KEYS	SELECT ALL: (A)	CUT: (X)	COPY: (C)	PASTE: (V) (CTRL+)");
}
int T24Safety()
{
	T24ClearAllMessageBoxes();
	T24Box(PALEBLUE, 7, "ABANDON","F7");
	T24Box(BRICK, 8, "CANCEL","ESC/F8");
	T24Box(MANGO, 9, "SAVE","F9");
loopback:
	do {
		T24PutTime();
	} while(!keypressed());
	c=GetKey();
	switch( c )
	{
		case F7:	return(1);
		case F8:
		case 27:	return(2);
		case F9: 	return(3);
		default: 	goto loopback;
	}
}
void T24Infoxy()
{
	char LineNum[8];
	char ColNum[4];

	if( y < 0 ) y=0;
	rectfill(screen,540,13,620,39,LILAC);
	PutsLuna(550,20,BLACK,LILAC, "LINE");
	itoa(y+1,LineNum,10);
	PutsLuna(580,20,BLACK,LILAC, LineNum);
	rectfill(screen,620,13,700,39,LILAC);
	PutsLuna(620,20,BLACK,LILAC, "COL");
	itoa(x,ColNum,10);
	PutsLuna(650,20,BLACK,LILAC, ColNum);
}
void PromptOn()
{
	rectfill(screen,380,13,498,39,BLACK);
	PutsFont21(385, 15, ORANGE, "REPLACE? (Y/N)");
}
void PromptOff()
{
	rectfill(screen,340,13,498,39,LILAC);
}
void T24DialogBox()
{
	rectfill(screen,47,13,MaxX-138,39,BLACK);
	rectfill(screen,MaxX-12-219,13,MaxX-12-129,39,PALEBLUE);
	PutsLuna(MaxX-217,20,BLACK,PALEBLUE,"CANCEL: ESC");
}
void T24ClearDialogBox()
{
/*	rectfill(screen,12,13,MaxX-138,39,LILAC); */
	rectfill(screen,48,13,MaxX-138,39,LILAC);
}
void NoFindMessage()
{
	T24DialogBox();
	PutsFont19(52,18,ORANGE,"No match found");
	install_timer(); 
	rest(1000);
	remove_timer(); 
}
int Xfind()
{
	int z;
        size_t j;

	if ( ! (FindStr[0] >= 32 ) ) goto out;
	j=strlen(FindStr);
	submarine=TRUE;
	NoFind= TRUE;

	while( NoFind != FALSE && y <= EndText-Limit ) {
		for( z=x-1; z< x+j+1; ++z ) {  /* slick mid$ */
					t=Ln[y][z-1];
					RightStr[z-x]=( t );
		}
		RightStr[z-x]=(null);
		NoFind=memcmp( RightStr, FindStr, strlen(FindStr) );
		if ( y >= EndText-Limit && x >= strlen(Ln[y])-(j) ) {
			submarine=FALSE;
			return(1);
		}
		if(CursorRight()) {
			CursorLeft();
			submarine=FALSE;
			return(1);
		}
	}
	CursorLeft();
out:	submarine=FALSE;
	return(0);
}
void Dcursor()
{
	int q,z;

	cx=0;
	for( z=0; z<dx-1; ++z) {
		q=InputStr[z];
		cx=cx+ Font19[q] -65;
		}
	cy=31;
	xor_mode(TRUE);
	rectfill(screen,cx+158,cy+7,cx+166,cy+10, makecol(255,255,255));
	xor_mode(FALSE);
}
void DisplayInputString()
{
	rectfill(screen,152, 13, MaxX-12-221, 40,BLACK);
	PutsFont19(158,17,PALEBLUE,InputStr);
}
void Dleft()
{
	if( dx==1 ) return;
	--dx;
}
void Dright()
{
	k=strlen( InputStr );
	if( dx > k ) return;
		++dx;
}
void Ddel()
{
	int z;

	k= strlen( InputStr );
	if( x > k ) return;
	for( z=dx-1; z < k; ++z) {
		InputStr[z]=InputStr[z+1];
	}
	DisplayInputString();
}
void Dbs()
{
	int z;

	Dleft();
	if( x < 1 ) return;
	k= strlen( InputStr );
	for( z=dx-1; z < k; ++z) {
		InputStr[z]=InputStr[z+1];
	}
	DisplayInputString();
}
void Dchar()
{
	int q,z;

	if( c < 32 ) return;
	q=StrLenFont19(InputStr);
	k= strlen( InputStr );
	if( x < k &&  q > MaxX-145) return;

	if(dx < k) for(z=k; z >= dx; --z) InputStr[z]=InputStr[z-1];
	if(!(dx-1 > k ) )	InputStr[dx-1] =( c );
	DisplayInputString();
	Dright();
}
void T24GetDialogInput()
{
	dx=1;
	memset(InputStr,0,100);
	rectfill(screen,12, 48, MaxX-124, 40,BLACK);
loopback:

	Dcursor();
	do {
		T24PutTime();
	} while(!keypressed());
	c=GetKey();
	Dcursor();
	switch( c )
	{
		case 27:  x=xholder;
				y=yholder;
				Offset=offsetholder;
				Abort=TRUE;
				return;
		case BS:	Dbs();
				goto loopback;
		case 13:
				return;
		case LEFTARROW: Dleft();
				goto loopback;
		case RIGHTARROW: Dright();
				goto loopback;
		case DELKEY:	Ddel();
				goto loopback;
		case PGUPKEY:
				goto loopback;
		case PGDNKEY:
				goto loopback;
		default: 	if( c > 31 && c < 123) Dchar();
				goto loopback;
	}
}
int T24Find()
{
	  FindMode=1;
	xholder=x;
	yholder=y;
	offsetholder=Offset;
	T24DialogBox();
	PutsFont21(117,15,ORANGE,"FIND:");
	Abort=FALSE;
	T24GetDialogInput();
	memcpy(FindStr,InputStr,99);
	  Xfind();
	if( Abort==TRUE) goto bypass;
	if( NoFind != FALSE) {
		NoFindMessage();
		x=xholder;
		y=yholder;
		Offset=offsetholder;
	}
bypass:
	T24ClearDialogBox();
	if( EndText-5-y > NumLns/2 && Offset >10 ) Offset +=NumLns/2;
	sy=y+1-Offset;
	if( sy >=NumLns-1 ) JumpUp();
	T24RefreshAll();
	return(Result);
}
void T24Replace()
{
	size_t z;

	MarkFindStr=1;
	T24DrawCursor();
	PromptOn();
loopback:
	do {
		T24PutTime();
	} while(!keypressed());
	c=GetKey();
	switch( c )
	{
		case 27:  x=xholder;
				y=yholder;
				Offset=offsetholder;
				Abort=TRUE;
				goto out;
		case 25:
		case 89:
		case 121:	goto exchange;
		case 14:
		case 78:
		case 110: goto out;
		default: 	goto loopback;
	}
exchange:
	submarine=TRUE;
	for(z=0; z < strlen(FindStr); ++z) SilentDel();
	if(strlen(ReplaceStr)==0) {
		PromptOff();
		submarine=FALSE;
		MarkFindStr=0;
		T24RefreshAll();
		return;
	}
	for(z=0; z<strlen(ReplaceStr); ++z) {
		c=ReplaceStr[z];
		T24PutOneChar();
	}
out: PromptOff();
	submarine=FALSE;
	MarkFindStr=0;
}
int T24FindAndReplace()
{
	FindMode=2;
	xholder=x;
	yholder=y;
	offsetholder=Offset;
	T24DialogBox();
	PutsFont21(117,15,ORANGE,"FIND:");
	Abort=FALSE;
	T24GetDialogInput();
	if( Abort==TRUE) goto bypass;
	memcpy(FindStr,InputStr,99);
	rectfill(screen,115, 13, MaxX-12-221, 80,BLACK);
	PutsFont21(52,15,ORANGE,"REPLACE WITH:");
	T24GetDialogInput();
	memcpy(ReplaceStr,InputStr,99);
	Xfind();
	if( Abort==TRUE) goto bypass;
	if( NoFind != FALSE) {
		NoFindMessage();
		x=xholder;
		y=yholder;
		Offset=offsetholder;
	}
bypass:
	T24ClearDialogBox();
	if( EndText-5-y > NumLns/2 && Offset >10 ) Offset +=NumLns/2;
	sy=y+1-Offset;
	if( sy >=NumLns-1 ) JumpUp();
	T24RefreshAll();
	if( NoFind==FALSE && Abort==FALSE) T24Replace();
	return(Result);
}
void T24NextFind()
{
	xholder=x;
	yholder=y;
	offsetholder=Offset;
	Xfind();
	if( NoFind != FALSE) {
		NoFindMessage();
		x=xholder;
		y=yholder;
		Offset=offsetholder;
		T24ClearDialogBox();
	}
	sy=y+1-Offset;
	if( sy >=NumLns-1 ) JumpUp();
	T24RefreshAll();
	if( NoFind==FALSE && FindMode==2 ) T24Replace();
}
/********* New file  stuff ************/

void ShiftSelectOff()
{
	ShiftSelect=0;
/*
	if(ActiveList==2) T24Box(PALEBLUE, 6, "CUT (X)","OFF");
	if(ActiveList==2) T24Box(PALEBLUE, 7, "COPY (C)","OFF");
*/
}
void ShiftSelectOn()
{
	ShiftSelect=1;
/*
	if(ActiveList==2) T24Box(PALEBLUE, 6, "CUT (X)","F6");
	if(ActiveList==2) T24Box(PALEBLUE, 7, "COPY (C)","F7");
*/
}
int T24Pick(char MenuMode[10])
{
	int Result;

	strcpy(Mode,MenuMode);

	if(strcmp(Mode,"NEW")==0) {
		strcpy( CurrentFile, PathName);
		DisplayFilename();
		LoadTextFile();	 /* ?? */
		x=1;
		y=0;
		Offset=0;
		T24RefreshAll();
/*		UndoFlag=0; */
/*		if(ActiveList==2) T24Box(PALEBLUE, 9, "UNDO (Z)","OFF"); */
		ShiftSelectOff();
		return(0);
	}
	Result=FileMenu(get_extension(CurrentFile));
	rectfill(screen,0,0,800,600,BLACK);
	T24Screen1();
	if(strcmp(Mode,"OPEN")==0) {
		strcpy( CurrentFile, PathName);
		DisplayFilename();
		LoadTextFile();
		x=1;
		y=0;
		Offset=0;
		T24RefreshAll();
		if(stricmp(get_filename(CurrentFile),"Spelling.txt")==0 && ActiveList==4) T24Box(BRICK, 9, "SPELL CHECK","OFF");
/*		UndoFlag=0; */
/*		if(ActiveList==2) T24Box(PALEBLUE, 9, "UNDO (Z)","OFF"); */
		ShiftSelectOff();
		return(0);
	}
	if(strcmp(Mode,"ESC")==0) {
		DisplayFilename();
		T24RefreshAll();
		return(0);
	}
	if(strcmp(Mode,"SAVE AS")==0) {
		strcpy( CurrentFile, PathName);
		DisplayFilename();
		T24RefreshAll();
		T24Box(NAPLES, 1, "SAVING","");
		SaveTextFile();
		Action=0;
		T24Box(PURPLE, 1, "SAVE (S)","F1");
		return(0);
	}
	return(0);
}
/***** routines to execute the various menu items, in order ***/

void T24ClearWindow()
{
	for (y=0; y< LINECOUNT-1; ++y) memset(Ln[y],0,LINELENGTH);
/*
	t=32;
	Ln[0][0]=(t);
*/
	y=0;
	x=1;
	AutoCorrectDone=x;
	EndText=1;
	Offset=0;
	Action=0;
	cx=0;
	rectfill(screen,1+12,42,MaxX-124,MaxY-42,BLACK);
	rectfill(screen,MaxX-123, 47+12, MaxX-100-13, MaxY-48-12,BLACK);
}

int T24DoNew()
{
	if(Action!=0) {
		Result=T24Safety();
			if(Result==1) {
				T24ClearWindow();
				T24MessageBoxes();
				T24LowerMessageBoxes();
				strcpy(CurrentFile,"NAMELESS.TXT");
				DisplayFilename();
				return(0);
			}
			if(Result==2) {
				T24MessageBoxes();
				T24LowerMessageBoxes();
				return(0);
			}
			if(Result==3) {
				T24Box(NAPLES, 1, "SAVING", "");
				SaveTextFile();
				Action=0;
				T24Box(PURPLE, 1, "SAVE (S)","F1");
				T24ClearWindow();
				T24MessageBoxes();
				T24LowerMessageBoxes();
				strcpy(CurrentFile,"NAMELESS.TXT");
				DisplayFilename();
				return(0);
			}
		} else {
			T24ClearWindow();
			T24MessageBoxes();
			T24LowerMessageBoxes();
			strcpy(CurrentFile,"NAMELESS.TXT");
			DisplayFilename();
			return(0);
	}
	return(1);
}
int T24DoOpen()
{
	if(Action!=0) {
		Result=T24Safety();
			if(Result==1) {
			T24Pick("OPEN");
			Action=0;
			goto out;
		}
		if(Result==2) {
			T24MessageBoxes();
			T24LowerMessageBoxes();
			return(0);
		}
		if(Result==3) {
			SaveTextFile();
			T24Pick("OPEN");
			Action=0;
			goto out;
		}
	} else {
		T24Pick("OPEN");
		Action=0;
	}
out:
	if(load_abort==TRUE) {
		T24ClearWindow();
		T24MessageBoxes();
		T24LowerMessageBoxes();
		strcpy(CurrentFile,"NAMELESS.TXT");
		DisplayFilename();
		load_abort=FALSE;
		file_too_long=FALSE;
	}
	return(0);
}
void T24DoSave()
{
	T24Box(NAPLES, 1, "SAVING", "");
	SaveTextFile();
	Action=0;
	T24Box(PURPLE, 1, "SAVE (S)","F1");
}
void T24DoTextColor()
{
	if(TextColor==MANGO) {
		TextColor=ORANGE;
		ShiftSelectOff();
		T24RefreshAll();
		return;
	}
	if(TextColor==ORANGE) {
		TextColor=NAPLES;
		ShiftSelectOff();
		T24RefreshAll();
		return;
	}
	if(TextColor==ORANGE) {
		TextColor=NAPLES;
		ShiftSelectOff();
		T24RefreshAll();
		return;
	}
	if(TextColor==NAPLES) {
		TextColor=PALEBLUE;
		ShiftSelectOff();
		T24RefreshAll();
		return;
	}
	if(TextColor==PALEBLUE) {
		TextColor=MANGO;
		ShiftSelectOff();
		T24RefreshAll();
		return;
	}
}
void T24DoSaveAs()
{
	T24Pick("SAVE AS");
}
void T24DoCopy()
{
	int z, i;
	int cr=13;
	int lf=10;
	PACKFILE *Fp;
	char ClipPath[80];

	strcpy(ClipPath, LcarsPath);
	strcat(ClipPath,"\\ABC-TXT\\CLPBOARD.TXT");

	if(ShiftSelect==0) return;
	if ( ( Fp=pack_fopen(ClipPath, "w" ))==NULL ) {
		return;
	}
	z=BlockStartY;
	i=BlockStartX-1;    /* ????? */
	t=32;
	do {
		if( BlockEndX==1) {
			if( z >= BlockEndY) break;  /* added=*/
		}
		if( BlockEndX > 1) {
			if( z==BlockEndY && i==BlockEndX-1) break;
		}
		t=Ln[z][i];
		if(  t==(null) ) {
			pack_putc( (cr), Fp);
			pack_putc( (lf), Fp);
			++z;
			i=0;
		} else {
			pack_putc( (t), Fp);
			++i;
		}
	}  while(1);
	pack_putc( (cr), Fp);
	pack_putc( (lf), Fp);
	pack_fclose( Fp );
/*	UndoFlag=0; */
/*	if(ActiveList==2) T24Box(PALEBLUE, 9, "UNDO (Z)","OFF"); */
}
void T24DoCut()
{
	char Rt[LINELENGTH];
	int Diff,a,b,z, starting_endtext;

	starting_endtext=EndText;
	if(ShiftSelect==0) return;
	T24DoCopy();
	sy=y+1-Offset;
/*	UndoFlag=1; */
/*	if(ActiveList==2) T24Box(PALEBLUE, 9, "UNDO (Z)","F9"); */
	submarine=TRUE;
	if(BlockEndX > 1) {
		a=BlockEndX-1;
		b=LINELENGTH-a;
		for( z=0; z<b; ++z) Rt[z]=Ln[BlockEndY][a+z];
		memset(Ln[BlockEndY],0,LINELENGTH);
		strcpy(Ln[BlockEndY], Rt);
/*		--BlockEndY;	*/
	}
	if(BlockStartX > 1) {
		for( z=BlockStartX-1; z<LINELENGTH; ++z) Ln[BlockStartY][z]=(null);
		++BlockStartY;
	}
	y=BlockStartY;
	x=1;

	Diff=BlockEndY - BlockStartY;

	for( z=0; z <= EndText-Diff; ++z) {
		memcpy( Ln[z+y], Ln[z+y+Diff],LINELENGTH);
	}
	Offset=y+2 - CutSY;
	EndText -= Diff;
	if(EndText < 0) EndText=0;
	for( z=EndText+1; z <= starting_endtext+3; ++z) {
		memset(Ln[z],0, LINELENGTH );
	}
	if(EndText < 1) EndText=1;
	if( Offset < 0 ) Offset=0;
	if( y < 0 ) y=0;
	submarine=FALSE;
	Unselect();
	Action=1;
}
void T24DoPaste()
{
	long z;
	int i;
	unsigned short t;
	PACKFILE *Fp;
	char ClipPath[80];

	strcpy(ClipPath, LcarsPath);
	strcat(ClipPath,"\\ABC-TXT\\CLPBOARD.TXT");

	if ( ( Fp=pack_fopen(ClipPath, "r" ))==NULL ) {
		return;
	}
	submarine=TRUE;
	if(y==0 && x==1) Xreturn();
	if(x>1) Xreturn();
	++EndText;
	for( z=EndText; z >= y; --z) {
		memcpy( Ln[z+1], Ln[z],LINELENGTH);
	}
	i=0;
	t=32;
	do {
		if(pack_feof(Fp)) break;
		t=pack_getc(Fp);
			if( t==13 ) {
			 Ln[y][i]=(null);
			++EndText;
			for( z=EndText; z >= y+1; --z) {
				memcpy( Ln[z+1], Ln[z],LINELENGTH);
				memset(Ln[z],0,LINELENGTH);
			}
			 i=0;
			if(y+1-Offset >= NumLns) ScrollUp();
			 ++y;
		}  else {
			if(t != 10 && t != 13) {
				Ln[y][i]=(t);
				++i;
			}
		}
	}  while(1);
	 Ln[y][i]=(null);
	pack_fclose( Fp );
	if( i==0 ) {
		x=1;
		memset(Ln[y],0,LINELENGTH);
		DelKey();
	}
	CursorLeft();
	DelKey();
	submarine=FALSE;
	T24RefreshAll();
	Action=1;
/*	UndoFlag=0; */
/*	if(ActiveList==2) T24Box(PALEBLUE, 9, "UNDO (Z)","OFF"); */
}
/*
void T24DoUndo()
{
	if(UndoFlag==0) return;
	T24DoPaste();
}
*/
void T24DoFind()
{
	if(EndText >1) T24Find();
	if(NoFind==FALSE && Abort==FALSE) MarkFindStr=1;
	rectfill(screen,12,13,MaxX-12-126,39,LILAC);
	Title(ProgramTitle);
	DisplayFilename();
}
void T24DoFindAndReplace()
{
	if(EndText >1) T24FindAndReplace();
	rectfill(screen,12,13,MaxX-12-126,39,LILAC);
	Title(ProgramTitle);
	DisplayFilename();
}
void T24DoNext()
{
	if(NoFind==FALSE) {
		if(WordRight()==1) {
			NoFindMessage();
			T24ClearDialogBox();
			Title(ProgramTitle);
			DisplayFilename();
			return;
		}
		T24NextFind();
	}
	if(NoFind==FALSE) MarkFindStr=1;
	if(FindMode==2) MarkFindStr=0;
	Title(ProgramTitle);
	DisplayFilename();
}
void T24DoAlign()
{
	AlignParagraph();
}
void T24DoWordCount()
{
	WordCount();
}
void T24DoAddToDict()
{
	if ( isalpha(Ln[y][x])==0 ) {
		T24ClearSpellBoxes();
		return;
	}
	AddToDictionary();
	T24DoSpellCheck();
}
void T24DoSpellCheck()
{
	if( DictionaryMissing==TRUE ) goto out;
	if( PersonalDictionaryMissing==TRUE ) goto out;
/*	if(stricmp(get_filename(CurrentFile),"Spelling.txt")==0) return; */
	T24Box(NAPLES, 7, "CHECKING","");
	T24Box(BLACK, 8, "","");
	SpellBoxesDisplayed=TRUE;
	k=strlen(Ln[y]);
	if( y >= EndText && k==0) goto out;
	if( x != 1 && isspace(Ln[y][x-1]) != 0) WordLeft();
	if(SpellCheck()==2) {
		T24Box(BRICK, 7, "ADD TO DICT","F7");
		T24Box(BRICK, 8, "SKIP","F8");
		return;
	}
out:		T24ClearSpellBoxes();
}
void T24DoSkip()
{
	if(DictionaryMissing==TRUE) return;
	AddToSkipList();
	WordRight();
/*
	T24Box(BLACK, 7, "","");
	T24Box(BLACK, 8, "","");
*/
	T24DoSpellCheck();
}
void T24DoHelp()
{
	char HelpPath[80];

	strcpy(HelpPath, LcarsPath);
	strcat(HelpPath,"\\LC24APPS\\TEXT24\\T24HELP.TXT");
	OpenHelp(HelpPath);
	min_old=70;
}
void T24ShowAbbrList()
{
	char HelpPath[80];

	strcpy(HelpPath, LcarsPath);
	strcat(HelpPath,"\\LC24APPS\\TEXT24\\ABBRFILE.TXT");
	OpenHelp(HelpPath);
	min_old=70;
}

/***** Graphical editing routines *****/

void cxUpdate()
{
	unsigned int q,z;

	cx=0;
	for( z=0; z<x-1; ++z) {
		q=Ln[y][z];
		if( q==9 ) {
			cx += 40;
			if( cx > 40) cx=(cx/40)*40;
		} else {
			if(MonoType==0)  cx += Font21[q]-65;
				else cx += 8;
		}
	}
}
void HighlightSelection()
{
	if(Ln[y][0]==0) return;
	if(Ln[y][0]==26) return;
	cxUpdate();
	g2=cx;
	cy=3+((y+1-Offset)*lp)+lp;
	xor_mode(TRUE);
	if(MonoType == 0) rectfill(screen,17+g1, cy-26, 16+g2, cy+6, makecol(255,255,255));
		else rectfill(screen,47+g1, cy-1, 46+g2, cy+18, makecol(255,255,255));
	xor_mode(FALSE);
/* ???? */

}
void HighlightSelectionBackwards()
{
	if(Ln[y][0]==0) return;
	cxUpdate();
	g2=cx;
	cy=3+((y+1-Offset)*lp)+lp;
	xor_mode(TRUE);
	if(MonoType == 0) rectfill(screen,16+g1, cy-26, 17+g2, cy+6, makecol(255,255,255));
		else rectfill(screen,46+g1, cy-1, 47+g2, cy+18, makecol(255,255,255));
	xor_mode(FALSE);
}
void T24DrawCursor()
{
	if(MarkWord==2) {
		T24DisplayString();
		MarkWord=0;
/*		T24ClearSpellBoxes(); */
		return;
	}
	if(MarkWord==1) {
		HighlightWord();
		MarkWord=2;
	}
	if(MarkFindStr==2) {
		T24DisplayString();
		MarkFindStr=0;
		return;
	}
	if(MarkFindStr==1) {
		HighlightFindStr();
		MarkFindStr=2;
	}
	cxUpdate();
	if(Ln[y][0] < 32 && Ln[y][0] != 9 ) cx=0;
	cy=3+((y+1-Offset)*lp)+lp;
	xor_mode(TRUE);
	if(MonoType==0)	rectfill(screen,cx+17, cy+5, cx+26, cy+1, makecol(255,255,255));
		else rectfill(screen,cx+18+29, cy+4+15, cx+25+29, cy+2+15, makecol(255,255,255));
	xor_mode(FALSE);
}
void T24RefreshAll()
{
	int z;

	clear_to_color(T24buf,BLACK);
	BackgroundColor=BLACK;
	if(submarine==TRUE) return;
	if(MonoType != 0) {
		rectfill(screen,0,47,799,49,BLACK);
		rectfill(screen,0,551,799,553,BLACK);
	}
	for(z=1; z<=NumLns; ++z) {
		if(MonoType==0) Headline21(T24buf,2,4+(z*lp)-lp,TextColor,Ln[z-1+Offset]);
			else PutsMono13(T24buf,2,4+(z*lp)-lp,TextColor,Ln[z-1+Offset]);
	}
	if(MonoType==0) blit(T24buf, screen, 0, 0, 16, 49, 650, 504);
		else blit(T24buf, screen, 0, 0, 45, 49, 784, 504);
}
void TopOfFile()
{
	offsetholder=Offset;
	Offset=0;
	y=0;
	x=1;
	if( offsetholder > 0) T24RefreshAll();
}
void BottomOfFile()
{
	if( EndText < NumLns-1 ) {
		TopOfFile();
		y=EndText-1;
		return;
	}
	y=EndText-1;
	Offset=(EndText-NumLns/2)-1;
	T24RefreshAll();
	x=1;
	CursorEOL();
}
void PageUp()
{
	if( Offset < NumLns ) {  /* was -3, then +1 */
		TopOfFile();
		return;
	}
	y-=NumLns-1;
	Offset-=(NumLns-1);
	if( Offset < 0 ) Offset=0;
	x=1;
	T24RefreshAll();
}
void PageDown()
{
	if(EndText<NumLns) return;
	if(y >= EndText-7) return;  			/* could be better */
	if( y >= EndText - ((NumLns)-1) ) {
		BottomOfFile();
		return;
	}
	y+=(NumLns-1);
	Offset+=(NumLns-1);
	if(y>=EndText) {
		BottomOfFile();
		return;
	}
	x=1;
	T24RefreshAll();
}
void ScrollUp()
{
	++Offset;
	if(submarine==FALSE) {
		clear_to_color(T24buf,BLACK);
		if (MonoType==0) {
			blit(screen, T24buf, 0, 85, 0, 0, 650, 468);
			blit(T24buf, screen, 0, 0, 0, 49, 650, 468);
		} else {
			blit(screen, T24buf, 0, 73, 0, 0, 784, 480);
			blit(T24buf, screen, 0, 0, 0, 49, 784, 480);
		}

		T24DisplayString();
		if(ShiftSelect > 0) {
			x=1;
			cxUpdate();
			g1=cx;
			k=strlen( Ln[y] );
			x=k+1;
			if(x>1) HighlightSelection();
		}
	}
}
void ScrollDown()
{
	--Offset;
	if(submarine==FALSE) {
		clear_to_color(T24buf,BLACK);
		if (MonoType==0) {
			blit(screen, T24buf, 0, 49, 0, 0, 650, 468);
			blit(T24buf, screen, 0, 0, 0, 85, 650, 468);
		} else {
			blit(screen, T24buf, 0, 49, 0, 0, 784, 480);
			blit(T24buf, screen, 0, 0, 0, 73, 784, 480);
		}
		T24DisplayString();
		if(ShiftSelect > 0) {
			k=strlen( Ln[y] );
			x=k+1;
			cxUpdate();
			g1=cx;
			x=1;
			if(k>0) HighlightSelectionBackwards();
		}
	}
}
int WordLeft()
{
	int a,b;

	if( y==0 && x ==1) return(1);
retry:  if( x==1 ) {
		CursorLeft();
		CursorLeft();
	}
	do {
	if( y==0 && x ==1) return(1);
		CursorLeft();
		a=Ln[y][x-2];
		b=Ln[y][x-1];
	} while (!( (a==32 && b >= 33) || x==1 ) );
	if( y==0 && x ==1) return(1);
	if (x==1 && Ln[y][0]==32) goto retry;
	return(0);
}
int WordRight()
{
	int a,b,z;
	int LastSpace=0;
	int x_holder,y_holder,offset_holder;

	x_holder=x;
	y_holder=y;
	offset_holder=Offset;

	if( y==EndText ) {
		if(x-k==1) goto guardrail;
		if(Ln[y][x]==32) {
			return(CursorRight());
		}
		if(x >= k-3) {
			CursorEOL();
			return(1);
		}
		for(z=x; z<=k-2; ++z) {
			if( Ln[y][z]==32 ) LastSpace=1;
		}
		if( LastSpace==0 ) goto guardrail;
	}
	if(x >= k) {
		if( y==EndText ) return(1);
		if(CursorRight() !=0) goto guardrail;
	}
	do {
		if(CursorRight() !=0) goto guardrail;
		a=Ln[y][x-2];
		b=Ln[y][x-1];
	} while (!( (a==32 && b >= 33) || x==1 ) );

	if(submarine==TRUE) return(2);
	if(Ln[y][0]==0 && y < EndText) {
		while(Ln[y][0]==0 && y < EndText) CursorDown();
		while(Ln[y][x-1] < 33) {
			if(CursorRight() !=0) goto guardrail;
		}
	}
	return(0);
guardrail:
	x=x_holder;
	y=y_holder;
	Offset=offset_holder;
	return(1);
}
void Xreturn()
{
	int z;

	if( y>EndText) return;
	if(x==1 && y == 0) {
		++EndText;
		for( z=EndText; z >= 0; --z) {
			memcpy( Ln[z+1], Ln[z],LINELENGTH);
		}
		memset(Ln[0],0,LINELENGTH);
		T24RefreshAll();
		++y;
		return;
	}
	if(x==1) {
		++EndText;
		for( z=EndText; z >= y; --z) {
			memcpy( Ln[z+1], Ln[z],LINELENGTH);
		}
		memset(Ln[y],0,LINELENGTH);
		T24RefreshAll();
		if(y+1-Offset >= NumLns) ScrollUp();
		++y;
		return;
	}
	++EndText;
	for( z=EndText; z > y; --z) {
		memcpy( Ln[z+1], Ln[z],LINELENGTH);
	}
	t=32;
	memset(Ln[y+1],0,LINELENGTH);
	k = strlen(Ln[y]);
	if( x <= k ) {
		for( z=0; z <= k-x+1; ++z) {
			t=Ln[y][x-1+z];
			Ln[y+1][z]=(t);
		}
		Ln[y+1][z+1]=(null);
	}
	Ln[y][x-1]=(null);
	CursorRight();
	if(y==0) y=1;
	T24RefreshAll();
}
void Wordwrap(int GrWidth)
{
	char Buf1[LINELENGTH];
	char Buf2[LINELENGTH];
	char TestBuf[LINELENGTH];
	int x_holder=x;
	int y_holder;
	int a,b,i,z;
	int k;

	k=strlen( Ln[y] );
	sy=y+1-Offset;
	if( sy >=NumLns-1 ) JumpUp();
	if( GrWidth <= 500 && k < 75) return;

	y_holder=y;

	if( x>=k+1) {
		submarine=TRUE;
		++EndText;
		for( z=EndText; z >= y+1; --z) {
			memcpy( Ln[z+1], Ln[z],LINELENGTH);
		}
		memset(Ln[y+1],0,LINELENGTH);
		memset(Buf1,0,LINELENGTH);
		memset(Buf2,0,LINELENGTH);
		b=x-1;	/* was b=x */
		WordLeft();
		a=x-1;
		i=b-a;
		for( z=0; z < i; ++z) {	/* was <=  */
			t=Ln[y][z+a];
			Buf2[z]=(t);
		}
		for( z=0; z < a; ++z) {
			t=Ln[y][z];
			Buf1[z]=(t);
		}

/* test before invoking, if not perfect, later, Alligator */

		if( k < 77) {  /* two chances to get it right */
			memcpy(TestBuf,Buf1,b);
			strcat(TestBuf,Buf2);
			if(memcmp(Ln[y],TestBuf,k) !=0) return;
		}

		memcpy(Ln[y],Buf1,b);
		memcpy(Ln[y+1],Buf2,i);

		CursorDown();
		CursorEOL();
		AlignParagraph();

		submarine=FALSE;
		T24RefreshAll();
		return;
	} else {
		CursorEOL();
		submarine=TRUE;
		WordLeft();
		a=x;
		Xreturn();
		CursorUp();
		CursorEOL();
		if( x_holder < x ) {
			while(x > x_holder) CursorLeft();
			submarine=FALSE;
			AlignParagraph();
			T24RefreshAll();
			return;
		}
			else {  /* cursor within word dropped */
				CursorDown();
				CursorBOL();
				while(x < x_holder-a) CursorRight();
				submarine=FALSE;
				AlignParagraph();
				T24RefreshAll();
				return;
			}
	}
	T24RefreshAll();
}
void T24DisplayString()
{
	clear_to_color(T24linebuf,BLACK);
	BackgroundColor=BLACK;
	if(submarine==TRUE) return;
	sy=y+1-Offset;
	if(MonoType==0) Headline21(T24linebuf,2,4,TextColor,Ln[y]);
		else PutsMono13(T24linebuf,2,4,TextColor,Ln[y]);
	if(MonoType==0) blit(T24linebuf, screen, 0, 0, 16, 13+(sy*lp), 650, lp);
		else blit(T24linebuf, screen, 0, 0, 45, 25+(sy*lp), 784, lp);
}
void T24DisplayRight()
{
	unsigned int z;

	cxUpdate();
	sy=y+1-Offset;
	for( z=x-1; z< x+k+1; ++z ) {  /* right$ clone */
			 t=Ln[y][z-1];
			 RightStr[z-x]=( t );
	}
	RightStr[z-x]=(null);

	if(MonoType==0) {
		rectfill(screen,11+cx+6,13+(sy*lp),MaxX-124,13+(sy*lp)+lp,BLACK);
		PutsFont21(12+cx+6,12+5+(sy*lp),TextColor,RightStr);
	} else {
		rectfill(screen,11+cx+6+29,26+(sy*lp),MaxX-124,13+9+(sy*lp)+lp,BLACK);
		PutsMono13(screen,47+cx,29+(sy*lp),TextColor,RightStr);
	}
}
void JumpUp()
{
	sy=y+1-Offset;
	if( sy <= 6 ) return;
	Offset+=4;
	T24RefreshAll();
}
void Unselect()
{
	ShiftSelectOff();
	BlockStartX=0;
	BlockEndX=0;
	BlockStartY=0;
	BlockEndY=0;
	T24RefreshAll();
}
void SelectAll()
{
	int z, x_holder,y_holder;

	ShiftSelectOff();
	if(ShiftSelect==2) return;
	if(ShiftSelect==1) Unselect();
	BottomOfFile();
	x_holder=x;
	y_holder=y;
	ShiftSelectOn();
	ShiftSelect=2;
	BlockStartX=1;
	BlockEndX=1;
	BlockStartY=0;
	BlockEndY=y;

	for(z=0; z<=NumLns; ++z) {
		y=z+Offset;
		k=strlen( Ln[y] );
		x=1;
		cxUpdate();
		g1=cx;
		x=k+1;
		HighlightSelection();
	}
	x=x_holder;
	y=y_holder;
}
void SelectLeft()
{
	if( x==1 && y==0) return;
	cxUpdate();
	g1=cx;
	if( x > 1 ) {
		--x;
		HighlightSelectionBackwards();
		if(ShiftSelect==0) {
			ShiftSelectOn();
			BlockEndX=x+1;
			BlockEndY=y;
			BlockStartX=x;
			BlockStartY=y;
			CutSY=y+1-Offset;
		} else {
			if(BlockStartY==y || BlockEndY==y ) {
				if(x >= BlockStartX) --BlockEndX;
					else --BlockStartX;
			}
		}
	}
	if( x==1) {
		SelectUp();
		CursorEOL();
	}
}
void SelectRight()
{
	cxUpdate();
	g1=cx;
	k=strlen( Ln[y] );
	if( x <=k ) {
		++x;
		HighlightSelection();
		if(ShiftSelect==0) {
			ShiftSelectOn();
			BlockEndX=x;
			BlockEndY=y;
			BlockStartX=x-1;
			BlockStartY=y;
			CutSY=y+1-Offset;
		} else {
			if(BlockStartY==y || BlockEndY==y ) {
				if(x <= BlockEndX) ++BlockStartX;
					else ++BlockEndX;
			}
		}
	} else {
		if( y+1 > EndText ) return;
		x=1;
		++y;
		cx=0;
	}
	if( x==1) --BlockEndY;
	if( y+1-Offset > NumLns ) ScrollUp();
}
void SelectWordRight()
{
	int a,b,z;
	int LastSpace=0;

	cxUpdate();
	g1=cx;
	if( y==EndText ) {
		if(x-k==1) return;
		if(Ln[y][x]==32) {
			CursorRight();
			HighlightSelection();
		}
		if(x >= k-3) {
			CursorEOL();
			return;
		}
		for(z=x; z<=k-2; ++z) {
			if( Ln[y][z]==32 ) LastSpace=1;
		}
		if( LastSpace==0 ) {
			return;
		}
	}
	if(x >= k) {
		if( y==EndText ) {
			return;
		}
		SelectRight();
	}
	do {
		SelectRight();
		a=Ln[y][x-2];
		b=Ln[y][x-1];
	} while (!( (a==32 && b >= 33) || x==1 ) );
}
void SelectUp()
{
	int x_holder;

	if( y==0 ) return;
	x_holder=x;
	if(ShiftSelect==0) {
		ShiftSelectOn();
		BlockStartX=1;
		BlockEndX=x;
		BlockStartY=y-1;
		BlockEndY=y;
		CutSY=y+1-Offset;
	} else {
		if(y-1 >= BlockStartY) --BlockEndY;
			else --BlockStartY;
	}
	--y;
	x=1;
	if(y+1-Offset < 1) ScrollDown();
	else {
		cxUpdate();
		g1=cx;
		x=x_holder;
		if(x>1) {
			++y;
			HighlightSelection();
			--y;
		}
		k=strlen( Ln[y] );
		x=k+1;
		HighlightSelection();
		x=1;
	}
}
void SelectDown()
{
	int x_holder;

	if( y+1 > EndText ) return;
	x_holder=x;
	k=strlen( Ln[y] );
	if( x <=k ) {
		cxUpdate();
		g1=cx;
		x=k+1;
		HighlightSelection();
	}
	x=1;
	++y;
	if(ShiftSelect==0) {
		ShiftSelectOn();
		BlockStartX=x_holder;
		BlockEndX=1;
		BlockStartY=y-1;
		BlockEndY=y;
		CutSY=y+1-Offset;
	} else {
		if(y <= BlockEndY) ++BlockStartY;
			else ++BlockEndY;
	}
	if(y+1-Offset > NumLns) ScrollUp();
}
void CursorEOL()
{
	if(ShiftSelect > 0) Unselect();
	k=strlen(Ln[y]);
	x=k+1;
	cxUpdate();
}
void CursorBOL()
{
	if(ShiftSelect > 0) Unselect();
	x=1;
	cx=0;
}
int CursorLeft()
{
	if(ShiftSelect > 0) Unselect();
	if( x==1 && y==0) return(1);
	if( x==1) {
		if(!CursorUp()) CursorEOL();
		return(0);
	}
	--x;
	return(0);
}
int CursorRight()
{
	if(ShiftSelect > 0) Unselect();
	k=strlen( Ln[y] );
	if( x <=k ) {
		++x;
	} else {
		if( y >= EndText-1 ) { EndText=y+1; return(1); }
		x=1;
		++y;
		cx=0;
	}
	if(y+1-Offset > NumLns) ScrollUp();
	return(0);
}
int CursorUp()
{
	int x_holder;

	if(ShiftSelect > 0) Unselect();
	if(y==0) return(1);
	x_holder=x;
	--y;
	k=strlen(Ln[y]);
	if( x_holder > k+1) x=k+1;
	if(y+1-Offset < 1) ScrollDown();
	return(0);
}
int CursorDown()
{
	int x_holder;

	if(ShiftSelect > 0) Unselect();
	if( y >= EndText-1 ) { EndText=y+1; return(1); }
	if( y < EndText ) {
		x_holder=x;
		++y;
		k=strlen( Ln[y] );
		if( x_holder > k+1) x=k+1;
	}
	if(y+1-Offset > NumLns) ScrollUp();
	return(0);
}
void Contract()
{
	unsigned int z;

	if( y==EndText ) return;
	if(MonoType==0 && StrLenFont21(Ln[y])+StrLenFont21(Ln[y+1]) > MaxX-300) return;
	k=strlen(Ln[y+1]);

	for( z=0; z <= k; ++z) {
		t=Ln[y+1][z];
		Ln[y][z+x-1]=( t );
	}
/*	Ln[y][z]=0;
*/	for( z=y+1; z <= EndText; ++z) {  /* removed +2, added=( now <= ) */
		memcpy( Ln[z], Ln[z+1],LINELENGTH);
	}
	memset(Ln[EndText+1],0,LINELENGTH);
	memset(Ln[EndText+2],0,LINELENGTH); /* added */

	--EndText;
}
void DelKey()
{
	int z;

	k= strlen( Ln[y] );
	if( x > k && EndText==y ) return;
	if( x > k && EndText > y ) {  /* removed the added = */
		if( strlen(Ln[y+1])+k < LINELENGTH-2 ) {
			Contract();
			if( y > EndText) CursorUp();  /* added patch */
			if(submarine==FALSE) T24RefreshAll();
		}
		return;
	}
	for( z=x-1; z < k; ++z) Ln[y][z]=Ln[y][z+1];
	T24DisplayString();
}
void CtrlU()
{
	if(Clipboard[0]==0) return;
	if(x > 1) Xreturn();
	Xreturn();
	CursorUp();
	memset(Ln[y],0,LINELENGTH);
	memcpy(Ln[y],Clipboard,LINELENGTH);
	T24DisplayString();
}
void CtrlY()
{
	x=1;
	memcpy(Clipboard,Ln[y],LINELENGTH);
	memset(Ln[y],0,LINELENGTH);
	DelKey();
}
void Backspace()
{
	int z;

	if(x==1 && y==0) return;
	if(x==1 && Ln[y-1][0]==(null)) {
		CursorUp();
		Contract();
		T24RefreshAll();
		return;
	}
	CursorLeft();
	if( x < 1 ) return;
	k= strlen( Ln[y] );
	for( z=x-1; z < k; ++z) Ln[y][z]=Ln[y][z+1];
	T24DisplayString();
}
void Tab()
{
	t=9;
	T24PutOneChar();
}
void AutoCap()
{
	if(! islower(c)) return;
	c=toupper(c);
	if(UserCap !=1) UserCap=0;
}
void T24PutOneChar()  /* ### */
{
	int z, q;
	char WrapDone=0;

	if( c==0 ) return; /* shouldn't happen */
	if( isupper(c) != 0) UserCap=1; /* capital typed by user */
	if( c < 32 && c != 9) return;
	if( x > 3 && Ln[y][x-2]==32 && Ln[y][x-3]==32) AutoCap();
	if( x==1 && y==0) AutoCap();
	if( x==1 && y >= 1 && Ln[y-1][0]==0) AutoCap();
	if( x>1 && Ln[y][x-2]==9) AutoCap();
	if( isspace(c) != 0) UserCap=0;
	q=StrLenFont21(Ln[y]);
	k=strlen( Ln[y] );
	if(x==k+1 &&  ((x> 74) | (q>499)) && Ln[y][x-1]==32) {
		if(c==32) strcat(Ln[y], " ");
		Xreturn();
		WrapDone=1;
	}

	if(x <= k) for(z=k; z >= x; --z) Ln[y][z]=Ln[y][z-1];
	Ln[y][x-1]=(c);
	Ln[y][k+1]=(null);
	if( c==9) T24DisplayString();
		else T24DisplayRight();
	CursorRight();
	if(WrapDone==0) Wordwrap(q);
	if(c==32 && AutoCorrectOff==FALSE) AutoCorrect();
	AutoCorrectDone=x;
}
void WordCount()
{
	char NumOfWords[10];
	int i=0;
	int x_holder=x;
	int y_holder=y;
	int offset_holder=Offset;

	submarine=TRUE;
	y=EndText-1;
	x=1;
	CursorEOL();
	do {
		if( x==1 && y==0) break;
	  	WordLeft();
		++i;
	} while(1);
	i--;
	if(i < 0) i=0;
	submarine=FALSE;
	x=x_holder;
	y=y_holder;
	Offset=offset_holder;
	rectfill(screen,380,13,540,39,LILAC);
	PutsLuna(380,20,BLACK,LILAC, "WC:");
	itoa(i,NumOfWords,10);
	PutsLuna(410,20,BLACK,LILAC, NumOfWords);
}
int FindGraphicalLength(int gx, int gy)
{
	int i,q;
	int len=0;

	for( i=0; i<=gx; ++i) {
		q=Ln[gy][i];
		if(MonoType==0) len += Font21[q] -65;
			else len += Mono13[q] -65;
	}
	return(len);
}
int AlignLine(int linenum)
{  /* moves as many words that will fit from the second of two lines to
		the end of the first, to be called by AlignParagraph()  */

	char wordbuf[LINELENGTH];
	char linebuf[LINELENGTH];
	int lx,wx;
        size_t len2, starting_len2;
	int rm=66;

	memset(wordbuf,0,LINELENGTH);
	memset(linebuf,0,LINELENGTH);
	lx=wx=0;
	len2=strlen(Ln[linenum+1]);
	starting_len2=len2;

/* lengthen the first line */
	while( lx < len2) {
		while( Ln[linenum+1][lx] !=32 && Ln[linenum+1][lx] !=0) {
			wordbuf[wx]=Ln[linenum+1][lx];
			lx++;
			wx++;
		}
		if(strlen(Ln[linenum]) + strlen(wordbuf) > rm) break;
		wordbuf[wx]=Ln[linenum+1][lx];
		strcat(Ln[linenum], wordbuf);
		lx++;
		wx=0;
		memset(wordbuf,0,LINELENGTH);
	}
/* shorten the second line */
	while( lx < len2) {
		while( Ln[linenum+1][lx] !=32 && Ln[linenum+1][lx] !=0) {
			wordbuf[wx]=Ln[linenum+1][lx];
			lx++;
			wx++;
		}
		wordbuf[wx]=Ln[linenum+1][lx];
		strcat(linebuf, wordbuf);
		lx++;
		wx=0;
		memset(wordbuf,0,LINELENGTH);
	}
	strcpy(Ln[linenum+1], linebuf);
	strcat(Ln[linenum+1], wordbuf);

	len2=strlen(Ln[linenum+1]);
	if(starting_len2==0) return(100); /* prevent unwanted contraction */
		else return(len2);		  /* contract if necessary */
}
void AlignParagraph()
{
	int x_holder=x;
	int y_holder=y;
	int offset_holder=Offset;
	int Result;

	submarine=FALSE;
	if(Ln[y+1][0] ==0) return;
	if(y==EndText || y+1==EndText) return;
	if(Ln[y][0]==0) return;
	if(Ln[y+1][0] <=32) return;

	if(y==EndText || y+1==EndText) return;
	if(Ln[y][0]==0) return;
	if(Ln[y+1][0] <=32) return;

	submarine=TRUE;
	do {
		Result=AlignLine(y);
		if( Result==0 ) {		/* contract if necessary  */
			CursorDown(); 	/* during insert wordwrap */
			DelKey();
		}
		if(y==EndText || y+1==EndText) break;
		if(Ln[y][0]==0) break;
		if(Ln[y+1][0] ==0) break;
		if(Ln[y+1][0] <=32) break;
		CursorDown();
	} while(1);

	CursorDown();
	if(Ln[y][0]==0 && Ln[y+1][0]==0) Contract();
	y=y_holder;
	x=x_holder;
	Offset=offset_holder;
	submarine=FALSE;
	T24RefreshAll();
	Action=1;
}
void HighlightFindStr()
{
	int wx1, wx2, x_holder,z;

	x_holder=x;
	ShiftSelectOff();
	ShiftSelect=3;
	submarine=TRUE;
	z=0;
	x+=strlen(FindStr);
	cxUpdate();
	wx2=cx;
	x=x_holder;
	submarine=FALSE;
	cxUpdate();
	wx1=cx;
	cy=3+((y+1-Offset)*lp)+lp;
	xor_mode(TRUE);
	if(MonoType == 0) rectfill(screen,17+wx1, cy-26, 16+wx2, cy+6, makecol(255,255,255));
		else rectfill(screen,47+wx1, cy-1, 46+wx2, cy+18, makecol(255,255,255));
	xor_mode(FALSE);
}
void HighlightWord()
{
	int wx1, wx2;

	ShiftSelectOff();
	ShiftSelect=3;
	submarine=TRUE;
	WordRight();
	if( x==1) CursorLeft();
	cxUpdate();
	wx2=cx;
	WordLeft();
	submarine=FALSE;
	cxUpdate();
	wx1=cx;
	cy=3+((y+1-Offset)*lp)+lp;
	xor_mode(TRUE);
	if(MonoType == 0) rectfill(screen,17+wx1, cy-26, 16+wx2, cy+6, makecol(255,255,255));
		else rectfill(screen,47+wx1, cy-1, 46+wx2, cy+18, makecol(255,255,255));
	xor_mode(FALSE);
}
void T24Edit()
{
	int Result;

	x=1;
	y=0;
	T24PutTime();
	T24DrawCursor();

eraseboxes: if(SpellBoxesDisplayed==TRUE) T24ClearSpellBoxes();

loopback:


	T24Infoxy();
	T24DrawCursor();  /* erases by drawing, if already displayed */
	do {

		if( y<0 || y>EndText) {  /* silly error trap */
			TopOfFile();
			if(EndText < NumLns) T24DrawCursor();
			goto loopback;
		}

		T24PutTime();

/*
		if(key_shifts & KB_ALT_FLAG) {
			if(!key_shifts & KB_ALT_FLAG) goto loopback;
			yholder=y;
			if(file_too_long==FALSE) Result=Supertype();
				else goto loopback;
			submarine=FALSE;
			if( Result !=0 ) goto loopback;
			if(y>yholder) {
				y--;
				T24RefreshAll();
				y++;
			}
			T24DrawCursor();
			install_timer(); 
			rest(300);
			remove_timer(); 
			T24DrawCursor();
			do {
				T24PutTime();
			} while(key_shifts & KB_ALT_FLAG);
			goto loopback;
		}
*/

	} while(!keypressed());
	c=GetKey();
	T24DrawCursor();
	if(file_too_long==TRUE) goto loopback;
	if( c > 31 && c < 126) {
		T24PutOneChar();
		Action=1;
		goto eraseboxes;
	}

	switch( c )
	{
		case 27:
/*		case 354:	 */	/* Japanese Muhenkan key */
/*		case 353: */		/* Japanese Henkan key */
					yholder=y;
					if(!file_too_long) Result=Supertype();
						else goto loopback;

					submarine=FALSE;
					if( Result !=0 ) goto loopback;
					if(y>yholder) {
						y--;
						T24RefreshAll();
						y++;
					}
					T24DrawCursor();
					install_timer(); 
					rest(300);
					remove_timer(); 
					T24DrawCursor();
					Action=1;
					goto loopback;
		case 1:			SelectAll();
					goto loopback;
		case 2:			goto loopback;
		case 3:			T24DoCopy();
					goto loopback;
		case 6:			T24DoFind();
					goto loopback;
		case 8: 		if(file_too_long==TRUE) goto loopback;
					if(ControlKeyStatus()) T24DoFindAndReplace();
					Action=1;
					goto eraseboxes;
		case BS:                Backspace();
					Action=1;
					goto eraseboxes;
		case 9:			if(file_too_long==TRUE) goto loopback;
					Tab();
					Action=1;
					goto eraseboxes;
		case 12:		T24DoNext();
					goto loopback;
		case 13:		if(file_too_long==TRUE) goto loopback;
					Xreturn();
					Action=1;
					goto eraseboxes;
		case 14: 		T24DoNew();
					goto eraseboxes;
		case 15: 		T24DoOpen();
					goto eraseboxes;
		case 18: 		T24DoSaveAs();
					goto eraseboxes;
		case 19:		if(file_too_long==TRUE) goto loopback;
					T24DoSave();
					goto eraseboxes;
		case 20: 		T24DoTextColor();
					goto loopback;
		case 21:		if(file_too_long==TRUE) goto loopback;
					CtrlU();
					goto eraseboxes;
		case 22:		if(file_too_long==TRUE) goto loopback;
					T24DoPaste();
					goto eraseboxes;
		case 24:		if(file_too_long==TRUE) goto loopback;
					T24DoCut();
					goto eraseboxes;
		case 25:		if(file_too_long==TRUE) goto loopback;
					CtrlY();
					Action=1;
					goto eraseboxes;
		case 26:		/* T24DoUndo(); */
					goto loopback;
		case LEFTARROW: 	CursorLeft();
					goto eraseboxes;
		case SHFT_LEFTARROW: 	SelectLeft();
					goto eraseboxes;
		case RIGHTARROW: 	CursorRight();
					goto eraseboxes;
		case SHFT_RIGHTARROW:	SelectRight();
					goto eraseboxes;
		case CTRL_UPARROW:
		case UPARROW:		CursorUp();
					clear_keybuf(); 
					goto eraseboxes;
		case SHFT_UPARROW:	SelectUp();
					clear_keybuf(); 
					goto eraseboxes;
		case CTRL_DOWNARROW:
		case DOWNARROW:	CursorDown();
					clear_keybuf(); 
					goto eraseboxes;
		case SHFT_DOWNARROW:	SelectDown();
					clear_keybuf(); 
					goto eraseboxes;
		case DELKEY:		if(file_too_long==TRUE) goto loopback;
					DelKey();
					Action=1;
					goto eraseboxes;
		case PGUPKEY: 		PageUp();
					goto eraseboxes;
		case PGDNKEY: 		PageDown();
					goto eraseboxes;
		case HOMEKEY: 		CursorBOL();
					goto eraseboxes;
		case ENDKEY: 		CursorEOL();
					goto eraseboxes;
		case CTRL_LEFTARROW: 	WordLeft();
					goto eraseboxes;
		case CTRL_RIGHTARROW:	WordRight();
					goto eraseboxes;
		case SHFT_CTRL_RIGHTARROW: SelectWordRight();
					goto eraseboxes;
		case CTRL_HOMEKEY:	TopOfFile();
					goto eraseboxes;
		case CTRL_ENDKEY:	BottomOfFile();
					goto eraseboxes;
		case F1:		if(file_too_long==TRUE) goto loopback;
					if(strcmp(CurrentFile,"NAMELESS.TXT")==0) {
						T24DoSaveAs();
						goto eraseboxes;
					}
					T24DoSave();
					goto eraseboxes;
		case F2:		T24DoOpen();
					goto eraseboxes;
		case F3:		T24DoNew();
					goto eraseboxes;
		case F4:		T24DoSaveAs();
					goto eraseboxes;
		case F5:		if(file_too_long==TRUE) goto loopback;
					T24DoWordCount();
					goto eraseboxes;
		case F6:		T24DoTextColor();
					goto eraseboxes;
		case F7:		if(file_too_long==TRUE) goto loopback;
					if(SpellBoxesDisplayed==FALSE) goto loopback;
					T24DoAddToDict();
					goto loopback;
		case F8:                if(SpellBoxesDisplayed==FALSE) {
						if(AutoCorrectOff==FALSE) AutoCorrectOff=TRUE;
							else AutoCorrectOff=FALSE;
						T24ClearSpellBoxes();
						goto loopback;
					} else {
						T24DoSkip();
						goto loopback;
					}
		case F9:		if(file_too_long==TRUE) goto loopback;
					T24DoSpellCheck();
					goto loopback;
		case F10:		if(file_too_long==TRUE) goto loopback;
					T24DoAlign();
					goto eraseboxes;
		case F11:		T24DoHelp();
					PanelBeep();
					goto eraseboxes;
		case F12: 		if(Action !=0) {
						Result=T24Safety();
						if(Result==1) return;
						if(Result==2) {
							T24MessageBoxes();
							T24LowerMessageBoxes();
							goto loopback;
						}
						if(Result==3) {
							SaveTextFile();
							return;
						}
					} else {
						return;
					}
		case CTRL_F1: 		Screenshot792("Text8.bmp");
					goto loopback;
		case CTRL_F2: 		Screenshot1024("Text10.bmp");
					goto loopback;
		case CTRL_F11:		T24ShowAbbrList();
					PanelBeep();
					goto loopback;
		default:		goto eraseboxes;
	}
}
void LoadAbbr()
{
	int z;
        size_t i;

	SetCurrentFile("\\LC24APPS\\TEXT24\\ABBRFILE.TXT");
	LoadTextFile();
	AbbrEnd=EndText;
	for(z=1; z<=EndText-1; ++z) {
		for(x=0; x<=30; ++x) {
			AbbrBuf[z-1][x]=Ln[z][x];
		}
	if(Ln[z][0] < 48) AbbrEnd=z;
	}
	for (z=0; z < AbbrEnd;  ++z) {
		memcpy(ShortKey[z],Ln[z],2);
	}
	for (z=0; z < AbbrEnd;  ++z) {
		for ( i=0; i <= strlen(Ln[z]); ++i ) {
			AbbrBuf[z][i]=Ln[z][i+3];
		}
		AbbrBuf[z][i-4]=(null);
	}
	for(z=0; z< LINECOUNT-1; ++z) memset(Ln[z],0,LINELENGTH);
}
void T24Init()
{
	null=0;
	capture_x=0;
	capture_y=0;
	do_again=FALSE;
	EndText=1;
	Offset=0;
	min_old=70;
	submarine=FALSE;
	Action=0;
	load_abort=FALSE;
	Abort=FALSE;
	NumLns=14;
	NoFind=TRUE;
	Limit=1;
	UserCap=0;
	DictionaryLoaded=0;
	PersonalDictionaryLoaded=0;
	PersonalDictionaryUpdated=0;
	DictionaryMissing=FALSE;
	PersonalDictionaryMissing=FALSE;
	ActiveList=1;
	ShiftSelect=0;
	MarkWord=0;
	MarkFindStr=0;
	FindMode=1;
	TextColor=MANGO;
	SpellBoxesDisplayed=FALSE;
	MaxX=799;
	MaxY=599;
	strcpy(AmPmString,"X.X.");
	MonoType=0;
	lp=36; /* line pitch */
}
int Text24Mode(char *filespec)
{
	T24Init();
	T24Screen1();
	LoadAbbr();
	T24buf=create_bitmap(650,504);
	T24linebuf=create_bitmap(650,lp);
	strcpy( CurrentFile, filespec);
	AutoCorrectOff=FALSE;
	T24ClearWindow();
	if(memicmp(CurrentFile,"NAMELESS.TXT",12) != 0) LoadTextFile();
	DisplayFilename();
	T24RefreshAll();
	T24DrawCursor();
	PanelBeep();
	T24Edit();
	if(PersonalDictionaryUpdated==1 ) SaveDictionary();
	y=0;
	EndText=1;
	Offset=0;
	destroy_bitmap(T24buf);
	destroy_bitmap(T24linebuf);
	return(0);
}
int OpenText24(char *filespec)
{	/* saves the screen then restores it when Text 24 closes */
	/* for calling Text 24 with a filename to open */

	BITMAP *bmp = create_bitmap(800,600);

	clear_bitmap(bmp);
	blit(screen, bmp, 0, 0, 0, 0, 800, 600);
	Text24Mode(filespec);
	rectfill(screen,0,0,800,600, BLACK);
	blit(bmp, screen, 0, 0, 0, 0, 800, 600);
	destroy_bitmap(bmp);
	return(0);
}


