-width = 500
-height = 500
-
-# globals
-$svg = null # jquery object for svg element
-svg = null # dom object for svg element
-$tool_options = null # jquery object for tool options line
-selection = []
-svg_ns = 'http://www.w3.org/2000/svg'
-cur_tool = null
-cur_tool_name = null
-mouse = x: 0, y: 0, buttons: [0,0,0]
-
-class EditableThing
- constructor: ->
- @el = null
- click_proximity: (x, y) ->
- return null
- clicked: ->
- update: ->
- destructor: ->
- if @el?
- svg.removeChild @el
- @el = null
-
-class PolyLine extends EditableThing
- constructor: (args) ->
- super args
- @drawing = args?.drawing ? false
- @el = document.createElementNS svg_ns, "path"
- svg.appendChild @el
- @points = args?.points ? []
- @update()
- update: (args) ->
- if args?.drawing?
- @drawing = args.drawing
- d = ''
- l = ''
- sep = 'M'
- for loc, i in @points
- d += l = "#{sep} #{loc[0]} #{loc[1]}"
- sep = ' L'
- if args?.to_mouse?
- d += l = "#{sep} #{args.mouse_x} #{args.mouse_y}"
- if args?.close # FIXME ?remove
- d += l = ' z'
- if @points.length > 0
- if l is " L #{@points[0][0]} #{@points[0][1]}"
- d = d.substr 0, d.length - l.length
- d += ' z'
- @el.setAttribute "d", d
- add_point: (x, y) ->
- @points.push [x, y]
- close_loop: ->
- if @points.length > 2
- @add_point @points[0][0], @points[0][1]
-
-class Tool
- constructor: (args) ->
- @button = args.button
- if @button?
- @button.addClass 'disabled'
- @tool_options = args.tool_options
- click: (x, y) ->
- mousemove: (x, y) ->
- keydown: (keycode) ->
- disable: ->
- if @button?
- @button.removeClass 'disabled'
- @tool_options.empty()
-
-class TutorialTool extends Tool
- constructor: (args) ->
- super args
- @paths = []
- choose = [
- [[219,34],[53,141],[96,143],[92,255],[365,257],[362,145],[407,144,'z']],
- [[161,118],[144,106],[130,115],[128,152],[140,160],[156,150]],
- [[173,107],[169,159],[180,137],[189,133],[193,160]],
- [[218,135],[205,144],[205,158],[215,164],[225,156],[225,144,'z']],
- [[242,135],[233,145],[233,157],[244,168],[256,158],[254,144,'z']],
- [[278,141],[269,135],[261,142],[264,151],[278,153],[281,162],[271,170],[264,163]],
- [[291,151],[305,151],[312,143],[299,135],[288,140],[293,160],[302,167],[313,158]],
- [[136,208],[121,206],[116,226],[128,233],[136,229],[137,209],[140,233]],
- [[160,207],[191,205]],
- [[176,184],[174,228],[180,238]],
- [[198,216],[187,223],[189,236],[200,242],[210,235],[209,224,'z']],
- [[227,216],[216,222],[216,236],[224,244],[237,240],[237,226,'z']],
- [[247,187],[249,241],[254,243]]
- ]
- for c in choose
- path = data: c, element: document.createElementNS svg_ns, "path"
- update_path path, close: c[c.length - 1][2] is 'z'
- svg.appendChild path.element
- @paths.push path
- @tip = $ "<span> </span>"
- @tool_options.append @tip
- disable: ->
- super()
- for p in @paths
- svg.removeChild p.element
-
-class DrawTool extends Tool
- constructor: (args) ->
- super args
- @tool_options.append $ "<span>Draw tool helpers:</span>"
- @stop_button = $ '<span class="button" title="keyboard shortcut: space">finish line</span>'
- @stop_close_button = $ '<span class="button" title="keyboard shortcut: O">close (loop)</span>'
- @cancel_button = $ '<span class="button" title="keyboard shortcut: Esc">cancel line</span>'
- @tool_options.append @stop_button
- @tool_options.append @stop_close_button
- @tool_options.append @cancel_button
- @stop_button.click @stop_drawing.bind @
- @stop_close_button.click @stop_close_drawing.bind @
- @cancel_button.click @cancel_drawing.bind @
- @update_helper_buttons()
- click: (x, y) ->
- if selection.length and not selection[0].drawing?
- selection = []
- unless selection.length
- selection.push new PolyLine drawing: true
- selection[0].add_point x, y
- selection[0].update()
- @update_helper_buttons()
- update_helper_buttons: ->
- if selection[0]?.drawing? and selection[0]?.points.length > 0
- @cancel_button.removeClass 'disabled'
- else
- @cancel_button.addClass 'disabled'
- if selection[0]?.drawing? and selection[0]?.points.length > 1
- @stop_button.removeClass 'disabled'
- else
- @stop_button.addClass 'disabled'
- if selection[0]?.drawing? and selection[0]?.points.length > 2
- @stop_close_button.removeClass 'disabled'
- else
- @stop_close_button.addClass 'disabled'
- cancel_drawing: ->
- if selection[0]?.drawing?
- selection[0].destructor()
- selection = []
- @update_helper_buttons()
- return false
- stop_drawing: ->
- if selection[0]?.drawing?
- if selection[0]?.points.length < 2
- return @cancel_drawing()
- if selection[0]?
- selection[0].update()
- selection = []
- @update_helper_buttons()
- return false
- stop_close_drawing: ->
- if selection[0]?.drawing?
- if selection[0]?.points.length < 3
- return @stop_drawing()
- selection[0].close_loop()
- selection[0].update drawing: false
- selection = []
- @update_helper_buttons()
- return false
- mousemove: (x, y) ->
- mouse.x = x
- mouse.y = y
- if selection[0]?.drawing?
- selection[0].update to_mouse: true, mouse_x: x, mouse_y: y
- keydown: (keycode) ->
- switch keycode
- when ('O'.charCodeAt 0), ('0'.charCodeAt 0)
- return @stop_close_drawing()
- when (' '.charCodeAt 0), 13, 10
- return @stop_drawing()
- when 27
- return @cancel_drawing()
- disable: ->
- super()
- @stop_drawing()
-
-class EditTool extends Tool
- constructor: (args) ->
- super args
- args.tool_options.append $ "<span>Oops, the edit tool isn't implemented yet</span>"
-
-class DeleteTool extends Tool
- constructor: (args) ->
- super args
- args.tool_options.append $ "<span>To delete: click on a line below</span>"
- click: (x, y) ->
- $svg.find('path:hover').remove()
- return false
-
-update_path = (path, flags) ->
- d = ''
- sep = 'M'
- for loc, i in path.data
- d += "#{sep} #{loc[0]} #{loc[1]}"
- sep = ' L'
- if flags?.to_mouse?
- d += "#{sep} #{mouse.x} #{mouse.y}"
- if flags?.close
- d += " z"
- path.element.setAttribute "d", d
-
-switch_to_tool = (tool_class) ->