\ togglebutton

needs core-ext
needs struct
needs case
needs events
needs ids
needs forms
needs drawbitmapresource
\ needs rectangletype
needs click
needs gadgetutil

decimal

\ don't change these, they're used
\ in a select/xt below
0 constant tglstoff
1 constant tglston
2 constant tglstoffpending
3 constant tglstonpending
4 constant tglstoffcancel
5 constant tglstoncancel

struct
    1 cells field tgl.state
    1 cells field tgl.xtsetreset
    1 cells field tgl.gadget-id
    1 cells field tgl.onbmp-id
    1 cells field tgl.offbmp-id
    1 cells field tgl.midbmp-id
end-struct Toggle:

0 value tgl

: gadget-index@  ( -- gadgetindex )
    tgl tgl.gadget-id @ ( gadgetID )
    GetObjectIndex  ;

: draw-state  ( bitmpID -- )
    gadget-index@
    draw-gadget ;

: draw-midstate  ( -- ) 
    tgl tgl.midbmp-id @ draw-state ;

: draw-onstate  ( -- ) 
    tgl tgl.onbmp-id @ draw-state ;

: draw-offstate  ( -- ) 
    tgl tgl.offbmp-id @ draw-state ;

: in-tglgadget?  ( gadget-id -- flag )
    gadget-index@
    in-gadget? ;

: do-tglstate-offcancel
    ( event -- )
    case
    penUpEvent of
        tglston
        tgl tgl.state !
        draw-onstate
    endof
    penMoveEvent of
        in-tglgadget? if
            tglstoffpending
            tgl tgl.state !
           draw-midstate
        then
    endof
    endcase ;

: do-tglstate-offpending
    ( event -- )
    case
    penUpEvent of
        tglstoff
        tgl tgl.state !
        draw-offstate
        \ notify that switch is off
        0 tgl tgl.xtsetreset @ execute
        click
    endof
    penMoveEvent of
        in-tglgadget? 0= if
            tglstoffcancel
            tgl tgl.state !
            draw-onstate
        then
   endof
    endcase ;

: do-tglstate-on
    ( event -- )
    penDownEvent =  
    in-tglgadget? and
    if
        tglstoffpending
        tgl tgl.state !
        draw-midstate
    then ;

: do-tglstate-oncancel
    ( event -- )
    case
    penUpEvent of
        tglstoff
        tgl tgl.state !
        draw-offstate
    endof
    penMoveEvent of
        in-tglgadget? if
            tglstonpending
            tgl tgl.state !
           draw-midstate
        then
    endof
    endcase ;

: do-tglstate-onpending
    ( event -- )
    case
    penUpEvent of
        tglston
        tgl tgl.state !
        draw-onstate
        \ notify that switch is on
        -1 tgl tgl.xtsetreset @ execute 
        click 
    endof
    penMoveEvent of
        in-tglgadget? 0= if
            tglstoncancel
            tgl tgl.state !
            draw-offstate
        then
    endof
    endcase ;

: do-tglstate-off
    ( event -- )
    penDownEvent =   
    in-tglgadget? and
    if
        tglstonpending
        tgl tgl.state !
        draw-midstate
    then ;

: do-toggle-event
    ( event tglobj -- )
    to tgl        ( event )
    tgl tgl.state @  select
        xt do-tglstate-off
        xt do-tglstate-on
        xt do-tglstate-offpending
        xt do-tglstate-onpending
        xt do-tglstate-offcancel
        xt do-tglstate-oncancel
    end-select  execute ;

: init-toggle  
    ( state-flag xtsetreset tglobj -- )
    to tgl
    tgl tgl.xtsetreset !   ( state-flag )
    if
        tglston
        tgl tgl.state !
        draw-onstate
    else
        tglstoff
        tgl tgl.state !
        draw-offstate
    then ;
    


