# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# Source-Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
#####################################################
##
## Class hierarchy that can be integrated in any subwindow.
##
#####################################################
itcl_class ClassTree& {
	constructor {{config ""}} {
		global sn_options
		
		set class [$this info class]
		@@rename $this $this-tmp-
		@@frame $this -class $class
		set bg [$this cget -background]
		@@rename $this $this-win-
		@@rename $this-tmp- $this
		
		set can $this.can
		set topw [winfo toplevel $this]
		
		#set default layout and order for classtree
		global $this-layoutstyle
		global $this-order
		@@set $this-order $sn_options(def,ctree-view-order)
		@@set $this-layoutstyle $sn_options(def,ctree-layout)
		
		canvas $can -borderwidth 2\
			-xscrollcommand "$this.scrollx set"\
			-yscrollcommand "$this.scrolly set"\
			-xscrollincrement 20\
			-yscrollincrement 20

		scrollbar $this.scrollx -orient horiz -command "$can xview"\
			-jump $sn_options(def,canvas-tree-jump)

		scrollbar $this.scrolly -command "$can yview"\
			-jump $sn_options(def,canvas-tree-jump)

		pack $this.scrollx -side bottom -fill x
		pack $this.scrolly -side right -fill y
		pack $can -side top -fill both -expand y
		
		$can bind cl <1> "$this mark_class"
		$can bind cl <Control-1> "watch y $topw; $this Focus_On current 0; watch n $topw"
		$can bind cl <Shift-1>   "watch y $topw; $this Focus_On current 0; watch n $topw"
		$can bind cl <Double-1>  "watch y $topw
								  $this edit_it \[%W itemcget current -text\]
								  watch n $topw"

		#display filenames with the classes
		global $this-disp-files
		@@set $this-disp-files $display_filenames
		
		#Add menu entries for the class hierarchy
		if {$menu != "" && [winfo exists $menu]} {
			set ctree $menu
			$ctree add command -label [get_indep String MultiHierDef] \
				-underline [get_indep Pos MultiHierDef] \
				-command "watch y $topw; $this Focus_On; watch n $topw" \
				-state disabled
			$ctree add command -label [get_indep String MultiHierRel] \
				-underline [get_indep Pos MultiHierRel] \
				-command "watch y $topw; $this Focus_On \[$can select item\] 0; watch n $topw" \
				-state disabled
			$ctree add command -label [get_indep String MultiHierAll] \
				-underline [get_indep Pos MultiHierAll] \
				-command "watch y $topw; $this DrawAll; watch n $topw" \
				-state disabled
				
			$ctree add separator
			$ctree add checkbutton \
					-label [get_indep String HierDispFiles] \
					-underline [get_indep Pos HierDispFiles] \
					-variable $this-disp-files \
					-command "$this toggle_disp_files"
		}

		#view icons on the toolbar
		if {$toolbar != ""} {
			set exp $toolbar.ctreefr
			pack [frame $exp] -side left
			button $exp.tree -image tree_image \
				-takefocus 0 \
				-command " " \
				-state normal
			@@bind $exp.tree <Any-ButtonPress> \
				"if {%b == 1} {
					watch y $topw; $this DrawAll;watch n $topw
				}"
			balloon_bind_info $exp.tree [get_indep String MultiHierAllINFO]
	
			button $exp.deftree -image stree_image\
				-takefocus 0 \
				-command " "\
				-state disabled
			@@bind $exp.deftree <Any-ButtonPress> \
				"if {%b == 1} {
					watch y $topw; $this Focus_On; watch n $topw
				}"
			balloon_bind_info $exp.deftree [get_indep String MultiHierDefINFO]
	
			button $exp.down -image down_image\
				-takefocus 0 \
				-command " "\
				-state disabled
			@@bind $exp.down <Any-ButtonPress> \
				"if {%b == 1} {
					watch y $topw; $this Focus_On \[$can select item\] 0; watch n $topw
				}"
			balloon_bind_info $exp.down [get_indep String MultiHierRelINFO]
			
			pack $exp.tree -side left
			pack $exp.deftree -side left
			pack $exp.down -side left
		}

		#Option menu for Class Tree items
		menu $can.menu \
				-tearoff 0 \
				-background $bg \
				-postcommand "$this update_post_menu $can.menu"
		wm overrideredirect $can.menu 1

		#See super- and baseclasses
		$can.menu add command \
				-label [get_indep String MultiHierDef]\
				-underline [get_indep Pos MultiHierDef]\
				-command "watch y $topw; $this Focus_On; watch n $topw" \
				-state disabled

		#See superclasses
		$can.menu add command \
				-label [get_indep String MultiHierRel]\
				-underline [get_indep Pos MultiHierRel]\
				-command "watch y $topw; $this Focus_On \[$can select item\] 0; watch n $topw" \
				-state disabled
		$can.menu add separator
		$can.menu add checkbutton \
				-label [get_indep String HierDispFiles] \
				-underline [get_indep Pos HierDispFiles] \
				-variable $this-disp-files \
				-command "$this toggle_disp_files"
		$can.menu add separator

		#bind option menu
		$can bind cl <ButtonPress-3> \
			"$this mark_class; tk_popup $can.menu %X %Y"
		
		#init some variables
		FillValues
		
		Update_Layout

		#as first step load all availiable classes and build the
		#hierarchy
		if {[@@info commands paf_db_cl] == ""} {
			reset
		}

		#is a class selected?
		goto "" $classname
		
		#call user defined procedure
		catch {sn_rc_classhierarchy $this $can}
	}
	destructor {
		# If this is the last object, reset the common variables.
		if {[string compare [itcl_info objects "*" -class [info class]] $this] == 0} {
			reset
		}
		foreach v [@@info globals "$this-*"] {
			catch {uplevel #0 unset $v}
		}
	}
	method config {config} {
	}
	
	method update_post_menu {m} {
		#set clname [$can itemcget current -text]
		set clname [currentclass current]
		
		set state normal
		$m entryconfig [get_indep String MultiHierDef] -state $state
		$m entryconfig [get_indep String MultiHierRel] -state $state
		
		set num [$m index end]
		if {$num >= 5} {
			$m delete 5 end
		}
		
		#set vw "[get_indep String View] "
		set vw ""
		
		set lbl " [get_indep String Of] '$clname'"
		#Editor
		$m add command \
				-label "$vw[get_indep String MultiEditor]$lbl" \
				-underline [get_indep Pos MultiEditor]\
				-command "watch y $topw; $this edit_it $clname; watch n $topw" \
				-state normal
						  
		#Class
		$m add command \
				-label "$vw[get_indep String MultiClass]$lbl" \
				-underline [get_indep Pos MultiClass]\
				-command "watch y $topw; sn_classbrowser $clname; watch n $topw" \
				-state normal
				
		#Xref
		$m add command \
				-label "$vw[get_indep String MultiXRef]$lbl" \
				-underline [get_indep Pos MultiXRef]\
				-command "sn_xref both ${clname}(cl)" \
				-state normal
	}
	
	method print {} {
		global sn_options tcl_platform

		if {$tcl_platform(platform)=="windows"} {

			ide_print_canvas $can
		} else {
			if {$print_dialog == "" || [itcl_info objects $print_dialog] == ""} {
				set print_dialog [PrintDialog& #auto -canvas $can\
					-leader $topw\
					-file [file join $sn_options(profile_dir) tree.ps]]
			} else {
				$print_dialog raise
			}
		}
	}

	#returns a list of all classes that inherit the specified
	#class
	proc parent_inh {cls} {
		global sn_sep
		if {! [info exists parent_classes($cls)]} {
			if {[@@info commands paf_db_in] != ""} {
				set parent_classes($cls) \
						[@@lunique [@@lsort \
						  -dictionary [paf_db_in seq -data -col 1 "$cls$sn_sep"]]]
			} else {
				set parent_classes($cls) ""
			}
		}
		return $parent_classes($cls)
	}

	method get_parent {id} {
		set found 0
		set CanDraw($id) 1
		set prnts ""
		foreach a [parent_inh $id] {
			set found 1
			#set CanDraw($a) 1
			if {! [get_parent $a]} {
				lappend tag_level $a
			}
		}
		return $found
	}

	method Draw_Classes {rot {all 0} {base ""}} {
		global sn_options
		upvar #0 $can-SupNum SupNum
		upvar #0 $can-BasNum BasNum
	
		if {[info exists class_drawn($rot)]} {
			if {$base != ""} {
				if {![info exists SupNum($base)]} {
					set SupNum($base) 1
				} else {
					incr SupNum($base)
				}
				if {![info exists BasNum($rot)]} {
					set BasNum($rot) 1
				} else {
					incr BasNum($rot)
				}
			}
			return
		}
		
		foreach entry [all_inheritences $rot] {
			if {$rot != $entry} {
				Draw_Classes $entry $all $rot
			}
		}

		if {$all || ![info exists CanDraw] || [info exists CanDraw($rot)] && $CanDraw($rot)} {
			set class_drawn($rot) 1

			if {$base != ""} {
				if {![info exists SupNum($base)]} {
					set SupNum($base) 1
				} else {
					incr SupNum($base)
				}
				if {![info exists BasNum($rot)]} {
					set BasNum($rot) 1
				} else {
					incr BasNum($rot)
				}
			}
			if {[is_abstract $rot]} {
				set fnt $sn_options(def,abstract-font)
			} else {
				set fnt $sn_options(def,ctree-font)
			}
			if {$display_filenames} {
				set cnt [read_matched_from_db "" \
					cl \
					-exact \
					$rot \
					"" \
					"" \
					"" \
					-1 -1 0 \
					0]
				set file [lindex [split $cnt \t] 4]
				if {$file != ""} {
					set file "\n$file"
				}
				$can create text -1000 -1000 \
					-text $rot$file \
					-tags [list $rot cl]\
					-anchor nw -font $fnt
			} else {
				$can create text -1000 -1000 \
					-text $rot \
					-tags [list $rot cl]\
					-anchor nw -font $fnt
			}
		}
	}

	method Draw_Links {} {
		global sn_options
		foreach cls [all_sorted_cls] {
			if {![info exists class_drawn($cls)]} {
				continue
			}
			foreach child [all_inheritences $cls] {
				if {[info exists class_drawn($child)]} {
					#refer itself, unended loop, catch it
					if { $child != $cls } {
						$can create edge -1m -1m -1m -1m\
							-tag [list ch:$child e:$child e:$cls]\
							-arrow last \
							-fill $sn_options(def,canv-line-fg) \
							-from $cls \
							-to $child
					}
				}
			}
		}
	}

	#invoked to view the super- or subclasses of a specified class
	method Focus_On {{tag ""} {lev -1}} {
		if {$tag == ""} {
			set id [$can select item]
			if {$id == ""} {
				return
			}
			#set tag [$can itemcget $id -text]
			set tag [currentclass $id]
		} elseif {$tag == "current"} {
			#set tag [$can itemcget $tag -text]
			set tag [currentclass $tag]
		}

		if {$tag == ""} {
			return
		}

		catch {unset CanDraw}
		
		if {$lev == -1} {
			set RelativClass $tag
			
			#get the first base class of the specified class
			#view super- and subcalsses
			set tag_level ""
			get_parent $tag
			
			if {$tag_level == ""} {
				set show_tags $tag
			} else {
				set show_tags $tag_level
			}
		} else {
			#make the specified class to be root (view subclasses)
			#set show_tags [$can itemcget $tag -text]
			set show_tags [currentclass $tag]
			set tag $show_tags
		}
		if {$show_tags != ""} {
			set base_root $show_tags
			Redraw
			see_item $tag
		}
	}

	method edit_it {name} {
		if {$name == ""} {
			return
		}
		if {$doubleclickcommand != ""} {
			@@eval $doubleclickcommand [Selection]
		}
	}

	method mark_class {{cname ""}} {
		global sn_options
		upvar #0 $can-marked_edges m_edges
		upvar #0 $can-SupNum SupNum
		upvar #0 $can-BasNum BasNum

		if {$cname == ""} {
			set id current
			#set cname [$can itemcget $id -text]
			set cname [currentclass $id]
		} else {
			set id [$can find withtag $cname]
		}

		if {$cname == "" && $mesg_area != ""} {
			uplevel #0 {set $mesg_area " "}
			return
		}
		catch {$can select from $id 0}
		catch {$can select to $id end}
		
		# If the selection is not owned by us we do not want the marking to disappear.
		selection own $can " "

		#unmark old selection.
		catch {$can itemconfig "e:$m_edges" -fill $sn_options(def,canv-line-fg)}
		@@set m_edges $cname

		$can itemconfig e:$cname -fill $sn_options(def,tree-select-line)
		$can raise e:$cname

		control_buttons normal

		#display number of super- and baseclasses of the marked class
		if {[info exists SupNum($cname)]} {
			set supnum $SupNum($cname)
		} else {
			set supnum 0
		}
		if {[info exists BasNum($cname)]} {
			set basnum $BasNum($cname)
		} else {
			set basnum 0
		}
		
		if {$mesg_area != ""} {
			if {[expr $basnum + $supnum] == 0} {
				uplevel #0 "set $mesg_area \" \""
			} else {
				uplevel #0 "set $mesg_area \"Baseclasses: $basnum, Superclasses: $supnum\""
			}
		}

		#execute assigned command, if availiable
		if {$selectcommand != ""} {
			watch y $topw
			@@eval $selectcommand [Selection]
			watch n $topw
		}
		
		if {$symbols != ""} {
			$symbols selecttext $cname
		}
		return [list $cname $id]
	}

	# This function assures that the item will be on the screen.
	method see_item {cname ""} {
		if {[string match {[0-9]*} $cname] == 0} {
			set opts [mark_class $cname]
			set cname [lindex $opts 0]
			set id [lindex $opts 1]
		} else {
			set id $cname
		}
		
		#selected class isn't drawn
		if {"$id" == "" || $id == -1} {
			return "error"
		}
		
		set coords [$can bbox $id]
		set x1 [$can canvasx 0]
		set x2 [$can canvasx [winfo width $can]]
		set y1 [$can canvasy 0]
		set y2 [$can canvasy [winfo height $can]]
		set enclosed [$can find enclosed $x1 $y1 $x2 $y2]
		# If the item is not fully on the screen, we scroll the canvas.
		if {[lsearch -exact $enclosed $id] == -1} {
			set scr_reg [lindex [$can configure -scrollregion] 4]

			if {$scr_reg == ""} {
				return ""
			}

			set wid [expr [lindex $scr_reg 2] - [lindex $scr_reg 0]]
			set hei [expr [lindex $scr_reg 3] - [lindex $scr_reg 1]]

			set xoff [expr double([winfo width $can]) / 3]
			set pos [expr double([lindex $coords 0] - $xoff) / $wid]
			if {$pos < 0.0} {
				set pos 0.0
			}
			$can xview moveto $pos

			set yoff [expr double([winfo height $can]) / 3]
			set pos [expr double([lindex $coords 1] - $yoff) / $hei]
			$can yview moveto $pos
		}
		return ""
	}

	method toggle_disp_files {} {
		upvar #0 $this-disp-files dispfiles
		set display_filenames $dispfiles
		Redraw
	}

	method DrawAll {} {
		set old_cls [lindex [Selection] 1]
		set base_root ""

		Redraw
		
		if {$old_cls != ""} {
			goto "" $old_cls
		} else {
			control_buttons disabled
		}
	}

	method Redraw {} {
		graph $can destroy
		$can delete all

		upvar #0 $can-SupNum SupNum
		upvar #0 $can-BasNum BasNum
		
		catch {unset class_drawn}
		catch {unset SupNum}
		catch {unset BasNum}

		#draw all classes
		if {$base_root == ""} {
			foreach entry [all_sorted_cls] {
				Draw_Classes $entry 1
			}
		#draw related classes
		} else {
			if {[info exists CanDraw]} {
				Draw_Classes $RelativClass 1
			}
			foreach entry $base_root {
				Draw_Classes $entry
			}
		}

		Draw_Links
		set_sorted_order
		graph_new_layout

		#to refill classes into combo box.
		set displayed 0
	}

	method values {} {
		return $base_root
	}

	method control_buttons {state} {
		if {$base_root == ""} {
			set allstate disabled
			set allrel sunken
		} else {
			set allstate normal
			set allrel raised
		}
		if {$menu != "" && [winfo exists $menu]} {
			$menu entryconfig [get_indep String MultiHierDef] -state $state
			$menu entryconfig [get_indep String MultiHierRel] -state $state
			$menu entryconfig [get_indep String MultiHierAll] -state $allstate
		}
		if {$toolbar != ""} {
			set exp $toolbar.ctreefr
			$exp.down config -state $state
			if {$state == "disabled"} {
				set relief "-relief raised"
			} else {
				set relief ""
			}
			$exp.deftree config -state $state
			$exp.tree config -state $allstate -relief $allrel
		}
	}

	method set_sorted_order {} {
		set items [$can find withtag all]
		if {$items != ""} {
			eval graph $can add $items
			return ""
		} else {
			return "error"
		}
	}

	method graph_new_layout {{redraw 1}} {
		global sn_options
		upvar #0 $this-order order
		upvar #0 $this-layoutstyle layout

		if {$redraw} {
			graph $can clear
			if {[set_sorted_order] != ""} {
				return
			}
		}

		if {$order == ""} {
			set order 0
		}
		set cmd [list graph $can config -gridlock 1 -order $order]
		if {$order == 0} {
			lappend cmd -nodespacev $sn_options(def,ctree-horizspace) \
						-nodespaceh $sn_options(def,ctree-vertspace)
		} else {
			lappend cmd -nodespacev $sn_options(def,ctree-vertspace) \
						-nodespaceh $sn_options(def,ctree-horizspace)
		}
		#execute graph command
		eval $cmd

		graph $can layout $layout

		set reg [$can bbox all]

		set wd [lindex $reg 2]
		set he [lindex $reg 3]
		$can configure -scrollregion [list 0 0 $wd $he]

		return [list $wd $he]
	}

	method Title {{full 1}} {
		global sn_options
		set t "[get_indep String ClassHierarchy]"
		if {$base_root != ""} {
			set t "$t: $base_root"
		}
		if {$full} {
			return [sn_title $t]
		} else {
			return $t
		}
	}
	method Icon {} {
		return [sn_view_icon [get_indep String ClassHierarchy] $base_root]
	}
	method SetTitle {} {
		wm title    $topw [Title]
		wm iconname $topw [Icon]
	}
	
	#fill combobox with the correct entries
	#Filter for symbols
	method filter {{all 0}} {
		upvar #0 $symbols_filter-related related
		if {$symbols != ""} {
			if {$related && $base_root != ""} {
				$symbols contents [array names class_drawn]
			} else {
				$symbols contents [all_sorted_cls]
			}
		}
	}
	
	#this function is called, when the symbols combobox
	#is called
	method postcommand {m} {
		if {! $displayed} {
			filter
			set displayed 1
		}
	}

	method activate {} {
		#display the contents always by activating
		set displayed 0
		
		if {$menu != "" && [winfo exists $menu]} {
			set mn [string range $menu 0 [expr [string last "." $menu] - 1]]
			$mn entryconfig [get_indep String MultiClassHierarchy] -state normal
		}
		if {$toolbar != ""} {
			pack $toolbar.ctreefr -side left
		}
		if {$symbols != ""} {
			$symbols enable
			#delete old contents
			$symbols contents ""
			$symbols selecttext $base_root
		}
	}
	
	method deactivate {} {
		if {$menu != "" && [winfo exists $menu]} {
			set mn [string range $menu 0 [expr [string last "." $menu] - 1]]
			$mn entryconfig [get_indep String MultiClassHierarchy]	-state disabled
		}
		if {$toolbar != ""} {
			pack forget $toolbar.ctreefr
		}
	}
	
	method gotosymbol {{scope ""} {sym ""} {cls ""} {file ""} {from ""} {type ""} {prm ""} {to ""} {always 1}} {
		if {$cls != ""} {
			return [goto "" $cls]
		}
		if {$sym != ""} {
			return [goto "" $sym]
		}
		return 0
	}
	
	method goto {combo class} {
		global sn_options sn_sep
		if {$class == ""} {
			return
		}
		
		#is the class availiable
		if {[@@info commands paf_db_cl] != ""}  {
			set avail [paf_db_cl seq -data -first -col 0 "$class$sn_sep"]
			if {$avail == ""} {
				return
			}
		} else {
			return
		}
			
		#dump the current view into the history stack
		$topw history_stack_add_point $this
		
		#class already displayed
		if {[see_item $class] == ""} {
			return
		}
		#draw the new class
		Focus_On $class
		
		if {$symbols != ""} {
			$symbols selecttext $class
		}
	}
	
	method currentclass {{id ""}} {
		if {$id == ""} {
			set id current
		}
		return [lindex [split [$can itemcget $id -text] \n] 0]
	}

	method Selection {} {
		set sel [$can itemcget [$can select item] -text]
		set sel [lindex [split $sel \n] 0]
		if {$sel != ""} {
			return [list cl $sel "" "" "" "" "" ""]
		}
		return ""
	}
	
	method clearselection {} {
		$can select clear
	}
	
	method Focus {} {
		focus $can
	}

	#make a title for the Dump position, this is usefull
	#for the views stack (prev/next)
	method DumpTitle {{dump ""}} {
		if {$dump == ""} {
			set dump [Dump]
		}
		return "CTree [lindex $dump 1]"
	}

	method AddHistoryFromDump {dump title} {
		set class [lindex $dump 1]
		sn_add_history ctree \
			$class \
			[sn_make_history_title tree "" $class] \
			sn_classtree
	}

	#return the important data to restore this widget
	#in later time again (used by saving the project)
	method Dump {} {
		return [Selection]
	}
	
	#gets the result from the function "Dump" to
	#restore the older state (used by restoring the project)
	method Restore {str} {
		eval $this gotosymbol $str
		#Focus
	}
	
	method Close {{mode 0}} {
		return 1
	}
	
	method Refresh_Display {} {
		global sn_options
		reset
		catch {unset sorted_classes}
	}
	
	method Update_Layout {} {
		global sn_options
		
		global $this-layoutstyle
		global $this-order
		
		#apply new colors to the canvas
		$can config \
			-selectforeground $sn_options(def,select-fg) \
			-selectbackground $sn_options(def,select-bg)
			
		@@set $this-layoutstyle $sn_options(def,ctree-layout)
		@@set $this-order $sn_options(def,ctree-view-order)
		
		graph_new_layout 1
	}
	
	method whoami {} {
		return ctree
	}
	method next {} {
		return $next
	}

	proc reset {} {
		catch {unset abstract_classes}
		catch {unset sorted_classes}
		catch {unset parent_classes}
	}

	proc is_abstract {cls} {
		global sn_sep
		#use cache to determine if the class has abstracts
		if {[info exists abstract_classes($cls)]} {
			return $abstract_classes($cls)
		}
		if {[@@info commands paf_db_md] != ""} {
			set virtuals [paf_db_md seq -first \
					-col [list 0 1 "5 :$virt_bit:$virt_bit"] \
					"$cls$sn_sep"]
			if {$virtuals == ""} {
				set virtuals [paf_db_md seq -first \
					-col [list 0 1 "5 :$purevirt_bit:$purevirt_bit"] \
					"$cls$sn_sep"]
			}
		} else {
			set virtuals ""
		}
		if {$virtuals != ""} {
			set abstract_classes($cls) 1
		} else {
			set abstract_classes($cls) 0
		}
		return $abstract_classes($cls)
	}
		
	proc all_sorted_cls {} {
		if {[info exists sorted_classes]} {
			return $sorted_classes
		}

		if {[@@info commands paf_db_cl] != ""} {
			set sorted_classes [@@lunique [@@lsort -dictionary \
				[paf_db_cl seq -uniq -data -col 0]]]
		} else {
			set sorted_classes ""
		}
		return $sorted_classes
	}

	#return a list of all inheritences of a class
	proc all_inheritences {cls} {
		if {[info exists inh_classes($cls)]} {
			return $inh_classes($cls)
		}
		if {[@@info commands paf_db_in] != ""} {
			set inh_classes($cls) \
					[@@lunique [@@lsort -dictionary \
						[paf_db_in seq -data -col [list 0 "1 +$cls"]]]]
		} else {
			set inh_classes($cls) ""
		}
		return $inh_classes($cls)
	}
	
	proc FillValues {} {
		global sn_options
		if {![info exists virt_bit]} {
			set virt_bit  [Class& @@ convert_sym_to_bit {virtual}]
			set purevirt_bit [Class& @@ convert_sym_to_bit {{pure virtual}}]
		}
	}

	#view the hierarchy of a specified class.
	#probably create a new window
	proc ClassHierarchy {{class ""}} {
		global tkeWinNumber
		set s [MultiWindow& @@ find_Reusable]
		if {$s == ""} {
			set new 1
			incr tkeWinNumber
			set s ".multiwindow-$tkeWinNumber"
			MultiWindow& $s -raise ctree
		} else {
			$s view ctree
		}
		[$s ActiveWidget] gotosymbol cl $class
	}

	protected print_dialog ""
	protected topw "."
	protected displayed 0
	protected CanDraw
	protected RelativClass ""
	protected class_drawn
	protected can ""
	protected list
	protected display_filenames 0
	
	common inh_classes
	common tag_level
	common abstract_classes
	common virt_bit
	common purevirt_bit
	common classes
	common sorted_classes
	common parent_classes
	
	public base_root ""
	#goto this class
	public classname "" {
		if {[winfo exists $can]} {
			goto "" $classname
		}
	}
	public width 640
	public height 480
	public symbols ""
	public symbols_filter ""
	public mesg_area ""
	public menu ""
	public toolbar ""
	public goto ""
	public selectcommand ""
	public doubleclickcommand ""
	
	#contains the next widget, when the window is spliten
	#into more than one area
	#Simulate a single chain
	public next ""
}

proc sn_classtree {{class ""}} {
	global Switch_Is_Enabled
	incr Switch_Is_Enabled -1
	
	ClassTree& @@ ClassHierarchy $class
	
	incr Switch_Is_Enabled
}


