#!/bin/sh
# the next line restarts using wish\
exec tixwish "$0" "$@"
#
# tKMailHonArc.tcl
# convert KMail folder to HTML with MHonArc (http://www.mhonarc.org/)
# using tix (http://tix.sourceforge.net)
# Martin Bernreuther <martin@bernreuther.net>
# 15.04.2003
# License: GPL (http://www.gnu.org/copyleft/gpl.html)

# Scriptname & Version
set ScriptName "tKMailHonArc"
set ScriptVersion "0.1.2"

set OutRootDir  "~"
#set OutRootDir  [pwd]
set RootDir [file join ~ Mail]
set Folder ""
set MHonArcRC ""
set Mozilla false


set MHonArcOK false

set folderimg [tix getimage "folder"]
set fileimg [list [tix getimage "no_entry"] [tix getimage "textfile"] [tix getimage "file"]]

set folderTypes {"none" "mbox" "maildir"}

#=======================================================================
# command line arguments

set i 0
while {$i<$argc} {
	switch -- [lindex $argv $i] {
	"--outdir" {
		incr i
		if {$i<$argc} {
			set OutRootDir [lindex $argv $i]
			puts "Output directory:\t$OutRootDir"
		}
	}
	"--rcfile" {
		incr i
		if {$i<$argc} {
			set MHonArcRC [lindex $argv $i]
			set MHonArcRC [glob -nocomplain -type f -- $MHonArcRC]
			if {$MHonArcRC!=""} {puts "MHonArc RC file:\t$MHonArcRC"}
		}
	}
	"--maildir" {
		incr i
		if {$i<$argc} {
			set RootDir [lindex $argv $i]
			puts "Mail directory:\t$RootDir"
		}
	}
	"--inifolder" {
		incr i
		if {$i<$argc} {
			set Folder [lindex $argv $i]
			puts "initial Folder:\t$Folder"
		}
	}
	"--mozilla" {
		puts "Mozilla mail directory"
		set Mozilla true
	}
	"--version" {
		puts "$ScriptName V$ScriptVersion"
		#exit
	}
	default {
		if {[lindex $argv $i]!="--help"} {puts "unknown option [lindex $argv $i]"}
		puts "usage: $ScriptName \[--outdir <OutputDirectory>\] \[--rcfile <MHonArcRCfile>\] \[--maildir <MailDirectory>\] \[--inifolder <initialFolderEntry>\] \[--mozilla\] \[--version\]"
		exit
	}
	}
	incr i
}

#=======================================================================
# exeCommand
proc exeCommand {} {
	global OutRootDir RootDir Folder MHonArcRC MHonArcOK errorCode errorInfo
	.fLogOutput.text configure -state normal
	.fLogOutput.text yview end
	if {!$MHonArcOK} {
		.fLogOutput.text insert end "mhonarc not in PATH!\n"
		return
	}
	set folder [file join $RootDir $Folder]
	set outdir [getOutDir]
	switch -- [foldertype $folder] {
		1 {
			set folder [glob $folder]
			.fLogOutput.text insert end "converting mbox $folder:\n"
			makedir $outdir
			if {$MHonArcRC!=""} {
				set retcode  [catch { set CmdOutput [exec -keepnewline -- mhonarc $folder -outdir $outdir -rcfile $MHonArcRC]}]
			} else {
				set retcode  [catch { set CmdOutput [exec -keepnewline -- mhonarc $folder -outdir $outdir]}]
			}
		}
		2 {
			set folder [glob $folder]
			.fLogOutput.text insert end "converting maildir $folder (cur and new):\n"
			makedir $outdir
			if {$MHonArcRC!=""} {
				set retcode  [catch { set CmdOutput [exec -keepnewline -- mhonarc -mhpattern ^\[^\\.\] [file join $folder cur] [file join $folder new] -outdir $outdir -rcfile $MHonArcRC]}]
			} else {
				set retcode  [catch { set CmdOutput [exec -keepnewline -- mhonarc -mhpattern ^\[^\\.\] [file join $folder cur] [file join $folder new] -outdir $outdir]}]
			}
		}
		default {
			.fLogOutput.text insert end "$folder is not a valid mail archive!\n"
			.fLogOutput.text configure -state disabled
			return
		}
	}
	if {$retcode} {
		.fLogOutput.text insert end "Error converting $folder to $outdir:\n"
		.fLogOutput.text insert end "\n----------------------------------------\n"
		.fLogOutput.text insert end "Error code: $errorCode\n"
		.fLogOutput.text insert end "Error information:\n$errorInfo\n"
		.fLogOutput.text insert end "----------------------------------------\n\n"
	} else {
		.fLogOutput.text insert end $CmdOutput
		.fLogOutput.text insert end "\n"
		#exit
	}
	.fLogOutput.text configure -state disabled
	.fLogOutput.text yview end
}

