--
-- Copyright (C) 2022  <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/>.
--



separate (adagate)

procedure drawroom(
	numport: integer; -- 0, 1, 2
	insideportal: boolean := false;
	avx,avy,avz,angl : float
) is


	dangx, ahoriangx,
	dxp,dzp : float := 0.0;
	isel : glint := 0;

	ballsec: gldouble;
	ibsec,ii,kk: integer;
	nslic: constant integer := 1000; --partitions per direction
	xfb1 : constant float := -xmax+fballrad;       -- one end
	xfb2 : constant float := +xmax-fballrad;       -- other end
	xxfb,yyfb,zzfb : float;

	et: gldouble;
	extension: float;



procedure getFireBallPos(xxx,yyy,zzz: out float) is
begin
----------------------------------------------------------------------
			ballsec := 60.0*glfwGetTime;
			ibsec := integer( ballsec );
			kk:= ibsec/nslic;
			ii:= 1 + ibsec mod nslic; -- 1..nslic = 1..1000
			if (kk mod 2 = 1) then
				null;
			else
				ii:= 1 + nslic - ii; -- 1001-i = 1..1000
			end if;
			xxx := xfb1 + float(ii-1)/float(nslic) * (xfb2-xfb1);
			yyy:= -ymax+fballrad;
			zzz:= 2.0;
-----------------------------------------------------------------------
end getFireBallPos;


	xeye,yeye,zeye: float;


	procedure drawBarrels is separate;

	procedure drawLev1 is separate;
	procedure drawLev2 is separate;
	procedure drawLev3 is separate;
	procedure drawLev4 is separate;
	procedure drawLev5 is separate;



