#!/usr/bin/env wish

#
# This program gives a combined electronic diary and time clock.
# Copyright John Lines (john@paladin.demon.co.uk) November 1999
#
# This program is released under the terms of the GNU Public Licence
#

set version 0.1.52

proc sourcelibs {} {
global libsdir auto_path
# we will look for tag.tcl in the same directory as this script.
# and in /usr/local/lib/taglog, and /usr/lib/taglog, and /usr/lib/tag


set scriptdir [file dirname [info script]]


# I will use taglog_help.tcl as the file to indicate where the library
# files are.
if { [file readable "$scriptdir/taglog_help.tcl"] } {
  set libsdir $scriptdir
  } elseif { [file readable "~/lib/taglog/taglog_help.tcl"] } {
  set libsdir ~/lib/taglog
  } elseif { [file readable "/usr/lib/taglog/taglog_help.tcl"] } {
  set libsdir /usr/lib/taglog
  } elseif { [file readable "/usr/share/taglog/taglog_help.tcl"] } {
  set libsdir /usr/share/taglog
  } elseif { [file readable "/usr/local/lib/taglog/taglog_help.tcl"] } {
  set libsdir /usr/local/lib/taglog
  } else {
    error "Cant find taglog_help.tcl"
  }

# In order to be wrappable with sdx we need to require Tk

package require Tk


# append the libsdir directory to the auto_path

lappend auto_path $libsdir

# These may be in some real library location as they may not be exclusive
# to taglog

package require tag
package require smtpclient

# These are local taglog packages

package require taglog_help
package require taglog_report
package require taglog_init
package require taglog_util
package require taglog_project
package require taglog_action
package require taglog_contact
package require taglog_widgets
package require logEdit
package require mainwin
package require taglog_stack


if { [file readable "$libsdir/cal2.xbm"] } {
        global CALIMAGE
        set CALIMAGE $libsdir/cal2.xbm
        } else {
        error "Can not find $libsdir/cal2.xbm"
}


}



proc gettime {} {
 global hh mm ss tcl_platform
 if { [info tclversion] >=8.0 } {
    set d [clock format [clock seconds] -format "%H:%M:%S"]
    scan $d "%d:%d:%d" hh mm ss
    } else {
 if {$tcl_platform(platform) == "unix"} { 
 catch {exec date +%H:%M } d
 scan $d "%d:%d" hh mm
 } elseif {$tcl_platform(platform) == "windows"} {
    puts "Cant handle Windows yet - coming soon"
    exit
 } else {
    puts "Unknown platform $tcl_platform(platform) - please report to john+taglog@paladin.demon.co.uk"
    exit
  }
  }
 set hh [format "%02d" $hh]
 set mm [format "%02d" $mm]
 set ss [format "%02d" $ss]
}

proc getdate {} {
 global year month day
# catch {exec date +%Y-%m-%d } d
 set d [clock format [clock seconds] -format "%Y-%m-%d"]
 scan $d "%d-%d-%d" year month day
 set month [format "%02d" $month]
 set day [format "%02d" $day]
}
 


proc logfilename2date { filename args } {
global year dateformat_tcl dateformat_view
# Improved version thanks to Bruce Gingery

if { $filename == "" } {
	return ""
	}

if {[lindex $args 0] == "-iso" } {
	set mydateformat "YYYY-MM-DD"
	} elseif { [lindex $args 0] == "-us" } {
	set mydateformat "MM/DD/YYYY"
	} else {
	set mydateformat $dateformat_view
	}

set mmdd [file rootname [file tail $filename]]
set mm [ string range $mmdd 0 1]
set dd [string range $mmdd 2 3]

set logyear $year
regexp {^log(\d+)$} [file tail [file dirname $filename]] {} logyear

if { $mydateformat == "DD/MM/YYYY" } {
 set result "$dd/$mm/$logyear"
 } elseif { $mydateformat == "MM/DD/YYYY" } {
 set result "$mm/$dd/$logyear"
 } else {
# default to ISO format
  set result "$logyear-$mm-$dd"
 }
return $result
}

proc fieldname2index { fn } {
# take in a field name such as Email-status-to and return a value suitable
# for an array index - I think I can just change - to _

regsub -all -- "-" $fn _ result
return $result
}

proc index2fieldname { index } {

regsub -all _ $index "-" result
return $result
}



proc dologedit { entrynum } {
global logentries
global logedit_id logedit_start logedit_end logedit_description logedit_project logedit_action logedit_actiontitle logedit_activity logedit_contact logedit_rate logedit_stack_info

set entry ""
set logedit_description($entrynum) [string trim [.logedit$entrynum.description.v get 1.0 end]]

set entry [tagappend $entry Id $logedit_id($entrynum)]
set entry [tagappend $entry StartTime $logedit_start($entrynum)]
set entry [tagappend $entry EndTime $logedit_end($entrynum)]
set entry [tagappend $entry Project $logedit_project($entrynum)]
set entry [tagappend $entry Action $logedit_action($entrynum)]
set entry [tagappend $entry ActionTitle $logedit_actiontitle($entrynum)]
set entry [tagappend $entry Activity $logedit_activity($entrynum)]
set entry [tagappend $entry Contact $logedit_contact($entrynum)]
set entry [tagappend $entry Rate $logedit_rate($entrynum)]
set entry [tagappend $entry Stack-info $logedit_stack_info($entrynum)]
set entry [tagappend $entry Description $logedit_description($entrynum) END_D]

set endpair [list End ]
lappend entry $endpair

set logentries [lreplace $logentries $entrynum $entrynum $entry]
writelog -modify
fillpreventries .preventries.body

destroy .logedit$entrynum
}

