MODULE ObxLinks;
(**
	project	= "BlackBox"
	organization	= "www.oberon.ch"
	contributors	= "Oberon microsystems"
	version	= "System/Rsrc/About"
	copyright	= "System/Rsrc/About"
	license	= "Docu/BB-License"
	changes	= "
	- 20161216, center #144, inconsistent docu and usage of Files.Locator error codes
	"
	issues	= "
	- ...
	"

**)

	IMPORT
		Files, Stores, Converters, Fonts, Ports, Views,
		TextModels, TextMappers, TextViews, StdLinks;

	PROCEDURE PathToLoc (IN path: ARRAY OF CHAR; OUT loc: Files.Locator);
		VAR i, j: INTEGER; ch: CHAR; name: ARRAY 256 OF CHAR;
	BEGIN
		loc := Files.dir.This("");
		IF path # "" THEN
			i := 0; j := 0;
			REPEAT
				ch := path[i]; INC(i);
				IF (ch = "/") OR (ch = 0X) THEN name[j] := 0X; j := 0; loc := loc.This(name)
				ELSE name[j] := ch; INC(j)
				END
			UNTIL (ch = 0X) OR (loc.res # 0)
		END
	END PathToLoc;

	PROCEDURE Directory* (path: ARRAY OF CHAR);
		VAR t: TextModels.Model; f: TextMappers.Formatter; v: Views.View; tv: TextViews.View;
			old, new: TextModels.Attributes; conv: Converters.Converter;
			loc: Files.Locator; li: Files.LocInfo; fi: Files.FileInfo; str: ARRAY 256 OF CHAR; title: Views.Title;
	BEGIN
		t := TextModels.dir.New();
		f.ConnectTo(t);
		f.WriteString("Directories"); f.WriteLn;
		old := f.rider.attr;	(* save old text attributes for later use *)
		new := TextModels.NewStyle(old, old.font.style + {Fonts.underline});	(* use underline style *)
		new := TextModels.NewColor(new, Ports.blue);	(* use blue color *)
		f.rider.SetAttr(new);	(* change current attributes of formatter *)
		(* generate list of all locations *)
		PathToLoc(path, loc);
		li := Files.dir.LocList(loc);
		WHILE li # NIL DO	(* no particular sorting order is guaranteed *)
			str := "ObxLinks.Directory('";
			IF path # "" THEN str := str + path + "/" END;
			str := str + li.name + "')";
			v := StdLinks.dir.NewLink(str);
			f.WriteView(v);	(* insert left link view in text *)
			f.WriteString(li.name);
			v := StdLinks.dir.NewLink("");
			f.WriteView(v);	(* insert right link view in text *)
			f.WriteLn;
			li := li.next
		END;
		f.rider.SetAttr(old);	(* reset current attributes of formatter *)
		f.WriteLn;
		f.WriteString("Files"); f.WriteLn;
		f.rider.SetAttr(new);	(* change current attributes of formatter *)
		(* generate a list of all files *)
		fi := Files.dir.FileList(loc);
		WHILE fi # NIL DO	(* no particular sorting order is guaranteed *)
			conv := Converters.list; WHILE (conv # NIL) & (conv.fileType # fi.type) DO conv := conv.next END;
			IF conv # NIL THEN	(* there is a converter for this file type *)
				str := "ObxLinks.Open('"; str := str + path + "', '";
				str := str + fi.name + "')";
				v := StdLinks.dir.NewLink(str);
				f.WriteView(v);	(* insert left link view in text *)
				f.WriteString(fi.name);
				v := StdLinks.dir.NewLink("");
				f.WriteView(v);	(* insert right link view in text *)
				f.WriteLn
			END;
			fi := fi.next
		END;
		tv := TextViews.dir.New(t);
		(* set Browser mode: *)
		title := "Directory of " + path;
		Views.OpenAux(tv, title)
	END Directory;

	PROCEDURE Open* (path, name: ARRAY OF CHAR);
		VAR loc: Files.Locator; f: Files.File; c: Converters.Converter; n: Files.Name; s: Stores.Store;
	BEGIN
		PathToLoc(path, loc); n := name$;
		IF loc.res = 0 THEN
			f := Files.dir.Old(loc, n, Files.shared);
			IF f # NIL THEN
				(* search in converter list for a converter that can import a file of this type *)
				c := Converters.list; WHILE (c # NIL) & (c.fileType # f.type) DO c := c.next END;
				IF c # NIL THEN
					Converters.Import(loc, n, c, s);
					WITH s: Views.View DO
						Views.Open(s, loc, n, c)
					ELSE
					END
				END
			END
		END
	END Open;

END ObxLinks.
