-- Trivial_Trie - Provide a trivial trie type for what needs to create but not to destroy them.
-- Copyright (C) 2022 Prince Trippy <programmer@verisimilitudes.net>.

-- This program is free software: you can redistribute it and/or modify it under the terms of the
-- GNU Affero General Public License version 3 as published by the Free Software Foundation.

-- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
-- even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Affero General Public License for more details.

-- You should have received a copy of the GNU Affero General Public License along with this program.
-- If not, see <http://www.gnu.org/licenses/>.

package body Trivial_Trie is
   procedure Give (Path : in Input_Type; Tree : in out Trie; What : in Stored_Type) is
      T : Trie;
   begin
      if Tree = null then
	 Tree := new Node;
      end if;
      T := Tree;
      for I in Path'Range loop
         if T.Past(Path(I)) = null then
            T.Past(Path(I)) := new Node;
         end if;
         T := T.Past(Path(I));
      end loop;
      T.Just := True;
      T.Here := What;
   end Give;

   procedure Take (Path : in Input_Type; Tree : in out Trie) is
      T : Trie;
      S : Boolean;
   begin
      Sift(Path, Tree, S, T);
      if S then T.Just := False; end if;
   end Take;

   procedure Find (Path : in Input_Type; Tree : in Trie; Seen : out Boolean; Unto : out Stored_Type)
   is
      T : Trie;
   begin
      Sift(Path, Tree, Seen, T);
      if Seen and then T.Just then
         Unto := T.Here;
      else
         Seen := False;
      end if;
   end Find;

   procedure Sift (Path : in Input_Type; Tree : in Trie; Seen : out Boolean; Unto : out Trie) is
      T : Trie := Tree;
   begin
      Seen := False;
      if Tree = null then return; end if;
      for I in Path'Range loop
	 T := T.Past(Path(I));
         if T = null then return; end if;
      end loop;
      Seen := True;
      Unto := T;
   end Sift;
end Trivial_Trie;