--
-- Copyright (C) 2020  <fastrgv@gmail.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- 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 General Public License for more details.
--
-- You may read the full text of the GNU General Public License
-- at <http://www.gnu.org/licenses/>.
--





with sndloop;
with snd;
with text_io; use text_io;
with gl; use gl;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with ada.direct_io;
with system;
with pcm_h;




package body snd4ada_hpp is

	subtype namerng is integer range 1..80;
	type nametype is new string(namerng);

	maxbuf : constant int := 26;
	subtype bufrng is int range 0..maxbuf;
	tbuf: bufrng := 0;

	tsk : array(bufrng) of sndloop.iplaytask;
	itask : array(bufrng) of snd.iplaytask;

	isloop,running : array(bufrng) of boolean := (others=>false);





   procedure initSnds is
	begin
		null;
	end initSnds;

   function initSnd (
		pc : Interfaces.C.Strings.chars_ptr; 
		vol : int
		) return int is

		lt: constant size_t := Strlen(pc);
		ln: constant namerng := namerng(lt);
	begin

		tbuf:=tbuf+1;
		itask(tbuf).Init( value(pc) );

		return tbuf;

	end initSnd;


	--transient sound...play Once:
   procedure playSnd (nbuf : int) is
	begin
		itask(nbuf).start;
	end playSnd;


   function initLoop (
		pc : Interfaces.C.Strings.chars_ptr; 
		dur : gldouble; --duration of sound clip
		vol : int
		) return int is
	begin

		tbuf:=tbuf+1;
		isloop(tbuf):=true;
		running(tbuf):=false;
		tsk(tbuf).Init( value(pc), dur ); -- "value" returns string
		return tbuf;

	end initLoop;


	--sound loop...play Many using task:
   procedure playLoop (nbuf : int) is
	begin

		if nbuf>=1 and nbuf<=tbuf then
			if isloop(nbuf) and not running(nbuf) then
				running(nbuf):=true;
				tsk(nbuf).start;
			end if;
		end if;

		exception
			when others =>
				put_line("snd4ada.playLoop error");
				raise;
	end playLoop;



   procedure stopLoop (nbuf : int) is
	begin

		if nbuf>=1 and nbuf<=tbuf then
			if isloop(nbuf) and running(nbuf) then
				tsk(nbuf).stop;
				running(nbuf):=false;
			end if;
		end if;

		exception
			when others =>
				put_line("snd4ada.stopLoop error");
				raise;

	end stopLoop;

	procedure stopLoops is
	begin
		for i in bufrng range 1..tbuf loop
			stopLoop(i);
		end loop;
	end stopLoops;


   procedure termSnds is
	begin
		stopLoops;
		for nbuf in bufrng range 1..tbuf loop
		if isloop(nbuf) then
			tsk(nbuf).quit;
		else
			itask(nbuf).quit;
		end if;
		end loop;
	end termSnds;



end snd4ada_hpp;
