/* COMM3.C      This is part three of the mince command set

	This file contains the Control-X  command execution
routines for the mince editor. There are also a small number of
subordinate routines. */

#include "mince.gbl"	    /* Only when seperate files */

MLstBuffs()		     /* print a list of the buffers */
{
	tmp= -1;
	tlrow = -1;		     /* forget any saved row */
	for (cnt=BUFFSMAX-1; cnt>=0; --cnt) if (buffs[cnt].bbuff) {
		TSetPoint(++tmp,0);
		TCLEOL();
		BSetMod(BScrnMrk(tmp));
		TPrntStr(buffs[cnt].bname);
		TSetPoint(tmp,9);
		if (BModp(buffs[cnt].bbuff)) TPrntChar('*');
		else TPrntChar(' ');
		TPrntChar(' ');

		ltot(BLength(buffs[cnt].bbuff));
		TSetPoint(tmp,18);
		TPrntStr(buffs[cnt].fname);
		TKbChk();
		}
	TSetPoint(++tmp,0);
	TCLEOL();
	BSetMod(BScrnMrk(tmp));
	TForce();
	KbWait();
	if (tmp>=divide) ModeLine();
	}

AnyModified()			/* check if we have modified files about */
{
	tmp=FALSE;
	for (cnt=BUFFSMAX-1; cnt>=0; --cnt) if (buffs[cnt].bbuff)
		tmp |= BModp(buffs[cnt].bbuff);
	if (tmp && !Ask("Ignore changes this session? ")) return(TRUE);
	else return(FALSE);
	}


MExit()			 /* exit this level of the editor */
{
	arg=0;
	if(!AnyModified()){
		abort = TRUE;
	}
}

MFindFile()		     /* Find a file */
{
	char tfname[FILMAX], tbname[BUFNAMMAX];

	arg=0;
	*tfname='\0';
	do if (!GetArg("File to Find <CR>: ",CR,tfname,FILMAX)) return;
		while (*tfname=='\0');
	strip(tbname,tfname);
	dfltext(tfname, MSS);
	UpCase(tfname);
	LowCase(tbname);
	for (cnt=BUFFSMAX-1; cnt>=0 && (buffs[cnt].bbuff==NULL ||
		strcmp(tfname,buffs[cnt].fname)); --cnt);
	TKbChk();               
	if (cnt<0) {            
		cnt=CFindBuff(tbname);
		if (cnt>=0) {      
			if (!GetArg("Buffer Exists!  Buffer to Use <CR>: ",
				CR,tbname,BUFNAMMAX)) return;
			LowCase(tbname);
			cnt=CFindBuff(tbname);
			ClrEcho();    
			}             
		if (cnt<0) if ((cnt=CMakeBuff(tbname,tfname))<0) return;
		*(buffs[cnt].bmodes)='\0';
		strcpy(buffs[cnt].fname,tfname);
		BSwitchTo(buffs[cnt].bbuff);
		if (!BReadFile(tfname)) Echo("New File");
		}
	CSwitchTo(cnt);
	ScrnRange();
	}

MSetTabs()		      /* Set the tab increment to arg */
{
	if (argp)
		tabincr=arg;
	else
		tabincr=BGetCol();
	if(tabincr == 0)
		tabincr = 1;
	arg=0;
	NewDsp();		       /* force redisplay */
	}

MDelMode()		      /* remove a mode */
{
	char *bptr;

	arg=0;
	if (!(tmp=GetModeId("Delete Mode <CR>: "))) return;
	bptr = buffs[cbuff].bmodes;
	for (cnt=MAXMODES-1; cnt>=0; --cnt){
		if (tmp == *(bptr + cnt)){
			while (cnt>0 && *(bptr + cnt)){
				*(bptr + cnt) = *(bptr + cnt - 1);
				--cnt;
				}
			*(bptr + cnt) = '\0';
			SetModes();
			}
	}
}

MFileRead()		     /* read a file into the buffer */
{
	arg=0;
	if (BModp(buffs[cbuff].bbuff) && !Ask("Discard modifications you have made? ")) {
		ClrEcho();
		return;
		}
	if (!GetArg("File To Read <CR>: ",CR,buffs[cbuff].fname,FILMAX))
		return;
	dfltext(buffs[cbuff].fname, MSS);
	UpCase(buffs[cbuff].fname);
	if (!BReadFile(buffs[cbuff].fname)) Echo("New File");
	else ClrEcho();
	ModeLine();
	}

