implementation module wormshow

import	StdInt, StdBool, StdList, StdFunc, StdString
import	StdPicture
import	wormstate

//	The drawing constants.
WormBackGroundColour	:==	RGB {r=MaxRGB,g=MaxRGB,b=MaxRGB*3/4}
WormFontSize			:==	12
PointsPos				:== {x=72, y=15}
LifesPos				:== {x=255,y= 5}
LevelPos				:== {x=465,y=15}
CornerX					:== 15
CornerY					:== 23
SegSize					:== 4
CellSize				:== 10

//	Draw the game.
DrawGame :: !Level !Food !Points !Worm !Lives !*Picture -> *Picture
DrawGame {level,obstacles} food points worm lives pict
	# pict = unfill	{	corner1={x=CornerX-8,y=0}
					,	corner2={x=CornerX+SizeX*CellSize+16,y=CornerY+SizeY*CellSize+16}
					}					pict
	# pict = DrawBorders				pict
	# pict = DrawObstacles	obstacles	pict
	# pict = DrawPoints		points		pict
	# pict = DrawWorm		worm		pict
	# pict = DrawFood		food		pict
	# pict = DrawLevel		level		pict
	# pict = DrawLives		lives		pict
	= pict
where
	DrawObstacles :: ![Obstacle] !*Picture -> *Picture
	DrawObstacles [] pict
		= pict
	DrawObstacles obstacles pict
		# pict	= setPenColour (RGB {r=MaxRGB/2,g=MaxRGB/2,b=0})	pict
		# pict	= seq (map DrawObstacle obstacles)	pict
		# pict	= setPenColour Black				pict
		= pict
	where
		DrawObstacle :: !Obstacle !*Picture -> *Picture
		DrawObstacle {corner1={x=ltx,y=lty},corner2={x=rbx,y=rby}} pict
			= fill {corner1={x=lx,y=ty},corner2={x=rx,y=by}} pict
		where
			lx	= CornerX+CellSize*ltx-2
			ty	= CornerY+CellSize*lty-2
			rx	= CornerX+CellSize*rbx+2
			by	= CornerY+CellSize*rby+2
	
	DrawPoints :: !Points !*Picture -> *Picture
	DrawPoints points pict
		# pict	= setPenColour Magenta						pict
		# pict	= drawAt {PointsPos & x=x-57} "Points: "	pict
		# pict	= setPenColour	Black						pict
		# pict	= DrawNewPoints	points						pict
		= pict
	where
		{x}		= PointsPos
	
	DrawWorm :: !Worm !*Picture -> *Picture
	DrawWorm [head:rest] pict
		# pict	= seq (map (DrawSegment Red) rest)	pict
		# pict	= DrawSegment	Green head			pict
		# pict	= setPenColour	Black				pict
		= pict
	
	DrawLevel :: !Int !*Picture -> *Picture
	DrawLevel level pict
		# pict	= setPenColour Magenta					pict
		# pict	= drawAt {LevelPos & x=x-50} "Level: "	pict
		# pict	= setPenColour Black					pict
		# pict	= unfill {corner1={x=x-1,y=y-12},corner2={x=x+100,y=y+4}}
		  												pict
		# pict	= drawAt LevelPos (toString level)		pict
		= pict
	where
		{x,y}	= LevelPos
	
	DrawLives :: !Lives !*Picture -> *Picture
	DrawLives lives pict
		| lives<>0
			= DrawLittleWorms lives				pict
		| otherwise
			# pict	= setPenColour	Magenta		pict
			# pict	= drawAt {x=lx-63,y=ly+10} "No more worms!"	pict
			# pict	= setPenColour	Black		pict
			= pict
	where
		{x=lx,y=ly}	= LifesPos
		
		DrawLittleWorms :: !Lives !*Picture -> *Picture
		DrawLittleWorms lives pict
			| lives>0
				= DrawLittleWorms (lives-1) (DrawLittleWorm lives pict)
			| otherwise
				# pict	= setPenColour	Magenta	pict
				# pict	= drawAt {x=lx-63,y=ly+10} "Worms:"	pict
				# pict	= setPenColour	Black	pict
				= pict
		where
			{x=lx,y=ly}	= LifesPos
			
			DrawLittleWorm :: !Int !*Picture -> *Picture
			DrawLittleWorm n pict
				# pict		= setPenSize	5				pict		// PA: 5<--(4,5)
				# pict		= setPenColour	Red				pict
				# pict		= setPenPos		{x=x,y=y}		pict
				# pict		= drawLineTo	{x=x+9,y=y}		pict
				# pict		= setPenColour	Green			pict
				# pict		= drawLineTo	{x=x+10,y=y}	pict
				# pict		= setPenSize	1				pict
				# pict		= setPenColour	Black			pict
				= pict
			where
				x			= lx+20*(dec n / 2) 
				y			= ly+ 7*(dec n rem 2) 
				{x=lx,y=ly}	= LifesPos

