#    Copyright (C) 1998  Dennis Roddeman
#    email: dennis.roddeman@uibk.ac.at
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
# 
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#   
#   
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software Foundation
#    59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA

proc file_file {} {

  global tnpath
  source $tnpath/vtn/global.tcl

#  file window
  set w_filebox .filebox
  catch {destroy $w_filebox}
  toplevel $w_filebox
  wm title $w_filebox "File"
  wm geometry $w_filebox $window_offset
  focus $w_filebox

#  initialise file names
  set file_open "none"
  set file_save "none"
  set file_view "none"

#  message
  label $w_filebox.msg -wraplength 4i -justify left \
    -text "Enter a file name or click on the \"Browse\" buttons."
  pack $w_filebox.msg -side top

#  buttons 
  frame $w_filebox.buttons
  pack $w_filebox.buttons -side bottom -fill x -pady 2m
  button $w_filebox.buttons.cancel -text Cancel -command "destroy $w_filebox"
  button $w_filebox.buttons.ok -text Ok -command {
    file_read_initia $file_open 
    file_read_data $file_open
    file_write $file_save initia_and_data
    viewfile $file_view 
    destroy .filebox
  }
  pack $w_filebox.buttons.ok $w_filebox.buttons.cancel -side left
  foreach i {open save view} {
    set f [frame $w_filebox.$i]
    label $f.lab -text "Select a file to $i: " -anchor w
    entry $f.ent -textvariable file_$i
    bind $f.ent <Return> {
      file_read_initia $file_open 
      file_read_data $file_open
      file_write $file_save initia_and_data 
      viewfile $file_view 
      destroy $w_filebox
    }
    pack $f.lab -side left
    pack $f.ent -side left -expand yes -fill x
    button $f.but -text "Browse ..." -command "fileDialog $w_filebox $i"
    pack $f.but -side left
    pack $f -fill x -padx 1c -pady 3
  }

}

proc fileDialog {w operation} {

  global tnpath
  source $tnpath/vtn/global.tcl

#   file dialog window
  set w_fileDialog .fileDialog
  catch {destroy $w_fileDialog}
  toplevel $w_fileDialog
  wm title $w_fileDialog "File browser"
  wm geometry $w_fileDialog 300x300
  wm geometry $w_fileDialog $window_offset
  focus $w_fileDialog

#   main frame
  set f $w_fileDialog.frame
  frame $f -relief groove -borderwidth 2
  pack $f -expand 1 -fill both

#   buttons
  frame $f.framespecials -relief flat
  pack $f.framespecials -fill x -side bottom
  button $f.framespecials.ready -text "Ready" -command " destroy $w_fileDialog "
  button $f.framespecials.help -text "Help" -command {
    help "Double click on a file name to select."
  }
  pack $f.framespecials.ready -side left -pady 4m -anchor w
  pack $f.framespecials.help -side right -pady 4m -anchor w

#   list of files
  frame $f.framelist -relief flat
  pack $f.framelist -fill both -side top -expand 1
  listbox $f.framelist.listbox -relief raised -yscrollcommand "$f.framelist.scroll set"
  scrollbar $f.framelist.scroll -command "$f.framelist.listbox yview"
  pack $f.framelist.scroll -side right -fill y
  pack $f.framelist.listbox -side left -fill both -expand 1

#   bindings
  set file_acces $operation
  bind $f.framelist.listbox <Double-1> {
    if       { $file_acces == "open" } {
      set file_open [selection get]
    } elseif { $file_acces == "save" } {
      set file_save [selection get]
    } else {
      set file_view [selection get]
    }
    wm withdraw $w_fileDialog
  }
  cd $directory_start
  set files_list [glob *.dat *.dbs *.out]
  foreach file $files_list { $f.framelist.listbox insert end $file }

}

# 

