#!/bin/bash
#\
exec wishx -f $0 "$@"

# NAME
#    xskim
# DESCRIPTION
#    A graphical interface for skim, based on TclX/Tk.
# COPYRIGHT
#    xskim - Graphical interface for skim.
#
#    xskim is based on skim.tcl, which is Copyright (C) 1995 Christoph Neerfeld.
#    skim.tcl is in the skim_tcl package which was uploaded to sunsite.unc.edu
#    as an optional graphical interface for skim version 0.1. From skim version
#    0.4 onwards skim.tcl is renamed to xskim and is integrated in the Skim 
#    package. Changes to xskim are documented in the README file.
#
#    Skim - Off-line news reading package optimized for slow lines.
#    Copyright (C) 1995  Rene W.J. Pijlman
#
#    This program 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 of the License, or
#    (at your option) any later version.
#
#    This program 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 this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# VERSION
#    Skim version 0.6.
#    /home/rene/sys/CVS_MasterSourceRepository/skim/xskim,v 1.28 1995/08/17 23:32:22 rpijlman Exp

# Just a dummy call to skim to create the directory structure if necessary.
exec skim version >/dev/null

# Use the default value when SKIMDIR is not set.
if { [lsearch [array names env] SKIMDIR] >= 0 } {
    set skimhome $env(SKIMDIR)
} else {
    set skimhome [glob ~/Skim]
}

set text_font         "-*-New Century Schoolbook-Medium-R-Normal-*-140-*"
set edit_font          "-*-Courier-Medium-R-Normal-*-140-*"
set subj_group_name ""
set save_name ""
set MustSave 0
set current_subj_index 0
set CurrentGroupIndex 0

#-------------
# disp_article
#-------------
proc disp_article {CurrentArticleIndex} {

	global skimhome text_font
	global subjlist
	global current_name
	global subject_name
	global current_subj_index

	set current_subj_index $CurrentArticleIndex

        .r.subj.list select from $CurrentArticleIndex

	if [info exists subjlist] {
	    set current [lindex $subjlist $CurrentArticleIndex]
	    if {$current != ""} {
		.bottomline.b_del configure -state normal
		.bottomline.b_keep configure -state normal
		.bottomline.b_reply configure -state normal
		pack forget .bottomline.save
		.article configure -font $text_font
		.article configure -state normal
		.article delete 0.0 end

		if {[file exists $skimhome/Articles/$current]} {
		    .article insert 0.0 [read_file $skimhome/Articles/$current ]

		    .article configure -state disabled
		    set current_name $current
		    set subject_name [.r.subj.list get $CurrentArticleIndex]
		    if {[file exists $skimhome/Post/$current_name.reply]} {
			    pack .bottomline.replied -side right -padx 20
			    pack .bottomline.del_repl -side right -padx 10
		    } else {
			    pack forget .bottomline.replied
			    pack forget .bottomline.del_repl
		    }
		} else {
		    # The article for this entry in the index is missing.
		    # The user must have removed it. Let's rebuild the indexes.
		    exec skim indexes
		    pack_article 0
		}
	    }
	}
}

#-------------
# pack_article
#-------------
proc pack_article {GroupIndex} {

	global skimhome

	.bottomline.b_del configure -state disabled
	.bottomline.b_keep configure -state disabled
	.bottomline.b_reply configure -state disabled

	.r.group.list delete 0 end
	set grouplist [exec find $skimhome/Indexes/Articles -type f -printf "%f\n"]
	foreach i [split $grouplist "\n"] {
	    .r.group.list insert end $i
	}

	pack .bottomline -side bottom -padx 3m -fill x
	place .scroll -in .dummy -relheight 1.0
	place .article -relheight 1.0 -relwidth 0.7 -in .dummy -x 17
	place .r       -relheight 1.0 -relwidth 0.27 -in .dummy -anchor ne -relx 1.0

	bind .r.group.list <Button-1> {
            .r.group.list select from [.r.group.list nearest %y]
	    wm title . "xskim [.r.group.list get [.r.group.list nearest %y]]"
	    getsubjects [.r.group.list nearest %y]
	}

        if {$GroupIndex >= [.r.group.list size]} {
            set GroupIndex 0
	}

        getsubjects $GroupIndex
	wm title .  "xskim [.r.group.list get $GroupIndex]"
}

#---------------
# unpack_article
#---------------
proc unpack_article {} {
	place forget .r
	place forget .article
	pack forget .bottomline
	place forget .scroll
}