# About
proc about {} {
	global ScriptName ScriptVersion
	tk_dialog .dialog {"About"} \
	"$ScriptName V$ScriptVersion\nby M. Bernreuther (http://www.bernreuther.net/martin/)\n\nPurpose: Convert a KMail email folder to HTML using MHonArc (http://www.mhonarc.org/)\n" \
	{} 0 {Ok}
}

# foldertype
proc foldertype {folder} {
	global Mozilla
	if {![file exists $folder]} {return 0}
	if {![file isdirectory $folder]} {
		# file
		if {$Mozilla && [regexp -- "\[.\](?:smn|msf)\$" $folder]} {
			return -1
		} else {
			return 1
		}
	} elseif { [file exists [file join $folder cur]] } {
		# directory with cur subdirectory
		return 2
	} else {
		# directory without cur subdirectory
		return 0
	}
}


proc chooseFolder {entry} {
	global Folder RootDir folderTypes
	set folder [file join $RootDir $entry]
	set type [foldertype $folder]
	if { $type } {
		set Folder $entry
		set infotext [lindex $folderTypes $type]
		switch -- $type {
			2 {
				set fsize 0
				set nummsg 0
				foreach f [glob -nocomplain -directory $folder -- [file join cur *] [file join new *]] {
					incr fsize [file size $f]
					incr nummsg 1
				}
			}
			default {
				set fsize [file size $folder]
				# grep "^From " $folder | wc -l
				set nummsg 0
			}
		}
		set fsizeunit "Byte"
		if {$fsize>1024} {
			set fsize [expr $fsize/1024.]
			set fsizeunit "kByte"
		}
		if {$fsize>1024} {
			set fsize [expr $fsize/1024.]
			set fsizeunit "MByte"
		}
		if {$nummsg} {
			append infotext " with $nummsg messages"
		}
		if {$fsize==0} {
			append infotext " (empty)"
		} else {
			if {$fsize==int($fsize)} {
				append infotext " ([expr int($fsize)] $fsizeunit)"
			} else {
				append infotext " ([format %.2f $fsize] $fsizeunit)"
			}
		}
		.fDir.fFolder.labelType config -text $infotext
		.fDir.fOutRootDir.labelOutDir configure -text [getOutDir]
	}
}

proc inittree { {dir ""} } {
	global RootDir Mozilla folderimg fileimg
	set hlist [.fDir.fFolder.tree subwidget hlist]
	if {$Mozilla} {
		# directories: *.sbd
		set folderlist [lsort [glob -nocomplain -directory [file join $RootDir $dir] -- *]]
	} else {
		# directories: .*.directory
		set folderlist [lsort [glob -nocomplain -directory [file join $RootDir $dir] -- * .*.directory]]
	}
	foreach f  $folderlist {
		set folder [file tail $f]
		set dirfolder $folder
		if {$dir!=""} {
			set dirfolder $dir/$folder
		}
		switch -- [foldertype $f] {
			0 {
				$hlist add $dirfolder -image $folderimg -text $folder
				inittree $dirfolder
			}
			1 {
				$hlist add $dirfolder -image [lindex $fileimg 1] -text $folder
			}
			2 {
				$hlist add $dirfolder -image [lindex $fileimg 2] -text $folder
			}
		}
	}

}

proc setOutRootDir {dir} {
	global OutRootDir errorCode
	if {![file exists $dir]} {
		.fDir.fOutRootDir.labelOutDir configure -text "$dir does not exist!"
	} elseif {![file writable $dir]} {
		.fDir.fOutRootDir.labelOutDir configure -text "$dir not writable!"
	} else {
		set OutRootDir $dir
		set retcode [catch {cd $OutRootDir}]
		if {$retcode} {
			.fLogOutput.text insert end "could not change current directory to $OutRootDir!\n"
		} else {
			.fDir.fOutRootDir.labelOutDir configure -text [getOutDir]
		}
	}
	#.fDir.fOutRootDir.dirtree configure -directory [glob $OutRootDir]
	.fDir.fOutRootDir.dirtree chdir [pwd]
	set hlist [.fDir.fOutRootDir.dirtree subwidget hlist]
	catch {
		$hlist see [pwd]
		$hlist selection clear
		$hlist selection set [pwd]
	}
	# in case of an error, show OutDir after error message
	after 3000 { .fDir.fOutRootDir.labelOutDir configure -text [getOutDir] }
}

proc getOutDir {} {
	global Folder Mozilla
	set folderitems [split $Folder "/"]
	set OutDir [pwd]
	for {set i 0} {$i<[llength $folderitems]} {incr i 1} {
		set entry [lindex $folderitems $i]
		if {$Mozilla} {
			regsub -all -- "\[.\]sdb$" $entry "" modentry
		} else {
			regsub -all -- "^\[.\]|\[.\]directory$" $entry "" modentry
		}
		set OutDir [file join $OutDir $modentry]
	}
	return $OutDir
}

