###########################################################################
###########################################################################
# state.tcl - obtention, chargement, sauvegarde de l'etat du fichier
# (marques, tags, cusreurs, selection, position de la scrollbar, etat propre
# ou "sale")
###########################################################################
###########################################################################

package provide stead 2.0

## xtext_getState -- return non-text content of a text widget
# 
# modifs 
#   10/09/00 (diam) 
#     sauvegarde de la position revalive du caractere en haut à gauche
#     xviewr et yviewr 
# 
#   09/12/99 (diam) utilisation de la variabkle locale SEL_ONLY
#    ON NE SAUVEGARDE QUE LA SELECTION : pour les autres tag (en pratique)
#    seulement la colorisation automatique)
#    Il se trouve que c'est plus rapide de recoloriser que de restituer 
#    les tag auriginaux (CA POURAIT CHANGER AVEC TCK82 88)
#    En attendant le undo rame atrocement si gros fichier latex ou tcl !)
# 
#    Par contre : il faut relancer la procédure "refresh_colors" (~?)
#    (si elle est définie !) apres chaque set_state
# 
# A FAIRE :
#    prévoir option pour le choix des tags sauvegardés (SEL_ONLY)
# 
proc xtext_getState { {w .main.t} } {
    global EDITPREFS
    
    # Si SEL_ONLY=1 : seule le tag sel est sauvé
    set SEL_ONLY 1
    # set SEL_ONLY 0
    # 
    set tags {}
    set marks {}
    foreach tag [$w tag names] {
        if {![string match sel $tag] && $SEL_ONLY} {
            continue
        }
        set ranges [$w tag ranges $tag]
        if {"x$ranges" != "x"} {
            lappend tags [list $tag $ranges]
        }
    }
    foreach mark [$w mark names] {
        # # # report -v mark
        if {[regexp -- {M\d+.*} $mark]} {
            # On ignore les marques temporaire du genre M123, mais aussi
            # les mark de la forme "M123 linestart"(e.g. utilisée pendant 
            # la coloration)
            # diam le 04/12/01 : je remets pour vérifier si ça gène depuis 
            # les modif (suppression des markque temporaire avant les return
            continue
        }
        
        # # # report "lappend marks [list $mark [$w index $mark]]"
        lappend marks [list $mark [$w index $mark]]
    }
    # sauvegarde de l'état "propre" ou "sale" du texte
    set dirty  [xtext_isDirty $w]
    
  
    # Les positions relatives du caractere en haut et a gauche :
    set xviewr [lindex [$w xview] 0]
    set yviewr [lindex [$w yview] 0]
  
    return [list $tags $marks $dirty  $xviewr $yviewr]
}


## xtext_setState t state - set non-text content of a file
# 
# initialement dans state.tcl - déplacé pour accélérer le lancement
# 
# modif 
#   10/09/00 (diam) 
#     sauvegarde de la position revalive du caractere en haut à gauche
#     xviewr et yviewr 
#     BUT : améliorer la gestion de l'insert pour eviter les changements
#           inutiles de scroll
#   diam 08/12/99 : gestion des tag en fin de procédure.
#   diam 09/12/99 : exécution de la procédure "refresh_colors"
#      si elle existe pour relancer la colorisation des mots clés.
#      En effet la proc "xtext_getState" a été modifiée pour ne plus 
#      sauvegarder d'autre tab que la sélection (car le undo rame pour
#      de gros fichier latex ou tcl, alors que la colorisation automatique
#      est rapide !)
# 
# A FAIRE :
#  prévoir option pour forcer la visibilité de l'insert au cas ou la fenetre
#  à été redimentionnée (en plus petit)
# 
# 
proc xtext_setState { w state } {

    # Cette future option imposera la visibilité de l'insert, ce qui est
    # normalement le cas sauf si on a retréci la taille de la fenetre,
    # car seul le haut de la fenetre est restitué par le undo
    set opt(-see) 1
  
    # recupération des composantes du state dans des variables séparées :
    foreach {tags marks is_dirty xviewr yviewr} $state   { break } 
    
    # récupération des marques
    # # # set marks [lindex $state 1]
    # 
    # BIDOUILLE PROVISOIRE : suppression de toute les anciennes marques
    #    En particulier destruction des markques provisoire du style M324
    #    créées pendant la colorisation
    foreach m [$w mark names]    {
        $w mark unset $m
    }
    
    foreach pair $marks {
      $w mark set [lindex $pair 0] [lindex $pair 1]
    }
  
    if {$is_dirty} {
          xtext_markDirty $w
    } else {
          xtext_markClean $w
    }
    $w xview moveto $xviewr
    $w yview moveto $yviewr
    
  
    # récupération des tags
    foreach pair $tags {
        set tag [lindex $pair 0]
        set ranges [lindex $pair 1]
        set length [llength $ranges]
        for {set i 0; set i1 1} {$i1 < $length} {incr i 2; incr i1 2} {
            $w tag add $tag [lindex $ranges $i] [lindex $ranges $i1]
        }
    }
    
    # Ceci n'est en principe à pas faire 
    # Par ailleurs, pourquoi limiter cette action au cas ou il y a une 
    # selection ??
    # On pour passer une option ??
    
    if {$opt(-see)} {
        $w see [$w index insert]
    }
    
    update ;# update avant refrechissement des couleurs
    stead:styleRefresh 
  
    xtext_updateFocusIn $w

}


######################################################################
# stead:writeState filename ?t? - write out non-text content of a file
######################################################################

proc stead:writeState { filename  {w .main.t}} {
  set dirname [file dirname $filename]
  set tail [file tail $filename]
  set filename "$dirname/.state.$tail"
  if [file writable $filename] {
    set state [xtext_getState $w]
    # on marque toujours le widget propre dans l'etat qu'on sauve
    set state [lreplace $state 2 2 0]  
    set file [open $filename {w}]
    puts $file [xtext_getState $w]
    close $file
  }
}
#./
