#!/bin/sh
              # the next line restarts using wish \
              exec wish "$0" "$@"
#
# IceWMConf 2.1.0
# Versions <= 1.0.0 are copyright 1999 MJ Ray <markj@stu.uea.ac.uk>
# Versions >= 1.10 are copyright 2001 by Scott D. Boyd <sdboyd56@swbell.net>
#
# You may use, copy, modify, distribute and sublicense this
# software for any purpose, provided that existing copyright
# notices are retained in all copies and that this notice is
# included verbatim in any distributions. No written agreement,
# licence, or royalty fee is required for any of the authorized
# uses.  Distributed modifications to this software must
# include an alphabetic extension to the version ID and be
# submitted to the address above for possible inclusion in
# future versions.  THE AUTHORS AND DISTRIBUTORS SPECIFICALLY
# DISCLAIM ALL WARRANTIES.  This agreement is under English
# jurisdiction.  (BSD-Artistic hybrid)

set ver "2.1.0"
set fnt "Helvetica 12"
set dfalt_file "1"

proc mergepref {filename system} {
  global setting status dfaltlist dfalt_file
  catch {set chanid [open $filename]}
  if [info exists chanid] {
    set conf [split [read $chanid] "\n"]
    close $chanid  
    # $conf is now an array containing the lines of the config file
    # now merge them into the array called setting
    foreach item $conf {
      if [expr $system ? [regexp {^(# *)?[^ ]+=} $item] : [regexp {^[^#]+=} $item] ] { 
        regsub {^# *} $item {} newitem
        set list [split $newitem "="]
        if {$dfalt_file}  {
          # these commands will execute only if we are reading the system default config file
          set def_list [split $newitem "="]
          lappend dfaltlist $newitem
          set def_setting([string trim [lindex $def_list 0]]) [lindex $def_list 1]
        }
        set setting([string trim [lindex $list 0]]) [lindex $list 1]
      }
    }
    set status "$status $filename merged."
  } else {
     set status "$status $filename not found."
  }
}

# option displayer
proc display {re} { 
  global setting status fnt
  catch {destroy .frame.c}
  canvas .frame.c -yscrollcommand ".s set"
  frame .frame.c.c
  set y 2
  foreach item [lsort [array names setting]] {
    if [regexp $re $item] {
      label .frame.c.c.label$item -text $item -font $fnt
      entry .frame.c.c.entry$item -textvariable setting($item) -font $fnt
      grid .frame.c.c.label$item .frame.c.c.entry$item -sticky e
      incr y [winfo reqheight .frame.c.c.entry$item]
    }
    .frame.c create window 2 2 -window .frame.c.c -anchor nw
  }
  .frame.c configure -scrollregion [list 0 0 0 $y] -height $y
  place .frame.c -relx 0 -rely 0 -relheight 1 -relwidth 1
  .frame.c.c configure -width [winfo width .frame.c] -height [winfo height .frame.c]
  set status "$re options displayed"
}

proc savepref {} {
  global setting status env ver dfaltlist
  catch {set chanid [open "[string trim $env(HOME)]/.icewm/preferences" "w"]}
  if [info exists chanid] {
    puts $chanid "# Generated by IceWMConf $ver"
    foreach item [lsort [array names setting]] {
      set newsetting "$item=$setting($item)"
      # check to see if preference value has changed from default
      # if so, then write the preference to the config file
      set chkchange [lsearch -exact $dfaltlist $newsetting] 
        if {$chkchange  < 0} {
          puts $chanid "$item=$setting($item)"
        } else {
          puts $chanid "# $item=$setting($item)"
        }
    }
    close $chanid
    set status "Saved [string trim $env(HOME)]/.icewm/preferences"
  } else {
     set status "[string trim $env(HOME)]/.icewm/preferences save failed"
  }
}

proc findmanual {} {
  return [exec sh -c "locate icewm.html|head -1"]
}

# The "About IceWMConf" infobox
proc myokbox {string} {
  global fnt
  catch {destroy .box}
  toplevel .box
  wm title .box "About IceWMConf"
  label .box.text -text $string -font $fnt
  button .box.button -text "OK" -command {destroy .box} -font $fnt
  pack .box.text -side top -anchor n -fill both -expand 1
  pack .box.button -side bottom -anchor s
  bind .box.button <Return> {destroy .box}
  focus .box.button
}

# Code for the searchbox
proc searchbox {} {
  global fnt
  catch {destroy .sbox}
  toplevel .sbox
  wm title .sbox "IceWMConf Search"
  label .sbox.text -text "Search for (regexp)" -font $fnt
  entry .sbox.term -textvariable searchterm -font $fnt
  button .sbox.go -text "Search" -command {display $searchterm} -font $fnt
  button .sbox.stop -text "Close" -command {destroy .sbox} -font $fnt
  grid .sbox.text .sbox.term -sticky ew
  grid .sbox.go -sticky e
  grid .sbox.stop -row 1 -column 1 -sticky w
  bind .sbox.term <Return> {display $searchterm}
  bind .sbox.go <Return> {display $searchterm}
  bind .sbox.stop <Return> {destroy .sbox}
  focus .sbox.term
}

proc about {} {
  global ver
  myokbox "IceWMConf $ver\nCopyright 2001 - Scott D. Boyd\n\
  Copyright 1999 - MJ Ray\n\n\
  sdboyd56@swbell.net\nhttp://sdboyd.dyndns.org/icewmconf/\n" 
}

proc optionhelp {} {
  myokbox {

More information on the options should be in the doc directory
of the icewm package.  You might also like to consider using
IcePref for a more verbose configuration tool.
  }
}

proc themehelp {} {
  myokbox {

Themes are beyond the scope of this simple customisation tool,
although you can set your default theme name.  For help on
theme creation, installation and usage, visit 
http://icewm.themes.org/
  }
}

proc restart {} {
  global status
  set status "Restarted IceWM"
  exec kill {-HUP} [exec /sbin/pidof icewm]
}

# Begin the main, building the static menus
menu .main 
. configure -menu .main

menu .main.file -tearoff 0
.main.file add command -command savepref -label "Save (Ctrl+S)" -font $fnt
bind . <Control-S> {savepref}
bind . <Control-s> {savepref}
.main.file add command -command restart -label "Restart IceWM (Ctrl+R)" -font $fnt
bind . <Control-R> {restart}
bind . <Control-r> {restart}
.main.file add command -command exit -label "Quit (Ctrl+Q)" -font $fnt
bind . <Control-Q> {exit}
bind . <Control-q> {exit}
.main add cascade -menu .main.file -label {File} -underline 0 -font $fnt

menu .main.search -tearoff 0
.main add command -command searchbox -label {Search} -underline 0 -font $fnt
bind . <Alt-S> {searchbox}

menu .main.help
.main.help add command -command about -label "About IceWMConf" -underline 0 -font $fnt
.main.help add command -command optionhelp -label "Help with Options" -underline 10 -font $fnt
.main.help add command -command themehelp -label "Help with Themes" -underline 10 -font $fnt
.main.help add separator
.main.help add command -command {exec netscape [findmanual] &} -label "IceWM Manual Netscape" -font $fnt
.main.help add command -command {exec rxvt -e lynx [findmanual] &} -label "IceWM Manual Lynx (F1)" -font $fnt
bind all <F1> {exec rxvt -e lynx [findmanual]}
.main.help add command -command {exec rxvt -e w3m [findmanual] &} -label "IceWM Manual w3m" -font $fnt
.main add cascade -menu .main.help -label {Help} -underline 0 -font $fnt

# status bar
entry .info -takefocus 0 -state disabled -textvariable status -font $fnt
pack .info -side bottom -fill x

# scrollbar and main window
frame .frame
scrollbar .s -orient vertical -command ".frame.c yview" -width 10
bind . <Prior> {.frame.c yview scroll -1 page}
bind . <Next> {.frame.c yview scroll 1 page}
pack .s -side right -fill y
pack .frame -fill both

# print welcome message
canvas .frame.c -yscrollcommand ".s set"
label .frame.c.c -font $fnt  -wrap 512 -justify left -text "
Welcome to IceWMConf $ver

At the bottom of this window is the status bar, which\
should tell you which config files it found and merged\
in with your config file.  Options in the later ones will\
have overridden earlier options.

Most of the time, you will probably work by selecting\
categories from the Options menu, although you can also use the\
search box to find them.  Either method will fill this box with a\
list of settable options and text entry fields containing their\
value.  As soon as you edit the value, it is set and ready to\
be saved to your personal preferences file, using File->Save.  \
Only the options that are different than the default options will \
be saved.

The Help menu contains a few informative info boxes\
and three methods to view the IceWM manual.

This message will disappear when you pick an option category.
"
.frame.c configure -scrollregion [list 0 0 0 [winfo reqheight .frame.c.c]] -height [winfo reqheight .frame.c.c] -width [winfo reqwidth .frame.c.c]
.frame.c create window 0 0 -window .frame.c.c -anchor nw
pack .frame.c -anchor n

bind .frame.c <Configure> { # teach it how to resize itself
  pack .frame -fill both -expand 1
  place .frame.c -relx 0 -rely 0 -relwidth 1 -relwidth 1
  #  puts "[winfo reqheight .frame.c] in [winfo reqheight .frame]"
}

# load the preferences files
mergepref "/usr/pkg/lib/X11/icewm/preferences" 1
set dfalt_file "0"
mergepref "[string trim $env(HOME)]/.icewm/preferences" 0

# Now build the dynamic options menu
.main add cascade -menu .main.menu -label {Options} -underline 0 -font $fnt
menu .main.menu

foreach item [lsort [array names setting]] {
  regsub {(^[A-Z][a-z0-9]*).*} $item {\1} tli
  set toplevel($tli) 1
  set first [string tolower [string index $tli 0]]
  if [expr ! [winfo exists .main.menu.$first]] {
    #  puts $tli
    menu .main.menu.$first -font $fnt -tearoff 0
    .main.menu add cascade -menu .main.menu.$first -label [string toupper $first] -font $fnt
  }
}

foreach item [lsort [array names toplevel]] {
  set first [string tolower [string index $item 0]]
  .main.menu.$first add command -label $item -command "display $item" -font $fnt
}



