#! /usr/bin/python3
# Last edited on 2021-05-25 02:05:05 by jstolfi

import path_hp
import path
import path_example
import block
import block_example
import job_parms
import move_parms

import sys
import rn
from math import sqrt, sin, cos, log, exp, floor, ceil, inf, nan, pi

parms = job_parms.typical_js()
parms['solid_raster_width'] = 1.0
parms['contour_trace_width'] = 0.5

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

def test_groups():
  sys.stderr.write("--- testing {set_group,get_group} ---\n")
  
  ph = path_example.misc_B(mp_fill, mp_jump)
  
  assert path_hp.get_group(ph) == None
  assert path_hp.get_group(path.rev(ph)) == None

  for oph in ph, path.rev(ph):
    path_hp.set_group(oph, 418)
    assert path_hp.get_group(oph) == 418
    path_hp.set_group(path.rev(oph), 4615)
    assert path_hp.get_group(oph) == 4615
  
  return 
  # ----------------------------------------------------------------------

def test_contacts():
  sys.stderr.write("--- testing {get_contacts,set_contacts} ---\n")
  
  ph = path_example.misc_B(mp_fill, mp_jump)
  
  # ??? Should test with real contacts ???
  ct1 = "FOO"
  ct2 = "BAR"
  ct3 = "BAZ"
  
  for oph in ph, path.rev(ph):
    path_hp.clear_contacts(oph)
    assert tuple(path_hp.get_contacts(oph, 0)) == ()
    assert tuple(path_hp.get_contacts(oph, 1)) == ()
    path_hp.add_contact(oph, 0, ct1)
    path_hp.add_contact(oph, 0, ct2)
    path_hp.add_contact(oph, 1, ct3)
    assert tuple(path_hp.get_contacts(oph, 0)) == (ct1, ct2,)
    assert tuple(path_hp.get_contacts(oph, 1)) == (ct3,)
  
  return 
  # ----------------------------------------------------------------------

def test_blocks():
  sys.stderr.write("--- testing {get_block,set_block} ---\n")
  
  ph = path_example.misc_B(mp_fill, mp_jump)
  
  bc = block.from_paths([ph, path.rev(ph)])
  path_hp.set_block(ph, bc)
  bc1 = path_hp.get_block(ph)
  assert bc1 == bc
  
  return 
  # ----------------------------------------------------------------------