DrawBorders :: !*Picture -> *Picture
DrawBorders pict
	# pict	= setPenColour	Black	pict
	# pict	= setPenSize	3		pict
	# pict	= draw	{	corner1={x=CornerX-3,y=CornerY-3}
	  				,	corner2={x=CornerX+SizeX*CellSize+11,y=CornerY+SizeY*CellSize+11}}
									pict
	# pict	= setPenSize	1		pict
	= pict

DrawSegment :: !Colour !Segment !*Picture -> *Picture
DrawSegment color {x,y} pict
	# pict	= setPenColour color pict
	# pict	= fillAt {x=CornerX+CellSize*x,y=CornerY+CellSize*y} {oval_rx=SegSize,oval_ry=SegSize} pict
	= pict

EraseSegment :: !Segment !*Picture -> *Picture
EraseSegment segment pict
	= DrawSegment WormBackGroundColour segment pict

DrawFood :: !Food !*Picture -> *Picture
DrawFood {pos} pict
	# pict	= setPenColour	Magenta					pict
	# pict	= fillAt {x=x,y=y} {box_w=6,box_h=6}	pict
	# pict	= setPenColour	Black					pict
	= pict
where
	x		= CornerX+CellSize*pos.x-3
	y		= CornerY+CellSize*pos.y-3
	
EraseFood :: !Food !*Picture -> *Picture
EraseFood {pos} pict
	= unfillAt {x=x,y=y} {box_w=6,box_h=6} pict
where
	x		= CornerX+CellSize*pos.x-3
	y		= CornerY+CellSize*pos.y-3

DrawNewPoints :: !Points !*Picture -> *Picture
DrawNewPoints points pict
	# pict	= unfill {corner1={x=x-1,y=y-12},corner2={x=x+100,y=y+4}}	pict
	# pict	= drawAt PointsPos (toString points)	pict
	= pict
where
	{x,y}	= PointsPos


//	Show a step of the worm.
DrawStep :: !Bool !Food !Food !Points !Segment !Segment !Segment !*Picture -> *Picture
DrawStep scored oldfood newfood points oldh head tail pict
	| not scored
		= DrawMove oldh head tail	pict
	| otherwise
		# pict	= EraseFood		oldfood			pict
		# pict	= DrawFood		newfood			pict
		# pict	= DrawNewPoints	points			pict
		# pict	= DrawMove		oldh head tail	pict
		= pict
where
	DrawMove :: !Segment !Segment !Segment !*Picture -> *Picture
	DrawMove oldh head {x=0,y=0} pict
		# pict	= DrawSegment	Red					 oldh pict
		# pict	= DrawSegment	Green				 head pict
		# pict	= setPenColour	Black					  pict
		= pict
	DrawMove oldh head tail pict
		# pict	= DrawSegment	Red					 oldh pict
		# pict	= DrawSegment	Green				 head pict
		# pict	= DrawSegment	WormBackGroundColour tail pict
		# pict	= setPenColour	Black					  pict
		= pict


//	Close the Playfield between two levels.
DrawAnimation :: !Int !Int !*Picture -> *Picture
DrawAnimation 40 1 pict
	# pict		= setPenColour	White	pict
	# pict		= DrawBorders			pict
	# pict		= setPenColour	Black	pict
	= pict
DrawAnimation n step pict
	| step<0
		# pict	= setPenSize	3 pict
		# pict	= unfill		{corner1={x=l,y=b},corner2={x=x,y=y}} pict
		# pict	= unfill		{corner1={x=r,y=t},corner2={x=x,y=y}} pict
		# pict	= draw			{corner1={x=l,y=t},corner2={x=r,y=b}} pict
		= pict
	| otherwise
		# pict	= setPenSize	3 pict
		# pict	= unfill		{corner1={x=l,y=b},corner2={x=x,  y=y-3}} pict
		# pict	= unfill		{corner1={x=r,y=t},corner2={x=x-3,y=y  }} pict
		# pict	= draw			{corner1={x=l,y=t},corner2={x=r,  y=b  }} pict
		= pict
where
	l			= CornerX-3
	t			= CornerY-3
	r			= l+w*n
	b			= t+h*n 
	x			= r-step*w
	y			= b-step*h 
	w			= (48+SizeX*CellSize)/40
	h			= (48+SizeY*CellSize)/40
