
package require BWidget
package require unique
package provide comancheTree

class comancheTree {
    variable view
    variable tree
    variable default 
    variable mapping
    constructor { frame observerView} {
	array set default { -openImage openFolder.gif \
		-closedImage closedFolder.gif \
		-text "default text"\
		-type container }
	set scwindow [ScrolledWindow $frame.scwindow]  
	set tree  [Tree $scwindow.tree \
		-deltay 22\
		-bg white\
		-showlines true\
		-deltax 14\
		-opencmd "$this _openNode"\
		]
	pack $tree -fill both -expand true
	$scwindow setwidget $tree
	pack $scwindow -fill both -expand true
	set view $observerView
	$tree bindText <ButtonPress-1> \
		"$this _selectNode"
	$tree bindText <ButtonPress-3>  \
		"$this _rightClick"
	$tree bindImage <ButtonPress-1> \
		"$this _toggleNode"
	$tree  bindText <Double-ButtonPress-1> \
		"$this _toggleNode"
	set mapping(root,-type) container
    }
    method setView {newView} { set view $newView }
    
    method addNode { parentNodeId nodeId args }
    method deleteNode { nodeId }
    method configureNode { nodeId args }
    
    method getSelectedNode
    method getParentNode
    method selectNode
    
    method _selectNode
    method _toggleNode
    method _openNode
    method _closeNode
    method _populateNode
    method _rightClick
}

body comancheTree::_rightClick { node } {
    _selectNode $node
    $view showMenuRequest $node
}

body comancheTree::getSelectedNode {} {
    return [$tree selection get]
}

body comancheTree::getParentNode { nodeId } {
    return [$tree parent $nodeId]
}


body comancheTree::addNode { parentNodeId nodeId args} {
    if ![string compare $mapping($parentNodeId,-type) leaf] {
	error "Trying to add a node to a leaf node ($parentNodeId)"
    }  else {
	array set options [array get default]
	if [catch [list array set options $args] ] {
	    error "Wrong arguments $args"
	} else {
	    foreach attr [array names options] {
		set mapping($nodeId,$attr) $options($attr)
	    }
	    set mapping($nodeId,-virgin) 1
	    set mapping($parentNodeId,-virgin) 0
	    $tree insert end $parentNodeId $nodeId\
		    -text $options(-text)\
		    -image $options(-closedImage)\
		    -drawcross allways\
		    -data {}           
	    if ![string compare $options(-type) leaf] {
		set mapping($nodeId,-virgin) 0
		$tree itemconfigure $nodeId -drawcross never
	    }
	}
    }
    return $nodeId
}

body comancheTree::deleteNode { nodeId } {
    $tree delete $nodeId
}

body comancheTree::configureNode { nodeId args} {
    array set options [array get default]
    if [catch [list array set options $args] ] {
	error "Wrong arguments $args"
    } elsqe {
	foreach attr [array names options] {
	    set mapping($nodeId,$attr) $options($attr)
	}
	if [$tree itemcget $nodeId -open] {
	    set img $options(-openImage)
	} else {
	    set img $options(-closedImage)
	}   
	$tree itemconfigure $nodeId\
		-text $options(-text)\
		-image $img \
	    }
    return $nodeId
}

body comancheTree::_selectNode { nodeId } {
    $tree selection set $nodeId
    _populateNode $nodeId
    $view nodeSelectedNotify $nodeId 
}

body comancheTree::selectNode { nodeId } {
    _openNode [$tree parent $nodeId]
    _selectNode $nodeId
    $tree see $nodeId
}

body comancheTree::_toggleNode { nodeId } {
    if [$tree itemcget $nodeId -open] {
	$this _closeNode $nodeId
    } else {
	$this _openNode $nodeId
    }   
}

body comancheTree::_openNode { nodeId } {
    if [string match $nodeId root] {
        return
    }
    $this _populateNode $nodeId
    $tree itemconfigure $nodeId -image $mapping($nodeId,-openImage) \
	    -open 1
}

body comancheTree::_closeNode { nodeId } {
    $tree itemconfigure $nodeId -image $mapping($nodeId,-closedImage) \
	    -open 0        
}

body comancheTree::_populateNode { nodeId } {
    if $mapping($nodeId,-virgin)  {
	$view populateRequestNotify $nodeId
	set mapping($nodeId,-virgin) 0
	$tree itemconfigure $nodeId -image $mapping($nodeId,-closedImage) \
		-drawcross auto
    }
}