proc editpreventry { entrynum } {
global logentries
global logedit_id logedit_start logedit_end logedit_description logedit_project logedit_action logedit_actiontitle logedit_activity logedit_contact logedit_rate logedit_stack_info

set thisentry [lindex $logentries $entrynum]

toplevel .logedit$entrynum
wm title .logedit$entrynum "[mc {Edit log entry}] $entrynum"

frame .logedit$entrynum.id
menubutton .logedit$entrynum.id.n -text "Id" -menu .logedit$entrynum.id.n.m
menu .logedit$entrynum.id.n.m
.logedit$entrynum.id.n.m add command -label [mc Help] -command "taghelp logedit_id"
entry .logedit$entrynum.id.v -width 20 -textvariable logedit_id($entrynum)
pack .logedit$entrynum.id.n .logedit$entrynum.id.v -in .logedit$entrynum.id -side left
pack .logedit$entrynum.id

frame .logedit$entrynum.start
menubutton .logedit$entrynum.start.n -text [mc "Start Time"] -menu .logedit$entrynum.start.n.m
menu .logedit$entrynum.start.n.m
.logedit$entrynum.start.n.m add command -label [mc Help] -command "taghelp logedit_start"
entry .logedit$entrynum.start.v -width 10 -textvariable logedit_start($entrynum)
pack .logedit$entrynum.start.n .logedit$entrynum.start.v -in .logedit$entrynum.start -side left
pack .logedit$entrynum.start

frame .logedit$entrynum.end
menubutton .logedit$entrynum.end.n -text [mc "End Time"] -menu .logedit$entrynum.end.n.m
menu .logedit$entrynum.end.n.m
.logedit$entrynum.end.n.m add command -label [mc Help] -command "taghelp logedit_end"
entry .logedit$entrynum.end.v -width 10 -textvariable logedit_end($entrynum)
pack .logedit$entrynum.end.n .logedit$entrynum.end.v -in .logedit$entrynum.end -side left
pack .logedit$entrynum.end

set logedit_project($entrynum) ""
frame .logedit$entrynum.project
menu_create .logedit$entrynum.project.n [mc Project] logedit_project 1 projAll menu_setText .logedit$entrynum.project.v
entry .logedit$entrynum.project.v -width 20 -textvariable logedit_project($entrynum)
pack .logedit$entrynum.project.n .logedit$entrynum.project.v -in .logedit$entrynum.project -side left
pack .logedit$entrynum.project

set logedit_action($entrynum) ""
frame .logedit$entrynum.action
menubutton .logedit$entrynum.action.n -text [mc "Action"] -menu .logedit$entrynum.action.n.m
menu .logedit$entrynum.action.n.m
.logedit$entrynum.action.n.m add command -label [mc Help] -command "taghelp logedit_action"
entry .logedit$entrynum.action.v -width 20 -textvariable logedit_action($entrynum)
pack .logedit$entrynum.action.n .logedit$entrynum.action.v -in .logedit$entrynum.action -side left
pack .logedit$entrynum.action

set logedit_actiontitle($entrynum) ""
frame .logedit$entrynum.actiontitle
menubutton .logedit$entrynum.actiontitle.n -text [mc ActionTitle] -menu .logedit$entrynum.actiontitle.n.m
menu .logedit$entrynum.actiontitle.n.m
.logedit$entrynum.actiontitle.n.m add command -label [mc Help] -command "taghelp logedit_actiontitle"
entry .logedit$entrynum.actiontitle.v -width 20 -textvariable logedit_actiontitle($entrynum)
pack .logedit$entrynum.actiontitle.n .logedit$entrynum.actiontitle.v -in .logedit$entrynum.actiontitle -side left
pack .logedit$entrynum.actiontitle

set logedit_activity($entrynum) ""
frame .logedit$entrynum.activity
menu_create .logedit$entrynum.activity.n [mc "Activity"] logedit_activity 1 acties menu_setText .logedit$entrynum.activity.v
entry .logedit$entrynum.activity.v -width 20 -textvariable logedit_activity($entrynum)
pack .logedit$entrynum.activity.n .logedit$entrynum.activity.v -in .logedit$entrynum.activity -side left
pack .logedit$entrynum.activity

getallcontacts
set logedit_contact($entrynum) ""
frame .logedit$entrynum.contact
menu_create .logedit$entrynum.contact.n [mc "Contact"] logedit_contact 1 cont menu_setText .logedit$entrynum.contact.v
entry .logedit$entrynum.contact.v -width 20 -textvariable logedit_contact($entrynum)
pack .logedit$entrynum.contact.n .logedit$entrynum.contact.v -in .logedit$entrynum.contact -side left
pack .logedit$entrynum.contact

set logedit_rate($entrynum) ""
frame .logedit$entrynum.rate
menubutton .logedit$entrynum.rate.n -text [mc Rate] -menu .logedit$entrynum.rate.n.m
menu .logedit$entrynum.rate.n.m
.logedit$entrynum.rate.n.m add command -label "--" -command "set logedit_rate($entrynum) \"\""
.logedit$entrynum.rate.n.m add command -label [mc Overtime] -command "set logedit_rate($entrynum) Overtime"
.logedit$entrynum.rate.n.m add separator
.logedit$entrynum.rate.n.m add command -label [mc Help] -command "taghelp logedit_rate" 
entry .logedit$entrynum.rate.v -width 10 -textvariable logedit_rate($entrynum)
pack .logedit$entrynum.rate.n .logedit$entrynum.rate.v -in .logedit$entrynum.rate -side left
pack .logedit$entrynum.rate

set logedit_stack_info($entrynum) ""


set logedit_description($entrynum) ""
frame .logedit$entrynum.description
menubutton .logedit$entrynum.description.n -text [mc Description] -menu .logedit$entrynum.description.n.m
menu .logedit$entrynum.description.n.m
.logedit$entrynum.description.n.m add command -label [mc Help] -command "taghelp logedit_description"
text .logedit$entrynum.description.v -rel sunk -wrap word -yscrollcommand ".logedit$entrynum.description.sb set" -width 40 -height 5
scrollbar .logedit$entrynum.description.sb -rel sunk -command ".logedit$entrynum.description.v yview"
pack .logedit$entrynum.description.n -in .logedit$entrynum.description -side left
pack .logedit$entrynum.description.v -side right -in .logedit$entrynum.description -expand 1 -fill both
pack .logedit$entrynum.description.sb -side left -fill y -in .logedit$entrynum.description
pack .logedit$entrynum.description -expand 1 -fill both

frame .logedit$entrynum.bot
button .logedit$entrynum.bot.ok -text [mc "Save"] -command "dologedit $entrynum"
button .logedit$entrynum.bot.cancel -text [mc "Cancel"] -command "doCancel .logedit$entrynum"
button .logedit$entrynum.bot.help -text [mc "Help"] -command "taghelp logedit"
pack .logedit$entrynum.bot.ok .logedit$entrynum.bot.cancel .logedit$entrynum.bot.help -side left -in .logedit$entrynum.bot
pack .logedit$entrynum.bot


foreach item $thisentry {
  set tagname [lindex $item 0]
  set tagvalue [lindex $item 1]
  if { $tagname == "Id" } {
  set logedit_id($entrynum) $tagvalue
  } elseif { $tagname == "StartTime" } {
   set logedit_start($entrynum) $tagvalue
  } elseif { $tagname == "EndTime" } {
   set logedit_end($entrynum) $tagvalue
  } elseif { $tagname == "Project" } {
   set logedit_project($entrynum) $tagvalue
  } elseif { $tagname == "Description" } {
   set logentry_description($entrynum) $tagvalue
   .logedit$entrynum.description.v insert end "$tagvalue"
  } elseif { $tagname == "Action" } {
   set logedit_action($entrynum) $tagvalue
  } elseif { $tagname == "ActionTitle" } {
   set logedit_actiontitle($entrynum) $tagvalue
  } elseif { $tagname == "Activity" } {
   set logedit_activity($entrynum) $tagvalue
  } elseif { $tagname == "Contact" } {
   set logedit_contact($entrynum) $tagvalue
  } elseif { $tagname == "Rate" } {
   set logedit_rate($entrynum) $tagvalue
  } elseif { $tagname == "Stack-info" } {
   set logedit_stack_info($entrynum) $tagvalue

}

}

tkwait window .logedit$entrynum
}

