MODULE SqlObxNets;
(**
	project	= "BlackBox"
	organization	= "www.oberon.ch"
	contributors	= "Oberon microsystems"
	version	= "System/Rsrc/About"
	copyright	= "System/Rsrc/About"
	license	= "Docu/BB-License"
	changes	= "
	- YYYYMMDD, nn, ...
	"
	issues	= "
	- ...
	"

**)

	TYPE
		Net* = POINTER TO NetDesc;
		Node* = POINTER TO NodeDesc;

		Company* = POINTER TO RECORD
			id-: INTEGER;
			name-, ceo-: ARRAY 32 OF CHAR;
			employees-: INTEGER;
			ownedBy-: Node;	(* list of owner companies *)
			owns-: Node;	(* list of owned companies *)
			time*: INTEGER;	(* temporary data for layout algorithm *)
			x*, y*: INTEGER;	(* temporary data for layout algorithm *)
			next: Company
		END;

		NodeDesc* = RECORD
			next-: Node;
			percent-: INTEGER;
			company-: Company
		END;

		NetDesc* = RECORD
			first: Company
		END;

	PROCEDURE AddCompany* (g: Net; id: INTEGER; name, ceo: ARRAY OF CHAR; employees: INTEGER);
		VAR c: Company;
	BEGIN
		ASSERT(g # NIL, 20); ASSERT(id > 0, 21);
		c := g.first; WHILE (c # NIL) & (c.id # id) DO c := c.next END;
		IF c # NIL THEN
			IF c.name = "" THEN
				c.name := name$; c.ceo := ceo$; c.employees := employees;
			ELSE
				ASSERT((name = "") OR (c.name = name), 22)
			END
		ELSE
			NEW(c); c.id := id; c.name := name$; c.ceo := ceo$; c.employees := employees;
			c.next := g.first; g.first := c
		END
	END AddCompany;

	PROCEDURE AddNode (VAR h: Node; percent: INTEGER; company: Company);
		VAR n: Node;
	BEGIN
		NEW(n); n.percent := percent; n.company := company;
		IF h = NIL THEN
			h := n
		ELSE
			WHILE (h.percent >= percent) & (h.next # NIL) DO h := h.next END;
			n.next := h.next; h.next := n
		END
	END AddNode;

	PROCEDURE AddOwnership* (g: Net; owner, owned: INTEGER; percent: INTEGER);
		VAR h0, h1: Company;
	BEGIN
		ASSERT(g # NIL, 20); ASSERT(owner > 0, 21); ASSERT(owned > 0, 22);
		ASSERT(owned # owner, 23); ASSERT(percent > 0, 24); ASSERT(percent <= 100, 25);
		h0 := g.first; WHILE (h0 # NIL) & (h0.id # owner) DO h0 := h0.next END;
		IF h0 = NIL THEN
			AddCompany(g, owner, "", "", 0);
			h0 := g.first; WHILE (h0 # NIL) & (h0.id # owner) DO h0 := h0.next END; ASSERT(h0 # NIL, 100)
		END;
		h1 := g.first; WHILE (h1 # NIL) & (h1.id # owned) DO h1 := h1.next END;
		IF h1 = NIL THEN
			AddCompany(g, owned, "", "", 0);
			h1 := g.first; WHILE (h1 # NIL) & (h1.id # owned) DO h1 := h1.next END; ASSERT(h1 # NIL, 100)
		END;
		AddNode(h1.ownedBy, percent, h0);
		AddNode(h0.owns, percent, h1)
	END AddOwnership;

	PROCEDURE ThisCompany* (g: Net; id: INTEGER): Company;
		VAR h: Company;
	BEGIN
		ASSERT(g # NIL, 20); ASSERT(id > 0, 21);
		h := g.first; WHILE (h # NIL) & (h.id # id) DO h := h.next END;
		RETURN h
	END ThisCompany;

	PROCEDURE CompanyAt* (g: Net; x, y, w, h: INTEGER): Company;
	(* not a nice interface; could be improved *)
		VAR p: Company;
	BEGIN
		ASSERT(g # NIL, 20);
		p := g.first; WHILE (p # NIL) & ((x < p.x) OR (y < p.y) OR (x >= p.x + w) OR (y >= p.y + h)) DO p := p.next END;
		RETURN p
	END CompanyAt;

	PROCEDURE New* (): Net;
		VAR g: Net;
	BEGIN
		NEW(g); RETURN g
	END New;

END SqlObxNets.
