#! /usr/bin/python3
# Test program for module {block}
# Last edited on 2021-05-30 20:49:41 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_js()
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,get_name,set_name,tag_names} ---\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

  assert block.nchoices(bc0) == 4
  assert block.nchoices(bc1) == 2
  assert block.nchoices(bc2) == 1
  avgn = block.avg_choices([bc0,bc1,bc2])
  assert abs(avgn - 2.0) <= 1.0e-12
  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])
  
  # Two blocks with no name:
  bce = block.from_paths(OPHS[0:2])
  bcf = block.from_paths(OPHS[1:2])
  
  assert block.get_name(bce) == "B?"
  block.set_name(bce, "Lego")
  assert block.get_name(bce) == "Lego"
  
  sys.stderr.write("applying {block.tag_names}:\n")
  block.tag_names([bce, bcf], "Tag.")
  assert block.get_name(bce) == "Tag.Lego"
  assert block.get_name(bcf) == "Tag.B?"

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

def test_show():

  sys.stderr.write("--- testing {show,show_list} ---\n")

  BCS, OPHS, TRS, JMS = block_example.misc_A(mp_fill, mp_jump)
  
  sys.stderr.write("  ... {show} ...\n")
  wna = 5
  wnc = 5
  for k in range(3):
    paths = (k % 2 == 1)
    bc = BCS[k]
    sys.stderr.write("[")
    block.show(sys.stderr, bc, paths, 4, wna, wnc)
    sys.stderr.write("]\n")
    wna = wna + 2
    wnc = max(wnc - 1, 0)
  sys.stderr.write("]\n")
  
  sys.stderr.write("  ... {show_list} ...\n")
  block.show_list(sys.stderr, BCS, True, 2)
  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, move.rev(TRS[5])) == 0
  assert  block.find_block_with_move(BCS, move.rev(TRS[9])) == 1
  assert  block.find_block_with_move(BCS, move.rev(JMS[3])) == 2

  assert  block.find_block_with_move(BCS[:2], JMS[3]) == None

  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]
   
  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
 
  return
  # ----------------------------------------------------------------------

def test_timing():
  sys.stderr.write("--- testing {min_extime} ---\n")
  
  BCS, OPHS, TRS, JMS = block_example.misc_A(mp_fill, mp_jump)
  
  txm_tot_exp = 0
  for k in range(len(BCS)):
    bc = BCS[k]
    txm_exp = +inf
    for ich in range(block.nchoices(bc)):
      oph = block.choice(bc, ich)
      txm_exp = min(txm_exp, path.extime(oph))
    txm_cmp = block.min_extime(bc)
    sys.stderr.write("    min_extime(bc):  expected %20.16f  returned %20.16f\n" % (txm_exp,txm_cmp))
    assert txm_cmp == txm_exp
    txm_tot_exp += txm_exp
  txm_tot_cmp = block.min_tot_extime(BCS)
  sys.stderr.write("tot_min_extime(bc):  expected %20.16f  returned %20.16f\n" % (txm_tot_exp,txm_tot_cmp))
  assert txm_tot_cmp == txm_tot_exp
  return
  # ----------------------------------------------------------------------

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

  bc =  block_example.raster_rectangle((1,1), 5, 4, False, True, True, mp_fill, mp_jump)
  
  dp = (2,3)
  B = block.bbox([bc,])

  c, szx,szy = hacks.make_canvas(B, dp, True, True, 1, 1)

  block.plot_matter_shadow(c, bc, dp)
  fname = ("tests/out/block_TST_%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))

  # Find the bounding box:
  B = block.bbox(BCS)

  dp = (5,5)
  wd_axes = 0.05*wdf
  rwd = 0.80

  c, szx,szy = hacks.make_canvas(B, dp, True, True, 1, nch)

  block.plot_standard \
    ( c, BCS, nch, dp, ystep = szy, CLRS = CLRS, rwd=rwd, wd_axes=wd_axes,
      axes=True, dots=True, arrows=True, matter=True
    )
  fname = ("tests/out/block_TST_%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_%s" % tag)
  CLRS = hacks.trace_colors(len(BCS)) # Colors to use for different blocks.
  rwd = 0.80
  wd_axes = 0.05*wdf
  block.plot_to_files(fname, BCS, CLRS, rwd, wd_axes, matter=True)
  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)
  B = block.bbox([bc,])

  ich = 2
  dp = (2,3)
  clr = pyx.color.rgb(1.000, 0.700, 0.000)
  rwd = 0.80
  wd_axes = 0.05*wdf
  
  c, szx,szy = hacks.make_canvas(B, dp, True, True, 1, 1)
  block.plot_choice(c, bc, ich, dp, clr, rwd, wd_axes, axes=True, dots=True, arrows=True, matter=True)
  fname = ("tests/out/block_TST_%s" % tag)
  hacks.write_plot(c, fname)
  return
  # ----------------------------------------------------------------------

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

  BCS = block_example.misc_D(mp_fill)
  nbc = len(BCS)
  CLRS = hacks.trace_colors(nbc) # Colors to use for different blocks.

  dp = (2,3)
  rwd = 0.80
  wd_axes = 0.05*wdf
  B = block.bbox(BCS)
  c, szx,szy = hacks.make_canvas(B, dp, True, True, 1, 1)
  ich = 2
  axes = True
  dots = True
  arrows = True
  matter = True
  block.plot_choice_list(c, BCS, ich, dp, CLRS, rwd, wd_axes, axes, dots, arrows, matter)
  fname = ("tests/out/block_TST_%s" % tag)
  hacks.write_plot(c, fname)
  return
  # ----------------------------------------------------------------------
  
test_basics()
test_show()
test_finding()
test_timing()
test_plot_matter_shadow()
test_plot_standard()
test_plot_to_files()
test_plot_choice()
test_plot_choice_list()