proc fillpreventries { w } {
global logfilename logentries
global projTimes
global log_summary

# zero all the project times
 foreach index [array names projTimes] {
  set projTimes($index) "00:00"
  }

.preventries.body configure -state normal
.preventries.body delete 1.0 end
set logentries [tag readfile $logfilename]

# Get rid of the header
 set realentries [lrange $logentries 1 end ]

set entrynum 0
.preventries.body mark set prevmark 1.0
.preventries.body mark gravity prevmark left
foreach entry $realentries {
# .preventries.body mark set prevmark 1.0
 set starttime 0
 set endtime 0
 set thisproject [mc "unknown"]
 incr entrynum
# The entry should be a list of tag-value pairs
  foreach item $entry {
  set tagname [lindex $item 0]
  set tagvalue [lindex $item 1]
  if { $tagname == "End" } {
  # Because this is the end tag we should have all the values we are going
  # to get
  set duration [timediff $starttime $endtime]
  if { [info exists projTimes($thisproject)] } {
      inctime projTimes($thisproject) $duration
     } else {
      set projTimes($thisproject) "00:00"
      inctime projTimes($thisproject) $duration
     }
# The following does not work on TCL v8 (OK on 8.2) - hardwire for portability
#    .preventries.body insert end [string repeat _ 40] 
    .preventries.body insert end "_______________________________________"
   .preventries.body insert end "\n"
  .preventries.body tag add tag_$entrynum prevmark insert
#  .preventries.body tag add tag_$entrynum 1.0 1.end
#  puts "Added tag called tag_$entrynum "
#  puts [.preventries.body tag ranges tag_$entrynum]
#  puts [.preventries.body mark names]
#  puts [.preventries.body dump -all 1.0 end]
  .preventries.body tag bind tag_$entrynum <Button-3> "editpreventry $entrynum"
  .preventries.body mark set prevmark insert
#  puts "set prevmark - it is now"
#  puts [.preventries.body dump -mark 1.0 end]
#  puts "Tag values are now"
#  puts [.preventries.body dump -tag 1.0 end]
  } elseif { $tagname == "Id" } {
   # Dont bother to display Id's
   set thisentryid $tagvalue

  } elseif { $tagname == "StartTime" } {
   .preventries.body insert end "Start " 
   .preventries.body insert end "$tagvalue "
   set starttime $tagvalue
  } elseif { $tagname == "EndTime" } {
   .preventries.body insert end "[mc End] "
   .preventries.body insert end "$tagvalue\n"
   set endtime $tagvalue
  } elseif { $tagname == "Project" } {
    .preventries.body insert end "[mc Project]: $tagvalue\n"
    set thisproject $tagvalue
  } elseif { $tagname == "Summary" } {
    # Do not display the summary in the previous entries window
    set log_summary $tagvalue
  } else {
  .preventries.body insert end "[mc $tagname]: "
  .preventries.body insert end "$tagvalue"
  .preventries.body insert end "\n"
 }
}

}
 .preventries.body yview moveto 1
 .preventries.body configure -state disabled
}