MFileSave()		     /* write the buffer to the default file */
{
	arg=0;
	Echo("Writing...");
	if (!BWriteFile(buffs[cbuff].fname)) Error("Can't open file");
	else Echo ("File Written");
	}

MNxtOthrWind()		  /* scroll the other window down */
{
	if (divide>=TMaxRow()-2) return;
	MSwpWind();
	while (arg-- > 0) MNextPage();
	MSwpWind();
	}

MFileWrite()		    /* write the buffer to a file */
{
	arg=0;
	if (!GetArg("File To Write <CR>: ",CR,buffs[cbuff].fname,FILMAX)) return;
	dfltext(buffs[cbuff].fname, MSS);
	UpCase(buffs[cbuff].fname);
	MFileSave();
	ModeLine();
	}

MSwapMrk()		      /* Swap the point with the mark */
{
	BSwapPnt(mark);
	arg=0;
	}

MPrvOthrWind()		  /* scroll the other window up */
{
	if (divide>=TMaxRow()-2) return;
	MSwpWind();
	while (arg-- > 0) MPrevPage();
	MSwpWind();
	}

MSetIndent()		    /* set the indent column */
{
	if (argp) indentcol=arg;
	else indentcol=BGetCol();
	Echo("Left margin is ");
	itot(indentcol);
	DivideLine();
	arg=0;
	}

#ifdef YINYANG
MUnix()			 /* execute a shell command */
{
	char cmnd_line[80];
	int status;
	
	arg=0;
	*cmnd_line='\0';
	if (!GetArg("Shell Command <CR>: ",CR,cmnd_line,80)) return;
	TSetPoint(TMaxRow()-1,0);
	TCLEOL();
	TForce();
	TFini();
	system(cmnd_line);
	while (wait(&status) != -1);
	printf("[Hit <CR> to return to Mince]");
	while (getchar()!='\n');
	TInit();
	NewDsp();
	}
#endif

#ifdef UNIX
MPrintPos()			/* print the current position */
{
	long tmp, line;

	line = arg = 0;			/* set up */
	tmark=BCreMrk();			/* this is where we are */
	BToStart();				/* to the beginning */
	while(!BIsAfterMrk(tmark) &&	/* while ahead of this */
			!BIsEnd() ){		/* and not at the end */
		NLSrch();				/* look for NL */
		line++;				/* And count them */
		}
	if( BIsEnd() )line++;		/* correct it for special case */
	PtMkKill(tmark);			/* all done with that mark */
	BSwapPnt(mark);
	tmp=(long)BLocation();
	tmp=BLocation();
	BSwapPnt(mark);
	Echo("Point: ");
	ltot((long)BLocation());
	TPrntStr(" length: ");
	ltot((long)BLength(buffs[cbuff].bbuff));
	TPrntStr(" column: ");
	itot(BGetCol());
	TPrntStr(" mark: ");
	ltot((long)tmp);
	TPrntStr(" line: ");
	ltot((long)line);
	TForce();
	KbWait();
	ClrEcho();
	}
#else
MPrintPos()		     /* print the current position */
{
#ifndef CPM
	long tmp;
#endif

	BSwapPnt(mark);
	tmp=BLocation();
	BSwapPnt(mark);
	Echo("Point ");
#ifdef CPM
	itot(BLocation());
#else
	ltot(BLocation());
#endif
	TPrntStr("   length ");
#ifdef CPM
	itot(BLength(buffs[cbuff].bbuff));
#else
	ltot(BLength(buffs[cbuff].bbuff));
#endif
	TPrntStr("   column ");
	itot(BGetCol());
	TPrntStr("   mark ");
#ifdef CPM
	itot(tmp);
#else
	ltot(tmp);
#endif
	TForce();
	KbWait();
	ClrEcho();
	}
#endif

MOneWind()		      /* switch to one window mode */
{
	if (divide>=TMaxRow()-2) return;
	topp=TRUE;
	BSetMod(BScrnMrk(divide));
	divide=TMaxRow()-2;
	BKillMrk(altstart);
	BKillMrk(altpnt);
	sendp=FALSE;
	}

