{********************************************************************
 ***                       INPUT FILE NAME                        ***
 ********************************************************************}
{Asks user to type in a file name.  Size of 8 or 12 only must be given -
if 8, GetData/etc will return just the name part (not incl extension),
if 12 it will return the full name.

If MustExist is set, it will compare against existing files

if extensions are specified (given in the form eg 'HD1 HDR STL') then it will
limit input and listing to these files only}

{$I compdirs}
unit InpFName;

INTERFACE

uses objects,
			tuiedit,
			tuilist, views, dattime, inplist, drivers;

type
	TFileEditorProc = function (var FileName : FNameStr; const Ext : string) : word;

{function	BlankFileEditorProc(var FileName : FNameStr; const Ext : string) : word;{}

type
	PInputFName = ^TInputFName;
	TInputFName = object(TInputList)
		Ext : string[23];   {Extension list}
		Path : string[70];
		MustExist : boolean;
		FileEditor : TFileEditorProc; {for editing files}

		constructor INit(Bounds : TRect; const NFieldLen : byte;
											const NExtension,NPath : string;
											const NMustExist : boolean;
											const NFileEditor : TFileEditorProc);
		procedure Draw; virtual;
		procedure HandleEvent(var Event : TEvent); virtual;
		procedure ExecuteList;
		function Valid (Command : Word) : boolean; virtual;
	end;


	{links edtype - ie editor type - with inputform line so that inputform
		line takes correct path, etc}
	PFormedTypeLinker = ^TFormEdTypeLinker;
	TFormEdTypeLinker = object(TINputLinker)
		constructor Init(const edTypeLine, FormLine : PView; const EditBox : PEditBox);
		procedure CalculateLink(const CallingView : PView); virtual;
	end;



IMPLEMENTATION

uses dosutils,
			global,
			dos,
			{$IFDEF kwplink} kwplink, {$ENDIF}
			editfile, kamsetup, {for editors for linker}
			dialogs,
			help,
			tui,
			tuiboxes, stddlg,
			app,
			minilib,tuimsgs;


{************************************************************
 ***            edtype/formline linker                    ***
 ************************************************************}
{standard linker for use by other units for linking an editor type radiobutton
to a formline}
constructor TFormedTypeLinker.Init;
begin
	inherited Init(nil, EditBox);
	SetSourceView(edTypeLine, 1);
	SetTargetView(FormLine, 1);

	ForceInitLink := True;
end;

procedure TFormEdTypeLinker.CalculateLink;
var EditorType : word;
		B : byte;
begin
	PERadioButtons(SourceView[1])^.GetData(EditorType);

	case EditorType of
		edInternal : for B := 1 to 4 do if TargetView[B]<>nil then begin
			PInputFname(TargetView[B])^.FileEditor := EditTextFile;
			PInputFname(TargetView[B])^.Path := FormsPath;
		end;
{$IFDEF kwplink}
		edWP51 : for B := 1 to 4 do if TargetView[b]<>nil then begin
			PInputFname(TargetView[B])^.FileEditor := EditWPFile;
			PInputFname(TargetView[B])^.Path := WPSetup.FormsPath;
		end;
{$ENDIF}
	end;
end;


{************************************************************
 ***                INPUT A FILE NAME                     ***
 ************************************************************}
	constructor TInputFName.INit;
	begin
		if (NFieldLen<>8) and (NFieldLen<>12) then
			ProgramError('Check MakeEditBox Method'+#13+'InpFname must have length 8 or 12',hcInternalErrorMsg);
		inherited Init(Bounds, NFieldLen, 0);
		Ext := NExtension;
		Path := NPath;
		MustExist := NMustExist;
		FileEditor := NFileEditor;
		UpperCase := True;

		EventMask := EventMask or evBroadCast; {to pick up linker events}
	end;

	{Mark with an "F" for file}
	procedure TInputFName.Draw;
	begin
		inherited Draw;                  {Sets cursor pos & data}
		if not GetState(sfDisabled) then writeChar(0,0, 'F',4,1);         {Mark luminous F}
	end;

{	procedure TInputFName.GetData(var Rec);
	begin
		inherited GetData(Rec);
		string(Rec) := delspace(string(Rec)); {chop out spaces}
{	end;{}

{	procedure TInputFName.SetData(var Rec);
	begin
		inherited SetData(Rec);
		if (Ext <> '') and (pos(' ',Ext)=0) then begin
			if length(Data^)>Maxlen then Data^ := Copy(Data^,1,maxlen);  {Setting a name of xxxxxxx.eeee will make Data^[0] too big}
{			if (Pos('.',Data^)>0) then Data^ := Copy(Data^,1,Pos('.',Data^)-1); {Remove extension if present}
{		end;
	end;{}

	procedure TInputFName.HandleEvent;
	var FileName : FNameStr;
			Control : word;
	begin
		{--- Pick up message with file name from list ---}
		if Event.Command = cmAccept then begin
			{do through filename due to fun with getmem etc put aside for data}
			FileName := PString(Event.InfoPtr)^; {dereference full file name}
			if Maxlen=8 then FileName := copy(FileName,1,pos('.',FileName+'.')-1); {copy off ext if nec}
			SetData(FileName);
			ClearEvent(Event); {set to handled}
			Draw;
			SetChanged; CheckLink;   {Check any dependant boxes, and force update}
		end;

		{input validation}
		if (Event.What = evKeyboard) then begin
			if (Event.CharCode= '.') and (Maxlen=8) then begin
				ClearEvent(Event);
				WrongKeyBleep;
			end;
		end;

		inherited HandleEvent(Event);

		{--- Run the File selection list ----}
		if ((Event.What = evCommand) and (Event.Command = cmList)) and
			 ((ListOptions and loAllowList)>0) then begin
			ExecuteList;
			ClearEvent(Event);
		end;

		{--- Direct Edit ----}
		if ((Event.What = evKeyDown) and (Event.KeyCode = kbChange)) then begin
			Event.What := evCommand;
			Event.Command := cmEdit;
		end;

		if ((Event.What = evCommand) or (Event.What = evBroadCast)) and (Event.Command = cmEdit) then begin
			ClearEvent(Event);
			if delspaceR(Data^)='' then begin
				WrongKeyBleep;
				Owner^.ReDraw; {so edit button is drawn again, if that is what generated this event}
			end else
				if Valid(cmOK) then begin
					FileName := Path + delspace(Data^);
					if (Maxlen=8) then FileName := FileName + '.'+copy(Ext,1,3); {assume first extension}
					Control := FileEditor(FileName, Ext);
					if Control = cmOK then begin SetChanged; Checklink; end;
				end;
		end;

	end;


	procedure TInputFName.ExecuteList;
	var FileList : PListWindow;
			R : TRect;
			ListOrigin : TPoint;
			fdType : word;
			FileName,FullFileName : FNameStr;
			Control : word;

	begin
		{--- new standard turbo file dialog box ---}
		fdType := fdPickOnly + fdAcceptButton;
		if @FileEditor<>nil then fdType := fdType or fdEditButton or fdNewButton;

		FileName := Data^;

		repeat
			Control := FileSelectBox('FILE LIST','Form', FileName,Ext, Path, fdType, hcNoContext);

			case Control of
				cmNew : begin
					FullFIleName := Path; if pos(' ',Ext)=0 then FullFileName := FullFileName+'.'+Ext;
					FileEditor(FullFileName, Ext);
				end;
				cmAccept : begin
					if Maxlen=8 then FileName := copy(FileName,1,pos('.',FileName+'.')-1); {copy off ext if nec}
					SetData(FileName);
					DrawView;
					SetChanged;
					CheckLink;
				end;
				cmEdit : begin
					FullFileName := Path+FileName;
					FileEditor(FullFileName, Ext);
				end;
			end;

		until (Control = cmAccept) or (Control=cmCancel);
	end;

{*****************************
 ***        VALID?         ***
 *****************************}

function TInputFName.Valid;
var FName : string[10];
		FExt  : string[23];
		FullName : FNameStr;
		Error, S: string;
		V : boolean;

begin
	V := inherited Valid(Command);

	if V and DoValidFor(Command) then begin

		Data^ := delspace(Data^);

		if (Ext<>'') and (pos(' ',Ext)=0) and (Maxlen=12) then begin
			{only one extension allowed, and must be specified, so might as well set to it}
			if pos('.',Data^)>0 then Data^ := copy(Data^,1,pos('.',Data^)); {extract file name only}
			if length(Data^)<=8 then begin
				Data^ := Data^+'.'+Ext; {if valid name, add extension}
				Draw;
			end;
		end;

		{==== CHECK FORMAT OF STRING ===========}
		Error := '';

		if Maxlen=8 then begin
			if Pos('.',Data^)>0 then 	Error :='No Periods please';
		end else begin
			FName := Copy(Data^,1,Pos('.',Data^+'.')-1);
			FExt := Copy(Data^,Pos('.',Data^+'.')+1, length(Data^));
			if FName = '' 			then Error := 'No name';
			if length(FName)>8 	then Error := 'Name too long (>8)';
			if Length(FExt)>3 	then Error := 'Extension too long (>3)';
			if Pos('.',FExt)>0 	then Error := 'Too many periods';
			if (Ext<>'') and ((Pos(' '+FExt+' ', ' '+Ext+' ')=0) or (Fext='')) then Error := 'Extension should be one of '+Ext;
		end;

		if Error<>'' then begin
			Focus; {focus on line while error box displayed}
			InputWarning('File Name Incorrect'#13#10+Error,hcInvalidFNameMsg);
			V := False;
		end;

		{==== CHECK IF EXISTS ===========}
		{allow null entry - mustinput etc can be set separately}
		if V and MustExist and (delspace(Data^)<>'') and (Command<>cmReleasedFocus) then begin
			FullName := Path + delspace(Data^);
			if (Maxlen=12) then begin
				{-- full name 12-char input ---}
				if not FileExists(FullName) then V := False;
			end else begin
				{-- 8-char - have to check with extension(s) given ---}
				V := False;
				if Ext = '' then begin
					{no extension given - check for no-extension filename}
					if FileExists(FullName) then V := True
				end else begin
					{Extensions given, check each one}
					FExt := Ext+' ';
					repeat
						if FileExists(FullName + '.' + copy(FExt,1,pos(' ',FExt)-1)) then V := True;
						FExt := copy(FExt,pos(' ', FExt)+1, 99); {chop off checked ext}
					until FExt = '';
				end;
			end;
			if not V and (Command <>cmForceLink) then begin {don't bleep if checking for link - just return false}
				Focus;
				WrongFldBleep;
				DoList := True;
			end;

		end; {if mustexist}

	end;

	Valid := V;
end;



end.
