module blocks

use cinter, only: mvaddch, endwin
use shapes, only: Piece
use fields, only: field

implicit none (type, external)
private
public :: game_over, draw_piece, freeze

contains

subroutine draw_piece(P)
class(piece), intent(in) :: P

integer :: i, j, x, y

! not concurrent since "mvaddch" remembers its position
do i = 1, P%Ny
  y = (i-1) + P%y
  if (y<0) cycle

  do j = 1, P%Nx
    x = (j-1) + P%x

    if (P%values(i, j) /= 0) then
      ! zero-indexed, so another -1
      call mvaddch(y=y-1, x=(P%x0-1) + x-1, &
                    ch=P%ch(P%values(i, j)))
    endif
  end do

end do
end subroutine draw_piece


subroutine freeze(F, P, NP)
! Called when a piece has hit another and freezes
class(piece), intent(inout) :: P, NP
class(field), intent(inout) :: F

integer :: i, y, ix, x, Nx, ixs
character(120):: buf

if(.not. P%landed) return

x = P%x
Nx = P%Nx

! not concurrent due to impure "game over"
ix = max(1, x)
ixs = min(F%W, ix + Nx - (ix-x) - 1)
do i = 1, P%Ny
  if (all(P%values(i, :) == 0)) cycle

  y = i-1 + P%y

  if (y <= 1)  then
    write(buf,'(A12,I3,A3,I3)') 'freeze: x=',x,'y=',y
    call game_over(F, P, buf)
  endif

  where(F%screen(y, ix:ixs) == 1 .or. P%values(i,ix-x+1:ixs-x+1) ==1)
    F%screen(y, ix:ixs) = 1
  endwhere
end do

call F%clear_lines()
call P%spawn_block(F, NP)
end subroutine freeze


subroutine game_over(F, P, msg)
class(field), intent(in) :: F
class(piece), intent(in), optional :: P
character(*), intent(in), optional :: msg
integer :: i

call endwin()

do i = 1,size(F%screen,1)
  print '(100I1)',F%screen(i,:)
enddo

if(present(P)) print *, P%why
if(present(msg)) print *, msg

print *,' '
print *, 'Level:', F%level
Print *, 'Score:', F%score
print *, 'Number of Blocks:', F%Nblock
print *, 'Number of Lines Cleared:', F%Ncleared
print *, 'Block Sequence: ', F%blockseq(:F%Nblock)

if (F%debug) then
  write(F%udbg,*) 'Block Sequence: ', F%blockseq(:F%Nblock)
  close(F%udbg)
endif

stop 'Goodbye from Tetran'

end subroutine game_over

end module blocks
