#! /usr/bin/python3
# Test program for module {hacks}
# Last edited on 2021-02-13 23:52:58 by jstolfi

import hacks
import rn
import pyx
import sys
from math import sqrt, sin, cos, floor, ceil, inf, nan, pi

def test_adjust_dash_pattern():
  sys.stderr.write("--- testing {adjust_dash_pattern} ------------------\n")
  rlen = 0.3
  rgap = 0.2
  sys.stderr.write("ideal ratios: rlen = %.6f rgap = %.6f\n" % (rlen, rgap))
  D1 = tuple( 0.1*k for k in range(11) )
  D2 = tuple( 10+0.1*k for k in range(31) )
  for rdist in D1 + D2:
    dashed, dashpat = hacks.adjust_dash_pattern(rdist, rlen, rgap)
    sys.stderr.write("rdist = %.6f" % rdist)
    if dashed:
      assert type(dashpat) is list or type(dashpat) is tuple
      assert len(dashpat) == 2
      rlen1, rgap1 = dashpat
      sys.stderr.write(" dashed [ %.6f, %.6f]" % (rlen1, rgap1))
      n = int(floor((rdist-rlen1)/(rlen1+rgap1) + 0.5)) # Number of gaps.
      rdist1 = n*(rlen1+rgap1) + rlen1
      sys.stderr.write(" n = %d rdist1 = %.6f\n" % (n, rdist1))
      assert abs(rdist - rdist1) < 1.0e-8*rdist
    else:
      assert dashpat == None
      sys.stderr.write(" solid\n")
  return
  # ----------------------------------------------------------------------
  
def test_pyx_plot():
  sys.stderr.write("--- testing {pyx,plot_line,plot_box,plot_frame,plot_grid} ------------------\n")
  c = pyx.canvas.canvas()
  tan = pyx.color.rgb(0.800, 0.700, 0.600)
  glo = pyx.color.rgb(0.400, 0.900, 1.000)
  dp = (3,1)
  # Testing {pyx} line plotting:
  nwd = 5 # Number of line widths including negative and zero,
  wdmax = 0.10 # Max line width.
  Xlen = 1.5 # Length of lines.
  Ytot = 1.5 # Space for the lines.
  Xstep = Xlen + 1.5     # Disp between solid and dashed.
  Ystep = Ytot/(nwd-1) # Disp between different widths.
  Y = dp[1] + 1.25
  for kwd in range(nwd):
    X = dp[0] + 1.25
    for dashed in (False,True):
      wd = wdmax*(kwd-1)/(nwd-1)
      if wd > 0 or (not dashed):
        clr = pyx.color.rgb.blue
        p = ( X, Y )
        q = ( X + Xlen, Y )
        sty = [
          pyx.style.linecap.round,
          pyx.style.linejoin.round,
        ]  
        sty = sty + [ pyx.style.linewidth(wd), clr ]
        if dashed: sty = sty + [ pyx.style.linestyle(pyx.style.linecap.round, pyx.style.dash([2])) ]
        c.stroke(pyx.path.line(p[0], p[1], q[0], q[1]), sty)
      X += Xstep
    Y += Ystep

  szx = 1 + ceil(Xstep + Xlen) + 1
  szy = 1 + ceil(Ytot) + 1

  # Testing {Plot_line}:
  p = rn.add(dp, (3,1)); q = rn.add(dp, (4,3))
  clr = pyx.color.rgb.red; wd = 0.20
  hacks.plot_line(c, clr, wd, p, q)
  
  # Testing {plot_box}:
  B = (rn.add(dp, (3.1,1.8)), rn.add(dp, (3.9,2.2)))
  clr = pyx.color.rgb.green
  hacks.plot_box(c, clr, B)

  # Testing {plot.grid}:
  hacks.plot_grid(c, tan, 0.01, dp, szx,szy, -0.50, 0.50,0.20)
  hacks.plot_grid(c, glo, 0.03, dp, szx,szy, -0.35, 1.00,1.00)

  # Testing {plot.frame}:
  hacks.plot_frame(c, pyx.color.rgb.red,   0.06, dp, szx,szy, +0.20)
  hacks.plot_frame(c, pyx.color.rgb.black, 0.02, dp, szx,szy, 00.00)
  hacks.plot_frame(c, pyx.color.rgb.blue,  0.06, dp, szx,szy, -0.20)
  hacks.write_plot(c, "tests/out/hacks_TST_plot")

def test_quatratic_roots():
  sys.stderr.write("--- testing {real_quadratic_roots} ------------------\n")

  n = 5
  for iA in range(2*n+1):
    for iB in range(2*n+1):
      for iC in range(2*n+1):
        A = (iA-n)/n
        B = (iB-n)/n
        C = (iC-n)/n
        if (A != 0):
          t0, t1 = hacks.real_quadratic_roots(A, B, C)
          for t in t0, t1:
            if t != None:
              v = A*t*t + B*t + C
              if abs(v) > 1.0e-8:
                sys.stderr.write("** error? A = %10.7f B = %10.7f C = %10.7f" % (A, B, C))
                sys.stderr.write("  t = %21.15e v = %21.15e\n" % (t,v))
  return
  # ----------------------------------------------------------------------
  
sys.stderr.write("??? Needs more tests ???\n")

test_adjust_dash_pattern()
test_quatratic_roots()
test_pyx_plot()

