
# Canvas
snit::type canvas {
    typevariable itemtypes "line rectangle"
    typevariable opts.line {-fill strokeStyle -width lineWidth}
    typevariable opts.rectangle {-fill fillStyle -width lineWidth -outline strokeStyle}
    _wtkwidget
    _wtkoption -width 100 {$JS.width=$V;$JS.style.width='${V}px';}
    _wtkoption -height 100 {$JS.height=$V;$JS.style.height='${V}px';}
    _wtkoption -background "#ffffff" {$JS.style.background='$V';}

    variable mousedown 0
    variable nextid 1
    variable items
    method _createjs {} {return "wtk.createCanvas('[$self id]');"}
    method create {itemtype args} {
        if {$itemtype ni $itemtypes} {error "bad item type"}
        lassign [_parseCoordsAndOptions $args [set opts.$itemtype]] coords opts
        set cid $nextid; incr nextid
        set items($cid) [list type $itemtype coords $coords]
        wtk::toclient "wtk.objs\['[$self id]'\].createItem($cid,'$itemtype',\[[join $coords ,]\],$opts);"
        return $cid
    }
    method _event {which args} {; # todo - make generic
        if {$which=="mousedown"} {set mousedown 1; set subs [list %x [lindex $args 0] %y [lindex $args 1]]; $W _fireevent "<1>" $subs; if {[lindex $args 3]!=""} {$self _fireevent [lindex $args 3] "<1>" $subs}}
        if {$which=="mousemove"} {if {$mousedown} {set ev "<B1-Motion>"} else {set ev "<Motion>"}; $W _fireevent $ev [list %x [lindex $args 0] %y [lindex $args 1]]}
        if {$which=="mouseup"} {set mousedown 0; $W _fireevent "<B1-Release>" [list %x [lindex $args 0] %y [lindex $args 1]]}
    }
    proc _parseCoordsAndOptions {s optmap} {
        set coords ""; set inopts 0; set opts ""
        foreach {x y} [split $s] {
            if {!$inopts && [string is integer $x]} {
                if {![string is integer $y]} {error "odd number of coordinates"}
                lappend coords $x $y
            } else {
                set inopts 1
                if {![dict exists $optmap $x]} {error "bad option"}
                lappend opts "[dict get $optmap $x]:\"$y\""
            }
        }
        return [list $coords "\{[join $opts ,]\}"]
    }

    variable bindings
    method bind {id ev script} {set bindings(${id},$ev) $script}
    method _fireevent {id ev subs} {if {[info exists bindings(${id},$ev)]} {uplevel #0 [string map $subs $bindings(${id},$ev)]}}
}

