## -*-Tcl-*-
 # ###################################################################
 # 
 #  FILE: "addressbook2tex.tcl"
 #                                    created: 2007-01-11 16:32:54 
 #                                last update: 2007-01-12 16:06:48 
 #  Author: Frédéric Boulanger
 #  E-mail: Frederic.Boulanger@supelec.fr
 #    mail: Supélec - Département Informatique
 #          3 rue Joliot-Curie, 91192 Gif-sur-Yvette, France
 #     www: http://wwwsi.supelec.fr/fb/
 #  
 #  Description: 
 # 
 #  History
 # 
 #  modified   by  rev reason
 #  ---------- --- --- -----------
 #  2007-01-11 FBO 1.0 original
 # ###################################################################
 ##
# set suppressedFields [list \
#  ABDate \
#  ABPersonFlags \
#  ABRelatedNames \
#  AIMInstant \
#  Creation \
#  FirstPhonetic \
#  ICQInstant \
#  JabberInstant \
#  LastPhonetic \
#  MSNInstant \
#  MiddlePhonetic \
#  Modification \
#  UID \
#  YahooInstant \
# ]
proc exportAddressBook {} {
  set suppressedFields [list \
   ABDate \
   ABPersonFlags \
   ABRelatedNames \
   AIMInstant \
   Creation \
   FirstPhonetic \
   ICQInstant \
   JabberInstant \
   LastPhonetic \
   MSNInstant \
   MiddlePhonetic \
   Modification \
   UID \
   YahooInstant \
  ]
  
#   set expfilename [putfile "Save exported addresses to" "AddressBook-[ISOTime::ISODate].xml"]
#   if {[string length $expfilename] == 0} {
#     error "cancel"
#   }

  set expfilename "AddressBook-[clock format [clock seconds] -format "%Y-%m-%d"].tex"
  puts "Exporting AddressBook to $expfilename"
  
  set expfile [open $expfilename "w"]
  fconfigure $expfile -encoding macRoman -translation lf
  
  puts $expfile "\\documentclass{addressbook}"
  puts $expfile "\\usepackage\[T1]{fontenc}"
  puts $expfile "\\usepackage\[applemac]{inputenc}"
  puts $expfile ""
  puts $expfile "\\begin{document}"
  
  package require addressbook
  
  puts "Sorting AddressBook entries"
  set idlist [lsort -command compareEntries [addressbook persons -ids]]
  
  puts "Writing entries to $expfilename"
  set lastLetter ""
  foreach id $idlist {
    set data [addressbook record $id]
    set k [mapString [lindex [getKeyOfEntry $data] 0]]
    if {[string index $k 0] != $lastLetter} {
      set lastLetter [string index $k 0]
      puts $expfile "\\newLetter{[string toupper $lastLetter]}"
      puts $expfile ""
    }
    puts $expfile "\\person{"
    foreach field $data {
      set fieldname [lindex $field 0]
      set fieldvalue [lindex $field 1]
      if {[lsearch -exact $suppressedFields $fieldname] >= 0} {
        continue
      }
      switch -exact -- [addressbook property type -persons $fieldname] {
        Date    {
          set date [clock format $fieldvalue -format "%Y-%m-%d %H:%M:%S"]
          puts $expfile "  \\$fieldname{$date}"
        }
        Array   -
        Data    -
        Integer -
        Real    -
        String  {
          puts $expfile "  \\$fieldname{[normalize $fieldvalue]}"
        }
        MultiDate    {
          puts $expfile "  \\$fieldname{"
          foreach item $fieldvalue {
            set date [clock format [lindex $item 1] -format "%Y-%m-%d %H:%M:%S"]
            puts $expfile "    \\named{[lindex $item 0]}{$date}"
          }
          puts $expfile "  }"
        }
        Dictionary   -
        MultiArray   -
        MultiData    -
        MultiInteger -
        MultiReal    -
        MultiString  {
          puts $expfile "  \\$fieldname{"
          foreach item $fieldvalue {
            puts $expfile "    \\named{[lindex $item 0]}{[normalize [lindex $item 1]]}"
          }
          puts $expfile "  }"
        }
        MultiDictionary {
          puts $expfile "  \\$fieldname{"
          foreach item $fieldvalue {
            puts $expfile "    \\named{[lindex $item 0]}{"
            foreach subitem [lindex $item 1] {
              puts $expfile "      \\[lindex $subitem 0]{[normalize [lindex $subitem 1]]}"
            }
            puts $expfile "    }"
          }
          puts $expfile "  }"
        }
        
        default {
          error "Unknown property type \"[addressbook property type -persons $field]\""
        }
      }
    }
    set parents [addressbook parents -ids $id]
    foreach p $parents {
      if {[string length $p] == 0} continue
        puts $expfile "  \\ingroup{[normalize [addressbook set $p GroupName]]}"
    }
    puts $expfile "}"
    puts $expfile ""
  }
  
  puts $expfile "\\end{document}"
  close $expfile

  puts "Done."
}

proc normalize {s} {
  regsub -- {\[Comment\][\n\r]?} $s {} s
  regsub -- {\[Comments\][\n\r]?} $s {} s
  regsub -- {\[Commentaires\][\n\r]?} $s {} s
  regsub -all -- {([&_$#])} $s {\\\1} s
  regsub -all -- {[\n\r]} $s {\\newline }
  return $s
}

proc compareEntries {first second} {
  set fkey [getKeyOfEntry [addressbook record $first]]
  set skey [getKeyOfEntry [addressbook record $second]]
    
  set res [compareStrings [lindex $fkey 0] [lindex $skey 0]]
  if {$res == 0} {
    if {([llength $fkey] > 1) && ([llength $skey] > 1)} {
      set res [compareStrings [lindex $fkey 1] [lindex $skey 1]]
    }
  }
  return $res
}

proc getKeyOfEntry {record} {
  foreach item $record {
    array set data $item
  }
  if {[info exists data(Last)]} {
    lappend key $data(Last)
    if {[info exists data(First)]} {
      lappend key $data(First)
    }
  } elseif {[info exists data(Organization)]} {
    lappend key $data(Organization)
  } elseif {[info exists data(First)]} {
    lappend key $data(First)
  } else {
    lappend key ""
  }
  return $key
}


proc mapString {s} {
  string map { \
   à a á a ä a â a \
   ç c \
   è e é e ë e ê e \
   ì i í i ï i î i \
   ñ n \
   ò o ó o ö o ô o \
   ù u ú u ü u û u \
   ÿ y \
  } [string tolower $s]
}

proc compareStrings {s1 s2} {
  string compare [mapString $s1] [mapString $s2]
}

exportAddressBook
