###########################################################################
# Fichier config.tcl 
###########################################################################

lappend TE_SOURCED_FILES config.tcl

###########################################################################
###########################################################################
# config.tcl - gestion de la configuration de l'editeur (preferences,
# fichier de config utilisateur,)
###########################################################################
###########################################################################

###########################################################################
# te:create_dir - crée le récursivement le répertoire $d s'il n'existe pas.
# (Brent Welch)
###########################################################################

proc te:create_dir {d} {
  if {[file isdirectory $d]} {
    # te:alert -text $d -title "directory [file tail $d] already exist."
    return $d 
  } elseif { [file exist $d]} {
    # error "Non-directory [file tail $d] already exist."
  } else { 
    te:create_dir [file dirname $d]
    exec mkdir $d
    te:alert -title "Creating directory $d" -text "Done."
    return $d 
  }
}


###########################################################################
# te:edit_user_file - edite le fichier steadrc ou en propose un par defaut
# Modif diam le 29/10/99 (simplification et nettaoyage !
###########################################################################

proc te:edit_user_file {} {

    global stead


    # Le fichier utilisateur n'existe pas ou est vide : on propose
    # de recopier le modèle
    if {![file exists $stead(rcfile)] || [file size $stead(rcfile)] == 0} {
   
        set msg "Your configuration file doesn't exist\
                    or is empty. Do you \
                    want to copy default file in  $stead(userlib) ?"
        
        # Dans tous les cas,on crée le répertoire pour steadrc
        te:create_dir $stead(userlib)

        if {[te:confirm   -text $msg   -title "Try it !"]} {
       
            exec touch $stead(rcfile)
            exec rm $stead(rcfile)
            exec cp $stead(rcfile_proto) $stead(rcfile)
        }
    }    
    # # # exec $stead(exe) $stead(rcfile) &
    stead $stead(rcfile) 

}

#######################################################################
# jedit:reread_config : reread file $stead(rcfile)
#######################################################################

proc jedit:reread_config {} {

  jedit:init_prefs
  jedit:apply_prefs
  if {[info procs jedit:userhook] == "jedit:userhook"} {
  jedit:userhook
  }
}


###########################################################################
# te:edit_teprefs_file - edite le fichier des préférences utilisateur
###########################################################################

proc te:edit_teprefs_file  {} {
 global stead
 te:create_dir $stead(userlib)
 # # # exec $stead(exe) $stead(userlib)/stead-prefs &
 stead $stead(userlib)/stead-prefs 
}


######################################################################
# jedit:cmd:edit_prefs - editor-wide preferences panel
######################################################################