def test_links():
  sys.stderr.write("--- testing {clear_links,add_link,get_links,get_connecting_link} ---\n")
  
  OPHS = path_example.misc_H(mp_fill)
  sys.stderr.write("OPHS:\n")
  path.show_list(sys.stderr, OPHS, False, 2)
  
  def makelink(p,q):
    # A slightly twisted path from {p} to {q}
    m = rn.mix(0.45, rn.add(p,q), 0.10, (sin(100*p[0]), cos(200*p[1])))
    link = path.from_points((p,m,q,), mp_cont, None)
    return link
    # ......................................................................
  
  def listeq(L0,L1):
    # True iff path lists {L0} and {L1} are the same 
    # considering {(ph,0)} and {ph} equal.
    L0r = tuple( (path.unpack(oph)) for oph in L0 )
    L1r = tuple( (path.unpack(oph)) for oph in L1 )
    return L0r == L1r
    # ......................................................................
  
  def patheq(oph0,oph1):
    # True iff paths {oph0} and {oph11} are the same 
    # considering {(ph,0)} and {ph} equal.
    return (path.unpack(oph0)) == (path.unpack(oph1))
    # ......................................................................
  
  for oph in OPHS: path_hp.clear_links(oph)
  # Links along the square, and diagonals:
  LKSA = []
  LKSB = []
  for i, j in (0,1), (1,2), (2,3), (3,0), (0,2), (1,3):
    
    linkA = makelink(path.pini(OPHS[i]), path.pini(OPHS[j]))
    path.set_name(linkA, "LA%d%d" % (i,j))
    LKSA.append(linkA)
    path_hp.add_link(OPHS[i], path.rev(linkA))
    path_hp.add_link(OPHS[j], linkA)
    
    linkB = makelink(path.pfin(OPHS[i]), path.pfin(OPHS[j]))
    path.set_name(linkB, "LB%d%d" % (i,j))
    LKSB.append(linkB)
    path_hp.add_link(path.rev(OPHS[i]), path.rev(linkB))
    path_hp.add_link(path.rev(OPHS[j]), linkB)
   
  sys.stderr.write("LKSA:\n")
  path.show_list(sys.stderr, LKSA, False, 2)
  sys.stderr.write("LKSB:\n")
  path.show_list(sys.stderr, LKSB, False, 2)

  # Check:
  L00a = path_hp.get_links(OPHS[0])
  L00z = [ path.rev(LKSA[0]), LKSA[3], path.rev(LKSA[4]), ]
  sys.stderr.write("L00a:\n")
  path.show_list(sys.stderr, L00a, False, 2)
  sys.stderr.write("L00z:\n")
  path.show_list(sys.stderr, L00z, False, 2)
  assert listeq(L00a, L00z)
  
  L10a = path_hp.get_links(OPHS[1])
  sys.stderr.write("L10a:\n")
  path.show_list(sys.stderr, L10a, False, 2)
  L10z = [ LKSA[0], path.rev(LKSA[1]), path.rev(LKSA[5]), ]
  sys.stderr.write("L10z:\n")
  path.show_list(sys.stderr, L10z, False, 2)
  assert listeq(L10a, L10z)

  assert listeq(path_hp.get_links(path.rev(OPHS[0])), [ path.rev(LKSB[0]), LKSB[3], path.rev(LKSB[4]), ])
  assert listeq(path_hp.get_links(path.rev(OPHS[1])), [ LKSB[0], path.rev(LKSB[1]), path.rev(LKSB[5]), ])
  
  connR0P1 = path_hp.get_connecting_link(path.rev(OPHS[0]), OPHS[1])
  sys.stderr.write("connR0P1:\n")
  path.show(sys.stderr, connR0P1, False, 2, 0, 0); sys.stderr.write("\n")
  assert patheq(connR0P1, LKSA[0])
  
  assert patheq(path_hp.get_connecting_link(path.rev(OPHS[1]), OPHS[2]), LKSA[1])
  assert patheq(path_hp.get_connecting_link(path.rev(OPHS[0]), OPHS[2]), LKSA[4])
  
  assert patheq(path_hp.get_connecting_link(path.rev(OPHS[1]), OPHS[0]), path.rev(LKSA[0]))
  assert patheq(path_hp.get_connecting_link(path.rev(OPHS[2]), OPHS[1]), path.rev(LKSA[1]))
  assert patheq(path_hp.get_connecting_link(path.rev(OPHS[2]), OPHS[0]), path.rev(LKSA[4]))
  
  assert patheq(path_hp.get_connecting_link(OPHS[0], path.rev(OPHS[1])), LKSB[0])
  assert patheq(path_hp.get_connecting_link(OPHS[1], path.rev(OPHS[2])), LKSB[1])
  assert patheq(path_hp.get_connecting_link(OPHS[0], path.rev(OPHS[2])), LKSB[4])
                                                               
  assert patheq(path_hp.get_connecting_link(OPHS[1], path.rev(OPHS[0])), path.rev(LKSB[0]))
  assert patheq(path_hp.get_connecting_link(OPHS[2], path.rev(OPHS[1])), path.rev(LKSB[1]))
  assert patheq(path_hp.get_connecting_link(OPHS[2], path.rev(OPHS[0])), path.rev(LKSB[4]))
  
  return 
  # ----------------------------------------------------------------------

test_groups()
test_links()
test_contacts()
test_blocks()