proc file_read_initia { file_read } {

  global tnpath
  source $tnpath/vtn/global.tcl

  global line
  set define_list ""
  set define_strings_list ""

  if { $file_read != "" && $file_read != "none" } {

    if { $switch } { 
      puts "In proc FILE_READ_INITIA" 
      puts "reading initia of file $file_read"
    }

    initia_initialise

    cd $directory_start
    if { [ file exists $file_read ] } {
      set fileid [open $file_read r]
    } else {
      if { [ $file_read == "vtn.dbs" ] } {
        error_show "Cannot read file $file_read. Error in input file while running calculation?"
      } else {
        error_show "Cannot read file $file_read."
      }
      break
    }
    set reading_initia 1
    set reading_parenthesis 0
    while { [gets $fileid line]>=0 && $reading_initia } {
      convert_line
      set line_list [ split $line ]
      set first_word [ lindex $line_list 0 ]
      set second_word [ lindex $line_list 1 ]
      if { $switch } { 
        puts "reading_initia: $reading_initia"
        puts "reading line: $line"
      }
      set parenthesis [string first ( $line ]
      if { $parenthesis != -1 } { incr reading_parenthesis +1 }
      if { $reading_parenthesis } {
        set parenthesis [string first ) $line ]
        if { $parenthesis != -1 } { incr reading_parenthesis -1 }
      } elseif { $first_word == "end_initia" } {
        set reading_initia 0
      } elseif { $first_word == "ndim" } {
        set initia_array_values(1) $second_word
      } elseif { $first_word == "number_of_space_dimensions" } {
        set initia_array_values(1) $second_word
      } elseif { $first_word == "echo" } {
        if { $second_word == "-yes" } {
          set initia_array_values(0) 1
        } else {
          set initia_array_values(0) 0
        }
      } elseif { $first_word != "" } {
        set found 0
        for {set i 0} {$i<$initia_array_length} {incr i} {
          if { $first_word == $initia_array($i) } {
            if       { $initia_array_types($i) == "checkbutton" } {
              set initia_array_values($i) 1
              set found 1
            } elseif { $initia_array_types($i) == "entry" } {
              set initia_array_values($i) $second_word
              set found 1
            }
          }
        }
        if { !$found } { error_show "Unknown $first_word in initia part. File reading is terminated." }
      }
    }
    close $fileid

    if { $switch } { 
      puts "Out proc FILE_READ_INITIA" 
    }

  }

}

#

proc file_read_data { file_read } {

  if {  $file_read != "" && $file_read != "none" } {

    run only_initia foreground
    data_initialise

    global tnpath
    source $tnpath/vtn/global.tcl

    if { $switch } { 
      puts "In proc FILE_READ_DATA" 
      puts "reading data of file $file_read"
    }

    global line
    set define_list ""
    set define_strings_list ""
    cd $directory_start
    if { [ file exists $file_read ] } {
      set fileid [open $file_read r]
    } else {
      error_show "Cannot read file $file_read."
      break
    }
    set reading_initia 1
    set reading_data 0
    set reading_parenthesis 0
    set reading_define 0

    while { [gets $fileid line]>=0 } {

      if { $reading_initia || $reading_data } {

        convert_line
        set line_list [ split $line ]
        set first_word [ lindex $line_list 0 ]
        set second_word [ lindex $line_list 1 ]
        if { $switch } { 
          puts "reading_initia: $reading_initia"
          puts "reading_data: $reading_data"
          puts "reading_parenthesis: $reading_parenthesis"
          puts "reading_define: $reading_define"
          if { $reading_define } {
            puts "define_list: $define_list"
            puts "define_strings_list: $define_strings_list"
          }
          puts "reading line: $line"
          puts "first_word: $first_word"
          puts "second_word: $second_word"
        }
        set parenthesis [string first ( $line ]
        if { $parenthesis != -1 } { incr reading_parenthesis +1 }

        if       { $reading_parenthesis } {

          set parenthesis [string first ) $line ]
          if { $parenthesis != -1 } { incr reading_parenthesis -1 }

        } elseif { $reading_initia && $first_word == "end_initia" } {

          set reading_initia 0
          set reading_data 1

        } elseif { $reading_define } {

          if { $first_word == "end_define" } {
            set reading_define 0
          } else {
            set remainder_list [ lrange $line_list 1 end ]
            set remainder [ join $remainder_list ]
            lappend define_list $first_word
            lappend define_strings_list $remainder
          }

        } elseif { $reading_data } {

          if       { $first_word == "end_data" } {
            set reading_data 0
          } elseif { $first_word == "start_define" } {
            set reading_define 1
          } elseif { $first_word != "" } {
            set cmd_array_member $first_word
            set exists [info exists data_array_index_$cmd_array_member]
            if { !$exists } { 
              error_show "Unknown $first_word in data part. This data is neglected.\n\nThis message is shown only once. Further unknown data items are possible." 
            } else {
              set data_array_index [set data_array_index_$cmd_array_member]
              if { $switch } {
                puts "cmd_array_member: $cmd_array_member"
                puts "data_array_index: $data_array_index"
              }
              if { $data_array_index == 1 } {
                set index $second_word
                set remainder_list [ lrange $line_list 2 end ]
                set remainder [ join $remainder_list ]
              } else {
                set index 0
                set remainder_list [ lrange $line_list 1 end ]
                set remainder [ join $remainder_list ]
              }
              set data_array_values data_array_values_$cmd_array_member
              set [set data_array_values]($index) $remainder
              if { $switch } {
                puts "index: $index"
                puts "remainder: $remainder"
              }
            }
          }
        }
      }
    }

    close $fileid

    if { $switch } { 
      puts "Out proc FILE_READ_DATA" 
    }

  }

}