proc makedir {dir} {
	set parentdir [file dirname $dir]
	if {![file exists $parentdir]} { makedir $parentdir }
	file mkdir $dir
	.fLogOutput.text insert end "directory $dir created!\n"
}

# GUI

wm title . "$ScriptName $ScriptVersion"

frame .fDir
# Folder ---------------------------------------------------------------
frame .fDir.fFolder
label .fDir.fFolder.labelFolder -text "Choose Folder ($RootDir):"
pack .fDir.fFolder.labelFolder .fDir.fFolder -side top
tixTree .fDir.fFolder.tree -command chooseFolder -options {
		hlist.separator  /
		hlist.itemType   imagetext
		hlist.drawBranch true
		hlist.indent     18
}
pack .fDir.fFolder.tree -expand yes -fill both
inittree
.fDir.fFolder.tree autosetmode

entry .fDir.fFolder.entryFolder -textvariable Folder -width 60
pack .fDir.fFolder.entryFolder

label .fDir.fFolder.labelType
pack .fDir.fFolder.labelType

# OutRootDir ---------------------------------------------------------------
frame .fDir.fOutRootDir
label .fDir.fOutRootDir.labelOutRootDir -text "Choose output directory:"
pack .fDir.fOutRootDir.labelOutRootDir -side top

if {![file exists $OutRootDir]} {set OutRootDir [pwd]}
tixDirTree .fDir.fOutRootDir.dirtree -directory $OutRootDir -command "setOutRootDir"
pack .fDir.fOutRootDir.dirtree -expand yes -fill both

entry .fDir.fOutRootDir.entryOutRootDir -textvariable OutRootDir -width 60
bind .fDir.fOutRootDir.entryOutRootDir <Return> { setOutRootDir $OutRootDir }
pack .fDir.fOutRootDir.entryOutRootDir

label .fDir.fOutRootDir.labelOutDir -text [pwd]
pack .fDir.fOutRootDir.labelOutDir

setOutRootDir $OutRootDir

pack .fDir.fFolder .fDir.fOutRootDir -side left

# LogOutput ------------------------------------------------------------
frame .fLogOutput
text .fLogOutput.text -state disabled -relief sunken -bd 2 -yscrollcommand ".fLogOutput.scroll set" -setgrid 1 -height 10
scrollbar .fLogOutput.scroll -command ".fLogOutput.text yview"
pack .fLogOutput.scroll -side right -fill y
pack .fLogOutput.text -expand yes -fill both
.fLogOutput.text configure -state normal
.fLogOutput.text insert end "$ScriptName Log window ([clock format [clock seconds]])\n\n"
set retcode  [catch { set CmdOutput [exec -keepnewline -- which mhonarc]}]
if {!$retcode} {
	# mhonarc found
	.fLogOutput.text insert end "MHonArc executable: "
	.fLogOutput.text insert end $CmdOutput
	.fLogOutput.text insert end "\n"

	set retcode  [catch { set CmdOutput [exec -keepnewline -- mhonarc --v]}]
	if {$retcode} {
		.fLogOutput.text insert end "Error executing mhonarc:\n"
		.fLogOutput.text insert end "look at http://www.mhonarc.org/ for installation details...\n"
		.fLogOutput.text insert end "\n----------------------------------------\n"
		.fLogOutput.text insert end "Error code: $errorCode\n"
		.fLogOutput.text insert end "Error information:\n$errorInfo\n"
		.fLogOutput.text insert end "----------------------------------------\n\n"
	} else {
		.fLogOutput.text insert end "MHonArc installed:\n"
		.fLogOutput.text insert end $CmdOutput
		.fLogOutput.text insert end "\n"
		if {$MHonArcRC!=""} {
			.fLogOutput.text insert end "using MHonArc RC file:\t$MHonArcRC\n"
		}
		set MHonArcOK true
	}
} else {
	.fLogOutput.text insert end "MHonArc not installed?\n"
	.fLogOutput.text insert end "look at http://www.mhonarc.org/\n"
}
.fLogOutput.text yview end
.fLogOutput.text insert end "\n"
.fLogOutput.text configure -state disabled

# buttons --------------------------------------------------------------
frame .fButtons
button .fButtons.exec -text "Start" -command exeCommand
button .fButtons.about -text "About" -command about
button .fButtons.exit -text "Exit" -command exit
pack .fButtons.exec .fButtons.about .fButtons.exit -side left -expand 1 -fill x

pack .fDir .fLogOutput .fButtons -fill x -pady 2m