begin

	if thirdPerson then
		xeye:=xcam; yeye:=ycam; zeye:=zcam;
	else
		xeye:=xme; yeye:=yme; zeye:=zme;
	end if;


	if level<5 then  -- in-a-dungeon with many textured objects in common



		if thirdPerson then
			drawAvatar(currenttime, avx,avy,avz,angl);
		end if;



		if not insideportal then -- ZPMs mostly invisible if insideportal
			drawBarrels;
		end if; -- not insideportal



	-- draw most common textured objects using this single PID:
		glUseProgram( pidpgm16 );

		glUniform1i(side16, glint(numport) );
		glUniform3f(ieye16, glfloat(xeye),glfloat(yeye),glfloat(zeye));


		--new portal-hole setup: puts hole in roomwall about size of portal,
		--however, "holes" are actually prolate spheroids of transparency;
		--Be careful of size because we risk erasing any nearby objects in 3D

		glUniform3f(lprt16, glfloat(xtgt1),glfloat(ytgt1),glfloat(ztgt1) ); 
		--center p1 (left)

		glUniform3f(rprt16, glfloat(xtgt2),glfloat(ytgt2),glfloat(ztgt2) ); 
		--center p2 (right)


		if 
			(
				worm_active
				or (lshooting and rport_defined)
				or (rshooting and lport_defined)
			)
		then
			glUniform1f(irad16, glfloat(0.80) ); --radius (show holes, danger)

			if rport_defined and lport_defined then
				glUniform1i(isel16, 3 ); -- 0=>none, 3=>both, 1=>1, 2=>2
			elsif rport_defined then
				glUniform1i(isel16, 2 ); -- 0=>none, 3=>both, 1=>1, 2=>2
			elsif lport_defined then
				glUniform1i(isel16, 1 ); -- 0=>none, 3=>both, 1=>1, 2=>2
			end if;

		else
			glUniform1f(irad16, glfloat(0.0) ); --radius (no holes, no danger)
			glUniform1i(isel16, 0 ); -- 0=>none, 3=>both, 1=>1, 2=>2
		end if;



		gluniformmatrix4fv( imvp16, 1, gl_false, mvp(1,1)'address );
		gluniform1i(samp16,0);

		-- we now set fog level, color:
		if level=1 then -- adobe
			gluniform1i(flev16, 1 );
			gluniform1i(fcol16, 1 );
		elsif level=2 then -- wood
			gluniform1i(flev16, 1 );
			gluniform1i(fcol16, 1 );
		elsif level=3 then -- brick
			gluniform1i(flev16, 3 );
			gluniform1i(fcol16, 2 );
		elsif level=4 then -- granite
			gluniform1i(flev16, 1 );
			gluniform1i(fcol16, 3 );
		end if;

		gluniform1i(opac16, 1); -- 1=>normal opacity




		et := currenttime-dungeonEntryTime-islandWormDuration;
		if et<5.0 and et>0.0 then

			-- draw SG exit == entry into dungeon (13dec19).
			-- entry gate fades after 5 seconds...no way out.
			glbindtexture(gl_texture_2d, xbox3_texid);
			twictObj.draw(ebox, vertbuff,uvbuff,elembuff); --NO lighting here

		end if;


		glbindtexture(gl_texture_2d, room_texid);

		--draw dungeon room: ###########################################
		--if level=3 and not onMac then
		if level=3  then

			gluniform1i(flag16, 1); -- 1=> lightingEffects;  0=> normal

			--2 light sources within lava pool (?pcen=poolcenter)
			gluniform3f(posa16,
				glfloat(xpcen-xprad/6.0),
				glfloat(waterlevel+1.1),glfloat(zpcen) );
			gluniform3f(posb16,
				glfloat(xpcen+xprad/6.0),
				glfloat(waterlevel+1.1),glfloat(zpcen) );

			getFireBallPos(xxfb,yyfb,zzfb);

			--1 light source @ fireball center:
			gluniform3f(posc16,glfloat(xxfb),glfloat(yyfb),glfloat(zzfb) );

			-- color of light
			gluniform3f( lcol16, 
				254.0/255.0, 203.0/255.0, 33.0/255.0 ); --orange

			mroomobj.ldraw(rmo,vertbuff,uvbuff,normbuff,elembuff); 
			--textured room with floor-gap AND LightEffects

		else -- level 1,2,4 (no lighting)
			gluniform1i(flag16, 0); -- 1=> lightingEffects;  0=> normal
			mroomobj.draw(rmo,vertbuff,uvbuff,elembuff); 
			--textured room with floor-gap
		end if;

		glUniform1f(irad16, glfloat(0.0) ); --radius (disable further holes)
		glUniform1i(isel16, 0 ); -- 0=>none, 3=>both, 1=>1, 2=>2


		-- draw ZPM-receptacles on floor
		if not insideportal then -- typically invisible if insideportal

			if portalEnabled then
				glbindtexture(gl_texture_2d, barloc1_texid);
			else
				glbindtexture(gl_texture_2d, barloc0_texid);
			end if;

			if level=3 then
			gluniform1i(flag16, 0 ); -- do NOT apply lighting to receptacles
			end if;
			-- draw receptacles (using pidpgm16)
			for row in 1..nrows loop
				for col in 1..ncols loop
					if( rcpt(row,col) = true ) then
						pictobj.draw(sokrcpt(row,col),vertbuff,uvbuff,elembuff);
						-- note:  beyond range of lighting effects in level 3
					end if;
				end loop;
			end loop;
			if level=3 then
			gluniform1i(flag16, 1 ); -- restore lighting
			end if;

		end if; -- not insideportal



		--draw block wall dividers [was here]:

		--draw ledges [was here]:


		--draw ceilings:
		-- level#2: ceil [now] matches walls;
		-- level#3: ceil matches walls;   
		-- level#4: special fragshader
		if level=1 then 
			glbindtexture(gl_texture_2d, ceil_texid);
			rectobj.draw(ceil1,  vertbuff,uvbuff,elembuff); -- ceiling
		end if;

		-- 2 ordinary wall pictures:
		if (level=1) or (level=4) then
			glbindtexture(gl_texture_2d, pic_texid);
			pictobj.draw(pic,  vertbuff,uvbuff,elembuff); -- wall picture
		end if;


		-- Brick Lining of Pools
		glbindtexture(gl_texture_2d, lining_texid);

		--if level=3 and not onMac then
		if level=3 then
			rectobj.ldraw(pxp, vertbuff,uvbuff,normbuff,elembuff); --@+X
			rectobj.ldraw(pxm, vertbuff,uvbuff,normbuff,elembuff); --@-X
			rectobj.ldraw(pzp, vertbuff,uvbuff,normbuff,elembuff); --@+Z
			rectobj.ldraw(pzm, vertbuff,uvbuff,normbuff,elembuff); --@-Z
			rectobj.ldraw(pym, vertbuff,uvbuff,normbuff,elembuff); --@bottom
		else
			rectobj.draw(pxp, vertbuff,uvbuff,elembuff); --@+X
			rectobj.draw(pxm, vertbuff,uvbuff,elembuff); --@-X
			rectobj.draw(pzp, vertbuff,uvbuff,elembuff); --@+Z
			rectobj.draw(pzm, vertbuff,uvbuff,elembuff); --@-Z
			rectobj.draw(pym, vertbuff,uvbuff,elembuff); --@bottom
		end if;






		--draw portals
		if lport_located and lport_stable and lport_defined then
			glbindtexture(gl_texture_2d, offportg_texid);
			pict1obj.draw(lportal, vertbuff,uvbuff,elembuff);
		end if;
		if rport_located and rport_stable and rport_defined then
			glbindtexture(gl_texture_2d, offportr_texid);
			pict1obj.draw(rportal, vertbuff,uvbuff,elembuff);
		end if;




		-- draw sokoban walls:
		if level=1 then
			glbindtexture(gl_texture_2d, adobe_texid); --dark adobe
		elsif level=2 then
			glbindtexture(gl_texture_2d, woodt_texid);
		elsif level=3 then
			glbindtexture(gl_texture_2d, brick_texid);
		else
			glbindtexture(gl_texture_2d, granite_texid);
		end if;

		--  walls made up of short cubes (still using pidpgm16)
		for row in 1..nrows loop
			for col in 1..ncols loop
				-- if post exists here, draw short cube
				if( wall(row,col) = true ) then
					if level=3 then --exists option to use lighting
						rectobj.draw(sokwall(row,col),vertbuff,uvbuff,elembuff);
					else
						rectobj.draw(sokwall(row,col),vertbuff,uvbuff,elembuff);
					end if;
				end if;
			end loop;
		end loop;



		-- North/South picture frames
		glbindtexture(gl_texture_2d, grunge_texid);

		--if level=3 and not onMac then
		if level=3 then
			frameobj.ldraw(nfox,vertbuff,uvbuff,normbuff,elembuff);
			frameobj.ldraw(sfox,vertbuff,uvbuff,normbuff,elembuff);
		else
			frameobj.draw(nfox,vertbuff,uvbuff,elembuff);
			frameobj.draw(sfox,vertbuff,uvbuff,elembuff);
		end if;
		-- in case of problem, use ldraw only in level 3




--NOTE:  still using pidpgm16 to draw


		--draw ledges:
		if level=1 then
			glbindtexture(gl_texture_2d, adobe_texid); --dark adobe ledge
		else
			glbindtexture(gl_texture_2d, woodw_texid);
		end if;
		--if level=3 and not onMac then
		if level=3  then
			rectobj.ldraw(ledge,  vertbuff,uvbuff,normbuff,elembuff); 
			-- high ledge platform
		else
			rectobj.draw(ledge,  vertbuff,uvbuff,elembuff); 
			-- high ledge platform
		end if;



--NOTE:  still using pidpgm16 to draw

		--draw block wall dividers:
		if level=2 then
			glbindtexture(gl_texture_2d, woodt_texid); 
			mrectobj.draw(bloc2,vertbuff,uvbuff,elembuff);

			glbindtexture(gl_texture_2d, woodwr_texid);
			hcylobj.draw(cyl,vertbuff,uvbuff,elembuff); 
			-- new edge of ceiling (normal shader needed)


		elsif level=3 then
			glbindtexture(gl_texture_2d, woodw_texid);

			rectobj.ldraw(bloc3, vertbuff,uvbuff,normbuff,elembuff); 
			--block wall divider


		elsif level=1 then
			glbindtexture(gl_texture_2d, adobe_texid); --lev1, dark adobe wall
			rectobj.draw(bloc, vertbuff,uvbuff,elembuff); --block wall divider


		end if;








--NOTE:  still using pidpgm16 to draw


		--draw exit feature:
		if not xit or showExitFacade then --facade descending
			glbindtexture(gl_texture_2d, xbox1_texid);
			twictobj.draw(xbox,  vertbuff,uvbuff,elembuff); -- exit box
		else -- door ascending
			glbindtexture(gl_texture_2d, xbox2_texid);
			twictobj.draw(xbox,  vertbuff,uvbuff,elembuff); -- exit box

			if not exitwait then
				et:=1.5*(currenttime-exittime-8.0-gldouble(halfpi));
				-- -pi/2 @ wormhole activation

				extension:=0.75+0.75*fmath.sin(float(et)); -- 0..1.5..0
				if et>gldouble(twopi-halfpi) then
					extension:=0.0;
				end if;
				xckwh:=glfloat(xboxpos(1));
				yckwh:=glfloat(xboxpos(2));
				zckwh:=glfloat(xboxpos(3));
				xrkwh:=dkwrad;
				yrkwh:=dkwrad;
				zrkwh:=dkwrad;
				if level=4 then
					zrkwh:=dkwthk + dkwmax*glfloat( extension ); --19jan19
					--interior dimensions are 5x greater than exterior!
				else
					xrkwh:=dkwthk + dkwmax*glfloat( extension ); --19jan19
				end if;

				--CAUTION...this sets an alternate draw program
				drawKawhoosh(
					xckwh,yckwh,zckwh,
					xrkwh,yrkwh,zrkwh,
					glint(level),
					mvp);
			end if;

		end if;









		--IF et in dungeon < 3 secs, draw entry kawhoosh last...
		et := currenttime-dungeonEntryTime-islandWormDuration;
		if et<3.0 and et>0.0 then

			xrkwh:=dkwrad;
			yrkwh:=dkwrad;
			zrkwh:=dkwrad;
			if level=4 then
				zrkwh:=dkwthk;
				--interior dimensions are 5x greater than exterior!
			else
				xrkwh:=dkwthk;
			end if;


			--CAUTION...this MUST be last because
			-- it sets an alternate draw program
			drawKawhoosh(
					glfloat(xegate),glfloat(yegate),glfloat(zegate),
					xrkwh,yrkwh,zrkwh,
					glint(level),
					mvp);

		end if;




		-- now to finish using special shaders (not pidgm16):

		if level=1 then
			drawLev1; --pool + special shaders

		elsif level=2 then
			drawLev2; --reflective pool + special shaders

		elsif level=3 then
			drawLev3; --lavapool, etc

		elsif level=4 then
			drawLev4; --pool + special shaders

			--note:  because glass partition is translucent, we must
			--			first draw pool, lining, ceiling, etc.

			glUseProgram( pidpgm16 ); --resume use for final glass wall
			gluniform1i(flev16, 1 );
			gluniform1i(fcol16, 3 );
			gluniform1i(opac16, 1); -- 1=>normal opacity

			glbindtexture(gl_texture_2d, glassw_texid); -- for lev 4
			--note:  clear glass here requires different drawing order vs ceiling

			rectobj.draw(bloc, vertbuff,uvbuff,elembuff); --block wall divider


		end if;


	elsif level=5 then

		drawLev5; --remaining special shaders


	end if; -- in-a-dungeon (level < 5)

---------- end draw textured objects common to all levels ---------------








		if showCross and not insidePortal and not worming then -- also show gun icon
			if thirdPerson then
				if abs(xme-xcam)+abs(zme-zcam) < 0.001 then
					ahoriangx:=horiang;
				else
					ahoriangx := 
						branchnear(horiang,fmath.arctan(xme-xcam,zme-zcam));
				end if;
				dangx := mindifangl(horiang-ahoriangx);
				if dangx>onepi/15.0 then
					utex.print2d("{",0.40,0.1,180); --@botLfScreen
				elsif dangx<-onepi/10.0 then
					utex.print2d("}",0.65,0.1,180); --@botRtScreen
				else
					utex.print2d("|",0.60,0.1,180); --@botRtScreen
				end if;
			else
				utex.print2d("|",0.5,0.1,180); --@bottomScreen
			end if;
		end if;




end drawroom;







