MODULE InfoCmds;

	(* Helmut Zinn -   *)

	IMPORT
		Containers, Controllers, Dialog, HostDialog, InfoDialog, StdApi, StdFolds,
		TextCmds, TextViews, Views, WinApi;

	TYPE DocList = POINTER TO RECORD
			filename: ARRAY 256 OF CHAR;
			editable: BOOLEAN;
			last, next: DocList;
		END;

	VAR
		current: DocList;
		editable: BOOLEAN;

	PROCEDURE KeepInMind (IN file: ARRAY OF CHAR);
		VAR doc: DocList;
	BEGIN
		IF (current = NIL) OR (current.filename$ # file$) THEN
			NEW(doc);
			doc.filename := file$;
			doc.editable := editable;
			doc.last := NIL;
			doc.next := NIL;
			IF current # NIL THEN
				current .next := doc;
				doc.last := current;
			END;
			current := doc;
		END;
	END KeepInMind;

	PROCEDURE SetEditMode*;
		VAR v: Views.View; c: Containers.Controller;
	BEGIN
		v := Controllers.FocusView();
		IF (v # NIL) & (v IS Containers.View) THEN
			c := v(Containers.View).ThisController();
			IF c # NIL THEN
				Views.BeginModification(Views.invisible, v);
				c.SetOpts(c.opts - {Containers.noFocus, Containers.noSelection} - {Containers.noCaret});
				Views.EndModification(Views.invisible, v);
			END;
		END;
		editable := TRUE; IF current # NIL THEN current.editable := TRUE END;
		IF (v # NIL) & (v IS TextViews.View) THEN
			(* ShowMarks *)
			v(TextViews.View).DisplayMarks(TextViews.show)
		END;
	END SetEditMode;

	PROCEDURE SetBrowserMode*;
		VAR v: Views.View; c: Containers.Controller;
	BEGIN
		v := Controllers.FocusView();
		IF (v # NIL) & (v IS Containers.View) THEN
			c := v(Containers.View).ThisController();
			IF c # NIL THEN
				Views.BeginModification(Views.invisible, v);
				c.SetOpts(c.opts - {Containers.noFocus, Containers.noSelection} + {Containers.noCaret});
				Views.EndModification(Views.invisible, v);
			END;
		END;
		editable := FALSE; IF current # NIL THEN current.editable := FALSE END;
		IF (v # NIL) & (v IS TextViews.View) THEN
			(* HideMarks *)
			v(TextViews.View).DisplayMarks(TextViews.hide)
		END;
	END SetBrowserMode;

	PROCEDURE SetEditModeGuard* (VAR par: Dialog.Par);
	BEGIN
		IF editable THEN par.checked := TRUE ELSE par.checked := FALSE END;
	END SetEditModeGuard;

	PROCEDURE SetBrowserModeGuard* (VAR par: Dialog.Par);
	BEGIN
		IF ~editable THEN par.checked := TRUE ELSE par.checked := FALSE END;
	END SetBrowserModeGuard;

	PROCEDURE OpenDoc* (IN file: ARRAY OF CHAR);
		VAR v: Views.View;
	BEGIN
		KeepInMind(file);
		StdApi.OpenDoc(file, v);
		IF (v # NIL) & (v IS Containers.View) THEN
			IF editable THEN SetEditMode ELSE SetBrowserMode END;
		END;
	END OpenDoc;

	PROCEDURE Select* (IN pat: ARRAY OF CHAR);
	BEGIN
		IF InfoDialog.param.expand THEN StdFolds.Expand END;
		TextCmds.find.find := pat$;
		TextCmds.find.ignoreCase := TRUE;
		TextCmds.FindFirst('');
		Dialog.Update(TextCmds.find);
	END Select;

	PROCEDURE Start* (IN file: ARRAY OF CHAR);
		(* Do Command: Start program or Open file *)
		VAR fullname: ARRAY 260 OF CHAR; res: INTEGER; np: WinApi.PtrWSTR;
	BEGIN
		res := WinApi.ShellExecuteW(0, '', file, '', '', WinApi.SW_SHOWNORMAL);
		IF res = WinApi.ERROR_FILE_NOT_FOUND THEN
			(* if failed then translate relative filenames to absolute filenames and try again *)
			res := WinApi.GetFullPathNameW(file, LEN(fullname), fullname, np);
			res := WinApi.ShellExecuteW(0, '', fullname, '', '', WinApi.SW_SHOWNORMAL);
		END;
		IF res <= 32 THEN
			Dialog.ShowParamMsg("#System:FailedToOpen", file, "", "")
		END;
	END Start;

	PROCEDURE Start2* (IN command: ARRAY OF CHAR);
		(* Do Command including parameters *)
	BEGIN
		HostDialog.Start(command$);
	END Start2;

	PROCEDURE SetTopic* (IN root: ARRAY OF CHAR);
	BEGIN
		InfoDialog.param.source := root$;
		InfoDialog.ProofParam;
	END SetTopic;

	PROCEDURE OpenTopic* (IN root: ARRAY OF CHAR);
	BEGIN
		SetTopic(root);
		OpenDoc(InfoDialog.param.source$ + 'Inhalt');
	END OpenTopic;

	PROCEDURE LastDoc*;
	BEGIN
		IF (current # NIL) & (current.last # NIL) THEN
			current := current.last; editable := current.editable;
			OpenDoc(current.filename);
		END;
	END LastDoc;

	PROCEDURE NextDoc*;
	BEGIN
		IF (current # NIL) & (current.next # NIL) THEN
			current := current.next; editable := current.editable;
			OpenDoc(current.filename);
		END;
	END NextDoc;

	PROCEDURE LastDocGuard* (VAR p: Dialog.Par);
	BEGIN
		p.disabled := (current = NIL) OR (current.last = NIL)
	END LastDocGuard;

	PROCEDURE NextDocGuard* (VAR p: Dialog.Par);
	BEGIN
		p.disabled := (current = NIL) OR (current.next = NIL)
	END NextDocGuard;

BEGIN
	current := NIL;
	editable := TRUE;
END InfoCmds.
