#! /usr/bin/python3
# Test program for module {block}
# Last edited on 2021-03-21 11:56:59 by jstolfi

import block
import block_example
import move 
import move_parms
import path
import hacks
import job_parms
import rn
import pyx
import sys
from math import sqrt, sin, cos, floor, ceil, inf, nan, pi

parms = job_parms.typical()
parms['solid_raster_width'] = 1.00
parms['contour_trace_width'] = 0.50

mp_jump = move_parms.make_for_jumps(parms)
mp_cont = move_parms.make_for_contours(parms)
mp_fill = move_parms.make_for_fillings(parms)

wdf = move_parms.width(mp_fill)

def test_basics():
  sys.stderr.write("--- testing {from_paths,nchoices,choice} ---\n")
  
  BCS, OPHS, TRS, JMS = block_example.misc_A(mp_fill, mp_jump)

  bc0 = BCS[0]; block.validate(bc0)
  bc1 = BCS[1]; block.validate(bc1)
  bc2 = BCS[2]; block.validate(bc2)
  
  mex = min(path.extime(OPHS[0]), min(path.extime(OPHS[1]), path.extime(OPHS[2])))
  assert block.min_extime(bc0) == mex

  nch0 = block.nchoices(bc0)
  assert nch0 == 4
  assert block.choice(bc0, 0) == OPHS[0]
  assert block.choice(bc0, 1) == path.rev(OPHS[0])
  assert block.choice(bc0, 2) == OPHS[1]
  assert block.choice(bc0, 3) == path.rev(OPHS[1])

  return
  # ----------------------------------------------------------------------

def test_finding():
  sys.stderr.write("--- testing {moves,find_block_with_move,find_choice_with_move} ---\n")
  
  BCS, OPHS, TRS, JMS = block_example.misc_A(mp_fill, mp_jump)

  bc0 = BCS[0]
  bc1 = BCS[1]
  bc2 = BCS[2]
  
  MVS0_cp = block.moves(bc0)
  MVS0_ex = (TRS[0],JMS[0],TRS[6],TRS[2],JMS[1],TRS[5],JMS[2],TRS[4])
  assert set(MVS0_cp) == set(MVS0_ex)
  
  MVS1_cp = block.moves(bc1)
  MVS1_ex = (TRS[7],JMS[4],TRS[8],TRS[9])
  assert set(MVS1_cp) == set(MVS1_ex)
  
  MVS2_cp = block.moves(bc2)
  MVS2_ex = (TRS[3],JMS[3],TRS[1])
  assert set(MVS2_cp) == set(MVS2_ex)
  
  assert  block.find_block_with_move(BCS, TRS[5]) == 0
  assert  block.find_block_with_move(BCS, TRS[9]) == 1
  assert  block.find_block_with_move(BCS, JMS[3]) == 2
  assert  block.find_block_with_move(BCS[:2], JMS[3]) == None
  
  assert block.find_choice_with_move(bc0, JMS[0]) == 0
  assert block.find_choice_with_move(bc0, TRS[6]) == 0
  assert block.find_choice_with_move(bc0, TRS[4]) == 2
  assert block.find_choice_with_move(bc0, JMS[2]) == 2
  assert block.find_choice_with_move(bc0, TRS[7]) == None

  assert block.find_choice_with_move(bc1, TRS[4]) == None
  assert block.find_choice_with_move(bc1, TRS[7]) == 0
  assert block.find_choice_with_move(bc1, JMS[4]) == 0
  assert block.find_choice_with_move(bc1, TRS[8]) == 0
  assert block.find_choice_with_move(bc1, TRS[9]) == 1
  
  assert block.find_choice_with_move(bc2, TRS[4]) == None
  assert block.find_choice_with_move(bc2, JMS[0]) == None
  assert block.find_choice_with_move(bc2, TRS[3]) == 0
  assert block.find_choice_with_move(bc2, TRS[1]) == 0

  # Test {block.find_with_move}:
  assert BCS[block.find_block_with_move(BCS, path.elem(OPHS[0],2))] == bc0
  assert BCS[block.find_block_with_move(BCS, path.elem(OPHS[1],2))] == bc0
  assert BCS[block.find_block_with_move(BCS, path.elem(OPHS[2],2))] == bc2
  assert BCS[block.find_block_with_move(BCS, JMS[0]) == bc1]
  assert BCS[block.find_block_with_move(BCS, TRS[7]) == bc2]
  
  return
  # ----------------------------------------------------------------------

def test_timing():
  sys.stderr.write("--- testing {min_extime} ---\n")
  
  BCS, OPHS, TRS, JMS = block_example.misc_A(mp_fill, mp_jump)
  
  for k in range(len(BCS)):
    bc = BCS[k]
    tex_min = +inf
    for ich in range(block.nchoices(bc)):
      oph = block.choice(bc, ich)
      tex_min = min(tex_min, path.extime(oph))
    assert block.min_extime(bc) == tex_min
  return
  # ----------------------------------------------------------------------

def test_plot_choice():
  sys.stderr.write("--- testing {plot_choice} ---\n")
  tag = "plot_choice"

  bc =  block_example.raster_rectangle((1,1), 5, 4, False, True, True, mp_fill, mp_jump)
  ich = 2
  dp = (2,3)
  clr = pyx.color.rgb(1.000, 0.700, 0.000)
  wd_axes = 0.05*wdf
  c = pyx.canvas.canvas()
  block.plot_choice(c, bc, ich, dp, clr, wd_axes, axes=False, dots=True, arrows=True)
  fname = ("tests/out/block_TST_plot_choice_%s" % tag)
  hacks.write_plot(c, fname)
  return
  # ----------------------------------------------------------------------
  
def test_plot_standard():
  sys.stderr.write("--- testing {plot_standard} ---\n")
  tag = "plot_standard"

  BCS = block_example.misc_D(mp_fill)
  nbc = len(BCS)
  CLRS = hacks.trace_colors(nbc) # Colors to use for different blocks.
  nch = 0
  for bc in BCS: nch = max(nch, block.nchoices(bc))
  nch += 1  # Plot one row with just the matter shadows.

  wd_axes = 0.05*wdf
  c = pyx.canvas.canvas()
  dp = (5,5)
  
  # Find the bounding box and plot a frame:
  B = block.bbox(BCS)
  pbox = hacks.round_box(B, 1)
  szx, szy = rn.box_size(pbox)
  gbox = (pbox[0], rn.add(pbox[0], (szx, nch*szy)))
  
  wd_frame = 0.03
  hacks.plot_frame(c, None, wd_frame, dp, gbox, 3*wd_frame)
  
  ystep = szy
  block.plot_standard \
    ( c, BCS, nch, dp, ystep, CLRS, wd_axes=wd_axes,
      axes=True, dots=True, arrows=True, matter=True
    )
  fname = ("tests/out/block_TST_plot_standard_%s" % tag)
  hacks.write_plot(c, fname)
  return 
  # ----------------------------------------------------------------------

def test_plot_to_files():
  sys.stderr.write("--- testing {plot_to_files} ---\n")
  BCS = block_example.misc_D(mp_fill)
  tag = "plot_to_files"
  fname = ("tests/out/block_TST_plot_to_files_%s" % tag)
  CLRS = hacks.trace_colors(len(BCS)) # Colors to use for different blocks.
  wd_axes = 0.05*wdf
  block.plot_to_files(fname, BCS, CLRS, wd_axes, matter=True)
  return
  # ----------------------------------------------------------------------

test_plot_choice()
test_plot_standard()
test_plot_to_files()
test_basics()
test_finding()
test_timing()