proc dateRangeToLogfileList { startdate enddate } {
global rootdir
# return a list of all the log files which can be found on disk between the
# start and end dates. Either date as null string means first or last available
# (which will include today)

if { $startdate == "" } {
 set startdate "2000-01-01"
 }

if { $enddate == "" } {
 set enddate [clock format [clock seconds] -format "%Y-%m-%d"]
 }

set result {}

for { set thisdate $startdate } { [clock scan "$thisdate"] <= [clock scan "$enddate"] } { set thisdate [clock format [ clock scan "$thisdate 1 day" ] -format "%Y-%m-%d"] } {

# turn the date into a filename

scan $thisdate "%d-%d-%d" thisyear thismonth thisday
set thismonth [format "%02d" $thismonth]
set thisday [format "%02d" $thisday]

set filename "$rootdir/log$thisyear/$thismonth$thisday.tag"
if [file exists $filename] {
  lappend result $filename
 }
}
return $result
}



proc FindDefaultPrevday {} {
global prevdayfilename year month day rootdir

# The whole way this works is flawed - I think I need to just use glob to
# look at the files
return

getdate
set logdir "$rootdir/log$year"
# puts "day is $day"
set numday [ e $day ]
set prevday [format "%02d" [incr numday -1 ]]
set prevdayfilename "$logdir/$month$prevday.tag"


if { ! [ file exists $prevdayfilename ]} {
   set prevdayfilename ""
}


}

proc fillprevday {} {
global prevdayfilename display_prevday

if { $display_prevday } {
if { $prevdayfilename !="" } {
  # Fill the prevday.body window
   .prevday.body delete 1.0 end
   set f [open $prevdayfilename]
   while { ![eof $f]} {
        .prevday.body insert end [read $f 1000]
   }
   close $f
 .prevday.body yview moveto 1
 }
}
}


proc openlogfile { args } {
# Opens the logfile in the ~/diary/logyyy directory, named after the month and day
global logfile year month day logfilename rootdir
# args can be -write
set dowrite 0
foreach arg $args {
 switch -- $arg {
   "-write" { set dowrite 1 }
   }
 }

getdate

set logdir "$rootdir/log$year"
# create the directory if it does not already exist (with a prompt box)

if { ! [ file isdirectory $logdir ] } {
# mkdir does not like ~/diary - it needs a shell to expand it - work around
 set currentdir [ pwd ]
# we may not even have rootdir
 if { ! [ file isdirectory $rootdir ] } {
  file mkdir $rootdir
 }
 cd $rootdir
# catch {exec mkdir log$year } d
  file mkdir "$rootdir/log$year"
 cd $currentdir
# note that this does not work under Windows
 }

set logfilename "$logdir/$month$day.tag"


# create the file if it does not exist
if [ file exists $logfilename ] {
  set mode a
  if { $dowrite } {
	set mode w
	}
  set logfile [open $logfilename $mode ]
  # Fill the preventries.body window
  fillpreventries .preventries.body
} else {
  set logfile [openNewLogFile $logfilename]
}

fillprevday

}

proc closelogfile {} {
global logfile

close $logfile

}


proc dosummaryOK {} {
global logfile

puts $logfile "Summary:: END_S"

puts $logfile [.summaryBox.entry.body get 1.0 end]

puts $logfile "END_S"

destroy .summaryBox

}