MTwoWind()		      /* Switch to two window mode */
{
	if (divide>=TMaxRow()-2){
		altpnt=BCreMrk();
		BSwapPnt(sstart);
		altstart=BCreMrk();
		BSwapPnt(sstart);
		altbuff=cbuff;
	}
	BSetMod(BScrnMrk(divide));
	divide=TGetRow();
	if (divide>TMaxRow()-6)
		divide=TMaxRow()-6;
	if (divide<3)
		divide=3;
	ScrnRange();
	ModeLine();
}
/*
MTwoWind()		      /* Switch to two window mode */
{
	if (divide<TMaxRow()-2) return;
	divide=(TMaxRow()-2)/2;
	ScrnRange();
	altpnt=BCreMrk();
	BSwapPnt(sstart);
	altstart=BCreMrk();
	BSwapPnt(sstart);
	altbuff=cbuff;
	ModeLine();
	}
*/
MSwitchTo()		     /* switch buffers */
{
	int cnt;

	arg=0;
	if (!GetArg("Switch to Buffer <CR>: ",CR,namearg,BUFNAMMAX)) return;
	LowCase(namearg);
	cnt=CFindBuff(namearg);
	if (cnt<0 && (!Ask("Create new buffer?") ||
		(cnt=CMakeBuff(namearg,"NAME.ME"))<0)) return;
	CSwitchTo(cnt);
	ScrnRange();
	}

MSetFill()		      /* set the fill width */
{
	if (argp) fillwidth=arg;
	else fillwidth=BGetCol();
	Echo("Right margin is ");
	itot(fillwidth);
	DivideLine();
	arg=0;
	}

MKillBuff()		     /* delete a buffer */
{
	int cnt;

	arg=0;
	if (!GetArg("Delete Buffer <CR>: ",CR,namearg,BUFNAMMAX)) return;
	LowCase(namearg);
	if ((cnt=CFindBuff(namearg))<0) {
		Error("Does not exist");
		return;
		}
	if (cnt==cbuff) MSwitchTo();
	if (cnt==cbuff) {
		Error("Can't delete current");
		return;
		}
	if (BModp(buffs[cnt].bbuff) && !Ask("Delete Modified Buffer?")) return;
	if (divide<TMaxRow()-2 && cnt==altbuff) MOneWind();
	BDelBuff(buffs[cnt].bbuff);
	buffs[cnt].bbuff=NULL;
	strcpy(namearg,buffs[cbuff].bname);
	}

MAddMode()			      /* add a mode to the list */
{
	char *bptr;

	arg=0;
	if (!(tmp=GetModeId("Mode Name <CR>: "))) return;
	bptr = buffs[cbuff].bmodes;
	for (cnt=MAXMODES-1; cnt>=0; --cnt) {
		if(! *(bptr + cnt))
			*(bptr + cnt) = tmp;
		if(tmp == *(bptr + cnt)){
			SetModes();
			return;
			}
		}
	Error("No More Mode Room");
	}
	
MSwpWind()		      /* Switch which window we are in */
{
	int cnt;

	if (divide>=TMaxRow()-2) return;
	tmp=altstart;		   /* switch alt and cur screen start */
	altstart=sstart;
	sstart=tmp;
	tmp=altpnt;		     /* switch alt and cur point */
	altpnt=BCreMrk();
	cnt=cbuff;		      /* switch buffers */
	if (altbuff!=cbuff) CSwitchTo(altbuff);
	altbuff=cnt;
	sendp=FALSE;		    /* fix up sstart, psstart, and send */
	BPntToMrk(sstart);
	BMove(-1);
	BMrkToPnt(psstart);
	BPntToMrk(tmp);	 /* set new point */
	BKillMrk(tmp);
	topp = !topp;		   /* switch top for bottom */
	}

MGrowWind()		     /* grow the current window */
{
	if (divide>=TMaxRow()-2) return;
	BSetMod(BScrnMrk(divide));
	divide += topp? arg : -arg;
	if (divide>TMaxRow()-6) divide=TMaxRow()-6;
	if (divide<3) divide=3;
	ModeLine();
	arg=0;
	}

	/* page mode commands */
MTrimWhite()
{
	tmark=BCreMrk();
	BToStart();
	while (!BIsEnd()) {
		ToEndLine();
		MDelWhite();
		BMove(1);
		}
	BPntToMrk(tmark);
	BKillMrk(tmark);
	}

/* END OF COMM3.C - Mince command routines */