#

proc file_write { file_write write_task } {

  global tnpath
  source $tnpath/vtn/global.tcl

  if { $file_write != "" && $file_write != "none" } {

    if { $switch } { 
      puts "In proc FILE_WRITE" 
      if { $write_task == "initia_and_data" } {
        puts "writing initia and data into file $file_write"
      } else {
        puts "writing initia into file $file_write"
      }
    } 

    set fileid [open $file_write w]

#     write initia part
    if { $initia_array_values(0) == "1" } {
      puts $fileid "echo -yes"
    } else {
      puts $fileid "echo -no"
    }
    puts $fileid "ndim $initia_array_values(1)"
    if { $initia_array_values(2) == "1" } {
      puts $fileid "derivatives"
    }
    for {set i 3} {$i<$initia_array_length} {incr i} {
      if { $initia_array_values($i) != "0" } {
        if { $initia_array_types($i) == "entry" } {
          puts $fileid "$initia_array($i) $initia_array_values($i)"
        } else {
          puts $fileid $initia_array($i)
        }
      }
    }
    puts $fileid "end_initia\n"

#     write data part
    if { $write_task == "initia_and_data" } {

      for {set idata 0} {$idata<$cmd_array_length} {incr idata} {

        set cmd_array_member $cmd_array($idata)
        set data_array_values data_array_values_$cmd_array_member
        set active_indices_tmp [array names $data_array_values]
        set active_indices [lsort $active_indices_tmp]
        if { $switch } { 
          puts "idata: $idata"
          puts "cmd_array_member: $cmd_array_member"
          puts "data_array_values: $data_array_values"
          puts "active_indices: $active_indices"
        }
        set anything 0
        foreach index $active_indices {
          if { $switch } { puts "index: $index" }
          set data_array_index [set data_array_index_$cmd_array_member]
          set tmp [set data_array_values]($index)
          if { $data_array_index == "1" } {
            puts $fileid "$cmd_array_member $index [set $tmp]"
          } else {
            puts $fileid "$cmd_array_member [set $tmp]"
          }
          set anything 1
        }
        if { $anything } { puts $fileid "" }

      }

    }
    puts $fileid "end_data"

    close $fileid 

    if { $switch } { 
      puts "closing file $file_write"
      puts "Out proc FILE_WRITE"
    }

  }

}