#--------------
# pack_subjects
#--------------
proc pack_subjects {} {

	global skimhome
	global MustSave

	.r.group.list delete 0 end
	.r.subj.list delete 0 end
	.l.n_selected.list delete 0 end
	.l.selected.list delete 0 end

	set grouplist [exec ListSubscribedNewsGroups]
	foreach i [split $grouplist "\n"] {
		if {[file exists $skimhome/Subjects/$i]} { .r.group.list insert end $i }
	}
	pack forget .r.subj .r.label2
	pack configure .r.group -expand 1
	place .l -relheight 1.0 -relwidth 0.7 -in .dummy 
	place .r -relheight 1.0 -relwidth 0.3 -in .dummy -relx 1.0 -anchor ne
	pack .r.b_get_subj   -side bottom -pady 1m

	bind .r.group.list <Button-1> {
	    outstanding_work
            .r.group.list select from [.r.group.list nearest %y]
	    wm title . "xskim [.r.group.list get [.r.group.list nearest %y]]"
	    get_selected %y
	}

        .r.group.list select from 0
	get_selected 0
	wm title .  "xskim [.r.group.list get 0]"
}


#----------------
# unpack_subjects
#----------------
proc unpack_subjects {} {
	place forget .r
	pack forget .r.b_get_subj
	place forget .l
	pack .r.subj -side bottom  -fill both -expand 1
	pack .r.label2 -side top -fill x
}

#-------------------------------------------------
#         procs for article mode
#-------------------------------------------------

#------------
# getsubjects
#------------
proc getsubjects {GroupIndex} {

	global skimhome
	global subjlist
	global CurrentGroupIndex

	set CurrentGroupIndex $GroupIndex

	set subjlist [list]

	.r.subj.list delete 0 end
	set current [.r.group.list get $GroupIndex]

	if {$current != "" && \
	    [file exists $skimhome/Indexes/Articles/$current]} {
	    set ArticleNumberAndSubjectList [exec cat \
		$skimhome/Indexes/Articles/$current]
	} else {
	    set ArticleNumberAndSubjectList ""
	}

	foreach i [split $ArticleNumberAndSubjectList "\n"] {
            set IndexOfSeparator [string first " " $i]
            set ArticleNumber [string range $i 0 [expr $IndexOfSeparator - 1]]
            set Subject [string range $i [expr $IndexOfSeparator + 1] end]

	    lappend subjlist $current.$ArticleNumber
	    .r.subj.list insert end $Subject
	}

        .r.subj.list select from 0
	disp_article 0
}

#------------
# move_article
#------------
proc move_article {Destination} {

	global CurrentGroupIndex
	global skimhome
	global current_name
	global subject_name
        global current_subj_index
	global subjlist

	if {$Destination == "delete" || $Destination == "keep"} {
	    exec skim $Destination $current_name
	} else {
	    error "Can't happen"
	}

	# Remove the article from the display.
	.article configure -state normal
	.article delete 1.0 end
	.article configure -state disabled

	# Remove entry from subject listbox.
	.r.subj.list delete $current_subj_index

	# Remove subject from list of subjects.
	set subjlist [lreplace $subjlist $current_subj_index $current_subj_index]

	if {[llength $subjlist] > 0} {
	    # Display the next article.
	    if {$current_subj_index >= [llength $subjlist]} {
	        disp_article [expr [llength $subjlist] - 1]
	    } else {
		disp_article $current_subj_index
	    }
	} else {
	    if {$CurrentGroupIndex >= [expr [.r.group.list size] - 1]} {
	        pack_article [expr [.r.group.list size] - 2]
	    } else {
	        pack_article $CurrentGroupIndex
	    }
	}
}

