# copyright (C) 1997-2001 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu

set rcsId {$Id: canvaswm.tcl,v 2.4 2000/12/31 23:14:19 jfontain Exp $}

class canvasWindowManager {

    proc canvasWindowManager {this canvas} {
        set ($this,canvas) $canvas
    }

    proc ~canvasWindowManager {this} {
        variable ${this}data

        foreach {name handle} [array get ${this}data handle,*] {
            delete $handle
        }
        catch {unset ${this}data}
    }

    proc manage {this path} {
        variable ${this}data

        set ${this}data(handle,$path) [new handles $($this,canvas) $this -path $path]
    }

    proc unmanage {this path} {
        variable ${this}data

        delete [set ${this}data(handle,$path)]
        unset ${this}data(handle,$path) ${this}data(relativeStackingLevel,$path)
    }

    proc configure {this path args} {
        variable ${this}data

        array set value $args
        if {![catch {string length $value(-level)} length]&&($length>0)} {
            # find out which managed widget to stack right below, if any. if none is found, widget defaults to top stack level
            set names [array names ${this}data relativeStackingLevel,*]
            if {[llength $names]>0} {                                                             ;# there are other managed widgets
                foreach name $names {                                                               ;# build path from level mapping
                    set pathFrom([set ${this}data($name)]) [lindex [split $name ,] end]
                }
                foreach level [lsort -integer [array names pathFrom]] {
                    if {$level>$value(-level)} {
                        handles::stackLower [set ${this}data(handle,$path)] [set ${this}data(handle,$pathFrom($level))]
                        break                                                            ;# found the handles for widget right above
                    }
                }
            }
            set ${this}data(relativeStackingLevel,$path) $value(-level)
        }
        catch {unset value(-level)}                                                        ;# handles do not handle the level option
        eval composite::configure [set ${this}data(handle,$path)] [array get value]
    }

    proc getGeometry {this path} {                                                        ;# return x, y, width and height as a list
        variable ${this}data

        return [handles::getGeometry [set ${this}data(handle,$path)]]
    }

    proc getStackLevel {this path} {                                                               ;# return relative stacking level
        variable ${this}data

        return [set ${this}data(relativeStackingLevel,$path)]
    }

    proc relativeStackingLevels {this} {                                  ;# return paths relative levels sorted in increasing order
        variable ${this}data

        set list {}
        foreach {name value} [array get ${this}data relativeStackingLevel,*] {
            lappend list $value
        }
        return [lsort -integer $list]
    }

    proc stacked {this path raised} {                           ;# parameter is a boolean: either raised to top or lowered to bottom
        variable ${this}data

        set levels [relativeStackingLevels $this]
        if {[llength $levels]==0} {                                                                ;# first widget to be positionned
            set ${this}data(relativeStackingLevel,$path) 0
        } elseif {$raised} {
            set ${this}data(relativeStackingLevel,$path) [expr {[lindex $levels end]+1}]          ;# place right above maximum level
        } else {
            set ${this}data(relativeStackingLevel,$path) [expr {[lindex $levels 0]-1}]            ;# place right below minimum level
        }
    }

    proc raisedOnTop {this path} {
        variable ${this}data

        return [expr {[set ${this}data(relativeStackingLevel,$path)]>=[lindex [relativeStackingLevels $this] end]}]
    }

}