proc dosummary {} {
global log_summary

toplevel .summaryBox
wm title .summaryBox "Summary of the day"


frame .summaryBox.top -relief raised
pack .summaryBox.top -side top -fill both
frame .summaryBox.entry
pack .summaryBox.entry
frame .summaryBox.bot
pack .summaryBox.bot -side bottom -fill both

message .summaryBox.top.msg -text \
 "Enter the summary of what you did today"
pack .summaryBox.top.msg -side right -expand 1 -fill both -padx 3m -pady 3m

text .summaryBox.entry.body -rel sunk -wrap word -yscrollcommand ".summaryBox.entry.sb set"
scrollbar .summaryBox.entry.sb -rel sunk -command ".summaryBox.entry.body yview"

pack .summaryBox.entry.body -side right -in .summaryBox.entry
pack .summaryBox.entry.sb -side right -fill y -in .summaryBox.entry

button .summaryBox.bot.ok -text "Save" -command dosummaryOK
button .summaryBox.bot.cancel -text [mc Cancel] -command { doCancel .summaryBox }
button .summaryBox.bot.help -text [mc Help] -command "taghelp summarybox"
pack .summaryBox.bot.ok .summaryBox.bot.cancel .summaryBox.bot.help -side left

.summaryBox.entry.body insert end $log_summary

# grab set .summaryBox
focus .summaryBox

tkwait window .summaryBox


}

proc writelog { args } {
global logfile hh mm ss year month day currentStart currentEnd currentProject currentActivity actionTitle logfilename logentries currentAction currentActionTitle rate currentContact stack_info
global num_today_actions

# args can be -writeactions -modify
set dowriteactions 0
set domodify 0
foreach arg $args {
 switch -- $arg {
   "-writeactions" { set dowriteactions 1 }
   "-modify" { set domodify 1 }
   }
}

# If we are modifying then we will have to close the log file and open
# it for writing
if { $domodify } {
closelogfile

# puts "about to write out the log file as $logentries"

 tag writefile $logfilename $logentries

openlogfile

# for now if we have written the logfile we will not do any more
return

}

 set logid "$year$month$day$hh$mm$ss"
 puts $logfile "Id: $logid"
 puts $logfile "StartTime: $currentStart"
 puts $logfile "EndTime: $currentEnd"
# If the current project is not null then write an entry for it too
if { $currentProject != "" } {
  puts $logfile "Project: $currentProject"
  } 

if { $rate != "" } {
  puts $logfile "Rate: $rate"
}
if { $currentContact != "" } {
  puts $logfile "Contact: $currentContact"
  set currentContact ""
}
if { $currentAction != "" } {
  puts $logfile "Action: $currentAction"
}
# always set currentAction to null after write as we are almost certainly
# changing what we do
set currentAction ""
if { $currentActionTitle != "" } {
  puts $logfile "ActionTitle: $currentActionTitle"
}
set currentActionTitle ""
if { $currentActivity != "" } {
  puts $logfile "Activity: $currentActivity"
 }

if { $stack_info != "" } {
  puts $logfile "Stack-info: $stack_info"
# If the stack_info was an interupt make it into a normal push after it
# has been written
  if { [string index $stack_info 0] == "!" } {
    set stack_info "+[string range $stack_info 1 end]"
  }
}
  
# Get the contents of the Description window
 set thisdescription [string trim [.description.body get 1.0 end]]
if { $thisdescription != ""} {
 puts $logfile "Description:: END_D"
 puts $logfile [.description.body get 1.0 end]
 puts $logfile "END_D"
}
if { $dowriteactions } {
  foreach i [array names actionTitle] {
   if { $actionTitle($i) != "" } {
	puts $logfile "Action-title.$i: $actionTitle($i)"
     }
  }
  dosummary
}
 puts $logfile "End:"
 puts $logfile ""
 flush $logfile

return $logid
}


proc doquit {} {

wm protocol . WM_DELETE_WINDOW

   if {[tk_messageBox -icon warning -title "Quit TAGLOG" -type yesno \
          -message "Quit without saving?" -default no] == "yes"} {
	closelogfile
	writeallact
	exit
	}
wm protocol . WM_DELETE_WINDOW doquit
}

proc doexit {} {

writelog -writeactions
writeallact
closelogfile
exit
}

proc doCancel { w } {

destroy $w
}

proc refreshLog {} {

closelogfile
openlogfile

}

proc dologviewSaveAsOK {} {
global SaveAsFilename lvsa_dirname

set filename "$lvsa_dirname/$SaveAsFilename"
set f [ open $filename w ]
 puts $f [ .logview.main.body get 1.0 end ]

 close $f

destroy .lvsa
}

