#!/bin/sh
## -*- tcl -*- \
exec tclsh "$0" ${1+"$@"}

# # ## ### ##### ######## ############# #####################
## Copyright (c) 2007 Andreas Kupries.
#
# This software is licensed as described in the file LICENSE, which
# you should have received as part of this distribution.
#
# This software consists of voluntary contributions made by many
# individuals.  For exact contribution history, see the revision
# history and logs, available at http://fossil-scm.hwaci.com/fossil
# # ## ### ##### ######## ############# #####################

## Command line application to extract the tree of symbols (tags and
## branches) from a state database and show it graphically. The code
## uses GraphViz's 'dot' to do the layouting and conversion into an
## image.

# # ## ### ##### ######## ############# #####################
## Requirements, extended package management for local packages.

lappend auto_path [file join [file dirname [info script]] lib]

package require Tcl 8.4                               ; # Required runtime.
package require struct::graph                         ; # Graph handling.
package require struct::list                          ; # Higher order list ops.
package require vc::fossil::import::cvs::state        ; # State storage.
package require vc::tools::dot                        ; # Graph export to DOT.

namespace import ::vc::fossil::import::cvs::state
namespace import ::vc::tools::dot

# Process the command line. Get the database to access.

state use [lindex $argv 0]
state reading symbol
state reading parent

# Get the data of all symbols in the state as a list for iteration,
# and as array for random access of neighbouring symbols.

foreach {sid name} [set symbols [state run { SELECT sid, name FROM symbol }]] {
    set sym($sid) [list $name]
}
foreach {sid lod} [state run { SELECT sid, lod FROM tag }] {
    lappend sym($sid) $lod $sym($lod) box Tag
}
foreach {sid lod} [state run { SELECT sid, lod FROM branch }] {
    lappend sym($sid) $lod $sym($lod) diamond Branch
}

# Start the graph

struct::graph dg

# Convert the symbols into nodes of the graph, and use node attributes
# to highlight various pieces of interest for the dot conversion.
# Label => Symbol name.

foreach sid [array names sym] {
    dg node insert $sid
    struct::list assign $sym($sid) name lod lodname shape what
    if {$shape eq ""} { set shape circle }
    if {$what ne ""} { append what " " }
    dg node set $sid label "$what$name"
    dg node set $sid shape $shape
}

# Go through the symbols a second time, now set up the arcs based on
# their parent choices. Use arc attributes to highlight interesting
# things (...).

foreach sid [array names sym] {
    struct::list assign $sym($sid) name lod lodname shape
    if {$lod eq ""} continue ; # Root has no parent.
    dg arc insert $sid $lod
}

# Convert the graph to dot, then run the layouter and convert to png,
# at last show the image.

vc::tools::dot layout png dg SymbolTree st.png
exec display st.png
file delete st.png
exit

