###############################################################
# guimenu.tcl - menu file for GUIs
# January 2006 Michael Barton, Arizona State University
# May 2006 Cedric Shock
# COPYRIGHT:	(C) 1999 - 2006 by the GRASS Development Team
#
#		This program is free software under the GNU General Public
#		License (>=v2). Read the file COPYING that comes with GRASS
#		for details.
###############################################################


# Before using this a script must:
# source lib/gtcltk/settings.tcl (gui.tcl does this)
# source lib/gtcltk/gmsg.tcl (gui.tcl does this)
# And must define all of these globally:

# execute        Run with a ui
# run_panel      Run a command with no ui.
# term           Run a command that needs a terminal
# spawn          Run a command in the background, don't wait for it to return
# guarantee_xmon Make sure there is an xmon available for the command

namespace eval GuiMenu {}

proc GuiMenu::tree {} {

	# Tear off menus (yes / no)
	global tmenu
	# Key to use for control (for menu accelerators)
	global keyctrl
	# The environment
	global env

	# Menus that can be injected in here
	set injected_menus {Menu_File_Top Menu_File_Bottom}
	foreach injected_menu $injected_menus {
		variable $injected_menu
		if {![info exists $injected_menu]} {
			set $injected_menu ""
		}
	}



	# if extensions dir exists: create an "Xtns" menu item
	# and read all menu descriptions from .gem files
	set dirName [set env(GISBASE)]/etc/gm/Xtns
	set XtnsMenu "False"
	set splitError "False"
	set XtnsMenuList ""

	if { [file exists $dirName] && [file isdirectory $dirName] } {	
		lappend listNames "Dummy"; # we need this to check for num of elements later
		foreach fileName [glob -nocomplain [file join $dirName *.gem]] {
			lappend listNames $fileName
		}
		if { [llength $listNames] > 1 } { #only do this, if there is at least one menu file
			set listNames [lreplace $listNames 0 0]; # let's get rid of the dummy element
			set listNames [lsort $listNames]
			#now read each menu file and append to list
			foreach fileName $listNames {
				set inputFile [open $fileName "r"]
				set line [read $inputFile]
				set splitLines [split $line "\n"]
				if { [llength $splitLines] == 1 } {
					# splitting didn't work.
					# maybe we have Mac style newlines, let's split again!
					set splitLines [split $line "\r"]
				}
				# split up into individual lines for processing
				foreach line $splitLines {
					# strip off comments
					set commentPos [string first "#" $line]
					# 1.: leading comment
					if { $commentPos == 0 } {
						set line ""
					}
					if { $commentPos > 0 } {
						set line [string range $line 0 [expr $commentPos-1]]
					}					
					set line [subst $line]; # substitute variables like $tmenu
					lappend splitLinesDone $line
				}
				# now join individual lines back into one string ...
				set line [join $splitLinesDone]
				# ... and append to list of submenus
				lappend XtnsMenuList [subst {$line}]
				set splitLinesDone ""
				close $inputFile
			}
			set XtnsMenu "True"
		}
	}
		

# This is the menu. This is in the proc GuiMenu::tree. It's not indented for the
# proc because the menu itself needs heavy indentation.

set descmenu [subst  {
 {[G_msg "&File"]} all file $tmenu {
	$Menu_File_Top
	{cascad {[G_msg "Import"]} {} "" $tmenu {			
		{cascad {[G_msg "Raster map"]} {} "" $tmenu {
			{command {[G_msg "Multiple formats using GDAL"]} {} "r.in.gdal" {} -command { execute r.in.gdal }}
			{separator}
			{command {[G_msg "Aggregate ASCII xyz data into raster grid"]} {} "r.in.xyz" {} -command { execute r.in.xyz }}
			{command {[G_msg "ASCII GRID (includes GRASS ASCII)"]} {} "r.in.ascii" {} -command { execute r.in.ascii }}
			{command {[G_msg "Polygons and lines from ASCII file"]} {} "r.in.poly" {} -command { execute r.in.poly }}
			{separator}
			{command {[G_msg "Binary file (includes GTOPO30 format)"]} {} "r.in.bin" {} -command { execute r.in.bin }}
			{command {[G_msg "ESRI Arc/Info ASCII grid"]} {} "r.in.arc" {} -command { execute r.in.arc }}
			{command {[G_msg "GRIDATB.FOR map file (TOPMODEL)"]} {} "r.in.gridatb" {} -command { execute r.in.gridatb }}
			{command {[G_msg "MAT-File (v.4) array (Matlab or Octave)"]} {} "r.in.mat" {} -command { execute r.in.mat }}
			{command {[G_msg "SPOT vegetation NDVI data sets"]} {} "i.in.spotvgt" {} -command { execute i.in.spotvgt }}
			{command {[G_msg "SRTM hgt files"]} {} "r.in.srtm" {} -command { execute r.in.srtm }}
			{command {[G_msg "Terra ASTER HDF files"]} {} "r.in.aster" {} -command { execute r.in.aster }}
			{separator}
			{command {[G_msg "Web Mapping Server"]} {} "r.in.wms" {} -command { execute r.in.wms }}
		}}
		{cascad {[G_msg "Vector map"]} {} "" $tmenu {			
			{command {[G_msg "Various formats using OGR"]} {} "v.in.ogr" {} -command { execute v.in.ogr }}
			{separator}
			{command {[G_msg "ASCII points file or GRASS ASCII vector file"]} {} "v.in.ascii" {} -command { execute v.in.ascii }}
			{command {[G_msg "Import old GRASS vector format"]} {} "v.convert" {} -command { execute v.convert }}
			{separator}
			{command {[G_msg "DXF file"]} {} "v.in.dxf" {} -command { execute v.in.dxf }}
			{command {[G_msg "ESRI e00 format"]} {} "v.in.e00" {} -command { execute v.in.e00 }}
			{command {[G_msg "Garmin GPS Waypoints/Routes/Tracks"]} {} "v.in.garmin" {} -command { execute v.in.garmin }}
			{command {[G_msg "GPS Waypoints/Routes/Tracks using GPSBabel"]} {} "v.in.gpsbabel" {} -command { execute v.in.gpsbabel }}
			{command {[G_msg "GEOnet Name server country files (US-NGA GNS)"]} {} "v.in.gns" {} -command { execute v.in.gns }}
			{command {[G_msg "Matlab and MapGen files"]} {} "v.in.mapgen" {} -command { execute v.in.mapgen }}
		}}
		{cascad {[G_msg "Grid 3D"]} {} "" $tmenu {			
			{command {[G_msg "ASCII 3D file"]} {} "r3.in.ascii" {} -command { execute r3.in.ascii }}
			{command {[G_msg "Vis5D file"]} {} "r3.in.v5d" {} -command { execute r3.in.v5d }}
		}}
	}}
	{cascad {[G_msg "Export"]} {} "" $tmenu {
		{cascad {[G_msg "Raster map"]} {} "" $tmenu {
			{command {[G_msg "Multiple formats using GDAL"]} {} "r.out.gdal" {} -command { execute r.out.gdal }}
			{separator}
			{command {[G_msg "ASCII grid (for GRASS, Surfer, Modflow, etc)"]} {} "r.out.ascii" {} -command { execute r.out.ascii }}
			{separator}
			{command {[G_msg "ESRI ARC/INFO ASCII grid"]} {} "r.out.arc" {} -command { execute r.out.arc }}
			{command {[G_msg "GRIDATB.FOR map file (TOPMODEL)"]} {} "r.out.gridatb" {} -command { execute r.out.gridatb }}
			{command {[G_msg "MAT-File (v.4) array (Matlab or Octave)"]} {} "r.out.mat" {} -command { execute r.out.mat }}
			{separator}
			{command {[G_msg "Binary file"]} {} "r.out.bin" {} -command { execute r.out.bin }}
			{separator}
			{command {[G_msg "MPEG-1 animations"]} {} "r.out.mpeg" {} -command { execute r.out.mpeg }}
			{command {[G_msg "PNG image (not georeferenced)"]} {} "r.out.png" {} -command { execute r.out.png }}
			{command {[G_msg "PPM image (24bit)"]} {} "r.out.ppm" {} -command { execute r.out.ppm }}
			{command {[G_msg "PPM image from red, green, blue raster maps"]} {} "r.out.ppm3" {} -command { execute r.out.ppm3 }}
			{command {[G_msg "POVray height-field"]} {} "r.out.pov" {} -command { execute r.out.pov }}
			{command {[G_msg "TIFF image (8/24bit)"]} {} "r.out.tiff" {} -command { execute r.out.tiff }}
			{command {[G_msg "VRML file"]} {} "r.out.vrml" {} -command { execute r.out.vrml }}
			{command {[G_msg "VTK ASCII file"]} {} "r.out.vtk" {} -command { execute r.out.vtk }}
		}}
		{cascad {[G_msg "Vector map"]} {} "" $tmenu {			
			{command {[G_msg "Various formats using OGR (SHAPE, MapInfo etc)"]} {} "v.out.ogr" {} -command { execute v.out.ogr }}
			{separator}
			{command {[G_msg "DXF file (ASCII)"]} {} "v.out.dxf" {} -command { execute v.out.dxf }}
			{command {[G_msg "ASCII vector or point file/old GRASS ASCII vector file"]} {} "v.out.ascii" {} -command { execute v.out.ascii }}
			{command {[G_msg "POV-Ray format"]} {} "v.out.pov" {} -command { execute v.out.pov }}
			{command {[G_msg "VTK ASCII file"]} {} "v.out.vtk" {} -command { execute v.out.vtk }}
		}}
		{cascad {[G_msg "Grid 3D"]} {} "" $tmenu {			
			{command {[G_msg "ASCII 3D file"]} {} "r3.out.ascii" {} -command { execute r3.out.ascii }}
			{command {[G_msg "Vis5D file"]} {} "r3.out.v5d" {} -command { execute r3.out.v5d }}
			{command {[G_msg "VTK ASCII file"]} {} "r3.out.vtk" {} -command { execute r3.out.vtk }}
		}}
	}}
	{separator}
	{cascad {[G_msg "Manage maps and volumes"]} {} "" $tmenu {			
		{command {[G_msg "Copy maps"]} {} "g.copy" {} -command {execute g.copy }}
		{command {[G_msg "List maps"]} {} "g.list" {} -command {execute g.list}}
		{command {[G_msg "List maps using expressions and 'wildcards'"]} {} "g.mlist" {} -command {execute g.mlist }}
		{command {[G_msg "Rename maps"]} {} "g.rename" {} -command {execute g.rename }}
		{command {[G_msg "Remove maps"]} {} "g.remove" {} -command {execute g.remove }}
		{command {[G_msg "Remove maps using expressions and 'wildcards'"]} {} "g.mremove" {} -command {execute g.mremove }}
	}}
	{cascad {[G_msg "Map type conversions"]} {} "" $tmenu {			
		{command {[G_msg "Raster to vector map"]} {} "r.to.vect" {} -command {execute r.to.vect }}
		{command {[G_msg "Raster map series to volume"]} {} "r.to.rast3" {} -command {execute r.to.rast3 }}
		{command {[G_msg "Raster 2.5D map to volume"]} {} "r.to.rast3elev" {} -command {execute r.to.rast3elev }}
		{command {[G_msg "Vector to raster"]} {} "v.to.rast" {} -command {execute v.to.rast }}
		{command {[G_msg "Vector to vector"]} {} "v.type" {} -command {execute v.type.sh }}
		{command {[G_msg "Vector lines to points"]} {} "v.to.points" {} -command {execute v.to.points }}
		{command {[G_msg "Vector 3D points to volume voxels"]} {} "v.to.rast3" {} -command {execute v.to.rast3 }}
		{command {[G_msg "Sites (GRASS 5.x) to vector"]} {} "v.in.sites" {} -command {execute v.in.sites }}
		{command {[G_msg "Volumes to raster map series"]} {} "r3.to.rast" {} -command {execute r3.to.rast }}
	}}
	$Menu_File_Bottom
 }
 {[G_msg "&Config"]} all options $tmenu {
	{cascad {[G_msg "Region"]} {} "" $tmenu {			
		{command {[G_msg "Display region settings"]} {} "g.region -p" {} -command {run_panel "g.region -p" }}
		{command {[G_msg "Change region settings"]} {} "g.region" {} -command {execute g.region }}
		{command {[G_msg "Zoom to maximum extent of all displayed maps"]} {} "d.extend" {} -command {run_panel d.extend }}
	}}
	{cascad {[G_msg "GRASS working environment"]} {} "" $tmenu {			
		{command {[G_msg "Access other mapsets in current location"]} {} "g.mapsets.tcl" {} -command {spawn $env(GISBASE)/etc/g.mapsets.tcl}}
		{command {[G_msg "Change current working session to new mapset, location, or GISDBASE"]} {} "g.mapset" {} -command {execute g.mapset }}
		{command {[G_msg "Modify access by other users to current mapset"]} {} "g.access" {} -command {execute g.access }}
		{command {[G_msg "Show current GRASS environment settings"]} {} "g.gisenv" {} -command {run_panel g.gisenv }}
		{command {[G_msg "Set GRASS environment settings"]} {} "g.gisenv" {} -command {execute g.gisenv }}
		{command {[G_msg "Show current GRASS version"]} {} "g.version -c" {} -command {run_panel "g.version -c" }}
	}}
	{cascad {[G_msg "Manage projections"]} {} "" $tmenu {			
		{command {[G_msg "Create/edit projection information for current location"]} {} "g.setproj" {} -command {term g.setproj }}
		{command {[G_msg "Show projection information and create projection files"]} {} "g.proj" {} -command {execute g.proj }}
		{separator}
		{command {[G_msg "Convert coordinates from one projection to another"]} {} "m.proj" {} -command {execute m.proj }}
	}}
	{cascad {[G_msg "X-monitor displays"]} {} "" $tmenu {
		{command {[G_msg "Configure xmonitor displays"]} {} "d.mon" {} -command {execute d.mon }}
		{command {[G_msg "Configure frames for xmonitors"]} {} "d.frame" {} -command {execute d.frame }}
		{command {[G_msg "Start/restart xmonitor at specified window size"]} {} "d.monsize" {} -command {execute d.monsize }}
		{command {[G_msg "Set active xmonitor to specified size"]} {} "d.resize" {} -command {execute d.resize }}
		{command {[G_msg "Display information about active xmonitor"]} {} "d.info" {} -command {execute d.info }}
	}}
 } 
 {[G_msg "&Raster"]} all options $tmenu {
	{cascad {[G_msg "Develop map"]} {} "" $tmenu {			
		{command {[G_msg "Digitize raster"]} {} "r.digit" {} -command {guarantee_xmon; term r.digit }}
		{separator}
		{command {[G_msg "Compress/decompress raster file"]} {} "r.compress" {} -command {execute r.compress }}
		{command {[G_msg "Manage boundary definitions"]} {} "r.region" {} -command {execute r.region }}
		{command {[G_msg "Manage null values"]} {} "r.null" {} -command {execute r.null }}
		{command {[G_msg "Manage timestamps for files"]} {} "r.timestamp" {} -command {execute r.timestamp }}
		{command {[G_msg "Quantization for floating-point maps"]} {} "r.quant" {} -command {execute r.quant }}
		{command {[G_msg "Resample (change resolution) using nearest neighbor method"]} {} "r.resample" {} -command {execute r.resample }}
		{command {[G_msg "Resample (change resolution) using regularized spline tension"]} {} "r.resamp.rst" {} -command {execute r.resamp.rst }}
		{command {[G_msg "Support file creation and maintenance"]} {} "r.support" {} -command {term r.support }}
		{separator}
		{command {[G_msg "Reproject raster from other location"]} {} "r.proj" {} -command {execute r.proj }}
		{command {[G_msg "Generate tiling for other projection"]} {} "r.tileset" {} -command {execute r.tileset }}
	}}
	{cascad {[G_msg "Manage map colors"]} {} "" $tmenu {			
		{command {[G_msg "Set colors to predefined color tables"]} {} "r.colors" {} -command {execute r.colors }}
		{command {[G_msg "Set colors using color rules"]} {} "r.colors.rules" {} -command {execute $env(GISBASE)/etc/gm/script/r.colors.rules }}
		{separator}
		{command {[G_msg "Blend 2 color maps to produce 3 RGB files"]} {} "r.blend" {} -command {execute r.blend }}
		{command {[G_msg "Create color image from RGB files"]} {} "r.composite" {} -command {execute r.composite }}
		{command {[G_msg "Create 3 RGB (red, green, blue) maps from 3 HIS (hue, intensity, saturation) maps"]} {} "r.his" {} -command {execute r.his }}
	}}
	{separator}
	{command {[G_msg "Query by coordinate(s)"]} {} "r.what" {} -command { execute r.what }}
	{separator}
	{command {[G_msg "Create raster buffers"]} {} "r.buffer" {} -command { execute r.buffer }}
	{command {[G_msg "Create raster MASK"]} {} "r.mask" {} -command { execute r.mask }}
	{command {[G_msg "Locate closest points between areas in 2 raster maps"]} {} "r.distance" {} -command { execute r.distance }}
	{command {[G_msg "Map calculator"]} {} "r.mapcalculator" {} -command { execute r.mapcalculator }}
	{cascad {[G_msg "Neighborhood analysis"]} {} "" $tmenu {			
		{command {[G_msg "Moving window analysis of raster cells"]} {} "r.neighbors" {} -command { execute r.neighbors }}
		{command {[G_msg "Analyze vector points in neighborhood of raster cells"]} {} "v.neighbors" {} -command { execute v.neighbors }}
	}}
	{cascad {[G_msg "Overlay maps"]} {} "" $tmenu {			
		{command {[G_msg "Cross product"]} {} "r.cross" {} -command {execute r.cross }}
		{command {[G_msg "Function of map series (time series)"]} {} "r.series" {} -command {execute r.series }}
		{command {[G_msg "Patch maps"]} {} "r.patch" {} -command {execute r.patch }}
		{separator}
		{command {[G_msg "Statistical calculations for cover map over base map"]} {} "r.statistics" {} -command {execute r.statistics }}
	}}
	{cascad {[G_msg "Solar radiance and shadows"]} {} "" $tmenu {			
		{command {[G_msg "Solar irradiance and daily irradiation"]} {} "r.sun" {} -command {execute r.sun }}
		{command {[G_msg "Shadows map for sun position or date/time"]} {} "r.sunmask" {} -command {execute r.sunmask }}
	}}
	{cascad {[G_msg "Terrain analysis"]} {} "" $tmenu {			
		{command {[G_msg "Calculate cumulative movement costs between locales"]} {} "r.walk" {} -command {execute r.walk }}
		{command {[G_msg "Cost surface"]} {} "r.cost" {} -command {execute r.cost }}
		{command {[G_msg "Least cost route or flow"]} {} "r.drain" {} -command {execute r.drain }}
		{command {[G_msg "Profile analysis"]} {} "d.profile" {} -command {guarantee_xmon; execute d.profile }}
		{command {[G_msg "Shaded relief map"]} {} "r.shaded.relief" {} -command {execute r.shaded.relief }}
		{command {[G_msg "Slope and aspect"]} {} "r.slope.aspect" {} -command {execute r.slope.aspect }}
		{command {[G_msg "Terrain parameters"]} {} "r.param.scale" {} -command {execute r.param.scale }}
		{command {[G_msg "Textural features"]} {} "r.texture" {} -command {execute r.texture }}
		{command {[G_msg "Visibility/line of sight"]} {} "r.los" {} -command {execute r.los }}
	}}
	{cascad {[G_msg "Transform features"]} {} "" $tmenu {			
		{command {[G_msg "Clump small areas (statistics calculated by r.volume)"]} {} "r.clump" {} -command {execute r.clump }}
		{command {[G_msg "Grow areas"]} {} "r.grow" {} -command {execute r.grow }}
		{command {[G_msg "Thin linear features"]} {} "r.thin" {} -command {execute r.thin }}
	}}
	{separator}
	{cascad {[G_msg "Hydrologic modeling"]} {} "" $tmenu {			
		{command {[G_msg "Carve stream channels into elevation map using vector streams map"]} {} "r.carve" {} -command {execute r.carve }}
		{command {[G_msg "Depressionless elevation map and flowline map"]} {} "r.fill.dir" {} -command {execute r.fill.dir }}
		{command {[G_msg "Fill lake from seed point to specified level"]} {} "r.lake" {} -command {execute r.lake }}
		{command {[G_msg "Flow accumulation for massive grids"]} {} "r.terraflow" {} -command {execute r.terraflow }}
		{command {[G_msg "Generate flow lines for raster map"]} {} "r.flow" {} -command {execute r.flow }}
		{command {[G_msg "SIMWE overland flow modeling"]} {} "r.sim.water" {} -command {execute r.sim.water }}
		{command {[G_msg "SIMWE sediment erosion, transport, & deposition modeling"]} {} "r.sim.sediment" {} -command {execute r.sim.sediment }}
		{command {[G_msg "Topographic index map"]} {} "r.topidx" {} -command {execute r.topidx }}
		{command {[G_msg "TOPMODEL simulation"]} {} "r.topmodel" {} -command {execute r.topmodel }}
		{command {[G_msg "Watershed subbasins"]} {} "r.basins.fill" {} -command {execute r.basins.fill }}
		{command {[G_msg "Watershed analysis"]} {} "r.watershed" {} -command {execute r.watershed }}
		{command {[G_msg "Watershed basin creation"]} {} "r.water.outlet" {} -command {execute r.water.outlet }}
	}}
	{cascad {[G_msg "Landscape structure modeling"]} {} "" $tmenu {			
		{command {[G_msg "Set up sampling and analysis framework"]} {} "r.le.setup" {} -command {guarantee_xmon; term r.le.setup }}
		{separator}
		{command {[G_msg "Analyze landscape characteristics"]} {} "r.le.pixel" {} -command {execute r.le.pixel }}
		{command {[G_msg "Analyze landscape patch characteristics"]} {} " r.le.patch" {} -command {execute r.le.patch }}
		{command {[G_msg "Output landscape patch information"]} {} "r.le.trace" {} -command {execute r.le.trace }}
	}}
	{cascad {[G_msg "Wildfire modeling"]} {} "" $tmenu {			
		{command {[G_msg "Generate rate of spread (ROS) maps"]} {} "r.ros" {} -command {execute r.ros }}
		{command {[G_msg "Generate least-cost spread paths"]} {} "r.spreadpath" {} -command {execute r.spreadpath }}
		{command {[G_msg "Simulate anisotropic spread phenomena"]} {} "r.spread" {} -command {execute r.spread }}
	}}
	{separator}
	{cascad {[G_msg "Change category values and labels"]} {} "" $tmenu {			
		{command {[G_msg "Edit category values of individual cells for displayed raster map"]} {} "d.rast.edit" {} \
			-command { tk_messageBox -type ok -icon error -title "d.rast.edit" \
			-message "Terribly sorry, but this command has been found to not work correctly from the GRASS 6.2 GUI menu.\
			However, it may be run from the GRASS command prompt, as follows:\n\n\
			d.mon x0\n\
			g.region rast=mapname\n\
			d.rast mapname\n\
			d.rast.edit\n\
			\nIn the next version of GRASS this module will be replaced with something better." }}
		{separator}
		{command {[G_msg "Reclassify categories for areas of specified sizes"]} {} "r.reclass.area" {} -command {execute r.reclass.area }}
		{command {[G_msg "Reclassify categories using rules"]} {} "r.reclass.rules" {} -command {execute $env(GISBASE)/etc/gm/script/r.reclass.rules }}
		{command {[G_msg "Reclassify categories using rules file"]} {} "r.reclass.file" {} -command {execute $env(GISBASE)/etc/gm/script/r.reclass.file }}
		{separator}
		{command {[G_msg "Recode categories using rules (create new map)"]} {} "r.recode.rules" {} -command {execute $env(GISBASE)/etc/gm/script/r.recode.rules }}
		{command {[G_msg "Recode categories using rules file (create new map)"]} {} "r.recode.file " {} -command {execute $env(GISBASE)/etc/gm/script/r.recode.file }}
		{separator}
		{command {[G_msg "Rescale categories (create new map)"]} {} "r.rescale" {} -command {execute r.rescale }}
		{command {[G_msg "Rescale categories with equalized histogram (create new map)"]} {} "r.rescale.eq" {} -command {execute r.rescale.eq }}
	}}
	{separator}
	{command {[G_msg "Generate concentric circles around points"]} {} "r.circle" {} -command { execute r.circle }}
	{cascad {[G_msg "Generate random raster cells"]} {} "" $tmenu {			
		{command {[G_msg "Generate random cells"]} {} "r.random.cells" {} -command {execute r.random.cells }}
		{command {[G_msg "Generate random cells and vector points from raster map"]} {} "r.random" {} -command {execute r.random }}
	}}
	{cascad {[G_msg "Generate surfaces"]} {} "" $tmenu {			
		{command {[G_msg "Generate density surface using moving Gausian kernal"]} {} "v.kernel" {} -command {execute v.kernel }}
		{command {[G_msg "Generate fractal surface"]} {} "r.surf.fractal" {} -command {execute r.surf.fractal }}
		{command {[G_msg "Generate gaussian deviates surface"]} {} "r.surf.gauss" {} -command {execute r.surf.gauss }}
		{command {[G_msg "Generate plane"]} {} "r.plane" {} -command {execute r.plane }}
		{command {[G_msg "Generate random deviates surface"]} {} "r.surf.random" {} -command {execute r.surf.random }}
		{command {[G_msg "Generate random surface with spatial dependence"]} {} "r.random.surface" {} -command {execute r.random.surface }}
	}}
	{command {[G_msg "Generate vector contour lines"]} {} "r.contour" {} -command { execute r.contour }}
	{cascad {[G_msg "Interpolate surfaces"]} {} "" $tmenu {			
		{command {[G_msg "Bilinear interpolation from raster points"]} {} "r.bilinear" {} -command { execute r.bilinear }}
		{command {[G_msg "Inverse distance weighted interpolation from raster points"]} {} "r.surf.idw" {} -command { execute r.surf.idw }}
		{command {[G_msg "Interpolation from raster contours"]} {} "r.surf.contour" {} -command { execute r.surf.contour }}
		{separator}
		{command {[G_msg "Inverse distance weighted interpolation from vector points"]} {} "v.surf.idw" {} -command { execute v.surf.idw }}
		{command {[G_msg "Regularized spline tension interpolation from vector points or contours"]} {} "v.surf.rst" {} -command { execute v.surf.rst }}
		{separator}
		{command {[G_msg "Fill NULL cells by interpolation using regularized spline tension"]} {} " r.fillnulls" {} -command {execute r.fillnulls }}
	}}
	{separator}
	{cascad {[G_msg "Reports and statistics"]} {} "" $tmenu {			
		{command {[G_msg "Report basic file information"]} {} "r.info" {} -command {execute r.info }}
		{command {[G_msg "Report category labels and values"]} {} "r.cats" {} -command {execute r.cats }}
		{separator}
		{command {[G_msg "General statistics"]} {} "r.stats" {} -command {execute r.stats }}
		{command {[G_msg "Range of all category values"]} {} "r.describe" {} -command {execute r.describe }}
		{command {[G_msg "Sum all cell category values"]} {} "r.sum" {} -command {execute r.sum }}
		{command {[G_msg "Sum area by map and category"]} {} "r.report" {} -command {execute r.report }}
		{command {[G_msg "Summary statistics for clumped cells (works with r.clump)"]} {} "r.volume" {} -command {execute r.volume }}
		{command {[G_msg "Total surface area corrected for topography"]} {} "r.surf.area" {} -command {execute r.surf.area }}
		{command {[G_msg "Univariate statistics"]} {} "r.univar" {} -command {execute r.univar }}
		{command {[G_msg "Univariate statistics (script version)"]} {} " r.univar.sh" {} -command {execute r.univar.sh }}
		{separator}
		{command {[G_msg "Sample values along transects"]} {} "r.profile" {} -command {execute r.profile }}
		{command {[G_msg "Sample values along transects (use azimuth, distance)"]} {} " r.transect" {} -command {execute r.transect }}
		{separator}
		{command {[G_msg "Covariance/correlation"]} {} "r.covar" {} -command {execute r.covar }}
		{command {[G_msg "Linear regression between 2 maps"]} {} "r.regression.line" {} -command {execute r.regression.line }}
		{command {[G_msg "Mutual category occurences (coincidence)"]} {} "r.coin" {} -command {execute r.coin }}
	}}
 } 
 {[G_msg "&Vector"]} all options $tmenu {
	{cascad {[G_msg "Develop map"]} {} "" $tmenu {			
		{command {[G_msg "Digitize"]} {} "v.digit" {} -command {guarantee_xmon; execute v.digit }}
		{separator}
		{command {[G_msg "Create/rebuild topology"]} {} "v.build" {} -command {execute v.build }}
		{command {[G_msg "Clean vector files"]} {} "v.clean" {} -command {execute v.clean }}
		{command {[G_msg "Add missing centroids"]} {} "v.centroids" {} -command {execute v.centroids }}
		{separator}
		{command {[G_msg "Build polylines from adjacent segments"]} {} "v.build.polylines" {} -command {execute v.build.polylines }}
		{command {[G_msg "Create points and line segments along a vector line"]} {} "v.segment" {} -command {execute v.segment }}
		{command {[G_msg "Create lines parallel to existing lines"]} {} "v.parallel" {} -command {execute v.parallel }}
		{command {[G_msg "Dissolve common boundaries"]} {} "v.dissolve" {} -command {execute v.dissolve }}
		{separator}
		{command {[G_msg "Convert vector feature types"]} {} "v.type" {} -command {execute v.type.sh }}
		{command {[G_msg "Convert 2D vector to 3D by sampling raster"]} {} "v.drape" {} -command {execute v.drape }}
		{command {[G_msg "Extrude 2D vector into 3D vector"]} {} "v.extrude" {} -command {execute v.extrude }}
		{separator}
		{command {[G_msg "Create text label file for vector features"]} {} "v.label" {} -command {execute v.label }}
		{separator}
		{command {[G_msg "Reproject vector from other location"]} {} "v.proj" {} -command {execute v.proj }}
	}}
	{cascad {[G_msg "Vector<->database connections"]} {} "" $tmenu {			
		{command {[G_msg "Create new vector as link to external OGR layer"]} {} "v.external" {} -command {execute v.external }}
		{command {[G_msg "Set database connection for vector attributes"]} {} "v.db.connect" {} -command {execute v.db.connect }}
	}}
	{command {[G_msg "Rectify and georeference vector map"]} {} "v.transform" {} -command {execute v.transform }}
	{separator}
	{command {[G_msg "Query by attributes"]} {} "v.extract" {} -command {execute v.extract }}
	{command {[G_msg "Query by coordinate(s)"]} {} "v.what" {} -command { execute v.what }}
	{command {[G_msg "Query by map features"]} {} " v.select" {} -command {execute v.select }}
	{separator}
	{command {[G_msg "Create vector buffers"]} {} "v.buffer" {} -command {execute v.buffer }}
	{cascad {[G_msg "Linear referencing for vectors"]} {} "" $tmenu {			
		{command {[G_msg "Some LRS modules require redirection of data from the command prompt"]} {} "" {} -state disabled }
		{separator}
		{command {[G_msg "Create linear reference system"]} {} "v.lrs.create" {} -command {execute v.lrs.create }}
		{command {[G_msg "Create stationing from imput lines, and linear reference system"]} {} "v.lrs.label" {} -command {execute v.lrs.label }}
		{command {[G_msg "Create points/segments from input lines, linear reference system and positions read from stdin"]} {} "v.lrs.segment" {} -command {execute v.lrs.segment }}
		{command {[G_msg "Find line id and real km+offset for given points in vector map using linear reference system"]} {} "v.lrs.where" {} -command {execute v.lrs.where }}
	}}
	{cascad {[G_msg "Neighborhood analysis"]} {} "" $tmenu {			
		{command {[G_msg "Locate nearest features to points or centroids"]} {} "v.distance" {} -command {execute v.distance }}
		{command {[G_msg "Generate Thiessen polygons around points (Voronoi diagram)"]} {} "v.voronoi" {} -command {execute v.voronoi }}
		{command {[G_msg "Connect points to create Delaunay triangles"]} {} "v.delauney" {} -command {execute v.delaunay }}
	}}
	{cascad {[G_msg "Network analysis"]} {} "" $tmenu {			
		{command {[G_msg "Allocate subnets"]} {} "v.net.alloc" {} -command {execute v.net.alloc }}
		{command {[G_msg "Network maintenance"]} {} "v.net" {} -command {execute v.net }}
		{command {[G_msg "Shortest route"]} {} "v.net.path" {} -command {execute v.net.path }}
		{command {[G_msg "Shortest route (visualization only)"]} {} "d.path" {} -command {guarantee_xmon; execute d.path }}
		{command {[G_msg "Split net to bands between cost isolines"]} {} "v.net.iso" {} -command {execute v.net.iso }}
		{command {[G_msg "Steiner tree"]} {} "v.net.steiner" {} -command {execute v.net.steiner }}
		{command {[G_msg "Traveling salesman analysis"]} {} "v.net.salesman" {} -command {execute v.net.salesman }}
	}}
	{cascad {[G_msg "Overlay maps"]} {} "" $tmenu {			
		{command {[G_msg "Overlay/combine 2 vector maps"]} {} "v.overlay" {} -command {execute v.overlay }}
		{command {[G_msg "Patch multiple maps (combine)"]} {} "v.patch" {} -command {execute v.patch }}
	}}
	{command {[G_msg "Generate area feature for extent of current region"]} {} "v.in.region" {} -command {execute v.in.region }}
	{command {[G_msg "Generate rectangular vector grid"]} {} "v.mkgrid" {} -command {execute v.mkgrid }}
	{separator}
	{cascad {[G_msg "Change attributes"]} {} "" $tmenu {			
		{command {[G_msg "Attach, delete, or report categories"]} {} "v.category" {} -command {execute v.category }}
		{command {[G_msg "Reclassify features using rules file"]} {} "v.reclass" {} -command {execute v.reclass }}
	}}
	{separator}
	{cascad {[G_msg "Work with vector points"]} {} "" $tmenu {			
 		{cascad {[G_msg "Generate points"]} {} "" $tmenu {			
			{command {[G_msg "Generate points from database with x/y coordinates"]} {} "v.in.db" {} -command {execute v.in.db }}
 			{command {[G_msg "Generate random points"]} {} "v.random" {} -command {execute v.random }}
 			{command {[G_msg "Random location perturbations of points"]} {} "v.perturb" {} -command {execute v.perturb }}
 		}}
 		{cascad {[G_msg "Generate areas from points"]} {} "" $tmenu {			
 			{command {[G_msg "Generate convex hull for point set"]} {} "v.hull" {} -command {execute v.hull }}
 			{command {[G_msg "Generate Delaunay triangles for point set"]} {} "v.delaunay" {} -command {execute v.delaunay }}
 			{command {[G_msg "Generate Voronoi diagram/Thiessen polygons for point set"]} {} "v.voronoi" {} -command {execute v.voronoi }}
 		}}
 		{cascad {[G_msg "Sample raster maps"]} {} "" $tmenu {			
 			{command {[G_msg "Calculate statistics for raster map overlain by vector map"]} {} "v.rast.stats" {} -command {execute v.rast.stats }}
 			{command {[G_msg "Sample raster map at point locations"]} {} "v.what.rast" {} -command {execute v.what.rast }}
 			{command {[G_msg "Sample raster neighborhood around points"]} {} "v.sample" {} -command {execute v.sample }}
 		}}
 		{command {[G_msg "Partition points into test/training sets for k-fold cross validatation"]} {} "v.kcv" {} -command {execute v.kcv }}
 		{command {[G_msg "Transfer attribute data from queried vector map to points"]} {} "v.what.vect" {} -command {execute v.what.vect }}
	}}
	{separator}
	{cascad {[G_msg "Reports and statistics"]} {} "" $tmenu {			
		{command {[G_msg "Basic information"]} {} "v.info" {} -command {execute v.info }}
		{command {[G_msg "Load vector attributes to database or create reports"]} {} "v.to.db" {} -command {execute v.to.db }}
		{command {[G_msg "Report areas for vector attribute categories"]} {} "v.report" {} -command {execute v.report }}
		{command {[G_msg "Univariate statistics"]} {} "v.univar" {} -command {execute v.univar }}
 		{separator}
		{command {[G_msg "Test normality of point distribution"]} {} "v.normal" {} -command {execute v.normal }}
		{command {[G_msg "Calculate stats for raster map underlying vector objects"]} {} "v.rast.stats" {} -command {execute v.rast.stats }}
		{command {[G_msg "Indices of point counts in quadrats"]} {} "v.qcount" {} -command {execute v.qcount }}
	}}
 } 
 {[G_msg "&Imagery"]} all options $tmenu {			
	{cascad {[G_msg "Develop images and groups"]} {} "" $tmenu {			
		{command {[G_msg "Create/edit imagery group"]} {} "i.group" {} -command {execute i.group }}			
		{command {[G_msg "Target imagery group"]} {} "i.target" {} -command {execute i.target }}
		{separator}
		{command {[G_msg "Mosaic up to 4 adjacent images"]} {} "i.image.mosaic" {} -command {execute i.image.mosaic }}
	}}
	{cascad {[G_msg "Manage image colors"]} {} "" $tmenu {			
		{command {[G_msg "Color balance and enhance color tables of multiband imagery for rgb display"]} {} "i.landsat.rgb" {} -command {execute i.landsat.rgb }}
		{command {[G_msg "Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)"]} {} "i.his.rgb" {} -command {execute i.his.rgb }}
		{command {[G_msg "Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)"]} {} "i.rgb.his" {} -command {execute i.rgb.his }}
	}}
	{cascad {[G_msg "Rectify and georeference image group"]} {} "" $tmenu {			
		{command {[G_msg "Set ground control points (GCP's) from raster map or keyboard entry"]} {} "i.points" {} \
		-command {guarantee_xmon; term i.points }}
		{command {[G_msg "Set ground control points (GCP's) from vector map or keyboard entry"]} {} "i.vpoints" {} \
		-command {guarantee_xmon; term i.vpoints }}
		{command {[G_msg "Affine and Polynomial rectification (rubber sheet)"]} {} "i.rectify" {} -command {execute i.rectify }}
		{command {[G_msg "Ortho photo rectification"]} {} "i.ortho.photo" {} -command {term i.ortho.photo }}
	}}
	{separator}
	{command {[G_msg "Brovey transformation and pan sharpening"]} {} "i.fusion.brovey" {} -command {execute i.fusion.brovey }}
	{cascad {[G_msg "Classify image"]} {} "" $tmenu {			
		{command {[G_msg "Clustering input for unsupervised classification"]} {} "i.cluster" {} -command {execute i.cluster }}
		{separator}
		{command {[G_msg "Maximum likelyhood classification (MLC)"]} {} "i.maxlik" {} -command {execute i.maxlik }}
		{command {[G_msg "Sequential maximum a posteriory classification (SMAP)"]} {} "i.smap" {} -command {execute i.smap }}
		{separator}
		{command {[G_msg "Interactive input for supervised classification"]} {} "i.class" {} -command {term i.class }}
		{command {[G_msg "Non-interactive input for supervised classification (MLC)"]} {} "i.gensig" {} -command {execute i.gensig }}
		{command {[G_msg "Non-interactive input for supervised classification (SMAP)"]} {} "i.gensigset" {} -command {execute i.gensigset }}
	}}
	{cascad {[G_msg "Filter image"]} {} "" $tmenu {			
		{command {[G_msg "Zero edge crossing detection"]} {} "i.zc" {} -command {execute i.zc }}
		{command {[G_msg "User defined matrix/convolving filter"]} {} "r.mfilter" {} -command {execute r.mfilter }}
	}}
	{command {[G_msg "Spectral response"]} {} "i.spectral" {} -command {execute i.spectral }}
	{command {[G_msg "Tassled cap vegetation index"]} {} "i.tasscap" {} -command {execute i.tasscap }}
	{cascad {[G_msg "Transform image"]} {} "" $tmenu {			
		{command {[G_msg "Canonical component"]} {} "i.cca" {} -command {execute i.cca }}
		{command {[G_msg "Principal component"]} {} "i.pca" {} -command {execute i.pca }}
		{command {[G_msg "Fast Fourier Transform"]} {} "i.fft" {} -command {execute i.fft }}
		{command {[G_msg "Inverse Fast Fourier Transform"]} {} "i.ifft" {} -command {execute i.ifft }}
	}}
	{separator}
	{cascad {[G_msg "Reports and statistics"]} {} "" $tmenu {			
		{command {[G_msg "Report basic file information"]} {} "r.info" {} -command {execute r.info }}
		{command {[G_msg "Range of image values"]} {} "r.describe" {} -command {execute r.describe }}
		{separator}
		{command {[G_msg "Bit pattern comparison for ID of low quality pixels"]} {} "r.bitpattern" {} -command {execute r.bitpattern }}
		{command {[G_msg "Kappa classification accuracy assessment"]} {} "r.kappa" {} -command {execute r.kappa }}
		{command {[G_msg "Optimum index factor for LandSat TM"]} {} "i.oif" {} -command {execute i.oif }}
	}}
 } 
 {[G_msg "&Grid3D"]} all options $tmenu {
	{cascad {[G_msg "Develop grid3D volumes"]} {} "" $tmenu {			
		{command {[G_msg "Manage nulls for grid3D volume"]} {} "r3.null" {} -command {execute r3.null }}
		{command {[G_msg "Manage timestamp for grid3D volume"]} {} "r3.timestamp" {} -command {execute r3.timestamp }}
	}}
	{command {[G_msg "Create 3D mask for grid3D operations"]} {} "r3.mask" {} -command {execute r3.mask }}
	{command {[G_msg "Create 2D raster cross section from grid3d volume"]} {} "r3.cross.rast" {} -command { execute r3.cross.rast }}
	{command {[G_msg "Map calculator for grid3D operations"]} {} "r3.mapcalculator" {} -command {execute r3.mapcalculator }}
	{command {[G_msg "Interpolate volume from vector points using splines"]} {} "v.vol.rst" {} -command {execute v.vol.rst }}
	{cascad {[G_msg "Report and Statistics"]} {} "" $tmenu {			
		{command {[G_msg "Display information about grid3D volume"]} {} "r3.info" {} -command {execute r3.info }}
	}}
 } 
 {[G_msg "&Databases"]} all options $tmenu {
	{cascad {[G_msg "Manage database"]} {} "" $tmenu {			
		{command {[G_msg "Connect to database"]} {} "db.connect" {} -command {execute db.connect }}
		{command {[G_msg "Login to database"]} {} "db.login" {} -command {execute db.login }}
		{separator}
		{command {[G_msg "Copy table"]} {} "db.copy" {} -command {execute db.copy }}
		{command {[G_msg "Add table to map"]} {} "v.db.addtable" {} -command {execute v.db.addtable }}
		{command {[G_msg "Add columns to table"]} {} "v.db.addcol" {} -command {execute v.db.addcol }}
		{command {[G_msg "Change values in a column"]} {} "v.db.update" {} -command {execute v.db.update }}
		{command {[G_msg "Test database"]} {} "db.test" {} -command {execute db.test }}
	}}
	{cascad {[G_msg "Database information"]} {} "" $tmenu {			
		{command {[G_msg "Describe table"]} {} "db.describe" {} -command {execute db.describe }}
		{command {[G_msg "List columns"]} {} "db.columns" {} -command {execute db.columns }}
		{command {[G_msg "List drivers"]} {} "db.drivers" {} -command {execute db.drivers }}
		{command {[G_msg "List tables"]} {} "db.tables" {} -command {execute db.tables }}
	}}
	{separator}
	{cascad {[G_msg "Query"]} {} "" $tmenu {			
		{command {[G_msg "Query data (SQL select)"]} {} "db.select" {} -command {execute db.select }}
		{command {[G_msg "Execute SQL statement"]} {} "db.execute" {} -command {execute db.execute }}
	}}
 } 

 }]

	# Should we add an Xtns menu entry?
	if { $XtnsMenu == "True" } {
		# build extension menu
		lappend descmenu [G_msg "&Xtns"]
		lappend descmenu all
		lappend descmenu options
		lappend descmenu $tmenu
		lappend descmenu $XtnsMenuList
	}
 
	# Return this whole mess!
	return $descmenu
}
