# lib.coffee

functions =

  draw_axis: (axis, svg) ->
  #
  # Draw a hive plot axis in the svg area.

    a_rad       = axis.angle * (Math.PI / 180.0)
    r_beg       = axis.r_beg
    r_end       = r_beg + axis.r_len

    [ height, width ] = [ svg.attr('height'), svg.attr('width') ]
    [ x_ctr,  y_ctr ] = [ height * 0.5,       width * 0.5       ]
    [ x_mul,  y_mul ] = [ Math.sin(a_rad),    Math.cos(a_rad)   ]

    axis.x_beg  = x_ctr + x_mul * r_beg
    axis.x_end  = x_ctr + x_mul * r_end
    axis.x_len  = axis.x_end - axis.x_beg
    axis.x_mul  = x_mul

    axis.y_beg  = y_ctr + y_mul * r_beg
    axis.y_end  = y_ctr + y_mul * r_end
    axis.y_len  = axis.y_end - axis.y_beg
    axis.y_mul  = y_mul

    a_func  = () -> "rotate(#{ -axis.angle } " +
                    "#{ axis.x_beg } #{ axis.y_beg })"

    axis_attrs =
      class:      'axis_rect'
      fill:       axis.color
      height:     axis.r_len
      transform:  a_func()
      stroke:     axis.color
      width:      2
      x:          axis.x_beg
      y:          axis.y_beg

    svg.append('rect')
      .call(set_attrs, axis_attrs)
      .append('title').text(axis.title)


  edge_dir: (axes, edge) ->
  #
  # Find the edge direction, given the axes hash and an edge

    edge_dir_h( axes[ edge[0] ].angle,
                axes[ edge[2] ].angle )


  edge_dir_h: (a_beg, a_end) ->
  #
  # Find the edge direction, given a pair (beginning, end) of angles.

    diff  = a_end - a_beg
    abs   = Math.abs(diff)
    tmp   = if diff < 0 then -1 else 1
    if abs < 180 then tmp else -tmp


  edge_path: (edge, axes, cp_off) ->
  #
  # Create an SVG path (between the relevant axes) for this edge.

    edge_dir    = edge[5]

    end_points  = (end_key) ->
    #
    # Calculate the edge's intersection and control points (ip, cp),
    # based on end_key.  cp is on the normal to the axis, near ip.

      if end_key == 'from' then [ dir, ndx ] = [  edge_dir, 0 ]
      else                      [ dir, ndx ] = [ -edge_dir, 2 ]

      name    = edge[ndx]
      start   = edge[ndx+1]
      axis    = axes[name]
      x_ip    = axis.x_beg + start * axis.x_len
      y_ip    = axis.y_beg + start * axis.y_len
      x_off   = cp_off * axis.y_mul
      y_off   = cp_off * axis.x_mul
      x_cp    = x_ip + x_off * dir
      y_cp    = y_ip - y_off * dir
      [ [ x_ip, y_ip ], [ x_cp, y_cp ] ]

    from  = end_points('from')
    to    = end_points('to').reverse()
    out   = from.concat(to)


  set_attrs: (object, hash) ->
  #
  # Set an object's attributes, based on a hash.

    object.attr(key, val) for key, val of hash


# Make functions global.

window[key] = val for key, val of functions