proc skim_cleanup {} {

	global skimhome

	toplevel .ask
	wm title .ask "Cleanup..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text \
"Do you realy want to remove the files in $skimhome/Skipped, $skimhome/Killed and $skimhome/Deleted?"
	pack .ask.top.l -side left
	
	button .ask.bottom.okay -text "Okay" -command {
		destroy .ask
		exec skim cleanup
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m \
	    -pady 1m -expand 1
}

#--------------
# skim_articles
#--------------
proc skim_articles {} {

    global skimhome

    .r.group.list delete 0 end
    set grouplist [exec ListSubscribedNewsGroups]
    foreach i [split $grouplist "\n"] {
	    if {[file exists $skimhome/Subjects/$i]} { .r.group.list insert end $i }
    }
    exec skim articles
    pack_article 0
}

#------
# reply
#------
proc reply {} {

	global skimhome
	global current_name save_name
	global subject_name
	
	if {[file exists $skimhome/Post/$current_name.reply]} {
		set save_name $skimhome/Post/$current_name.reply
		edit_arti $skimhome/Post/$current_name.reply
		return
	}

	toplevel .ask
	wm title .ask "Reply to Article..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text "Do you realy want to reply to: $subject_name ?"
	pack .ask.top.l -side left
	
	button .ask.bottom.okay -text "Okay" -command {
		destroy .ask
		exec skim replyto $current_name
		set save_name $skimhome/Post/$current_name.reply
		edit_arti $skimhome/Post/$current_name.reply
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1
}

#----------
# edit_arti
#----------
proc edit_arti {fname} {
    global env

    if { [lsearch [array names env] SKIMEDITOR] >= 0 } {
	eval exec $env(SKIMEDITOR) $fname
    } else {

	global skimhome textbuf col line goto_command edittab edit_font

        set trailing_spaces 0
        set col 0
        set line 0
	set textbuf .article
	set goto_command ""
	set edittab 5
	

	pack .bottomline.save -side left -padx 10m
	.bottomline.b_del   configure -state disabled
	.bottomline.b_keep   configure -state disabled
	.bottomline.b_reply configure -state disabled
	
	$textbuf configure -state normal
	$textbuf configure -font $edit_font
	$textbuf delete 0.0 end
	ReadFile $fname
	GotoXY $textbuf "1.0"
    }
}

#-------------
# delete_reply
#-------------
proc delete_reply {} {

	global skimhome current_name
	exec rm $skimhome/Post/$current_name.reply
	pack forget .bottomline.replied
	pack forget .bottomline.del_repl
	pack forget .bottomline.save
}

#-----------------------------------------------------------
# Comment from the original author of skim.tcl:
# This code I borrowed from XTeXShell by Michael T. Hofmann
#-----------------------------------------------------------
#-----------
# InsertText
#-----------
proc InsertText {textbuf text} {

#*** Insert text into editor. Move cursor to end of text

        global col line

        $textbuf insert $line.$col "$text"
        GotoXY $textbuf [$textbuf index insert]
}
#------------
# InserEditor
#------------
proc InsertEditor {text} {

#*** Insert text into editor, but only if editor exists. 
#*** Remove all tabs and replace by spaces. Do not move cursor

        global edittab textbuf
        
        set pos [$textbuf index insert]
        InsertText $textbuf "$text" 

#*** Now search through text in 512 byte blocks for tabs and replace them
#*** This routine must be very fast !!!!!

        if {[string first "\t" $text] >= 0} {
                for {set sblock 0} {1 < [clength [$textbuf get "0.0 + $sblock c" "0.0 + $sblock c + 2c"]]}\
			{incr sblock 512} {
                        while {1} {
                                set tpos [string first "\t" [$textbuf get "0.0 + $sblock c" \
					"0.0 + $sblock c + 512 c"]]
                                if {$tpos < 0} {break}

                                incr sblock $tpos
                                $textbuf mark set insert "0.0 + $sblock c"
                                $textbuf delete insert

                                set col [lindex [split [$textbuf index insert] "."] 1]
                                $textbuf insert insert [replicate " " [expr \
					[expr $edittab * ($col / $edittab+ 1)] - $col]]
                        }
                }
        }

#*** Set Cursor position

        GotoXY $textbuf $pos
}

#-------
# GotoXY
#-------
proc GotoXY {textbuf pos {wcol -1}} {

#*** Move Cursor to position pos.
#*** If wcol>=0, goto column wcol. If column wcol does not exist
#*** because the line is shorter, insert spaces at end of line
#*** until wcol is reached. Remove extra spaces when cursor is moved to
#*** the next line.

        global col line
        global goto_command

#*** Calculate new position

        set npos  [$textbuf index "$pos"]
        set nline [lindex [split $npos "."] 0]
        set ncol  [lindex [split $npos "."] 1]

#*** Execute goto_command command

        eval $goto_command
        set goto_command ""

#*** before the line changes, eat up ending spaces (if any)

        if {$line != $nline} {
                EatSpaces $textbuf $line.$col
        }

#*** Set Cursor

        while {1} {
                $textbuf insert $npos ""
                $textbuf mark set insert $npos

#*** Get Cursor position

                set col  [lindex [split [$textbuf index insert] "."] 1]
                set line [lindex [split [$textbuf index insert] "."] 0]

#*** If wcol >=0, check if new column=wcol. If not, insert spaces until
#*** column==wcol. This is important for cursor up/down if line length
#*** is smaller than the requested column

                if {$wcol >= 0 && $col < $wcol} {
                        set xpos [$textbuf index "$nline.0 lineend"]
                        $textbuf mark set insert $xpos

                        set len [expr $wcol - [lindex [split $xpos "."] 1]]
                        $textbuf insert insert [replicate " " $len]
                        set npos "$nline.$wcol"
                        set wcol -1
                        continue
                }

#*** Redisplay text window if neccessary

                $textbuf yview -pickplace insert
                focus $textbuf
                break
        }
}
#---------
#EatSpaces
#---------
proc EatSpaces {textbuf pos} {

#*** Eat all spaces at the end of line pos (YUMM, YUMM)

        set line  [$textbuf get "$pos linestart" "$pos lineend"]
        set len   [expr [clength $line] - [clength [string trimright $line]]]

        if {$len>0} {
                $textbuf delete "$pos lineend -$len c" "$pos lineend"
        }
}
#---------
# ReadFile
#---------
proc ReadFile {fname} {

#*** Include a file at current cursor position
#*** if fname == "", then ask for file name

        global textbuf

#*** Now read file

        set fd [open $fname "r"]
        InsertEditor [read $fd]
        close $fd
}
#-------------
# InsSelection
#-------------
proc InsSelection {textbuf} {

        $textbuf insert insert [selection get]
        GotoXY $textbuf [$textbuf index insert]
}


#----------
# save_arti
#----------
proc save_arti {} {

	global skimhome
	global current_name save_name

	write_file $save_name [.article get 0.0 end]
	pack forget .bottomline.save
	.article delete 0.0 end
	.article configure -state disabled
}

#----------
# make_arti
#----------
proc make_arti {} {
	global skimhome save_name

	toplevel .ask
	wm title .ask "Create new Article..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text "Creating a new Article"
	pack .ask.top.l -side top -anchor nw

	frame .ask.top.r
	pack .ask.top.r -side right
	label .ask.top.l_fname    -text "Local filename:"
	entry .ask.top.r.e_fname  -relief sunken
	label .ask.top.l_groups   -text "Newsgroups:"
	entry .ask.top.r.e_groups -relief sunken
	label .ask.top.l_subj     -text "Subject:"
	entry .ask.top.r.e_subj   -relief sunken
	pack .ask.top.l_fname    -side top -anchor ne
	pack .ask.top.r.e_fname  -side top -anchor nw
	pack .ask.top.l_groups   -side top -anchor ne
	pack .ask.top.r.e_groups -side top -anchor nw
	pack .ask.top.l_subj     -side top -anchor ne
	pack .ask.top.r.e_subj   -side top -anchor nw

	bind .ask.top.r.e_fname  <Up>     { focus .ask.top.r.e_subj }
	bind .ask.top.r.e_fname  <Down>   { focus .ask.top.r.e_groups }
	bind .ask.top.r.e_fname  <Return> { focus .ask.top.r.e_groups }
	bind .ask.top.r.e_groups <Up>     { focus .ask.top.r.e_fname }
	bind .ask.top.r.e_groups <Down>   { focus .ask.top.r.e_subj }
	bind .ask.top.r.e_groups <Return> { focus .ask.top.r.e_subj }
	bind .ask.top.r.e_subj   <Up>     { focus .ask.top.r.e_groups }
	bind .ask.top.r.e_subj   <Down>   { focus .ask.top.r.e_fname }
	bind .ask.top.r.e_subj   <Return> { .ask.bottom.okay invoke }
	focus .ask.top.r.e_fname
	button .ask.bottom.okay -text "Okay" -command {
		set fname [.ask.top.r.e_fname get]
		if {![string length [.ask.top.r.e_fname get]]} { destroy .ask; return }
		if {![string length [.ask.top.r.e_groups get]]} {destroy .ask; return }
		if {![string length [.ask.top.r.e_subj get]]} {destroy .ask; return }
		set save_name $skimhome/Post/$fname
		if {[file exists $skimhome/Post/$fname]} {
			destroy .ask
			edit_arti $skimhome/Post/$fname
			return
		}
                exec skim newarticle $fname [.ask.top.r.e_groups get] \
                                     [.ask.top.r.e_subj get]
		destroy .ask
		edit_arti $save_name
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1
}

#----------
# open_post
#----------
proc open_post {} {

	global skimhome
	global save_name
	
	toplevel .ask
	wm title .ask "Open Postfile..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top -side top -fill both
	label .ask.top.l -text "Double-click file you want to edit."
	pack .ask.top.l -side top

	frame .ask.file -relief groove -borderwidth 2
	scrollbar .ask.file.scroll -command ".ask.file.list yview"
	listbox .ask.file.list -yscroll ".ask.file.scroll set" -relief flat -geometry 30x15 \
		  -exportselection 1

	pack .ask.file  -side top -fill both -expand 1
	pack .ask.file.scroll -side right -fill y
	pack .ask.file.list   -side left -expand 1 -fill both
	.ask.file.list delete 0 end

	set filelist [exec ls $skimhome/Post]
       	foreach i [lsort [split $filelist "\n"]] {
              .ask.file.list insert end $i
       	}
	tk_listboxSingleSelect .ask.file.list
	bind .ask.file.list <Double-Button-1> {.ask.bottom.okay invoke }

	button .ask.bottom.okay -text "Okay" -command {
		if {[.ask.file.list curselection] != ""} {
		    set save_name $skimhome/Post/[.ask.file.list get \
		        [.ask.file.list curselection]]
		    destroy .ask
		    edit_arti $save_name
		}
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1	
	pack .ask.bottom -side bottom -fill both

}

#------------
# delete_post
#------------
proc delete_post {} {

	global skimhome
	global save_name
	
	toplevel .ask
	wm title .ask "Delete Postfile..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top -side top -fill both
	label .ask.top.l -text "Double-click file you want to DELETE."\
		 -background DarkSeaGreen  -foreground red
	pack .ask.top.l -side top

	frame .ask.file -relief groove -borderwidth 2
	scrollbar .ask.file.scroll -command ".ask.file.list yview"
	listbox   .ask.file.list   -yscroll ".ask.file.scroll set" -relief flat -geometry 30x15 \
		  -exportselection 1

	pack .ask.file  -side top -fill both -expand 1
	pack .ask.file.scroll -side right -fill y
	pack .ask.file.list   -side left -expand 1 -fill both

	.ask.file.list delete 0 end
	set filelist [exec ls $skimhome/Post]
       	foreach i [lsort [split $filelist "\n"]] {
              .ask.file.list insert end $i
       	}
	tk_listboxSingleSelect .ask.file.list
	bind .ask.file.list <Double-Button-1> {.ask.bottom.okay invoke }

	button .ask.bottom.okay -text "Okay" -command {
	    if {[.ask.file.list curselection] != ""} {
		set save_name $skimhome/Post/[.ask.file.list get \
		    [.ask.file.list curselection]]
		exec rm $save_name
		.ask.file.list delete 0 end
		set filelist [exec ls $skimhome/Post]
		foreach i [lsort [split $filelist "\n"]] {
		    .ask.file.list insert end $i
	        }
	    }
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1	
	pack .ask.bottom -side bottom -fill both

}

#------------
# post
#------------
proc post {} {

	global skimhome
	global save_name
	
	toplevel .ask
	wm title .ask "Post file..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top -side top -fill both
	label .ask.top.l -text "Double-click file you want to POST."
	pack .ask.top.l -side top

	frame .ask.file -relief groove -borderwidth 2
	scrollbar .ask.file.scroll -command ".ask.file.list yview"
	listbox   .ask.file.list   -yscroll ".ask.file.scroll set" -relief flat -geometry 30x15 \
		  -exportselection 1

	pack .ask.file  -side top -fill both -expand 1
	pack .ask.file.scroll -side right -fill y
	pack .ask.file.list   -side left -expand 1 -fill both
	.ask.file.list delete 0 end

	set filelist [exec ls $skimhome/Post]
       	foreach i [lsort [split $filelist "\n"]] {
              .ask.file.list insert end $i
       	}
	tk_listboxSingleSelect .ask.file.list
	bind .ask.file.list <Double-Button-1> {.ask.bottom.okay invoke }

	button .ask.bottom.okay -text "Okay" -command {
	        if {[.ask.file.list curselection] != ""} {
		    set save_name $skimhome/Post/[.ask.file.list get \
		        [.ask.file.list curselection]]
		    exec skim post $save_name
		    .ask.file.list delete 0 end
		    set filelist [exec ls $skimhome/Post]
	       	    foreach i [lsort [split $filelist "\n"]] {
	                  .ask.file.list insert end $i
	       	    }
		}
	}
	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1	
	pack .ask.bottom -side bottom -fill both
}


#-------------------------------------------------
#         procs for subjects mode
#-------------------------------------------------
# get_selected
#-------------
proc get_selected {ypos} {

	global skimhome
	global subj_group_name

	set current [.r.group.list get [.r.group.list nearest $ypos]]
	if {$current == ""} { return }
	if {![file exists $skimhome/Subjects/$current]} { return }
	.l.n_selected.list delete 0 end
	.l.selected.list   delete 0 end
	set subjlist [exec cat "$skimhome/Subjects/$current"]
        	foreach i [lsort [split $subjlist "\n"]] {
			# The pattern below is SPACE or TAB.
			if {[regexp {^[ 	]} $i]} {
				.l.selected.list insert end $i
		 	} else {
				.l.n_selected.list insert end $i
			}
	        }	
	set subj_group_name $current
}

#------------------
# ins_select
#------------------
proc ins_select {} {

	global skimhome
	global MustSave

	set sel " "
	set select_list [.l.n_selected.list curselection]
	if {![llength $select_list]} { return }
	.l.button_line.save configure -state normal
	set MustSave 1
	foreach i $select_list {
		set current [.l.n_selected.list get $i]
		append sel $current
		.l.selected.list insert end $sel
		set sel " "
	}
	.l.n_selected.list delete [lindex $select_list 0] \
		 [lindex $select_list [expr [llength $select_list] - 1]]

}

#-------------
# ins_n_select
#-------------
proc ins_n_select {} {

	global skimhome
	global MustSave
	
	set select_list [.l.selected.list curselection]
	if {![llength $select_list]} { return }
	.l.button_line.save configure -state normal
	set MustSave 1
	foreach i $select_list {
		.l.n_selected.list insert end [string range [.l.selected.list get $i] 1 end]

	}
	.l.selected.list delete  [lindex $select_list 0] \
		[lindex $select_list [expr [llength $select_list] - 1]]
}

proc save_subjlist {} {

    global skimhome
    global subj_group_name
    global MustSave

    exec rm $skimhome/Subjects/$subj_group_name

    set fid [open $skimhome/Subjects/$subj_group_name w]
    for {set i 0} {$i < [.l.selected.list size]} {incr i} {
	    puts $fid [.l.selected.list get $i]
    }
    for {set i 0} {$i < [.l.n_selected.list size]} {incr i} {
	    puts $fid [.l.n_selected.list get $i]
    }
    flush $fid
    close $fid

    .l.button_line.save configure -state disabled
    set MustSave 0
}


proc outstanding_work {} {

    global MustSave

    if {$MustSave} {ask_save_subjlist}
}


proc ask_save_subjlist {} {

	global skimhome
	global subj_group_name

	if {![string compare $subj_group_name ""]} {
		return
	}

	toplevel .ask
	wm title .ask "Save selected Articles..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text "Do you want to save the changes in: $subj_group_name ?"
	pack .ask.top.l -side left

	button .ask.bottom.okay -text "Save Changes" -command {
		destroy .ask
		save_subjlist
	}

	button .ask.bottom.cancel -text "Ignore changes" -command {
		.l.button_line.save configure -state disabled
		set MustSave 0
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1
        tkwait window .ask
}

proc old_save_subjlist {} {

	global skimhome
	global subj_group_name
	global MustSave

	if {![string compare $subj_group_name ""]} {
		return
	}

	toplevel .ask
	wm title .ask "Save selected Articles..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text "Do you really want to save the changes in: $subj_group_name ?"
	pack .ask.top.l -side left

	button .ask.bottom.okay -text "Okay" -command {
		destroy .ask
		save_subjlist
		.l.button_line.save configure -state disabled
		set MustSave 0
	}

	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1
        tkwait window .ask
}

#--------------
# save_subjlist
#--------------
proc old_save_subjlist {} {

	global skimhome
	global subj_group_name
	global MustSave

	if {![string compare $subj_group_name ""]} {
		return
	}

	toplevel .ask
	wm title .ask "Save selected Articles..."
	wm geometry .ask +100+100
	wm positionfrom .ask user
	frame .ask.top -bd 3 -relief groove
	frame .ask.bottom -bd 1
	pack .ask.top .ask.bottom -side top -fill both
	label .ask.top.l -text "Do you want to save the changes in: $subj_group_name ?"
	pack .ask.top.l -side left

	button .ask.bottom.okay -text "Okay" -command {
		destroy .ask
		exec rm $skimhome/Subjects/$subj_group_name
		
		set fid [open $skimhome/Subjects/$subj_group_name w]
		for {set i 0} {$i < [.l.selected.list size]} {incr i} {
			puts $fid [.l.selected.list get $i]
		}
		for {set i 0} {$i < [.l.n_selected.list size]} {incr i} {
			puts $fid [.l.n_selected.list get $i]
		}
		flush $fid
		close $fid
		.l.button_line.save configure -state disabled
		set MustSave 0
	}

	button .ask.bottom.cancel -text "Cancel" -command {
		destroy .ask
	}
	
	pack .ask.bottom.okay .ask.bottom.cancel -side left -padx 1m -pady 1m -expand 1
        tkwait window .ask
}

#--------------------------------------------------------------------------
# MAIN

wm minsize . 640 400
frame .dummy -width 640 -height 320 -borderwidth 2

#--------- topline
frame .topline -relief groove -borderwidth 3
button .topline.b_subs -text "Skim Subjects" -command { outstanding_work
                                                   unpack_article
						   pack_subjects
						 }
button .topline.b_arti -text "Skim Articles" -command { outstanding_work
                                                   unpack_subjects
						   pack_article 0
						 }
button .topline.b_make    -text "New Article"  -command { outstanding_work; .topline.b_arti invoke; make_arti }
button .topline.b_open    -text "Open Article" -command { outstanding_work; .topline.b_arti invoke; open_post}
button .topline.b_delete  -text "Delete Outgoing Article" -command { outstanding_work; delete_post}
button .topline.b_post    -text "Post"         -command { outstanding_work; post}
button .topline.b_postall -text "Post All"      -command { outstanding_work; exec skim postall}
button .topline.b_cleanup -text "Cleanup"      -command { outstanding_work; skim_cleanup}
button .topline.b_quit    -text "Quit"         -command { outstanding_work; exit }
pack .topline.b_subs -side left -padx 2m
pack .topline.b_arti -side left -padx 2m
pack .topline.b_make -side left -padx 2m
pack .topline.b_open -side left -padx 2m
pack .topline.b_delete -side left -padx 2m
pack .topline.b_post    -side left -padx 2m
pack .topline.b_postall -side left -padx 2m
pack .topline.b_cleanup -side left -padx 2m
pack .topline.b_quit -side right -padx 2m
pack .topline        -side top -fill x

#-----------------
# Articles 
#-----------------
frame  .bottomline         -relief groove -borderwidth 2
button .bottomline.b_del   -text "Delete Article" -activebackground red -state disabled -command {outstanding_work; move_article delete}
button .bottomline.b_keep   -text "Keep Article" -activebackground green -state disabled -command {outstanding_work; move_article keep}

button .bottomline.b_reply -text "Reply" -activebackground "light blue" -command {outstanding_work; reply} -state disabled
button .bottomline.del_repl -text "Delete Reply" -command {outstanding_work; delete_reply }
button .bottomline.b_new    -text "Get Selected Articles" -command {outstanding_work; skim_articles }
label  .bottomline.replied -text "Reply exists" -relief sunken
pack   .bottomline.b_del   -side left -padx 2m
pack   .bottomline.b_keep   -side left -padx 2m

pack   .bottomline.b_reply -side left -padx 2m
pack   .bottomline.b_new  -side right -padx 2m

scrollbar .scroll -command {.article yview}
text .article -yscroll ".scroll set" -relief raised -borderwidth 1 -height 40 -width 80 -state disabled\
	-font $text_font -setgrid 0

#---------- groups
frame .r
frame .r.group -relief groove -borderwidth 2
label .r.label1 -anchor nw -text "Groups:"
scrollbar .r.group.scroll -command ".r.group.list yview"
listbox   .r.group.list   -yscroll ".r.group.scroll set" -relief flat \
          -geometry 30x5 -exportselection 1

pack .r.label1 -side top -fill x
pack .r.group  -side top -fill both -expand 1
pack .r.group.scroll -side right -fill y
pack .r.group.list   -side left -expand 1 -fill both

#----------
frame .r.subj    -relief groove -borderwidth 2
label .r.label2  -anchor nw -text "Subjects:"
scrollbar .r.subj.scroll -command ".r.subj.list yview"
listbox   .r.subj.list   -yscroll ".r.subj.scroll set" -relief flat \
          -geometry 30x5

pack .r.label2 -side top -fill x
pack .r.subj -side bottom  -fill both -expand 1
pack .r.subj.scroll -side right -fill y
pack .r.subj.list   -side left -expand 1 -fill both


pack .dummy -side top -expand 1 -fill both -padx 2m -pady 1m

tk_listboxSingleSelect .r.subj.list .r.group.list

#--------------
# subjects
#--------------

frame .l
frame .l.selected -relief groove -borderwidth 2
label .l.label1 -anchor nw -text "Selected Subjects:"
scrollbar .l.selected.scroll -command ".l.selected.list yview"
listbox   .l.selected.list   -yscroll ".l.selected.scroll set" -relief flat -geometry 40x5 \
		  -exportselection 1

pack .l.label1 -side top -fill x
pack .l.selected  -side top -fill both -expand 1
pack .l.selected.scroll -side right -fill y
pack .l.selected.list   -side left -expand 1 -fill both

frame .l.n_selected -relief groove -borderwidth 2
label .l.label2 -anchor nw -text "Not selected Subjects:"
scrollbar .l.n_selected.scroll -command ".l.n_selected.list yview"
listbox   .l.n_selected.list   -yscroll ".l.n_selected.scroll set"\
		 -relief flat -geometry 40x5  -exportselection 0

frame  .l.button_line
button .l.button_line.sel    -text "Select" -command  { ins_select }
button .l.button_line.save -text "Save Changes" -command { save_subjlist } -state disabled
button .l.button_line.n_sel  -text "Unselect" -command { ins_n_select }
place  .l.button_line.sel    -rely 0.5 -relx 0.15 -anchor center -relwidth 0.25
place  .l.button_line.save -rely 0.5 -relx 0.5  -anchor center -relwidth 0.45
place  .l.button_line.n_sel  -rely 0.5 -relx 0.85 -anchor center -relwidth 0.25
pack   .l.button_line -side top -fill x -pady 1m -padx 10m -ipady 12

pack .l.label2 -side top -fill x
pack .l.n_selected  -side bottom -fill both -expand 1
pack .l.n_selected.scroll -side right -fill y
pack .l.n_selected.list   -side left -expand 1 -fill both

button .r.b_get_subj -text "Get New Subjects" -command {
    outstanding_work
    exec skim subjects
    pack_subjects
}


bind .r.subj.list <Button-1>      {
    .r.subj.list select from [.r.subj.list nearest %y]
    disp_article [.r.subj.list nearest %y]
}


#--------
# edit
#--------

button .bottomline.save -text "Save" -command {save_arti}
set trailing_spaces 0
set col 0
set line 0
set textbuf .article
set goto_command ""
$textbuf configure -state normal
bind $textbuf <Home>            {GotoXY  $textbuf [$textbuf index "insert linestart"]}
bind $textbuf <Up>              {GotoXY  $textbuf [$textbuf index insert-1l] $col}
bind $textbuf <Left>            {GotoXY  $textbuf [$textbuf index insert-1c]}
bind $textbuf <Right>           {GotoXY  $textbuf [$textbuf index insert+1c]}
bind $textbuf <Down>            {GotoXY  $textbuf [$textbuf index insert+1l] $col}
bind $textbuf <End>             {EatSpaces $textbuf $line.$col; GotoXY  $textbuf \
	[$textbuf index "insert lineend"]}
bind $textbuf <Prior>           {GotoXY  $textbuf [$textbuf index insert-25l] $col}
bind $textbuf <Next>            {GotoXY  $textbuf [$textbuf index insert+25l] $col}
bind $textbuf <Control-Prior>   {GotoXY  $textbuf [$textbuf index insert-100000l] $col}
bind $textbuf <Control-Next>    {GotoXY  $textbuf [$textbuf index insert+100000l] $col}
bind $textbuf <Double-2>        {InsSelection %W}
focus $textbuf
$textbuf configure -state disabled

# If there are articles to be read, start with the article screen. Otherwise,
# start with the subject screen.
pack_article 0
if {[.r.group.list size] == 0} {
    unpack_article
    pack_subjects
}