proc jedit:cmd:edit_prefs {} {
  global stead
  global EDITPREFS   editprefs_old

  if [winfo exists .edit_prefs] {destroy .edit_prefs}
  
  # valeurs actuelles de EDITPREFS sauvegardees dans editprefs_old
  
  foreach value [array names EDITPREFS] {
    set editprefs_old($value) $EDITPREFS($value)
  }
  
  set w .edit_prefs
  toplevel $w
  wm title $w "Editor Preferences"
  frame $w.values
  frame $w.values.left
  frame $w.values.right

###########################################################
# definition des boutons, boutons radios, "checks" boutons

set w .edit_prefs.values.left
    checkbutton $w.autoposition -relief flat -anchor w \
    -text {Auto-position dialogue boxes} \
    -variable EDITPREFS(autoposition)
#  checkbutton $w.confirm -relief flat -anchor w \
#    -text {Confirm actions} \
#    -variable EDITPREFS(confirm)
  checkbutton $w.j_fs_fast -relief flat -anchor w \
    -text {Fast file selector} \
    -variable EDITPREFS(j_fs_fast)
  checkbutton $w.motif -relief flat -anchor w \
    -text {Strict Motif emulation} \
    -variable EDITPREFS(tk_strictMotif)
  checkbutton $w.scrollbarside -relief flat -anchor w \
    -text {Scrollbars on left} \
    -variable EDITPREFS(scrollbarside) \
    -onvalue left -offvalue right
  frame $w.bindings
  radiobutton $w.bindings.basic -relief flat -anchor w \
    -text {Basic bindings} \
    -variable EDITPREFS(bindings) -value basic
  radiobutton $w.bindings.emacs -relief flat -anchor w \
    -text {Emacs bindings} \
    -variable EDITPREFS(bindings) -value emacs
    
  checkbutton $w.savestate -relief flat -anchor w \
    -text {Save/load highlighting and position} \
    -variable EDITPREFS(savestate)
  checkbutton $w.autobreak -relief flat -anchor w \
    -text {Break long lines with <Space>} \
    -variable EDITPREFS(autobreak)
  checkbutton $w.autoindent -relief flat -anchor w \
    -text {Preserve indentation with <Return>} \
    -variable EDITPREFS(autoindent)
  checkbutton $w.sabbrev -relief flat -anchor w \
    -text {Expand static abbreviations with <Space>} \
    -variable EDITPREFS(sabbrev)
  checkbutton $w.dabbrev -relief flat -anchor w \
    -text {Expand dynamic abbreviations with <Tab>} \
    -variable EDITPREFS(dabbrev)
  checkbutton $w.undoable -relief flat -anchor w \
    -text {Text Undoable} \
    -variable EDITPREFS(undoable) 
  checkbutton $w.clear_undo -relief flat -anchor w \
    -text {Clear Undo Information After Save} \
    -variable EDITPREFS(clear_undo)
        
  frame $w.wrap
  radiobutton $w.wrap.none -relief flat -anchor w \
    -text {Don't wrap lines} \
    -variable EDITPREFS(textwrap) -value none
  radiobutton $w.wrap.char -relief flat -anchor w \
    -text {Wrap lines on character boundaries} \
    -variable EDITPREFS(textwrap) -value char
  radiobutton $w.wrap.word -relief flat -anchor w \
    -text {Wrap lines at word boundaries} \
    -variable EDITPREFS(textwrap) -value word
    

  set w .edit_prefs.values.right
  
  te:colour_chooser $w.textbg -variable EDITPREFS(textbg) \
    -label "Text Normal Background:"
  te:colour_chooser $w.textfg -variable EDITPREFS(textfg) \
    -label "Text Normal Foreground:"
  te:colour_chooser $w.textsb -variable EDITPREFS(textsb) \
    -label "Text Selected Background:"
  te:colour_chooser $w.textsf -variable EDITPREFS(textsf) \
    -label "Text Selected Foreground:"
  te:colour_chooser $w.otherbg -variable EDITPREFS(otherbg) \
    -label "Editor Normal Background:"
  te:colour_chooser $w.otherfg -variable EDITPREFS(otherfg) \
    -label "Editor Normal Foreground:"
  te:colour_chooser $w.otherabg -variable EDITPREFS(otherabg) \
    -label "Editor Active Background:"
  te:colour_chooser $w.highlightbg -variable EDITPREFS(highlightbg) \
    -label "Editor Highlight Background:"
        
  label $w.undolevels-label -text "Undo Levels:" -anchor w
  scale $w.undolevels -from 1 -to 100  -orient horizontal \
    -command {set EDITPREFS(undolevels)}
  $w.undolevels set $EDITPREFS(undolevels)

  frame $w.printer
  label $w.printer.l -text {Printer:}
  entry $w.printer.e -relief sunken -width 50 \
    -textvariable EDITPREFS(print_command)

  frame $w.font
  frame $w.font.top
  label $w.font.top.l -text {Font:}
  button $w.font.top.default -width 8 -text {Default} -command {
    set EDITPREFS(textfont) \
    {-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-*}
  }
  button $w.font.top.choose -text {Choose . . .} -command {
    set EDITPREFS(textfont) [te:prompt_font]
  }
  frame $w.font.bot
  entry $w.font.bot.e -relief sunken -width 50 \
    -textvariable EDITPREFS(textfont)
  frame $w.size
  label $w.size.wl -text {Width:}
  entry $w.size.we -relief sunken -width 5 \
    -textvariable EDITPREFS(textwidth)
  label $w.size.hl -text {Height:}
  entry $w.size.he -relief sunken -width 5 \
    -textvariable EDITPREFS(textheight)

set w .edit_prefs
  te:buttonbar $w.b -default save -buttons [format {
    {
      save Save {
#        te:write_prefs -array EDITPREFS -directory $stead(userlib) \
          -file [file tail $stead(userlib)/stead-prefs]
         te:save_prefs
        %s.b.done invoke
      }
    } {
      done Done {
        if {$EDITPREFS(textwidth) < 20} {set EDITPREFS(textwidth) 20}
        if {$EDITPREFS(textheight) < 4} {set EDITPREFS(textheight) 4}
        jedit:apply_prefs
        unset editprefs_old
        destroy %s
      }
    } {
      cancel Cancel {   
        foreach value [array names editprefs_old] {
          set EDITPREFS($value) $editprefs_old($value)    
        }
        jedit:apply_prefs 
        unset editprefs_old
        destroy %s
      }
    } {
      reset "Reset to default Values" {
        te:set_default_prefs
        unset editprefs_old
        jedit:cmd:edit_prefs
      }
    }    
  } $w $w $w]
 
set w .edit_prefs.values.left

    pack $w.bindings.basic \
    $w.bindings.emacs \
    -in $w.bindings -side top -expand yes -fill x

    pack $w.wrap.none \
    $w.wrap.char \
    $w.wrap.word \
    -in $w.wrap -side top -expand yes -fill x

  pack $w.autoposition \
    $w.j_fs_fast \
    $w.motif \
    $w.scrollbarside \
    $w.savestate \
    $w.autobreak \
    $w.autoindent \
    $w.sabbrev \
    $w.dabbrev \
    $w.undoable \
    $w.clear_undo \
    -in $w -side top -expand yes -fill x
  pack [te:rule $w] -in $w -side top -fill x
  pack $w.bindings -in $w -side top -expand yes -fill x
  pack [te:rule $w] -in $w -side top -fill x
  pack $w.wrap -in $w -side top -expand yes -fill x
  
  set w .edit_prefs.values.right

  pack $w.printer.l -in $w.printer -side left
  pack $w.printer.e -in $w.printer \
    -expand yes -side left -padx 10 -pady 10

  pack $w.font.top.l -in $w.font.top -side left
  pack $w.font.top.choose -in $w.font.top -side right -padx 10 -pady 5
  pack $w.font.top.default -in $w.font.top -side right -pady 5
  pack $w.font.bot.e -in $w.font.bot -side left -padx 10 -pady 5
  pack $w.font.top \
       $w.font.bot \
       -in $w.font -side top -expand yes -fill x
  pack append $w.size \
    $w.size.wl {left fillx} \
    $w.size.we {left} \
    $w.size.hl {left fillx} \
    $w.size.he {left}

  pack $w.textbg \
    $w.textfg \
    $w.textsb \
    $w.textsf \
    $w.otherbg \
    $w.otherfg \
    $w.otherabg \
    $w.highlightbg \
    -in $w -side top -expand yes -fill x
   pack [te:rule $w] -in $w -side top -fill x

   pack $w.undolevels-label $w.undolevels \
    -in $w -side top -expand yes -fill x
   pack [te:rule $w] -in $w -side top -fill x
  pack $w.printer -in $w -side top -expand yes -fill x
  pack [te:rule $w] -in $w -side top -fill x
  
  pack $w.font -in $w -side top -fill x
  pack [te:rule $w] -in $w -side top -fill x
  pack $w.size -in $w -side top -expand yes -fill x 

  set w .edit_prefs

  
  pack $w.values.left -in $w.values -side left
  pack [te:rule $w.values] -in $w.values -side left -fill y
  pack $w.values.right -in $w.values -side left
  pack $w.values -in $w -side top
  pack [te:rule $w] -side top -fill x
  pack $w.b -in $w -side top -expand yes -fill x
 
  te:dialogue $w
  te:default_button $w.b.save $w
  focus $w
  tkwait window $w
}

###########################################################################
# écrit les préférences utilisateurs dans le fichier $stead(rcfile)
# inspiré de  mfv:eval-options de tkmail-2.0b6 de Paul Raines 
# 
# ANCIENNE VERSION A CONSERVER CAR UTILISE UN WIDGET text temporaire
# et conserve la mise en page et commentaire du texte original
# 
###########################################################################

proc te:save_prefs_old {} {

  global stead
  global EDITPREFS
  
  catch {destroy .tempo}
  text .tempo

  set varlist ""
  set in_usersect 0
  set found_end 0
  
  .tempo delete 1.0 end
  set i 1
  set sp "  "
  
  if {[file exists $stead(rcfile)]} {
      
      if {[catch "open $stead(rcfile) r" tfid]} {
        te:alert -text "$tfid" -title "Error during saving preferences: "
        return 0
      }
      .tempo insert 1.0 [read $tfid]
      catch {close $tfid}
      
      for {set i 1} {[.tempo compare $i.0 < end]} {incr i} {
        set line [.tempo get $i.0 "$i.0 lineend"]
        
        if {[regexp -nocase \
                 "^\[ \t]*#+\[ \t]*PREFERENCES UTILISATEUR\[ \t]*\$" $line]} {
          set in_usersect 1
          continue
        }
        if {!$in_usersect} continue
        if {[regexp -nocase \
          "^\[ \t]*#+\[ \t]*FIN DES PREFERENCES UTILISATEUR\[ \t]*\$" $line]} {
          set found_end 1
          break
        }
        if {[regexp "^(\[ \t]*)set\[ \t]*(EDITPREFS\\((\[-0-9a-z_]*)\\))" \
                 $line trash sp var name]} {
          set val [eval "set $var"]
          lappend varlist $name
          
          .tempo delete $i.0 "$i.0 lineend"
          .tempo mark set insert $i.0
          .tempo insert $i.0 "${sp}set $var {$val}"
          scan [.tempo index insert] %d i
          
        } else {
          if {![regexp "^\[ \t]*#" $line]} {
            .tempo delete $i.0 "$i.0 lineend"
          }
        }
      }  
  }

    
  .tempo mark set insert $i.0

  # on teste si on est bien au début d'une ligne
  # sinon on rajoute un retour chariot
  
  if {[lindex [split [.tempo index insert] .] 0] != 0} {
  .tempo insert insert \n
  }
  
  if {!$in_usersect} {
  .tempo insert insert "\# PREFERENCES UTILISATEUR\n"
  .tempo insert insert \
  "\# Tout ce qui est écrit entre ici et la ligne de commentaires\n"
  .tempo insert insert \
  "\# FIN DES PREFERENCES UTILISATEUR, sera écrasé lors d'une sauvegarde\n"
  .tempo insert insert \
  "\# des préférences (bouton Save du panneau de configuration Config)\n"
  .tempo insert insert \
  "\# n'écrivez que des set EDITPREFS(...) entre ces deux lignes.\n"
  }
  foreach name [lsort [array names EDITPREFS]] {
  if {[lsearch $varlist $name] == -1} {
    set val [eval "set EDITPREFS($name)"]
    .tempo insert insert "${sp}set EDITPREFS($name) {$val}\n"
  }
  }
  if {!$found_end} {
  .tempo insert insert "\# FIN DES PREFERENCES UTILISATEUR\n\n"
  }
  
  te:create_dir [file dirname $stead(rcfile)]
  if {[catch "open $stead(rcfile) w" tfid]} {
    te:alert -text $tfid -title "Error during preferences saving: "
    destroy .tempo
    return 0
  }
  puts $tfid [.tempo get 1.0 end]
  catch {close $tfid}
  destroy .tempo
}

######################################################################
# te:cmd:Source - Ask for , and source a file
######################################################################

proc te:cmd:source {} {
  global stead
  set prompt_result [te:fs -prompt "Source TCL file :"]
  if {$prompt_result != {}} then {
    te:source_config  $prompt_result
  }
}

########################################################################
# te:save_prefs
# 
# Nouvelle version en développement (diam le 29/10/99)
# 
# écrit les préférences utilisateurs dans le fichier $stead(rcfile)
#

proc te:save_prefs {} {

  global stead
  global EDITPREFS
  
  # les marqueurs délimitant le morceau de texte du fichier steadrc
  # qui sera automatiquement mis à jour par cette procédure :
  set prefix "PREFERENCES UTILISATEUR"
  set suffix "FIN DES PREFERENCES UTILISATEUR"
  
  set prefixPat "^\[ \t]*#+\[ \t]*$prefix\[ \t]*\$"
  set suffixPat "^\[ \t]*#+\[ \t]*$suffix\[ \t]*\$"
  
  # Construction du morceau de texte à sauvegarder
  set allPrefs [lsort [array names EDITPREFS]]
  
  set    newChunk ""
  append newChunk "# $prefix \n\n"
  
  append newChunk "# Ne rien modifier entre ces deux marqueurs : \n"
  append newChunk "#      \"$prefix\" et \"$suffix\"\n"
  append newChunk "# Ce texte serait écrasé à chaque sauvegarde"
  append newChunk                            " des préférences\n"
  append newChunk "# (par le menu \"Config/Save Current Preference\")\n"
  append newChunk "\n"
  
  # en prévoie une adentation des chaque affectation
  foreach pref $allPrefs {
      append newChunk "   [list set EDITPREFS($pref)  $EDITPREFS($pref)]\n"
  } ;# endforeach
  append newChunk "\n"
  append newChunk "# $suffix"
  
  # On s'assure que le fichier utilisateur existe
  if {![file exists $stead(rcfile)]} {
    te:create_dir $stead(userlib)
    exec touch $stead(rcfile)
  }
  set old_steadrc_txt [read_file $stead(rcfile)]

  set new_steadrc_txt    [text_updateChunk $old_steadrc_txt \
          $prefixPat $suffixPat $newChunk]


  write_file  $stead(rcfile) $new_steadrc_txt
  ######################################################################
}

########################################################################
# Procédure text_updateChunk tirée de updateCshrc : 
# sera incorporée à pist 
# !!!!!!!! N'EST PAS ENCORE UTILISEE DANS STEAD !!!!!!!

########################################################################
# text_updateChunk <inText> <prefPattern> <suffPattern> <chunkText>
#     retourne une chaine dans laquelle le bloc de texte compris 
#     entre les regexps <prefPattern> et <suffPattern> est remplacé 
#     par la chaine <chunkText>.
#     Si la première patterne n'est pas trouvée, la chaine est ajoutée
#     à la fin du résultat.
#     Tous les espaces et return finaux sont effacés.
# 
# Historique 
# 
# 03/09/97: diam si le marqueur suffixe n'existe pas : ce qui suit le 
#           préfixe est concervé au lieu d'etre supprimé !
# 03/09/97: diam création à partir de file:getMaj
#           prend du texte et sort du texte
# 
# Exemple :
# 
#   # On récupère une version mise à jour du .cshrc
#   set cshrcNewTxt    [text_updateChunk $cshrcText \
#           $up(prefPat) $up(suffPat) $up(chunkText)]

proc text_updateChunk {inText prefPattern suffPattern chunkText} {

    # on fera précéder la chaine de mise à jour par deux return 
    # ce qui donnera UNE SEULE ligne vide
    set chunkText \n\n$chunkText
    
    # initialisation du text correspondant au texte modifié
    set outText ""
    
    # contiendra ce qui suit le préfixe. Utile si on ne trouve pas 
    # le suffixe : toute la fin du texte pourrait etre supprimée 
    # par erreur.
    set oldChunk ""
    
    # ou on est ? (where vaut before | inside | after)
    set where "before"

    foreach line [split $inText \n] {

        # dans les lignes qui suivent, les cas les plus probables se 
        # produiront dans l'ordre
        switch -exact $where {

          before {
              if ![regexp $prefPattern $line] {
                  # on se contente de recopier les premières lignes
                  append outText $line\n
                  continue
              } else {
                  # on entre dans la zone à mettre à jour
                  # on va donc rajouter le bloc de texte à mettre à jour
                  # (en controlant le nombre de return)
                  set where "inside"
                  set outText "[string trimright $outText]$chunkText\n"
                  continue
              }
          }

          inside {
              if ![regexp $suffPattern $line] {
                  # Cette ligne devrait etre ignorée puisqu'elle a déja 
                  # été mise à jour .. à condition que le marqueur de fin 
                  # existe bien !!!
                  append oldChunk $line\n
                  continue
              } else {
                  # on sort de la zone de mise à jour
                  set where "after"
                  continue
              }
          }

          after {
              # on contente de recopier les dernières lignes
              append outText $line\n
              continue
          }
          
          default {
              # impossible (:-)
              error "$were inconnu ; doit-être before | inside | after\
                     (procédure text_updateChunk)"
          }
        } ;# endswitch

    } ;# endforeach

    # On supprime les espaces et return finaux :
    set outText [string trimright $outText]
    
    # Au cas ou on n'aurait pas trouver la ligne préfixe 
    # (cas d'un fichier n'ayant jamais été mis à jour),
    # on ajoute la mise à jour à la fin
    if {$where == "before"} {
        append outText $chunkText
    }
    # Au cas ou on n'aurait pas trouver la ligne suffixe 
    # (l'utilisateur l'a supprimé par erreur),
    # on ajoute ce qui suivait le marqueur préfixe
    if {$where == "inside"} {
        append outText $oldChunk
    }
    
    return $outText
    
} ;#endproc text_updateChunk

