AssertException = (message) ->
    @message = message
    @message

AssertException::toString = () ->
    'AssertException: ' + @message

assert = (exp, message) ->
    if not exp
        throw new AssertException(message)

konsole =
    log: (args) ->
    dir: (args) ->

if (typeof window.console != 'undefined' and typeof window.console.log == 'function')
    konsole = window.console


rad = (angle) -> (angle) * Math.PI / 180.0

norm_angle = (angle) ->
    angle = angle + TAU while angle < 0
    angle = angle - TAU while angle > TAU
    angle

pos = (angle, radius) ->
    x = Math.cos(angle).toFixed(15)
    y = Math.sin(angle).toFixed(15)
    {x: x * radius, y: y * radius, a: angle, r: radius}


PI = Math.PI
TAU = 2 * PI

class Arc

    constructor: (@canvas, @cx, @cy, @r1, @r2, ref_angle1, ref_angle2, init_dist = 2.5, stop_ease = 5) ->
        assert(ref_angle1 < ref_angle2, "Drawing in the wrong direction")
        @r_ang1 = rad(ref_angle1)
        @r_ang2 = rad(ref_angle2)
        @dist = rad(init_dist)
        @norm = rad(stop_ease)
        @ctx = @canvas.getContext('2d')

    intercept: (angle, dist) ->
        target_angle = angle + dist
        direc = if dist < 0 then -1 else 1

        tg_pos = pos(target_angle, @r1)
        rf_pos = pos(angle, @r1)

        d = (() ->
            xd = (tg_pos.x - rf_pos.x)
            yd = (tg_pos.y - rf_pos.y)
            Math.sqrt((xd * xd) + (yd * yd)))()
        nr = Math.asin(d / @r2)
        na = norm_angle(angle + (nr * direc))
        f_pos = pos(na, @r2)

        return {x: f_pos.x, y: f_pos.y, a: na, r: @r2}

    draw: () ->
        pos1 = pos(@r_ang1 + @dist, @r1)
        pos2 = pos(@r_ang2 - @dist, @r1)
        pos3 = @intercept(@r_ang1, @dist)
        pos4 = @intercept(@r_ang2, (-1 * @dist))

        # Draw the reference lines
        ((ctx) =>
            @ctx.lineWidth = 1.0
            @ctx.strokeStyle = 'darkorange'
            for p in [pos(@r_ang1, @r2), pos(@r_ang2, @r2)]
                @ctx.beginPath()
                @ctx.moveTo(@cx, @cy)
                @ctx.lineTo(@cx + p.x, @cy + p.y)
                @ctx.closePath()
                @ctx.stroke()
        )()

        @ctx.lineWidth = 4.0
        @ctx.strokeStyle = '#3b4449'

        @ctx.beginPath()
        @ctx.arc(@cx, @cy, @r1, pos1.a, pos2.a, false)
        @ctx.lineTo(pos4.x + @cx, pos4.y + @cy)
        @ctx.arc(@cx, @cy, @r2, pos4.a, pos3.a, true)
        @ctx.closePath()

        lingrad = @ctx.createLinearGradient(0, 0, 0, @r2 * 2)
        lingrad.addColorStop(1.0, '#526c7a')
        lingrad.addColorStop(0.0, '#64a0c1')
        @ctx.fillStyle = lingrad
        @ctx.stroke()
        @ctx.fill()

        # Intercept of line 3 and circle 1:


$ ->
    container = $('.canvas_demo')
    container.html('<canvas class="canvas_itself"></canvas>')
    canvas = $('canvas', container).get(0)
    canvas.width = container.width()
    canvas.height = container.height()
    ctx = canvas.getContext('2d')
    cd = (if canvas.width < canvas.height then canvas.width else canvas.height) / 2

    angle = 0
    slip = ->
        angle = angle + 1
        if angle < 360
            ctx.clearRect(0, 0, canvas.height, canvas.width)
            arc = new Arc(canvas, cd, cd, (cd * 0.85), (cd * 0.95), 0, angle)
            arc.draw()
            setTimeout(slip, 50);
    slip()