proc dologviewSaveAs {} {
global html_public_dir html_private_dir lvsa_dirname SaveAsFilename

toplevel .lvsa
wm title .lvsa [mc "Save Log View Display As ..."]

if { $lvsa_dirname=="" } {
set lvsa_dirname .
}
frame .lvsa.dirname
menubutton .lvsa.dirname.l -text [mc "Directory"] -menu .lvsa.dirname.l.m
menu .lvsa.dirname.l.m
.lvsa.dirname.l.m add command -label [mc "Current Directory"] -command "set lvsa_dirname \".\""
.lvsa.dirname.l.m add command -label "$html_public_dir" -command "set lvsa_dirname \"$html_public_dir\""
.lvsa.dirname.l.m add command -label "$html_private_dir" -command "set lvsa_dirname \"$html_private_dir\""
.lvsa.dirname.l.m add separator
.lvsa.dirname.l.m add command -label [mc "Help"] -command "taghelp lvsa_dirname"
entry .lvsa.dirname.e -textvariable lvsa_dirname -width 20
pack .lvsa.dirname.l .lvsa.dirname.e -in .lvsa.dirname -side left
pack .lvsa.dirname


if { ! [info exists SaveAsFilename] } {
 set SaveAsFilename "logsave"
}
if { $SaveAsFilename == "" } {
 set SaveAsFilename "logsave"
}
frame .lvsa.filename
label .lvsa.filename.label -text [mc "File name :"]
entry .lvsa.filename.name -relief sunken -textvariable SaveAsFilename
pack .lvsa.filename.label .lvsa.filename.name -side left -in .lvsa.filename
pack .lvsa.filename

frame .lvsa.bot
button .lvsa.bot.ok -text [mc "Save Text"] -command dologviewSaveAsOK
button .lvsa.bot.savehtml -text [mc "Save HTML"] -command dologviewSaveHtml
button .lvsa.bot.cancel -text [mc Cancel] -command { doCancel .lvsa }
pack .lvsa.bot.ok .lvsa.bot.savehtml .lvsa.bot.cancel -side left
pack .lvsa.bot

tkwait window .lvsa
}

proc dologviewSaveHtml {} {
global SaveAsFilename lvsa_dirname logsel_project logsel_descrString logsel_activity logsel_contact

if { [regexp -nocase { (.*\.html$)|(.*\.htm$) } $SaveAsFilename] } {
set extension ""
} else {
set extension ".html"
}

set filename "$lvsa_dirname/$SaveAsFilename$extension"
set f [ open $filename w ]
puts $f "<head><title>Saved log file</title></head>"
puts $f "<body>"

set filenames [logselfilenames]

foreach logfile $filenames {
set logs [getlogselection $logfile $logsel_project $logsel_descrString $logsel_activity $logsel_contact]
set dateseperator 0


if { [llength $logs] > 0 } {
 set headerdate [logfilename2date $logfile]
 puts $f "<h2>$headerdate</h2>"
 tag writehtml dlist $f $logs
}

}

puts $f "</body>"

close $f

destroy .lvsa
}

proc getlogselection { logfile logsel_project logsel_descrString logsel_activity logsel_contact } {

 set logs [ tag readfile $logfile ]
 set logs [lrange $logs 1 end ]

 set tests ""
 if { $logsel_project != "" } {
  set test [list Project == $logsel_project ]
  lappend tests $test
  }

 if { $logsel_descrString != ""} {
  set test [list Description -contains $logsel_descrString]
  lappend tests $test 
  }

 if { $logsel_activity != "" } {
  set test [list Activity == $logsel_activity]
  lappend tests $test
  }

 if { $logsel_contact != "" } {
  set test [list Contact == $logsel_contact]
  lappend tests $test
  }

 if { $tests != "" } {
   set logs [ tag extract $logs $tests ]
   }

return $logs

}

proc fillLogWin { win filenames logsel_project logsel_descrString logsel_activity logsel_contact } {


# Fill the window
$win delete 1.0 end

foreach logfile $filenames {
set logs [getlogselection $logfile $logsel_project $logsel_descrString $logsel_activity $logsel_contact]

# puts "logs is $logs"
 set dateseperator 0

 foreach entry $logs {
  foreach item $entry {
    set tagname [lindex $item 0]
 set tagvalue [lindex $item 1]

 if { ! $dateseperator } {
   set dateseperator 1
   set headerdate [logfilename2date $logfile]
   $win insert end "\n\n   $headerdate\n\n" 
 }

 if { $tagname == "End" } {
   $win insert end "_______________________________\n"
 } elseif {  $tagname == "Id" } {
	# dont do anything
 } else {
   $win insert end "$tagname: "
   $win insert end "$tagvalue"
   $win insert end "\n"
 }
}


 }
}

}

proc logselfilenames {} {
global logsel_years rootdir

foreach year $logsel_years {
  set decade [expr $year / 10]
  set fileselection [.logsel.fileselect.d$decade.y$year.files curselection]

  foreach selfile $fileselection {
   set fn [.logsel.fileselect.d$decade.y$year.files get $selfile]
   lappend filenames "$rootdir/log$year/$fn.tag"
   }


  }
return $filenames
}

