# Miscellaneous utility functions for the HotPath software.
# Last edited on 2021-03-11 12:18:32 by jstolfi

import color
import hacks_IMP
import pyx

# MATH HACKS:

def real_quadratic_roots(A, B, C):
  # Returns the roots {t0} and {t1} of the equation {A t^2 + B t + C =
  # 0}, with {t0 < t1}, if they are real and distinct. Otherwise returns
  # {None,None}. Requires {A != 0}. May return {-inf,+inf}.
  return hacks_IMP.real_quadratic_roots(A, B, C)

# GEOMETRIC HACKS

def is_point(p):
  # Returns {True} if {p} is a pair (2-tuple or 2-list) of floats,
  # {False} otherwise.
  return hacks_IMP.is_point(p)

# PLOTTING HACKS

def round_box(B, mrg):
  # Returns the given {box} rounded outwards to edges with integer
  # coordinates, at least {mrg} away from the original ones.
  return hacks_IMP.round_box(B, mrg)
  
def plot_line(c, clr, wd, p, q):
  # Plots on the {pyx} context {c} a line with color {crl} and width {wd} from {p} to {q}.
  hacks_IMP.plot_line(c, clr, wd, p, q)

def plot_box(c, clr, dp, B):
  # Plots on the {pyx} context {c} the box {B} displaced by the vector {dp} 
  # with color {clr}.  
  #
  # If {clr} is {None}, it defaults to black. If {dp} is {None}, it
  # defaults to {(0,0)}.
  hacks_IMP.plot_box(c, clr, dp, B)
  
def plot_frame(c, clr, wd, dp, B, mrg):
  # Plots on the {pyx} context {c} a frame around the box {B}, displaced by the vector {dp},
  # with color {clr} and line width {wd}.
  #
  # If {mrg} is not {None} the frame will be displaced outwards by {mrg}
  # (or inwards by {-mrg}, if negative). If {clr} is None, defaults to
  # black. If {dp} is {None}, it defaults to {(0,0)}.
  hacks_IMP.plot_frame(c, clr, wd, dp, B, mrg)

def plot_grid(c, clr, wd, dp, B, mrg, xstep, ystep):
  # Plots on the {pyx} context {c} a grid spanning the box {B}, 
  # inset by {mrg}.  The gid lines will be at coordinates that are integer
  # multiples of {xstep} and {ystep}.  If {dp} is not {None}, the whole 
  # grid will be displaced by {dp}.
  #
  # If {mrg} is not {None} the edge of the grid will be displaced
  # outwards by {mrg} (or inwards by {-mrg}, if negative). If {clr} is
  # None, defaults to a light gray.
  hacks_IMP.plot_grid(c, clr, wd, dp, B, mrg, xstep, ystep)
  
def write_plot(c, name):
  # Writes the {pyx} canvas {c} to an EPS file "{name}.eps" 
  # and a JPEG file "{name}.jpg".
  hacks_IMP.write_plot(c, name)

def adjust_dash_pattern(rdist, rlen, rgap):
  # Computes a dash pattern so that a dashed line will begin and end
  # with full dashes.
  #
  # The parameter {rdist} should be the distance to be traced divided by
  # the line width. The ideal dash pattern should have dashes of length
  # {rlen} separated bt gaps of lenth {rgap} both relative to the line
  # width.
  #
  # If the procedure succeeds, it returns {True, [a*rlen, a*rgap]} where
  # {a} is a suitable adjustment factor, near 1.
  #
  # The procedure fails if the distance {rdist} is too small to use a
  # dashed line. In that case it returns {False, None}.
  #
  # ??? Generalize to begin and end with dashes of relative length {rend*rlen} ???
  return hacks_IMP.adjust_dash_pattern(rdist, rlen, rgap)

def trace_colors(nc):
  # Returns an array {C} of {nc} colors that can be used to paint different paths, etc.
  # Each element is a {pyx.color.rgb} triple.  Color {C[nc-1-k}} is complementary 
  # to {C[k]}.
  return hacks_IMP.trace_colors(nc)

# IMAGE HACKS

def convert_eps_to_png(name):
  # Reads the file "{name}.eps" and converts it to a PNG image file "{name}.png".
  hacks_IMP.convert_eps_to_png(name)

def convert_eps_to_jpg(name):
  # Reads the file "{name}.eps" and converts it to a JPEG image file "{name}.jpg".
  hacks_IMP.convert_eps_to_jpg(name)

