{**************************************************************
 ***                                                        ***
 ***                     FIX IT MAINTENANCE                 ***
 ***                                                  Aug 93***
 **************************************************************}
{Various routines for fixing databases - ie re-indexing, etc}
{Mark temporary fixes with TEMPFIX so we can search for 'em & remove}
{$I CompFlgs}
unit FIXIT;

INTERFACE


{procedure ReIndexAll;{}

procedure ReIndex(fiType : word);
procedure ReConstructAll; {used in updater}
procedure DeleteAdminFiles; {used in updater}


IMPLEMENTATION

uses
			files,
			jimmys,
			alljimmy,
			jimhooks,
			tuimsgs,
			indexes,
			idindex,
			views,
			indxutil,
			tables,
			tasks,
			tuiboxes, tuilist,
			jimindxs,
			messtext,
			kmaint,
			objects,
			tuiedit,
			global,
			notes,
			linklist,
			app,
			kjob,
			help,
			dattime,
			dosUtils,

			kamsetup,
			minilib;

{****************************************************************************
 ***                                                                      ***
 ***                MAKE INDEX FILE FOR HOOKED JIMMYS                     ***
 ***                                                                      ***
 ****************************************************************************}

{NOT TESTED!}

procedure MakeJimmyIndex(fitype, srType : word; Title : string);
var	Hook : PHook;
		Jimmy : PJimmy;
		IndexItem : PIndexItem;
		ProBox : PProgressBox;
		IdxRec : PLongint;
		JfiType : byte;
		Key : string;
		RecNo : longint;
		ixType : byte;

begin
	FileAdmin(fiType)^.LogOn;  {index file}
	FileAdmin(fiHooks)^.LogOn;
	FileAdmin(fiJimmys)^.LogOn;

	{delete existing index file}
	Stream(fiType)^.Seek(0);
	Stream(fiType)^.Truncate;

	{Set up index item ready for general work use}
	New(IndexItem, init);

	{Build by running through hooks stream, picking up *all* jimmys of that
	srType}
	ProBox := NewProgressBox('Making '+Title+' Index','',mfCancelButton,hcNoContext);

	for RecNo := 0 to Stream(fiHooks)^.NoREcs-1 do begin
		if (RecNo mod 10) = 0 then ProBox^.Update('Reading Hooks',RecNo, Stream(fiHooks)^.NoRecs-1);
		Hook := PHook(Stream(fiHooks)^.GetAt(recNo));
		if Hook<>nil then begin
			if Hook^.srType = srType then begin
				Jimmy := PJimmy(JimmyStream^.GetAt(Hook^.JimmyID));
				if Jimmy<>nil then begin

					IndexItem^.Idx2Dat := Jimmy^.RecNo;

					{Jimmy OK and matches type - code taken from idxJimmy unit}
					for ixType := 1 to Jimmy^.Numixtypes do begin
						Jimmy^.GetIndex(ixType, IdxRec, JfiType);
						IndexItem^.ixType := ixType;
						IndexItem^.KeyString := Jimmy^.GetIndexKey(ixType);

						if (IndexItem^.KeyString <> '') and (JfiType=fiType) then begin {inserting not wanted for this index}
							{Insert & store index item}
							IdxRec^ := Stream(fiType)^.NoRecs; {just store index item at end for now - sort below}
							Stream(fiType)^.PutAt(IdxRec^, IndexItem);
{							done in idxrec^ Jimmy^.SetIdxPtr(ixType, IdxRec); {heap item}
							Jimmy^.StoreIdxPtr(ixType);		{Store pointer}
						end;
					end;

					dispose(jimmy, done);
				end else
					JimmyStream^.Reset;

			end; {matching srtype}
			dispose(Hook, done);
		end; {Hook not nil}

		if ProBox^.COmmand = cmCancel then break;

	end; {for}

	dispose(IndexItem, done);

	dispose(ProBox, done);

	QuickSort(IndexStream(fiType), True);
	MakeHoles(IndexStream(fiType), 5);

	FileAdmin(fiHooks)^.LogOff;
	FileAdmin(fiJimmys)^.LogOff;
	FileAdmin(fiType)^.LogOff;
end;

type
	TGetID = function (Jimmy : PJimmy) : longint;

procedure MakeJimmyIDIndex(srType,opType : word; GetID : TGetID; Title : string);
var	Hook : PHook;
		Jimmy : PJimmy;
		ProBox : PProgressBox;
		RecNo : longint;
		IDIndex : PIDIndexFile;

begin
	FileAdmin(fiHooks)^.LogOn;
	FileAdmin(fiJimmys)^.LogOn;

	New(IDindex, init(srType,opType));
	IDIndex^.Clear;

	{Build by running through hooks stream, picking up *all* jimmys of that
	srType}
	ProBox := NewProgressBox('Making '+Title+' Index','',mfCancelButton,hcNoContext);

	for RecNo := 0 to Stream(fiHooks)^.NoREcs-1 do begin
		if (RecNo mod 10) = 0 then ProBox^.Update('Reading Hooks',RecNo, Stream(fiHooks)^.NoRecs-1);
		Hook := PHook(Stream(fiHooks)^.GetAt(recNo));
		if Hook<>nil then begin
			if Hook^.srType = srType then begin
				Jimmy := PJimmy(JimmyStream^.GetAt(Hook^.JimmyID));
				if Jimmy<>nil then begin

					if opType=0 then
						IDIndex^.SetIDPtr(TGetID(GetID)(Jimmy), Jimmy^.RecNo)
					else
						IDIndex^.SetIDPtr(Jimmy^.GetopPtr(opType), Jimmy^.RecNo);{}

					dispose(jimmy, done);
				end else
					JimmyStream^.Reset;

			end; {matching srtype}
			dispose(Hook, done);
		end; {Hook not nil}

		if ProBox^.COmmand = cmCancel then break;

	end; {for}

	dispose(IDIndex, done);

	FileAdmin(fiHooks)^.LogOff;
	FileAdmin(fiJimmys)^.LogOff;

	if ProBox^.Command<>cmCancel then PauseMessage('MAKE ID INDEX','DONE!', mfMessage + mfWakeUpBleep);

	dispose(ProBox, done);

end;


{procedure MakeInvoiceIDIndex;
begin  MakeJimmyIndex(fiInvoiceIDIdx, srInvoice, 'Invoices'); end;

procedure MakeEstimateIDIndex;
begin  MakeJimmyIndex(fiEstimateIDIdx, srEstimate, 'Estimates'); end;{}

	function GetJobID(Jimmy : PJimmy) : longint; far;
	begin
		GetJobID := PJob(Jimmy)^.Ref;
	end;


procedure MakeJobIDIndex; far;
begin
	MakeJimmyIDIndex(srJobSheet,0, GetJobID, 'Jobs');
end;

{procedure MakeHWIDIndex;
begin	MakeJimmyIndex(fiHardwareIDIdx, srHardware, 'Hardware'); end;

procedure MakeOrderIDIndex;
begin MakeJimmyIndex(fiOrderIDIdx, srOrder, 'Orders'); end;{}

procedure TrimJobIDIndex; far;
var IDIndex : PIDIndexFile;
begin
	New(IDindex, init(srJobSheet, 0));
	IDIndex^.TrimNils;
	dispose(IDIndex, done);
	PauseMessage('TRIM','Done Trimming!',mfWakeUpBleep);
end;

procedure ListJobIDIndex; far;
var R : TRect;
begin
	R.XYLD(0,0,50,20);
	Desktop^.Insert(New(PLIstWindow, init(R, 'Jobs By ID',
		New(PRefNumList, init(R, srJobSheet, 0, lsNone)))));
end;



var
	FixfiType : longint;

procedure DoInsertIndexForJimmy(var Jimmy : PJimmy; var RecSize : word); far;
var ixType : byte;
		PIdxPtr : PLongint;
		fiType : byte;
		IdxRec : longint;
		IndexItem : PIndexItem;

begin
	for ixType := 0 to Jimmy^.Numixtypes do begin
		Jimmy^.GetIndex(ixType, Pidxptr, fitype);
		if fiType = FixfiType then begin
			{Set up index item ready for general work use}
			New(IndexItem, init);

			IndexItem^.Idx2Dat := Jimmy^.RecNo;

			IndexItem^.ixType := ixType;
			IndexItem^.KeyString := Jimmy^.GetIndexKey(ixType);

			if IndexItem^.KeyString<>'' then begin
				IndexStream(fiType)^.Insert(fiType, IndexItem, IdxRec);

				PIdxPtr^ := IdxRec;

				Jimmy^.StoreIdxPtr(ixType);		{Store pointer}
			end;

			dispose(IndexItem, done);
		end;
	end;
end;


procedure ReIndexJimmys; far;
var C : word;
begin
	FixfiType := 0;
	C := InputLintBox('MAKE INDEX','fiType', FixfiType);
	if C<>cmOK then exit;

	FileAdmin(FixfiType)^.LogOn;

	{delete existing index file}
	Stream(FixfiType)^.Seek(0);
	Stream(FixfiType)^.Truncate;

	C := ForAllJimmys('RE-INDEX '+N2Str(FixfiType),'',DoInsertIndexForJimmy,OnNilDostd);{}

	FileAdmin(FixfiType)^.LogOff;
end;




{****************************************************************************
 ***                                                                      ***
 ***                      RE-INDEX FROM EXISTING                          ***
 ***                                                                      ***
 ****************************************************************************}
{Useful for when the keystring method has changed - eg for the camel system,
ie changed the indexing so that the brand numbers were right set, and this
meant that the index had to be re-made from the existing ones.  ie the data
is fine, but it needs correcting.

So this routine runs through the existing index, getting each jimmy, puttin
a blank one (with the old ones) and then doing a store-self}

procedure ReIndex(fiType : word);
var IdxRec : longint;
		JimmyID : longint;
		IndexStream : PIndexStream;
		ProBox : PProgressBox;
		Jimmy,BlankJimmy : Pjimmy;
		hkType, ixType : byte;
		IndexItem : PIndexItem;
		ixfiType,lastixfitype : byte;
		RecSize : word;
		PL : plongint;
		Key : string;

begin
	FileAdmin(fiType)^.LogOn;
	FileAdmin(fiJimmys)^.LogOn;

	IndexStream := PIndexStream(Stream(fitype));

	MakeHoles(IndexStream, 2); {so that self-inserts don't clog up}

	ProBox := NewProgressBox('Re-indexing '+FileAdmin(fiType)^.Name^,'',mfCancelButton,hcNoContext);

	IdxRec := 0;
	while (IdxREc<IndexStream^.NoRecs) and (ProBox^.Command<>cmCancel) do begin
		ProBox^.Update('Reading Index Items ',IdxRec, IndexStream^.NoRecs-1);
		IndexItem := PIndexItem(IndexStream^.GetAt(IdxRec));
		if IndexItem<>nil then begin
			if not IndexItem^.Hole and (IndexItem^.Idx2Dat<>-1) then begin
				Jimmy := PJimmy(JimmyStream^.GetAt(IndexItem^.Idx2Dat));

				if Jimmy<>nil then begin
{RecordError('FIXIT REINDEX','Index Item '+N2Str(IdxRec)+'  Idx2Dat'+N2Str(IndexItem^.Idx2Dat),
															'Jimmy srtype '+N2Str(jimmy^.srtype));{}
					RecSize := Jimmy^.RecSize;
					DoJimmyStoreSelf(Jimmy, RecSize);

				end else
					ProgramWarning('nil Jimmy At '+N2Str(IndexItem^.Idx2Dat)+#13
													+' Index Rec='+N2Str(IdxRec),hcNoContext);
			end;
			dispose(IndexItem, done);
		end else
			ProgramWarning('nil Index Item At '+N2Str(IdxRec),hcNoContext);
		inc(IdxRec);
	end;

	FileAdmin(fiType)^.LogOff;
	FileAdmin(fiJimmys)^.LogOff;

	if ProBox^.Command<>cmCancel then PauseMessage('RE-INDEX','Done!',hcNoContext);

	dispose(ProBox, done);
end;

{****************************************************************************
 ***                                                                      ***
 ***                      UPDATE FROM INDEX                               ***
 ***                                                                      ***
 ****************************************************************************}
{There's a nasty in the middle of Rongai's Jimmmy file, so we can't do an
update the normal way.  Instead, this goes through an index simply getting
and putting the associated jimmy to update it to the latest version}

procedure UpdateFromIndex(fiType : word);
var IdxRec : longint;
		JimmyID : longint;
		IndexStream : PIndexStream;
		ProBox : PProgressBox;
		Jimmy,BlankJimmy : Pjimmy;
		hkType, ixType : byte;
		IndexItem : PIndexItem;
		ixfiType,lastixfitype : byte;
		RecSize : word;
		PL : plongint;
		Key : string;

begin
	FileAdmin(fiType)^.LogOn;
	FileAdmin(fiJimmys)^.LogOn;

	IndexStream := PIndexStream(Stream(fitype));

  ProBox := NewProgressBox('Updating Jimmys associated with '+FileAdmin(fiType)^.Name^,'',mfCancelButton,hcNoContext);

	IdxRec := 0;
	while (IdxREc<IndexStream^.NoRecs) and (ProBox^.Command<>cmCancel) do begin
		ProBox^.Update('Reading Index Items ',IdxRec, IndexStream^.NoRecs-1);
		IndexItem := PIndexItem(IndexStream^.GetAt(IdxRec));
		if IndexItem<>nil then begin
			if not IndexItem^.Hole and (IndexItem^.Idx2Dat<>-1) then begin
				Jimmy := PJimmy(JimmyStream^.GetAt(IndexItem^.Idx2Dat));

				if Jimmy<>nil then begin
{RecordError('FIXIT UPDATE FROM INDEX','Index Item '+N2Str(IdxRec)+'  Idx2Dat'+N2Str(IndexItem^.Idx2Dat),
															'Jimmy srtype '+N2Str(jimmy^.srtype));{}
          JimmyStream^.PutAt(IndexItem^.Idx2Dat, Jimmy);
				end else
					ProgramWarning('nil Jimmy At '+N2Str(IndexItem^.Idx2Dat)+#13
													+' Index Rec='+N2Str(IdxRec),hcNoContext);
			end;
			dispose(IndexItem, done);
		end else
			ProgramWarning('nil Index Item At '+N2Str(IdxRec),hcNoContext);
		inc(IdxRec);
	end;

	FileAdmin(fiType)^.LogOff;
	FileAdmin(fiJimmys)^.LogOff;

	if ProBox^.Command<>cmCancel then PauseMessage('RE-INDEX','Done!',hcNoContext);

	dispose(ProBox, done);
end;


{********************************************************************
 ***              COMPLETE RECONSTRUCTION                         ***
 ********************************************************************}
procedure DeleteAdminFiles;
var fiType : byte;
begin
	{$IFDEF MSDOS}
		for fiType := 1 to 99 do if SharedStream[fiType]<>nil then begin
			SharedStream[fiType]^.LogOn;
			if (pos('.IDX',Stream(fiType)^.FileName)>0) or (pos('.CHA',Stream(fiType)^.FileName)>0) then begin
				ThinkingOn('Deleting '+SharedStream[fiType]^.Name^);
				SharedStream[fiType]^.Close;
				DeleteFile(Stream(fiType)^.FileName);
				if (LastDOSFuncResult<>0) and (LastDOSFuncResult<>3) then
					ProgramWarning('Could not delete '+Stream(fiType)^.FileName+#13#10+IOError(LastDOSFuncREsult),hcInternalErrorMsg);
				SharedStream[fiType]^.Open;
				ThinkingOff;
			end;
			SharedStream[fiType]^.LogOff;
		end;
	{$ELSE}
		{doesn't work in real mode}
		DosCommand('DEL '+DataPath+'*.IDX', rnCheck);{}
		DosCommand('DEL '+DataPath+'*.CHA', rnCheck);{}
	{$ENDIF}
end;

procedure ReConstructAll;
var Control : word;
		fiType : word;
begin
	if MessageBox('RECONSTRUCT INDEXES & HOOKS',
									'Are you sure you want to do this?!',
									mfConfirmation + mfYesNo,hcNoContext) <> cmYes then exit;

	DeleteAdminFiles;

	Control := ForAllJimmys('RE-CONSTRUCT','Clearing idx & hook ptrs',DoClearJimmyPtrs,OnNilDostd);{}

	if Control<>cmCancel then
		Control := ForAllJimmys('RE-CONSTRUCT','Re-hooking & indexing',DoJimmyStoreSelf,OnNilDoStd);

	if Control<>cmCancel then begin
		WakeUpBleep;
		PauseMessage('RE-CONSTRUCT','Done!',hcNoContext);
	end;
end;

{****************************************************************************
 ***                                                                      ***
 ***                      TEKKY "USER" ACCESS                             ***
 ***                                                                      ***
 ****************************************************************************}

function InputByte(BoxTitle,LineTitle : string) : byte;
var EditBox : PEditBox;
		R : Trect;
		B : byte;
		Control : word;

begin
	B := 0;

	R.Assign(0,0,30,8); R.Move(20,5);
	New(EditBox, init(R, BoxTitle,nil));

	with EditBox^ do begin
		InstitledField(10, 2, 3, 1, LineTitle,   New(PInputByte, init(R, 3)));

		InsOKButton(5, 5, @B);
		InsCancelButton(16, 5);

		EndInit;
	end;

	Control := Desktop^.ExecView(EditBox);

	InputByte := B;
end;


procedure ReIndexFile; far;
var fiType : byte;
begin
	fiType := InputByte('Re-Index Jimmy Index', 'fiType');
	if fiType>0 then ReIndex(fiType);
end;

procedure UpdateFromIndexFile; far;
var fiType : byte;
begin
	fiType := InputByte('Update Jimmys in Index', 'fiType');
	if fiType>0 then UpdateFromIndex(fiType);
end;

procedure SortIndex; far;
var fiType : byte;
		IndexStream : PIndexStream;
begin
	fiType := InputByte('Quick Sort index', 'fiType');
	if fiType>0 then begin
		FileAdmin(fiType)^.LogOn;
		IndexStream := PINdexStream(Stream(fiType));
		QuickSort(IndexStream, True);
		FileAdmin(fiType)^.LogOff;
	end;
end;


{procedure ReIndexsrType;
var srType : byte;
begin
	srType := InputByte('Re-index jimmys', 'srType');
end;{}

{runs through jimmys getting and putting ---> latest vers}
procedure UpdateJimmys; far;
begin
	ForAllJimmys('UPDATING VERS','Getting & Putting',DoJimmyPut,OnNilDoStd);
end;



{***********************************************
 ***      EDIT JIMMY                         ***
 ***********************************************}
procedure EditjIMMY; far;
var	FileControl, ItemControl : word;
		Jimmy : PJimmy;
		EditBox : PEditBox;
		R : Trect;
		W : word;
		Inp : record
			RecordNum : longint;
		end;

begin
	FileAdmin(fiJimmys)^.LogOn;
	Inp.RecordNum := 0;

	repeat
		R.Assign(0,0,30,8); R.Move(20,5);
		New(EditBox, init(R, 'Jimmy Fix',nil));

		with EditBox^ do begin
			InsTitledField(10, 3, 9, 1, 'Record#', New(PInputLInt, init(R, 9)));

			InsOKButton(5, 5, @Inp);
			InsCancelButton(16, 5);

			EndInit;

			SetData(Inp);
		end;

		FileControl := Desktop^.ExecView(EditBox);

		dispose(EditBox, done);

		if FileControl<>cmCancel then begin
			Jimmy := PJimmy(Stream(fiJimmys)^.GetAt(Inp.RecordNum));

			if Jimmy <> nil then begin
				Jimmy^.Edit(Desktop,nil); {OK button does store}

			end else begin
				{not retrievable}
				PauseMessage('Could not retrieve item #'+N2Str(Inp.RecordNum)+', '+Stream(fiJimmys)^.StatusText,
											'Will look for previous',hcNoContext);
				Stream(fiJimmys)^.Reset;

				{look for previous}
				while (Jimmy = nil) and (Inp.RecordNum>0) do begin
					dec(Inp.RecordNum);
					Jimmy := PJimmy(Stream(fiJimmys)^.GetAt(Inp.RecordNum));
					Stream(fiJimmys)^.Reset;
				end;

				{found something}
				if Jimmy<>nil then begin
					Stream(fiJimmys)^.SeekRec(Inp.RecordNum);
					Stream(fiJimmys)^.Read(W, 2); {read ID}
					PauseMessage('Found','Nearest prev. object @'+N2Str(Inp.RecordNum)+' sr'+N2Str(W),hcNoContext);
					dispose(Jimmy, done);
				end;
			end;
		end;

	until FileControl = cmCancel;

	FileAdmin(fiJimmys)^.LogOff;
end;

{$IFDEF fixit}
procedure EditIndexItem; far;
var Control : word;
		fitype : byte;
		LfiType, RecNo : longint;
		IndexItem : PIndexItem;

begin
	LfiType := 0;
	RecNo := 0;
	Control := InputLintBox('Edit Index item','fiType',LfiType);
	fiType := LfiType;
	if Control<>cmCancel then begin
		Control := InputLintBox('Edit Index item','RecNo',RecNo);
		if Control<>cmCancel then begin
			FileAdmin(fiType)^.LogOn;
			IndexItem := PIndexItem(Stream(FiType)^.GetAt(RecNo));
			Control := IndexItem^.Edit(Desktop);
			if Control<>cmCancel then begin
				Stream(fiType)^.PutAt(RecNo, IndexItem);
			end;
			FileAdmin(fiType)^.LogOff;
		end;
	end;
end;

procedure EditHookItem; far;
var Control : word;
		Hook : PHook;
		RecNo : longint;

begin
	RecNo := 0;
	Control := InputLintBox('Edit Hook item','RecNo',RecNo);
	if Control<>cmCancel then begin
		FileAdmin(fiHooks)^.LogOn;
		Hook := PHook(Stream(FiHooks)^.GetAt(RecNo));
		Control := Hook^.Edit(Desktop);
		if Control<>cmCancel then begin
			Stream(fiHooks)^.PutAt(RecNo, Hook);
		end;
		FileAdmin(fiHooks)^.LogOff;
	end;
end;
{$ENDIF}


procedure EditTable; far;
var	C : word;
		Jimmy : PJimmy;
		EditBox : PEditBox;
		R : Trect;
		W : word;
		Inp : record
			fiType : word;
			X,Y : word;
		end;
		Ptr : longint;

begin
	repeat
		R.Assign(0,0,30,10); R.Move(20,5);
		New(EditBox, init(R, 'Jimmy Fix',nil));

		with EditBox^ do begin
			InsTitledField(10, 2, 9, 1, 'fitype', New(PInputword, init(R, 9)));
			InsTitledField(10, 4, 9, 1, 'X', New(PInputword, init(R, 9)));
			InsTitledField(10, 5, 9, 1, 'Y', New(PInputword, init(R, 9)));

			InsOKButton(5, 7, @Inp);
			InsCancelButton(16, 7);

			EndInit;
		end;

		C := Desktop^.ExecView(EditBox);

		dispose(EditBox, done);

		if C<>cmCancel then begin
			FileAdmin(Inp.fiType)^.LogOn;
			Ptr := TableStream(Inp.fiType)^.GetPtr(Inp.X,Inp.Y);

			C := InputLintBox('Table fixit','Ptr', Ptr);

			if C<>cmCancel then
				TableStream(Inp.fitype)^.SetPtr(Inp.X, Inp.Y, Ptr);

			FileAdmin(Inp.fiType)^.Logoff;
		end;

	until C = cmCancel;
end;


{***********************************************
 ***      EDIT LETTER ITEM                   ***
 ***********************************************}
function EditTextItem(TextItem : PTextItem) : word;
var R : TRect;
		EditBox : PEditBox;
begin
	R.Assign(0,0,42,11);
	New(Editbox, init(R, 'Text Item', Desktop));

	with EditBox^ do begin
		Options := Options or ofCentered;

		Insert(New(PSkipBytes, init(sizeof(TDataItem))));
		Insert(New(PSkipBytes, init(sizeof(PNode)*4))); {skip heap  pointers}

		InsTitledField(10,1,6,1, 'Next', New(PinputLint, init(R,6)));
		InsTitledField(10,2,6,1, 'Prev', New(PinputLint, init(R,6)));
		InsTitledField(10,3,6,1, 'Child', New(PinputLint, init(R,6)));

		InsTitledField(10,4,1,1, 'Exp', New(PInputBoolean, init(R)));

		InsTitledField(10,6,25,1, 'Data', New(PInputELine, init(R, 255)));

		InsOKButton(15,8, TextItem);
		InsCancelButton(26,8);

		EndInit;

		SetData(TextItem^);
	end;

	EditTextItem := Desktop^.ExecView(EditBox);

	dispose(EditBox, done);
end;



procedure EditLetterItem; far;
var	Control, ItemControl : word;
		TextItem : PTextItem;
		TExtFile : PTextStream;
		TextRec : longint;

begin
	New(TextFile, init('LETTERS.DAT', TLetterItemSize, StreamBufSize));
	TextRec := 0;

	repeat
		TextRec := 0;
		Control := InputLintBox('Letter Item (0-'+N2Str(TextFile^.NoRecs-1)+')', 'Rec #', TextRec);

		if (Control=cmOK) then begin
			TextItem := PTextItem(TextFile^.GetAt(TextRec));

			if TextItem<>nil then begin
				ItemControl := EditTextItem(TextItem);
				if ItemControl = cmOK then
					TextFile^.PutAt(TextRec, TextItem);
				dispose(TextItem, done);
			end;
		end;

	until Control = cmCancel;

	dispose(TextFile, done);
end;



{************************************************************
 ***          INITIALISATION                              ***
 ************************************************************}

begin
{$IFDEF fixit} writeln('Fixit...');

	{Register Tasks}
	RegisterTask(DesktopTasks, cmReIndexFile, @ReIndexFile);
	RegisterTask(DesktopTasks, cmReConstructAll, @ReConstructAll);
{	RegisterTask(DesktopTasks, cmReIndexsrType, ReIndexsrtype);{}
	RegisterTask(DesktopTasks, cmReIndexJimmys, @ReIndexJimmys);

	RegisterTask(DesktopTasks, cmSortIndex, @SortIndex);
	RegisterTask(DesktopTasks, cmUpdateJimmys, @UpdateJimmys);
	RegisterTask(DesktopTasks, cmUpdateFromIndex, @UpdateFromIndexFile);

	RegisterTask(DesktopTasks, cmEditJimmy, @EditJimmy);
	RegisterTask(DesktopTasks, cmEditIndexItem, @EditIndexItem);
	RegisterTask(DesktopTasks, cmEditHook, @EditHookItem);
	RegisterTask(DesktopTasks, cmEditLetterItem, @EditLetterItem);

	RegisterTask(DesktopTasks, cmEditTable, @EditTable);

	RegisterTask(DesktopTasks, cmMakeJobIDIndex, @MakeJobIDINdex);
	RegisterTask(DesktopTasks, cmTrimJobIDIndex, @TrimJobIDINdex);
	RegisterTask(DesktopTasks, cmListJobIDIndex, @ListJobIDINdex);
{$ENDIF}
end.