proc displayLogs {} {
global logsel_project logsel_years logsel_descrString logsel_activity logsel_contact

set filenames [logselfilenames]

toplevel .logview
wm title .logview [mc "Log view"]

frame .logview.main
text .logview.main.body -rel sunk -wrap word -yscrollcommand ".logview.main.sb set"
scrollbar .logview.main.sb -rel sunk -command ".logview.main.body yview"
pack .logview.main.body -side right -in .logview.main
pack .logview.main.sb -side right -fill y -in .logview.main
pack .logview.main

frame .logview.bot
button .logview.bot.ok -text OK -command { doCancel .logview }
button .logview.bot.saveas -text [mc "Save As..."] -command dologviewSaveAs
button .logview.bot.savehtml -text [mc "Save HTML..."] -command dologviewSaveHtml
pack .logview.bot.ok .logview.bot.saveas -side left
pack .logview.bot

# Fill the window
fillLogWin .logview.main.body $filenames $logsel_project $logsel_descrString $logsel_activity $logsel_contact


tkwait window .logview
}

proc logSelect {} {
global rootdir activities allcontacts logsel_years logsel_activity logsel_contact logsel_projstat

toplevel .logsel
wm title .logsel [mc "Select Log Files ..."]


frame .logsel.fileselect
set decade 0
set newdecade 0
# Find all the available years
foreach yeardir [lsort [glob "$rootdir/log*/"]] {
 set year [string range [file tail [string trimright $yeardir / ]] 3 end]
 lappend logsel_years $year
set thisdecade [expr $year / 10]
if { $thisdecade > $decade } {
 set decade $thisdecade
 frame .logsel.fileselect.d$decade
 set newdecade 1
}
frame .logsel.fileselect.d$decade.y$year
label .logsel.fileselect.d$decade.y$year.name -text $year
pack .logsel.fileselect.d$decade.y$year.name -in .logsel.fileselect.d$decade.y$year
listbox .logsel.fileselect.d$decade.y$year.files -relief raised -borderwidth 2 -yscrollcommand ".logsel.fileselect.d$decade.y$year.scroll set" -selectmode extended -exportselection false
pack .logsel.fileselect.d$decade.y$year.files -in .logsel.fileselect.d$decade.y$year -side left
scrollbar .logsel.fileselect.d$decade.y$year.scroll -command ".logsel.fileselect.d$decade.y$year.files yview"
pack .logsel.fileselect.d$decade.y$year.scroll -in .logsel.fileselect.d$decade.y$year -side right -fill y 
pack .logsel.fileselect.d$decade.y$year -in .logsel.fileselect.d$decade -side left


foreach filename [lsort [ glob $yeardir/*.tag ]] {
  set filebase [ file rootname [file tail $filename]]
  .logsel.fileselect.d$decade.y$year.files insert end $filebase
}

if { $newdecade } {
pack .logsel.fileselect.d$decade -in .logsel.fileselect
set newdecade 0
}

}
pack .logsel.fileselect

set logsel_projstat ""
frame .logsel.tagselect
menu_create .logsel.tagselect.project [mc Project] logsel_project 1 proj menu_setText .logsel.tagselect.projectentry
entry .logsel.tagselect.projectentry -textvariable logsel_project -width 10

pack .logsel.tagselect.project .logsel.tagselect.projectentry -in .logsel.tagselect -side left

label .logsel.tagselect.descrl -text [mc "Description contains"]
entry .logsel.tagselect.descre -textvariable logsel_descrString
pack .logsel.tagselect.descrl .logsel.tagselect.descre -in .logsel.tagselect -side left

pack .logsel.tagselect

frame .logsel.nextsel
set logsel_activity ""
menubutton .logsel.nextsel.activity -text [mc Activity] -menu .logsel.nextsel.activity.m
menu .logsel.nextsel.activity.m
.logsel.nextsel.activity.m add command -label "--" -command "set logsel_activity \"\""
foreach activity $activities {
 .logsel.nextsel.activity.m add command -label "$activity" -command "set logsel_activity \"$activity\""
 }
.logsel.nextsel.activity.m add separator
.logsel.nextsel.activity.m add command -label [mc Help] -command "taghelp logsel_activity"
entry .logsel.nextsel.activentry -textvariable logsel_activity

pack .logsel.nextsel.activity .logsel.nextsel.activentry -in .logsel.nextsel -side left

getallcontacts
set logsel_contact ""
menubutton .logsel.nextsel.contact -text [mc Contact] -menu .logsel.nextsel.contact.m
menu .logsel.nextsel.contact.m
.logsel.nextsel.contact.m add command -label "--" -command "set logsel_contact \"\""
foreach contact $allcontacts {
  foreach item $contact {
   if { [lindex $item 0] == "Id" } {
     .logsel.nextsel.contact.m add command -label [lindex $item 1] -command "set logsel_contact \"[lindex $item 1]\""
   }
 }
}
.logsel.nextsel.contact.m add separator
.logsel.nextsel.contact.m add command -label [mc Help] -command "taghelp logsel_contact"
entry .logsel.nextsel.contacte -textvariable logsel_contact

pack .logsel.nextsel.contact .logsel.nextsel.contacte -in .logsel.nextsel -side left
pack .logsel.nextsel

frame .logsel.bot
button .logsel.bot.ok -text OK -command displayLogs
button .logsel.bot.cancel -text [mc Cancel] -command { doCancel .logsel }
button .logsel.bot.help -text [mc Help] -command "taghelp logsel"
pack .logsel.bot.ok .logsel.bot.cancel .logsel.bot.help -side left
pack .logsel.bot

tkwait window .logsel

}


proc openNewLogFile {logfilename} {
# opens a log file with mode "w" and writes the header lines
   set logfile [open $logfilename w]
   set date [clock format [clock scan [logfilename2date $logfilename -us]] -format "%Y-%m-%d"]
   set weekday [clock format [clock scan [logfilename2date $logfilename -us]] -format "%A"]
   puts $logfile "Tag-worklog-version: 1.0"
   puts $logfile "Date: $date"
   puts $logfile "WeekDay: $weekday"
   puts $logfile "End:"
   puts $logfile ""
   return $logfile
}


proc setactionsmenu {} {
global activeactions num_today_actions
getactiveactions
 .actionbar.action.m delete 1 end
.actionbar.action.m add command -label "--" \
	-command "setcurrentAction -1"
for { set i 0 } {$i < [llength $activeactions]} {incr i} {
 .actionbar.action.m add command -label [lindex [ lindex $activeactions $i ] 1] \
	-command "setcurrentAction \"[lindex [lindex $activeactions $i ] 0]\""
}

for { set i 1 } { $i <= $num_today_actions } { incr i } {
 menu_create .actions.a$i.id [mc Action]$i actreminder 0 actAct menu_setText .actions.a$i.title
 }



}

proc doadjstartOK {} {
global currentStart logentries adjPrevEnd NewStart

if { $adjPrevEnd } {
# put the value of currentStart into the previous end time 

set lastitem [expr { [llength $logentries] - 1}]
set preventry [lindex $logentries $lastitem ]
tag replace preventry EndTime $NewStart

 set logentries [lreplace $logentries $lastitem $lastitem $preventry]

writelog -modify
fillpreventries .preventries.body


}
set currentStart $NewStart
destroy .adjstart
}

proc adjNewStart value {
global NewStart currentStart

set NewStart $currentStart
inctime NewStart [expr { - $value * 60 }]


}

proc adjustStart {} {
global currentStart logentries adjPrevEnd NewStart

set prevend ""
set prevstart ""
toplevel .adjstart
wm title .adjstart [mc "Adjust start time"]

set preventry [lindex $logentries [expr { [llength $logentries] -1} ]]

foreach item $preventry {
 if { [lindex $item 0 ] == "StartTime" } {
   set prevstart [lindex $item 1 ]
   }
 if { [lindex $item 0 ] == "EndTime" } {
   set prevend [lindex $item 1 ]
   }
}
frame .adjstart.top
if { $prevstart != ""} {
message .adjstart.top.msg -width 200 -text \
 "[mc {Adjust start time back towards previous start time of}] $prevstart"

} else {
message .adjstart.top.msg -text [mc "Adjust start time back towards the start of the day"]
}
pack .adjstart.top.msg
pack .adjstart.top

if { $prevstart == "" } {
	set prevstart "00:00:00"
}
set adjPrevEnd 0
if { $prevend != ""} {
 set adjPrevEnd 1
 checkbutton .adjstart.adjprev -text [mc "Adjust previous end time"] -variable adjPrevEnd  
 pack .adjstart.adjprev
} 

set NewStart $currentStart

frame .adjstart.newstart
label .adjstart.newstart.l -text [mc "New Start Time"]
entry .adjstart.newstart.e -width 10 -textvariable NewStart
pack .adjstart.newstart.l .adjstart.newstart.e -side left -in .adjstart.newstart
pack .adjstart.newstart

set adjTimeDiff [expr { [timediff $prevstart $currentStart] / 60 } ]

scale .adjstart.scale -label [mc "Minutes to Subtract from StartTime"] -orient horizontal -from 0 -to $adjTimeDiff -command adjNewStart -length 220
pack .adjstart.scale

frame .adjstart.bot
button .adjstart.bot.ok -text [mc "Set"] -command doadjstartOK
button .adjstart.bot.cancel -text [mc Cancel]  -command { doCancel .adjstart }
button .adjstart.bot.help -text [mc Help] -command "taghelp adjstart"
pack .adjstart.bot.ok .adjstart.bot.cancel .adjstart.bot.help -side left
pack .adjstart.bot

tkwait window .adjstart
}
 
sourcelibs
initialise

wm protocol . WM_DELETE_WINDOW doquit

# protect against mc being set on first initialise
if { [ llength [ info procs mc ]] == 0 } {
if { [info tclversion] >= 8.2 } {
 package require msgcat
 namespace import msgcat::mc
 msgcat::mclocale $language
 msgcat::mcload $libsdir
 } else {

 proc mc { msg } {
  return $msg
 }
}
}

setupdisplay
openlogfile
minuteTimer

activate_timeblocked

if { [llength start_procs] !=0 } {
 foreach p $start_procs {
  catch { eval $p } mesg
  if { $mesg != "" } {
    global errorInfo
    tk_messageBox -icon error -title [mc "Error in startprocs"] -type ok -message $errorInfo
    }
   
 }
}

