#!/bin/sh
# Call wish and restart \
exec wish "$0" -- "$@"

############################################################################
# bwedit: Version 2.2 (Experimental)
# Author: Abhijit Das (Barda) [abhij@csa.iisc.ernet.in]
# Last updated: May 19 1999
############################################################################

############################# ATTENTION ####################################
#
# Set the following variables, if the default values do not conform
# to your system settings.
#

# Edit the following two lines if you have bwedit library and bnr.gsf
# installed elsewhere. The former must be set appropriately. The latter
# is needed if you are using the PostScript exporter of bwedit.

set installdir "/usr/local/bwedit"
set psfontfile "/usr/share/ghostscript/fonts/bnr.gsf"

# Set dpyfont to fixed, if your X windowing system does not support
# a font named `variable'. Tk version 8.0 onwards replaces any
# non-existing font by `fixed'. If you are using earlier versions
# of Tk, you must set dpyfont yourself.

# set dpyfont fixed
set dpyfont variable

# Similarly set hdrfont according as your X installation
# set hdrfont fixed
# set hdrfont variable
set hdrfont "-*-helvetica-bold-r-*-*-20-*"

#################### DO NOT EDIT AFTER THIS LINE ###########################

######### Global stuff ###########
set fntprobe [ exec xlsfonts ]
if {[regexp "bengali" $fntprobe] == 0} {
   puts "\nERROR: Font not found ...."
   puts "I cannot detect Bengali fonts in your system."
   puts "First load the fonts and then run bwedit.\n"
   exit -1;
}
unset fntprobe
set fontlist [ exec xlsfonts | grep -v bengali]
set fontlist [ split $fontlist "\n" ]
set scriptlist [ list suptag supsuptag subsuptag subtag subsubtag supsubtag ]

set appbg "#d3d3d3"
set appfg "#000000"
set btnbg "#a9a9a9"
set btnfg "#000000"
set blnbg "#ffffaa"
set blnfg "#000000"

image create photo bweditlogo -file "$installdir/images/bwedit-logo.gif"

set browsedir [exec pwd]
proc browse { win } {
   global browsedir

   $win delete 0 end
   if [regexp {/\.\.$} $browsedir] {
      set browsedir [string range $browsedir 0 [expr [string length $browsedir] - 4]]
      set browsedir [string range $browsedir 0 [expr [string last "/" $browsedir] - 1]]
   }
   if {[string compare $browsedir ""] == 0} {
      foreach f [exec ls -a "/"] {
         if {[regexp {^\.$} $f] == 0} {
            if [file isdirectory /$f] {
               $win insert end /$f/
            } else {
               $win insert end /$f
            }
         }
      }
   } else {
      foreach f [exec ls -a $browsedir] {
         if {[regexp {^\.$} $f] == 0} {
            if [file isdirectory $browsedir/$f] {
               $win insert end $browsedir/$f/
            } else {
               $win insert end $browsedir/$f
            }
         }
      }
   }
}

proc getFileName { wtitle } {
   global appbg appfg btnbg btnfg browsedir newfname gfndbox gfnok

   set gfnok 0
   set gfndbox [toplevel .getfname]
   label $gfndbox.lbl -text "Enter filename: " -relief flat -fg $appfg -bg $appbg
   entry $gfndbox.ent -textvariable newfname -bg #88ddff -fg #000000 \
      -selectforeground #88ddff -selectbackground #000000 -selectborderwidth 0
   button $gfndbox.obtn -text "OK" -command {
      set newfname [string trim $newfname]
      if {![string compare $newfname ""]} {
         set gfnok 0
      } else {
         set newfname [glob -nocomplain $newfname]
         if [file isdirectory $newfname] {
            set browsedir $newfname
            browse $gfndbox.brfr.lbx
         } else {
            set gfnok 1
         }
      }
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   label $gfndbox.space -text "" -fg $appfg -bg $appbg
   button $gfndbox.cbtn -text "Cancel" -command "set gfnok 0" -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg
   frame $gfndbox.brfr -bg $appbg
   listbox $gfndbox.brfr.lbx -width 60 -height 12 -bg #88ddff -fg $btnfg \
      -xscroll "$gfndbox.xscr set" -yscr "$gfndbox.brfr.yscr set" -relief sunken \
      -selectmode single -selectforeground #88ddff -selectbackground $btnfg \
      -selectborderwidth 0
   scrollbar $gfndbox.brfr.yscr -command "$gfndbox.brfr.lbx yview" \
      -troughcolor #88ddff -orient vertical -bg $appbg -width 12 \
      -activebackground $appbg
   scrollbar $gfndbox.xscr -command "$gfndbox.brfr.lbx xview" \
      -troughcolor #88ddff -orient horizontal -bg $appbg -width 12 \
      -activebackground $appbg
   bind $gfndbox.ent <Return> {
      set newfname [string trim $newfname]
      if {![string compare $newfname ""]} {
         set gfnok 0
      } else {
         set newfname [glob -nocomplain $newfname]
         if [file isdirectory $newfname] {
            set browsedir $newfname
            browse $gfndbox.brfr.lbx
         } else {
            set gfnok 1
         }
      }
   }
   bind $gfndbox <Escape> "set gfnok 0"
   bind $gfndbox.brfr.lbx <ButtonRelease-1> {
      foreach si [$gfndbox.brfr.lbx curselection] {
         set f [$gfndbox.brfr.lbx get $si]
         if {![file isdirectory $f]} { set newfname $f }
      }
   }
   bind $gfndbox.brfr.lbx <Double-Button-1> {
      foreach si [$gfndbox.brfr.lbx curselection] {
         set newfname [$gfndbox.brfr.lbx get $si]
         if [file isdirectory $newfname] {
            set browsedir [string range $f 0 [expr [string length $f] - 2]]
            browse $gfndbox.brfr.lbx
         } else {
            set gfnok 1
         }
      }
   }

   pack $gfndbox.lbl -padx 10 -pady 5
   pack $gfndbox.ent -padx 10 -pady 5 -fill x
   pack $gfndbox.brfr.yscr $gfndbox.brfr.lbx -side right -padx 0 -pady 0 -fill y
   pack $gfndbox.brfr -padx 10 -pady 0
   pack $gfndbox.xscr -padx 10 -pady 0 -fill x
   pack $gfndbox.obtn -padx 10 -pady 5 -side left
   pack $gfndbox.space -padx 10 -pady 5 -expand yes -fill x -side left
   pack $gfndbox.cbtn -padx 10 -pady 5
   $gfndbox config -bg $appbg

   wm title $gfndbox "$wtitle"
   wm resizable $gfndbox false false
   if {![file readable $browsedir]} { set browsedir [exec pwd] }
   browse $gfndbox.brfr.lbx

   focus $gfndbox.ent
   grab $gfndbox
   tkwait variable gfnok
   grab release $gfndbox
   destroy $gfndbox

   if {$gfnok} { return [string trim $newfname] } else { return "" }
}

set cwinid -1
proc copyInfo {} {
   global bweditlogo installdir appbg appfg btnbg btnfg cwinid

   if {[winfo exists $cwinid]} {destroy $cwinid; set cwinid -1; return}
   set cwin [toplevel .copyright]
   set cwinid $cwin
   label $cwin.hdr -relief flat -fg $appfg -bg $appbg -image "bweditlogo" -cursor hand2
   bind $cwin.hdr <Button-1> { copyInfo }
   label $cwin.ver -relief ridge -fg #000000 -bg #ddddaa \
      -text " Version 2.2, May 1999 "
   message $cwin.cpy -relief ridge -fg #000000 -bg #ddddaa -width 800 -text \
"bwedit -- An X11 application for editing and processing Bengali text files.
   This is based on the Tcl/Tk shell wish. This requires a fixed X11 bitmap
   font for Bengali also designed by the author.

bwedit is a freeware. You can use and distribute it free of charge as long as
   the original author gets credit and this copyright notice remains intact."

   label $cwin.aut -relief ridge -fg #000000 -bg #ddddaa -text " Author: "
   message $cwin.add -relief ridge -fg #000000 -bg #ddddaa -width 500 -text \
"Abhijit Das (Barda)
Department of Computer Science and Automation
Indian Institute of Science
Bangalore 560 012
INDIA

E-mail: abhij@csa.iisc.ernet.in"

   button $cwin.btn -fg $btnfg -bg "$btnbg" -text " Dismiss " \
      -command "destroy $cwin" -activeforeground $btnfg -activebackground $btnbg

   pack $cwin.hdr -padx 0 -pady 5
   pack $cwin.ver -padx 0 -pady 5
   pack $cwin.cpy -padx 5 -pady 5
   pack $cwin.aut -padx 0 -pady 5
   pack $cwin.add -padx 0 -pady 5
   pack $cwin.btn -padx 0 -pady 5
   $cwin config -bg $appbg
   bind $cwin <Escape> "destroy $cwin"

   wm title $cwin "bwedit: copyright notice"
   wm resizable $cwin false false
   wm iconname $cwin "bwedit: copyright notice"
   wm iconbitmap $cwin @$installdir/images/bwedit-logo.xbm
}


############ Options ############
###### Default main window options #######
set textbg "#000000"
set textfg "#ffffff"
set textsbg "#ffffff"
set textsfg "#000000"
set textibg "#d0f080"
set textht 16
set textwd 72
set ptsize 120
set slant "r"
set mwno 0
set openkbdmap 0


###### Default transliterator window options #######
set textbg2 "#ffffff"
set textfg2 "#000000"
set textsbg2 "#ffffaa"
set textsfg2 "#000000"
set textibg2 "#CC00CC"
set textht2 24
set textwd2 80
set olbg "#000000"
set olfg "#00ffff"
set twno 0
set readencopt "0"
set encfnm "$installdir/lib/bn.enc"

###### Default mail options ######
regsub "~" "~/bwmail" [glob -nocomplain "~"] bwmaildir
set mailcmd "elm -s %s %r < %f"
set mimen "mimencode %f"
set mimed "mimencode -u %f"
set uun "uuencode %f %f"
set uud "uudecode %f -o /dev/stdout"
set inbox "/var/spool/mail/[exec whoami]"
set openmail 0

proc readOptions {} {
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant mwno openkbdmap
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 twno readencopt encfnm olbg olfg
   global bwmaildir mailcmd mimen mimed uun uud inbox openmail

   set rcfile "~/.bweditrc"
   if [file exists $rcfile] {
      set rcf [open $rcfile r]
      while { [gets $rcf rcline] >= 0 } {
         set rcline [string trim $rcline]
         set cidx [string first ":" $rcline]
         if {($cidx >= 0) && [string compare "#" [string index $rcline 0]]} {
            set rcName [ string range $rcline 0 [expr $cidx - 1] ]
            set rcVal [ string range $rcline [expr $cidx + 1] [expr [string length $rcline] - 1] ]
            set rcName [string tolower [string trim $rcName]]
            set rcVal [string tolower [string trim $rcVal]]
            switch -exact $rcName {
               "textbackground" { set textbg $rcVal }
               "textforeground" { set textfg $rcVal }
               "selectionbackground" { set textsbg $rcVal }
               "selectionforeground" { set textsfg $rcVal }
               "cursorcolor" { set textibg $rcVal }
               "textheight" { set textht $rcVal }
               "textwidth" { set textwd $rcVal }
               "defaultpointsize" { set ptsize $rcVal }
               "slant" { set slant $rcVal }
               "numwin" { set mwno $rcVal }
               "viewkbdmap" { set openkbdmap $rcVal }
               "textbackground2" { set textbg2 $rcVal }
               "textforeground2" { set textfg2 $rcVal }
               "selectionbackground2" { set textsbg2 $rcVal }
               "selectionforeground2" { set textsfg2 $rcVal }
               "cursorcolor2" { set textibg2 $rcVal }
               "textheight2" { set textht2 $rcVal }
               "textwidth2" { set textwd2 $rcVal }
               "onlineforeground" { set olfg $rcVal }
               "onlinebackground" { set olbg $rcVal }
               "numwin2" { set twno $rcVal }
               "encfile" { set encfnm $rcVal ; set readencopt 2 }
               "bwmaildir" { regsub "~" $rcVal [glob -nocomplain "~"] bwmaildir }
               "mailcommand" { set mailcmd $rcVal }
               "mimencommand" { set mimen $rcVal }
               "mimedcommand" { set mimed $rcVal }
               "uuncommand" { set uun $rcVal }
               "uudcommand" { set uud $rcVal }
               "mailinbox" { set inbox $rcVal }
               "readmail" { set openmail $rcVal }
            }
         }
      }
      close $rcf
   }
}

readOptions

proc saveOptions { flag { myid 0 } } {
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant mwno openkbdmap
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 olfg olbg twno encfnm
   global bwmaildir mailcmd mimen mimed uun uud inbox openmail

   set rcfile "~/.bweditrc"
   set rcf [open $rcfile w]
   puts $rcf "# Resource file for bwedit version 2.2"
   puts $rcf "# Do not edit. Use the \"Edit options\" menu of bwedit\n"
   puts $rcf "# Main window"
   puts $rcf "TextBackGround\t\t: $textbg"
   puts $rcf "TextForeGround\t\t: $textfg"
   puts $rcf "SelectionBackGround\t: $textsbg"
   puts $rcf "SelectionForeGround\t: $textsfg"
   puts $rcf "CursorColor\t\t: $textibg"
   puts $rcf "TextHeight\t\t: $textht"
   puts $rcf "TextWidth\t\t: $textwd"
   puts $rcf "DefaultPointSize\t: $ptsize"
   puts $rcf "Slant\t\t\t: $slant"
   puts $rcf "NumWin\t\t\t: $mwno"
   puts $rcf "ViewKbdMap\t\t: $openkbdmap"
   puts $rcf "\n# Roman window"
   puts $rcf "TextBackGround2\t\t: $textbg2"
   puts $rcf "TextForeGround2\t\t: $textfg2"
   puts $rcf "SelectionBackGround2\t: $textsbg2"
   puts $rcf "SelectionForeGround2\t: $textsfg2"
   puts $rcf "CursorColor2\t\t: $textibg2"
   puts $rcf "TextHeight2\t\t: $textht2"
   puts $rcf "TextWidth2\t\t: $textwd2"
   puts $rcf "OnlineForeGround\t: $olfg"
   puts $rcf "OnlineBackGround\t: $olbg"
   puts $rcf "NumWin2\t\t\t: $twno"
   puts $rcf "EncFile\t\t\t: $encfnm"
   puts $rcf "\n# Mail options"
   puts $rcf "BWMailDir\t\t: $bwmaildir"
   puts $rcf "MailCommand\t\t: $mailcmd"
   puts $rcf "MIMENCommand\t\t: $mimen"
   puts $rcf "MIMEDCommand\t\t: $mimed"
   puts $rcf "UUNCommand\t\t: $uun"
   puts $rcf "UUDCommand\t\t: $uud"
   puts $rcf "MailInBox\t\t: $inbox"
   puts $rcf "ReadMail\t\t: $openmail"
   puts $rcf "\n# End of .bweditrc"
   close $rcf

   if {($flag == 1)} {
      errmsg $myid "Options saved"
   } elseif {($flag == 2)} {
      errmsg2 $myid "Options saved"
   }
}

proc editOptions { flag { myid 0 } } {
   global appfg appbg btnfg btnbg opttype hdrtxt
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant
   global oldtextbg oldtextfg oldtextsbg oldtextsfg oldtextibg oldtextht oldtextwd oldptsize oldslant
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2
   global oldtextbg2 oldtextfg2 oldtextsbg2 oldtextsfg2 oldtextibg2 oldtextht2 oldtextwd2
   global oldolfg oldolbg olfg olbg
   global bwmaildir mailcmd mimen mimed uun uud inbox
   global oldbwmaildir oldmailcmd oldmimen oldmimed olduun olduud oldinbox
   global mwno twno openmail openkbdmap encfnm
   global oldmwno oldtwno oldopenmail oldopenkbdmap oldencfnm
   global hdrfont

   if {[winfo exists .option]} {
     switch -exact $opttype {
         "1" {
            pack forget .option.roman .option.mail .option.sep2 .option.btnfr
            pack .option.main -expand yes -fill both -pady 5
            pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
            pack .option.btnfr -expand no -pady 5
            set hdrtxt "Main window options"
         }
         "2" {
            pack forget .option.main .option.mail .option.sep2 .option.btnfr
            pack .option.roman -expand yes -fill both -pady 5
            pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
            pack .option.btnfr -expand no -pady 5
            set hdrtxt "Transliterator window options"
         }
         "3" {
            pack forget .option.main .option.roman .option.sep2 .option.btnfr
            pack .option.mail -expand yes -fill both -pady 5
            pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
            pack .option.btnfr -expand no -pady 5
            set hdrtxt "Mail options"
         }
      }
      focus .option; return
   }

   set oldtextbg $textbg
   set oldtextfg $textfg
   set oldtextsbg $textsbg
   set oldtextsfg $textsfg
   set oldtextibg $textibg
   set oldtextht $textht
   set oldtextwd $textwd
   set oldptsize $ptsize
   set oldslant $slant
   set oldtextbg2 $textbg2
   set oldtextfg2 $textfg2
   set oldtextsbg2 $textsbg2
   set oldtextsfg2 $textsfg2
   set oldtextibg2 $textibg2
   set oldtextht2 $textht2
   set oldtextwd2 $textwd2
   set oldolfg $olfg
   set oldolbg $olbg
   set oldbwmaildir $bwmaildir
   set oldmailcmd $mailcmd
   set oldmimen $mimen
   set oldmimed $mimed
   set olduun $uun
   set olduud $uud
   set oldinbox $inbox
   set oldmwno $mwno
   set oldtwno $twno
   set oldopenmail $openmail
   set oldopenkbdmap $openkbdmap
   set oldencfnm $encfnm

   set dbox [toplevel .option]
   $dbox config -bg $appbg
   wm title $dbox "bwedit: Edit options"
   wm resizable $dbox false false

   frame $dbox.selfr -bg $appbg -relief raised
   radiobutton $dbox.selfr.main -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 1 -text "Main"
   radiobutton $dbox.selfr.roman -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 2 -text "Transliterator"
   radiobutton $dbox.selfr.mail -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 3 -text "Mail"

   bind $dbox.selfr.main <ButtonPress-1> {
      if {$opttype != 1} {
         pack forget .option.roman .option.mail .option.sep2 .option.btnfr
         pack .option.main -expand yes -fill both -pady 5
         pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
         pack .option.btnfr -expand no -pady 5
         set hdrtxt "Main window options"
         set opttype 1
      }
   }
   bind $dbox.selfr.roman <ButtonPress-1> {
      if {$opttype != 2} {
         pack forget .option.main .option.mail .option.sep2 .option.btnfr
         pack .option.roman -expand yes -fill both -pady 5
         pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
         pack .option.btnfr -expand no -pady 5
         set hdrtxt "Transliterator window options"
         set opttype 2
      }
   }
   bind $dbox.selfr.mail <ButtonPress-1> {
      if {$opttype != 3} {
         pack forget .option.main .option.roman .option.sep2 .option.btnfr
         pack .option.mail -expand yes -fill both -pady 5
         pack .option.sep2 -expand yes -fill x -padx 5 -pady 5
         pack .option.btnfr -expand no -pady 5
         set hdrtxt "Mail options"
         set opttype 3
      }
   }

   frame $dbox.sep1 -bg $appfg -height 3 -relief flat
   frame $dbox.sep2 -bg $appfg -height 3 -relief flat

   switch -exact $opttype {
      2 { set hdrtxt "Transliterator window options" }
      3 { set hdrtxt "Mail options" }
      default { set hdrtxt "Main window options" }
   }
   label $dbox.hdr -bg $appbg -fg #8800AA -relief flat -textvariable hdrtxt -font $hdrfont

   frame $dbox.main -bg $appbg
   frame $dbox.main.fr1 -bg $appbg
   frame $dbox.main.fr2 -bg $appbg
   frame $dbox.main.fr3 -bg $appbg
   frame $dbox.main.fr4 -bg $appbg
   frame $dbox.main.fr5 -bg $appbg
   frame $dbox.main.fr6 -bg $appbg
   frame $dbox.main.fr7 -bg $appbg
   frame $dbox.main.fr8 -bg $appbg
   frame $dbox.main.fr9 -bg $appbg
   frame $dbox.main.frA -bg $appbg
   frame $dbox.main.frB -bg $appbg
   label $dbox.main.fr1.lbl -text "Text background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr1.ent -textvariable textbg -bg #ddaaaa -fg #000000
   label $dbox.main.fr2.lbl -text "Text foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr2.ent -textvariable textfg -bg #ddaaaa -fg #000000
   label $dbox.main.fr3.lbl -text "Selection background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr3.ent -textvariable textsbg -bg #ddaaaa -fg #000000
   label $dbox.main.fr4.lbl -text "Selection foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr4.ent -textvariable textsfg -bg #ddaaaa -fg #000000
   label $dbox.main.fr5.lbl -text "Cursor color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr5.ent -textvariable textibg -bg #ddaaaa -fg #000000
   label $dbox.main.fr6.lbl -text "Text height (number of lines): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr6.ent -textvariable textht -bg #ddaaaa -fg #000000
   label $dbox.main.fr7.lbl -text "Text width (in avg char width): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr7.ent -textvariable textwd -bg #ddaaaa -fg #000000
   label $dbox.main.fr8.lbl -text "Default point size: " -relief flat -anchor e -fg $appfg -bg $appbg
   menubutton $dbox.main.fr8.pt -textvariable ptsize -height 1 -width 8 \
      -relief raised -menu $dbox.main.fr8.pt.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg
   menu $dbox.main.fr8.pt.m -tearoff false -bg $appbg -fg $appfg
   $dbox.main.fr8.pt.m add command -label " 100 " -command {set ptsize 100}
   $dbox.main.fr8.pt.m add command -label " 120 " -command {set ptsize 120}
   $dbox.main.fr8.pt.m add command -label " 150 " -command {set ptsize 150}
   $dbox.main.fr8.pt.m add command -label " 180 " -command {set ptsize 180}
   $dbox.main.fr8.pt.m add command -label " 210 " -command {set ptsize 210}
   $dbox.main.fr8.pt.m add command -label " 250 " -command {set ptsize 250}
   $dbox.main.fr8.pt.m add command -label " 300 " -command {set ptsize 300}
   $dbox.main.fr8.pt.m add command -label " 360 " -command {set ptsize 360}
   checkbutton $dbox.main.fr9.cb1 -text " Use slanted font " \
      -variable slant -onvalue "o" -offvalue "r" -relief ridge \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg
   label $dbox.main.frA.lbl -text "Number of windows to launch: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.frA.ent -textvariable mwno -bg #ddaaaa -fg #000000
   checkbutton $dbox.main.frB.cb1 -text " Show keyboard map " \
      -variable openkbdmap -onvalue "1" -offvalue "0" -relief ridge \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg

   for {set i 1} {$i <= 7} {incr i 1} {
      pack $dbox.main.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.main.fr$i.ent -padx 5 -pady 5
      pack $dbox.main.fr$i -padx 5 -pady 2 -expand yes -fill x
   }
   pack $dbox.main.fr8.lbl $dbox.main.fr8.pt -padx 5 -pady 5 -side left
   pack $dbox.main.fr8 -padx 5 -pady 2
   pack $dbox.main.fr9.cb1 -padx 5 -pady 5 -side left
   pack $dbox.main.fr9 -padx 5 -pady 2
   pack $dbox.main.frA.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.main.frA.ent -padx 5 -pady 5
   pack $dbox.main.frA -padx 5 -pady 2 -expand yes -fill x
   pack $dbox.main.frB.cb1 -padx 5 -pady 5 -side left
   pack $dbox.main.frB -padx 5 -pady 2
   bind $dbox.main.fr1.ent <Return>  "focus $dbox.main.fr2.ent"
   bind $dbox.main.fr2.ent <Return>  "focus $dbox.main.fr3.ent"
   bind $dbox.main.fr3.ent <Return>  "focus $dbox.main.fr4.ent"
   bind $dbox.main.fr4.ent <Return>  "focus $dbox.main.fr5.ent"
   bind $dbox.main.fr5.ent <Return>  "focus $dbox.main.fr6.ent"
   bind $dbox.main.fr6.ent <Return>  "focus $dbox.main.fr7.ent"
   bind $dbox.main.fr7.ent <Return>  "focus $dbox.main.frA.ent"
   bind $dbox.main.frA.ent <Return>  "focus $dbox.main.fr1.ent"

   frame $dbox.roman -bg $appbg
   frame $dbox.roman.fr1 -bg $appbg
   frame $dbox.roman.fr2 -bg $appbg
   frame $dbox.roman.fr3 -bg $appbg
   frame $dbox.roman.fr4 -bg $appbg
   frame $dbox.roman.fr5 -bg $appbg
   frame $dbox.roman.fr6 -bg $appbg
   frame $dbox.roman.fr7 -bg $appbg
   frame $dbox.roman.fr8 -bg $appbg
   frame $dbox.roman.fr9 -bg $appbg
   frame $dbox.roman.fr10 -bg $appbg
   frame $dbox.roman.fr11 -bg $appbg
   label $dbox.roman.fr1.lbl -text "Text background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr1.ent -textvariable textbg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr2.lbl -text "Text foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr2.ent -textvariable textfg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr3.lbl -text "Selection background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr3.ent -textvariable textsbg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr4.lbl -text "Selection foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr4.ent -textvariable textsfg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr5.lbl -text "Cursor color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr5.ent -textvariable textibg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr6.lbl -text "Text height (number of lines): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr6.ent -textvariable textht2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr7.lbl -text "Text width (in avg char width): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr7.ent -textvariable textwd2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr8.lbl -text "Background color for online text: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr8.ent -textvariable olbg -bg #ddaaaa -fg #000000
   label $dbox.roman.fr9.lbl -text "Foreground color for online text: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr9.ent -textvariable olfg -bg #ddaaaa -fg #000000
   label $dbox.roman.fr10.lbl -text "Number of windows to launch: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr10.ent -textvariable twno -bg #ddaaaa -fg #000000
   label $dbox.roman.fr11.lbl -text "Read encoding from file: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr11.ent -textvariable encfnm -bg #ddaaaa -fg #000000

   for {set i 1} {$i <= 11} {incr i 1} {
      pack $dbox.roman.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.roman.fr$i.ent -padx 5 -pady 5
      pack $dbox.roman.fr$i -padx 5 -pady 2 -expand yes -fill x
   }

   bind $dbox.roman.fr1.ent <Return> "focus $dbox.roman.fr2.ent"
   bind $dbox.roman.fr2.ent <Return> "focus $dbox.roman.fr3.ent"
   bind $dbox.roman.fr3.ent <Return> "focus $dbox.roman.fr4.ent"
   bind $dbox.roman.fr4.ent <Return> "focus $dbox.roman.fr5.ent"
   bind $dbox.roman.fr5.ent <Return> "focus $dbox.roman.fr6.ent"
   bind $dbox.roman.fr6.ent <Return> "focus $dbox.roman.fr7.ent"
   bind $dbox.roman.fr7.ent <Return> "focus $dbox.roman.fr8.ent"
   bind $dbox.roman.fr8.ent <Return> "focus $dbox.roman.fr9.ent"
   bind $dbox.roman.fr9.ent <Return> "focus $dbox.roman.fr10.ent"
   bind $dbox.roman.fr10.ent <Return> "focus $dbox.roman.fr11.ent"
   bind $dbox.roman.fr11.ent <Return> "focus $dbox.roman.fr1.ent"

   frame $dbox.mail -bg $appbg
   frame $dbox.mail.fr1 -bg $appbg
   frame $dbox.mail.fr2 -bg $appbg
   frame $dbox.mail.fr3 -bg $appbg
   frame $dbox.mail.fr4 -bg $appbg
   frame $dbox.mail.fr5 -bg $appbg
   frame $dbox.mail.fr6 -bg $appbg
   frame $dbox.mail.fr7 -bg $appbg
   frame $dbox.mail.fr8 -bg $appbg

   label $dbox.mail.fr1.lbl -text "Mail cache directory: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr1.ent -textvariable bwmaildir -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr2.lbl -text "Send mail command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr2.ent -textvariable mailcmd -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr3.lbl -text "MIME encoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr3.ent -textvariable mimen -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr4.lbl -text "MIME decoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr4.ent -textvariable mimed -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr5.lbl -text "uuencoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr5.ent -textvariable uun -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr6.lbl -text "uudecoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr6.ent -textvariable uud -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr7.lbl -text "Mail inbox: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr7.ent -textvariable inbox -bg #ddaaaa -fg #000000 -width 30
   checkbutton $dbox.mail.fr8.cb1 -text " Launch read mail window " \
      -variable openmail -onvalue "1" -offvalue "0" -relief ridge \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg
   button $dbox.mail.clear -text "Clear mail cache" -relief raised -command {
      foreach file [glob -nocomplain $bwmaildir/raw.* $bwmaildir/snd.*] {
         exec rm -f $file
      }
   } -fg $appfg -bg $appbg -activeforeground $appfg -activebackground $appbg

   for {set i 1} {$i <= 7} {incr i 1} {
      pack $dbox.mail.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.mail.fr$i.ent -padx 5 -pady 5
      pack $dbox.mail.fr$i -padx 5 -pady 2 -expand yes -fill x
   }
   pack $dbox.mail.fr8.cb1 -padx 5 -pady 5 -side left
   pack $dbox.mail.fr8 -padx 5 -pady 2
   pack $dbox.mail.clear -pady 2 -expand no

   bind $dbox.mail.fr1.ent <Return>  "focus $dbox.mail.fr2.ent"
   bind $dbox.mail.fr2.ent <Return>  "focus $dbox.mail.fr3.ent"
   bind $dbox.mail.fr3.ent <Return>  "focus $dbox.mail.fr4.ent"
   bind $dbox.mail.fr4.ent <Return>  "focus $dbox.mail.fr5.ent"
   bind $dbox.mail.fr5.ent <Return>  "focus $dbox.mail.fr6.ent"
   bind $dbox.mail.fr6.ent <Return>  "focus $dbox.mail.fr1.ent"

   frame $dbox.btnfr -bg $appbg -relief flat
   button $dbox.btnfr.apply -text "Apply" -relief raised -command {
      switch -exact $opttype {
         2 {
            applyRomanOptions
            set oldtextbg2 $textbg2
            set oldtextfg2 $textfg2
            set oldtextsbg2 $textsbg2
            set oldtextsfg2 $textsfg2
            set oldtextibg2 $textibg2
            set oldtextht2 $textht2
            set oldtextwd2 $textwd2
            set oldolbg $olbg
            set oldolfg $olfg
            set oldtwno $twno
            set oldencfnm $encfnm
         }
         3 {
            set oldbwmaildir $bwmaildir
            set oldmailcmd $mailcmd
            set oldmimen $mimen
            set oldmimed $mimed
            set olduun $uun
            set olduud $uud
            set oldinbox $inbox
            set oldopenmail $openmail
         }
         default {
            applyMainOptions
            set oldtextbg $textbg
            set oldtextfg $textfg
            set oldtextsbg $textsbg
            set oldtextsfg $textsfg
            set oldtextibg $textibg
            set oldtextht $textht
            set oldtextwd $textwd
            set oldptsize $ptsize
            set oldslant $slant
            set oldmwno $mwno
            set oldopenkbdmap $openkbdmap
         }
      }
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $dbox.btnfr.default -text "Default" -relief raised -command {
      readOptions
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $dbox.btnfr.save -text "Save" -relief raised -command {
      saveOptions 0
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $dbox.btnfr.cancel -text "Cancel" -relief raised -command {
      set textbg $oldtextbg
      set textfg $oldtextfg
      set textsbg $oldtextsbg
      set textsfg $oldtextsfg
      set textibg $oldtextibg
      set textht $oldtextht
      set textwd $oldtextwd
      set ptsize $oldptsize
      set slant $oldslant
      set mwno $oldmwno
      set openkbdmap $oldopenkbdmap
      set textbg2 $oldtextbg2
      set textfg2 $oldtextfg2
      set textsbg2 $oldtextsbg2
      set textsfg2 $oldtextsfg2
      set textibg2 $oldtextibg2
      set textht2 $oldtextht2
      set textwd2 $oldtextwd2
      set olbg $oldolbg
      set olfg $oldolfg
      set twno $oldtwno
      set encfnm $oldencfnm
      set bwmaildir $oldbwmaildir
      set mailcmd $oldmailcmd
      set mimen $oldmimen
      set mimed $oldmimed
      set uun $olduun
      set uud $olduud
      set inbox $oldinbox
      set openmail $oldopenmail
      destroy .option
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $dbox.btnfr.done -text "Done" -relief raised -command {
      if {$opttype == 1} {applyMainOptions}
      if {$opttype == 2} {applyRomanOptions}
      destroy .option
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 2

   pack $dbox.selfr.main $dbox.selfr.roman $dbox.selfr.mail -padx 10 -expand no -side left
   pack $dbox.btnfr.apply $dbox.btnfr.default $dbox.btnfr.save $dbox.btnfr.cancel $dbox.btnfr.done -padx 5 -side left
   pack $dbox.selfr -expand no -pady 5
   pack $dbox.sep1 -expand yes -fill x -padx 5 -pady 5
   pack $dbox.hdr -expand no -pady 5
   switch -exact $opttype {
      2 { pack $dbox.roman -expand yes -fill both -pady 5 }
      3 { pack $dbox.mail -expand yes -fill both -pady 5 }
      default { pack $dbox.main -expand yes -fill both -pady 5 }
   }
   pack $dbox.sep2 -expand yes -fill x -padx 5 -pady 5
   pack $dbox.btnfr -expand no -pady 5

   bind $dbox <Escape> "destroy $dbox"
   bind $dbox <Alt-a> "$dbox.btnfr.apply invoke; break"
   bind $dbox <Alt-A> "$dbox.btnfr.apply invoke; break"
   bind $dbox <Alt-d> "$dbox.btnfr.default invoke; break"
   bind $dbox <Alt-D> "$dbox.btnfr.default invoke; break"
   bind $dbox <Alt-s> "$dbox.btnfr.save invoke; break"
   bind $dbox <Alt-S> "$dbox.btnfr.save invoke; break"
   bind $dbox <Alt-c> "$dbox.btnfr.cancel invoke; break"
   bind $dbox <Alt-C> "$dbox.btnfr.cancel invoke; break"
   bind $dbox <Alt-n> "$dbox.btnfr.done invoke; break"
   bind $dbox <Alt-N> "$dbox.btnfr.done invoke; break"
}

proc applyMainOptions { } {
   global mavail textbg textfg textsbg textsfg textibg textht textwd ptsize slant textsp3 openkbdmap

   switch -exact $ptsize {
      100 {set textsp3 4}
      120 {set textsp3 5}
      150 {set textsp3 6}
      180 {set textsp3 7}
      210 {set textsp3 8}
      250 {set textsp3 10}
      300 {set textsp3 12}
      360 {set textsp3 15}
      default {set textsp3 5}
   }

   for {set i 1} {$i < $mavail} {incr i 1} {
      if {[winfo exists .main$i]} {
         .main$i.mainfr.editfr.textarea config -height $textht -width $textwd \
             -font "-*-bengali-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific" \
             -spacing3 $textsp3 -insertbackground $textibg \
             -background $textbg -foreground $textfg \
             -selectbackground $textsbg -selectforeground $textsfg
      }
   }

   if {($openkbdmap == 1) && (![winfo exists .kbdmap])} {viewKbdMap}
}

proc applyRomanOptions { } {
   global ravail textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 olfg olbg encfnm

   for {set i 1} {$i < $ravail} {incr i 1} {
      if {[winfo exists .roman$i]} {
         .roman$i.mainfr.editfr.textarea config -height $textht2 -width $textwd2 \
            -insertbackground $textibg2 \
            -background $textbg2 -foreground $textfg2 \
            -selectbackground $textsbg2 -selectforeground $textsfg2
         .roman$i.mainfr.olview config -fg $olfg -bg $olbg \
            -selectforeground $olfg -selectbackground $olbg -selectborder 0
      }
   }

   if {[string length $encfnm] > 0} {readEnc 2 $encfnm}
}

set targetWin 0
set mtwin 0
set rmtwin 0
proc refreshAllWinList { } {
   refreshTargetWinList
   if {[winfo exists .kbdmap]} { updateWinMenu }
   if {[winfo exists .sendmail]} { mupdateMenus }
}

############ Main window #############
proc editMain { myid {fnm ""} } {
   global appbg appfg btnbg btnfg dirtybit opttype bweditlogo
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant textsp3
   global fname customfontno selstart selend asciimode ascin

   set myname ".main$myid"
   if {[winfo exists $myname]} {return}
   set mwin [toplevel $myname]
   $mwin config -bg $appbg
   wm title $mwin "bwedit: Main editor window $myid"

   frame $mwin.cmdfr -relief raised -borderwidth 2 -bg $appbg
   frame $mwin.namefr -bg $appbg
   frame $mwin.mainfr -bg $appbg
   frame $mwin.mainfr.editfr -bg $appbg

   # Tool bar
   menubutton $mwin.cmdfr.file -text "File" -height 1 -relief flat \
      -menu $mwin.cmdfr.file.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.edit -text "Edit" -height 1 -relief flat \
      -menu $mwin.cmdfr.edit.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.tag -text "Tag" -height 1 -relief flat \
      -menu $mwin.cmdfr.tag.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.import -text "Import" -height 1 -relief flat \
      -menu $mwin.cmdfr.import.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.export -text "Export" -height 1 -relief flat \
      -menu $mwin.cmdfr.export.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.mail -text "Mail" -height 1 -relief flat \
      -menu $mwin.cmdfr.mail.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.option -text "Option" -height 1 -relief flat \
      -menu $mwin.cmdfr.option.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $mwin.cmdfr.help -text "Help" -height 1 -relief flat \
      -menu $mwin.cmdfr.help.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg

   menu $mwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.file.m add command -label "  New main window " -accelerator " Alt+1 " -command "newMain" -underline 6
   $mwin.cmdfr.file.m add command -label "  New transliterator window " -accelerator " Alt+2 " -command "newRoman" -underline 6
   $mwin.cmdfr.file.m add separator
   $mwin.cmdfr.file.m add command -label "  New file " -accelerator " Alt+N " -command "newFile $myid" -underline 2
   $mwin.cmdfr.file.m add command -label "  Load file " -accelerator " F2 " -command "loadFile $myid" -underline 2
   $mwin.cmdfr.file.m add command -label "  Insert file " -accelerator " Alt+I " -command "insertFile $myid" -underline 2
   $mwin.cmdfr.file.m add command -label "  Append file " -accelerator " Alt+A " -command "appendFile $myid" -underline 2
   $mwin.cmdfr.file.m add command -label "  Save file " -accelerator " F3 " -command "saveThisFile $myid" -underline 4
   $mwin.cmdfr.file.m add command -label "  Save as file " -accelerator " Alt+S " -command "saveFile $myid" -underline 2
   $mwin.cmdfr.file.m add separator
   $mwin.cmdfr.file.m add command -label "  Close " -accelerator " Alt+C " -command "closeMain $myid" -underline 2
   $mwin.cmdfr.file.m add command -label "  Quit " -accelerator " Alt+Q " -command "quitEditor" -underline 2

   menu $mwin.cmdfr.edit.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.edit.m add command -label "  Clear  " -command "clearTextArea $myid ; incr dirtybit($myid) 1" -underline 2
   $mwin.cmdfr.edit.m add command -label "  Select all  " -command "selectAll $myid" -underline 9
   $mwin.cmdfr.edit.m add separator
   $mwin.cmdfr.edit.m add command -label "  Cut  " -accelerator " F4 " -command "cutBuffer $myid" -underline 4
   $mwin.cmdfr.edit.m add command -label "  Copy  " -accelerator " F5 " -command "copyBuffer $myid" -underline 5
   $mwin.cmdfr.edit.m add command -label "  Paste  " -accelerator " F6 " -command "pasteBuffer $myid" -underline 2
   $mwin.cmdfr.edit.m add separator
   $mwin.cmdfr.edit.m add command -label "  Search  " -accelerator " F11 " -command "searchExpr $myid" -underline 2

   menu $mwin.cmdfr.tag.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.tag.m add command -label "  Normal  " -command "normalSel $myid" -underline 2
   $mwin.cmdfr.tag.m add command -label "  Underline  " -command "ulSel $myid" -underline 2
   $mwin.cmdfr.tag.m add command -label "  Superscript  " -command "supSel $myid" -underline 4
   $mwin.cmdfr.tag.m add command -label "  Supersuperscript  " -command "supsupSel $myid" -underline 5
   $mwin.cmdfr.tag.m add command -label "  Subsuperscript  " -command "subsupSel $myid" -underline 9
   $mwin.cmdfr.tag.m add command -label "  Subscript  " -command "subSel $myid" -underline 4
   $mwin.cmdfr.tag.m add command -label "  Subsubscript  " -command "subsubSel $myid" -underline 9
   $mwin.cmdfr.tag.m add command -label "  Supersubscript  " -command "supsubSel $myid" -underline 15
   $mwin.cmdfr.tag.m add command -label "  Select font  " -command "fontSel $myid" -underline 9
   $mwin.cmdfr.tag.m add separator
   $mwin.cmdfr.tag.m add command -label "  Load tags  " -accelerator " Alt+G " -command "loadTags $myid" -underline 2
   $mwin.cmdfr.tag.m add command -label "  Save tags  " -accelerator " Alt+V " -command "saveTags $myid" -underline 4

   menu $mwin.cmdfr.import.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.import.m add command -label "  Read encoding from file " -command {readEnc 1} -underline 2
   $mwin.cmdfr.import.m add separator
   $mwin.cmdfr.import.m add command -label "  Load transliterated roman file  " -accelerator " Alt+T" -command "importRoman $myid 0" -underline 2
   $mwin.cmdfr.import.m add command -label "  Insert transliterated roman file  " -accelerator " Alt+R" -command "importRoman $myid 1" -underline 2
   $mwin.cmdfr.import.m add command -label "  Append transliterated roman file  " -command "importRoman $myid 2" -underline 2
   $mwin.cmdfr.import.m add separator
   $mwin.cmdfr.import.m add command -label "  Roman-to-Bengali transliteration rules  " -accelerator " Shift+F1 " -command {helpWinRoman} -underline 19

   menu $mwin.cmdfr.export.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.export.m add command -label "  To HTML  " -accelerator " Alt+H " -command "exportHTML $myid" -underline 5
   $mwin.cmdfr.export.m add command -label "  To LaTeX  " -accelerator " Alt+L " -command "exportLaTeX $myid" -underline 5
   $mwin.cmdfr.export.m add command -label "  To PostScript  " -accelerator " Alt+P " -command "exportPS $myid" -underline 5

   menu $mwin.cmdfr.mail.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.mail.m add command -label "  Read mail  " -accelerator " F9 " -command "readMail" -underline 2
   $mwin.cmdfr.mail.m add command -label "  Send mail  " -accelerator " Shift+F9 " -command "sendMail 1 $myid" -underline 2
   $mwin.cmdfr.mail.m add separator
   $mwin.cmdfr.mail.m add command -label "  Read bwencoded text  " -accelerator "Alt+5" -command "readBW 1 $myid" -underline 7
   $mwin.cmdfr.mail.m add command -label "  Read MIME-encoded text  "  -accelerator "Alt+6" -command "readMIME 1 $myid" -underline 7
   $mwin.cmdfr.mail.m add command -label "  Read uuencoded text  " -accelerator "Alt+7" -command "readUU 1 $myid" -underline 7
   $mwin.cmdfr.mail.m add separator
   $mwin.cmdfr.mail.m add command -label "  Edit mail options  " -command "set opttype 3; editOptions 1 $myid" -underline 2

   menu $mwin.cmdfr.option.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.option.m add command -label "  Select document font " -accelerator " Alt+D " -command {chooseBaseFont} -underline 9
   $mwin.cmdfr.option.m add separator
   $mwin.cmdfr.option.m add command -label "  Edit options " -accelerator " Alt+O " -command " set opttype 1 ; editOptions 1 $myid " -underline 7
   $mwin.cmdfr.option.m add command -label "  Save options  " -command " saveOptions 1 $myid " -underline 2

   menu $mwin.cmdfr.help.m -tearoff false -bg $appbg -fg $appfg
   $mwin.cmdfr.help.m add command -label "  Show Keyboard map " -accelerator " Alt+K " -command {viewKbdMap} -underline 7
   $mwin.cmdfr.help.m add separator
   $mwin.cmdfr.help.m add command -label "  About bwedit  " -accelerator " F1 " -command {helpWin} -underline 2
   $mwin.cmdfr.help.m add command -label "  Copyright notice  " -command {copyInfo} -underline 2

   label $mwin.cmdfr.blank -text "" -relief flat -bg $appbg -fg $appfg
   label $mwin.cmdfr.logo -image "bweditlogo" -relief flat -bg $appbg -fg $appfg -cursor hand2
   bind $mwin.cmdfr.logo <Button-1> { copyInfo }

   # File name
   label $mwin.namefr.lbl -text " File name: " -relief flat -foreground $appfg -background $appbg
   entry $mwin.namefr.ent -textvariable "fname($myid)" -relief sunken \
      -background #ffb6c1 -foreground #000000 \
      -selectbackground #000000 -selectforeground #ffb6c1 -selectborderwidth 0
   bind $mwin.namefr.ent <Return> "focus $mwin.mainfr.editfr.textarea"

   # Edit area
   text $mwin.mainfr.editfr.textarea -relief sunken -height $textht -width $textwd \
      -font "-*-bengali-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific" \
      -xscroll "$mwin.mainfr.hscroll set" -yscroll "$mwin.mainfr.editfr.scrbar set" \
      -wrap none -spacing3 $textsp3 -relief flat \
      -insertbackground $textibg -insertwidth 3 \
      -background $textbg -foreground $textfg -borderwidth 2 \
      -selectbackground $textsbg -selectforeground $textsfg -selectborderwidth 0
   scrollbar $mwin.mainfr.editfr.scrbar -relief sunken -orient vertical \
      -command "$mwin.mainfr.editfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   # Horizontal scrollbar
   scrollbar $mwin.mainfr.hscroll -relief sunken -orient horizontal \
      -command "$mwin.mainfr.editfr.textarea xview" -bg $appbg -width 12 \
      -activebackground $appbg

   pack $mwin.cmdfr.file $mwin.cmdfr.edit $mwin.cmdfr.tag $mwin.cmdfr.import \
      $mwin.cmdfr.export $mwin.cmdfr.mail $mwin.cmdfr.option $mwin.cmdfr.help \
      -side left -padx 4 -pady 0 -side left
   pack $mwin.cmdfr.blank -side left -expand yes -fill both
   pack $mwin.cmdfr.logo -side left -padx 5 -pady 0 -side left
   pack $mwin.namefr.lbl -side left -padx 0 -pady 0
   pack $mwin.namefr.ent -side left -padx 0 -pady 0 -expand yes -fill x
   pack $mwin.mainfr.editfr.scrbar -fill y -side right -padx 0 -pady 0
   pack $mwin.mainfr.editfr.textarea -expand yes -fill both -side right -padx 0 -pady 0
   pack $mwin.mainfr.hscroll -padx 0 -pady 0 -fill x -side bottom
   pack $mwin.mainfr.editfr -padx 0 -pady 0 -expand yes -fill both -side bottom
   pack $mwin.cmdfr -padx 0 -pady 0 -fill x
   pack $mwin.namefr -padx 5 -pady 5 -fill x
   pack $mwin.mainfr -padx 0 -pady 0 -expand yes -fill both

   configTags $myid
   set fnm [string trim $fnm]
   if {[string length $fnm] > 0} { tkwait visibility $mwin ; loadThisFile $myid $fnm }

   focus $mwin.mainfr.editfr.textarea
   refreshAllWinList

   # Function key bindings
   bind $mwin <F1> "helpWin"
   bind $mwin <Shift-F1> "helpWinRoman"
   bind $mwin <F2> "loadFile $myid"
   bind $mwin <F3> "saveThisFile $myid"
   bind $mwin <F4> "cutBuffer $myid"
   bind $mwin <F5> "copyBuffer $myid"
   bind $mwin <F6> "pasteBuffer $myid"
   set selstart($myid) ""
   set selend($myid) ""
   bind $mwin.mainfr.editfr.textarea <F7> "markbegin $myid"
   bind $mwin.mainfr.editfr.textarea <F8> "markend $myid"
   bind $mwin <F9> "readMail"
   bind $mwin <Shift-F9> "sendMail 1 $myid"
   bind $mwin <F10> "activateFileMenu $myid ; break"
   bind $mwin <F11> "searchExpr $myid"

   # Alt + key bindings
   bind $mwin <Alt-Key-1> "newMain"
   bind $mwin <Alt-Key-2> "newRoman"
   bind $mwin <Alt-Key-5> "readBW 1 $myid"
   bind $mwin <Alt-Key-6> "readMIME 1 $myid"
   bind $mwin <Alt-Key-7> "readUU 1 $myid"
   bind $mwin <Alt-a> "appendFile $myid"
   bind $mwin <Alt-A> "appendFile $myid"
   bind $mwin <Alt-c> "closeMain $myid; break"
   bind $mwin <Alt-C> "closeMain $myid; break"
   bind $mwin <Alt-d> "chooseBaseFont"
   bind $mwin <Alt-D> "chooseBaseFont"
   bind $mwin <Alt-g> "loadTags $myid"
   bind $mwin <Alt-G> "loadTags $myid"
   bind $mwin <Alt-h> "exportHTML $myid"
   bind $mwin <Alt-H> "exportHTML $myid"
   bind $mwin <Alt-i> "insertFile $myid"
   bind $mwin <Alt-I> "insertFile $myid"
   bind $mwin <Alt-k> "viewKbdMap"
   bind $mwin <Alt-K> "viewKbdMap"
   bind $mwin <Alt-l> "exportLaTeX $myid"
   bind $mwin <Alt-L> "exportLaTeX $myid"
   bind $mwin <Alt-n> "newFile $myid"
   bind $mwin <Alt-N> "newFile $myid"
   bind $mwin <Alt-o> "set opttype 1 ; editOptions 1 $myid"
   bind $mwin <Alt-O> "set opttype 1 ; editOptions 1 $myid"
   bind $mwin <Alt-p> "exportPS $myid"
   bind $mwin <Alt-P> "exportPS $myid"
   bind $mwin <Alt-q> "quitEditor; break"
   bind $mwin <Alt-Q> "quitEditor; break"
   bind $mwin <Alt-r> "importRoman $myid 1"
   bind $mwin <Alt-R> "importRoman $myid 1"
   bind $mwin <Alt-s> "saveFile $myid"
   bind $mwin <Alt-S> "saveFile $myid"
   bind $mwin <Alt-t> "importRoman $myid 0"
   bind $mwin <Alt-T> "importRoman $myid 0"
   bind $mwin <Alt-v> "saveTags $myid"
   bind $mwin <Alt-V> "saveTags $myid"

   # Escape binding
   set asciimode($myid) 0
   set ascin($myid) ""
   for {set i 0} {$i < 10} {incr i 1} {
      bind .main$myid.mainfr.editfr.textarea <Key-$i> "
         [ list eval if (\$asciimode($myid)) \{ set ascin($myid) \$ascin($myid)%A \; break \} else \{ incr dirtybit($myid) 1 \} ]
      "
      bind .main$myid.mainfr.editfr.textarea <Alt-Key-$i> { }
   }
   bind $mwin.mainfr.editfr.textarea <Escape> "procEsc $myid ; break"

   # Dirty bit
   bind $mwin.mainfr.editfr.textarea <Any-Key> "procKey $myid %A"
   bind $mwin.mainfr.editfr.textarea <Alt-Key> { }
   bind $mwin.mainfr.editfr.textarea <Control-Key> { }
   bind $mwin.mainfr.editfr.textarea <BackSpace> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-h> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Delete> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-d> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Meta-d> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-k> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-o> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-w> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-x> " incr dirtybit($myid) 1 "
   bind $mwin.mainfr.editfr.textarea <Control-t> " incr dirtybit($myid) 1 "

   # Menu bindings
   bind $mwin.cmdfr.file.m <Right> " grab release $mwin.cmdfr.file.m; $mwin.cmdfr.file.m unpost; activateEditMenu $myid ; break "
   bind $mwin.cmdfr.edit.m <Right> " grab release $mwin.cmdfr.edit.m; $mwin.cmdfr.edit.m unpost; activateTagMenu $myid ; break "
   bind $mwin.cmdfr.tag.m <Right> " grab release $mwin.cmdfr.tag.m; $mwin.cmdfr.tag.m unpost; activateImportMenu $myid ; break "
   bind $mwin.cmdfr.import.m <Right> " grab release $mwin.cmdfr.import.m; $mwin.cmdfr.import.m unpost; activateExportMenu $myid ; break "
   bind $mwin.cmdfr.export.m <Right> " grab release $mwin.cmdfr.export.m; $mwin.cmdfr.export.m unpost; activateMailMenu $myid ; break "
   bind $mwin.cmdfr.mail.m <Right> " grab release $mwin.cmdfr.mail.m; $mwin.cmdfr.mail.m unpost; activateOptionMenu $myid ; break "
   bind $mwin.cmdfr.option.m <Right> " grab release $mwin.cmdfr.option.m; $mwin.cmdfr.option.m unpost; activateHelpMenu $myid ; break "
   bind $mwin.cmdfr.help.m <Right> " grab release $mwin.cmdfr.help.m; $mwin.cmdfr.help.m unpost; activateFileMenu $myid ; break "
   bind $mwin.cmdfr.file.m <Left> " grab release $mwin.cmdfr.file.m; $mwin.cmdfr.file.m unpost; activateHelpMenu $myid ; break "
   bind $mwin.cmdfr.edit.m <Left> " grab release $mwin.cmdfr.edit.m; $mwin.cmdfr.edit.m unpost; activateFileMenu $myid ; break "
   bind $mwin.cmdfr.tag.m <Left> " grab release $mwin.cmdfr.tag.m; $mwin.cmdfr.tag.m unpost; activateEditMenu $myid ; break "
   bind $mwin.cmdfr.import.m <Left> " grab release $mwin.cmdfr.import.m; $mwin.cmdfr.import.m unpost; activateTagMenu $myid ; break "
   bind $mwin.cmdfr.export.m <Left> " grab release $mwin.cmdfr.export.m; $mwin.cmdfr.export.m unpost; activateImportMenu $myid ; break "
   bind $mwin.cmdfr.mail.m <Left> " grab release $mwin.cmdfr.mail.m; $mwin.cmdfr.mail.m unpost; activateExportMenu $myid ; break "
   bind $mwin.cmdfr.option.m <Left> " grab release $mwin.cmdfr.option.m; $mwin.cmdfr.option.m unpost; activateMailMenu $myid ; break "
   bind $mwin.cmdfr.help.m <Left> " grab release $mwin.cmdfr.help.m; $mwin.cmdfr.help.m unpost; activateOptionMenu $myid ; break "

   # Control + key bindings
   bind $mwin.mainfr.editfr.textarea <Control-Delete> " delword $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-BackSpace> " bsword $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-w> " deltotalword $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-j> " joinword $myid ; break "

   bind $mwin.mainfr.editfr.textarea <Control-Shift-Delete> " delline $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-Shift-BackSpace> " bsline $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-L> " deltotalline $myid ; break "
   bind $mwin.mainfr.editfr.textarea <Control-J> " joinline $myid ; break "

   bind $mwin.mainfr.editfr.textarea <Control-a> " $mwin.mainfr.editfr.textarea insert insert {a}; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-A> " $mwin.mainfr.editfr.textarea insert insert {aA}; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-i> " $mwin.mainfr.editfr.textarea insert insert [format %c 1]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-I> " $mwin.mainfr.editfr.textarea insert insert [format %c 2]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-u> " $mwin.mainfr.editfr.textarea insert insert [format %c 3]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-U> " $mwin.mainfr.editfr.textarea insert insert [format %c 4]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-R> " $mwin.mainfr.editfr.textarea insert insert [format %c 5]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-e> " $mwin.mainfr.editfr.textarea insert insert [format %c 6]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-E> " $mwin.mainfr.editfr.textarea insert insert [format %c 7]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-o> " $mwin.mainfr.editfr.textarea insert insert [format %c 8]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-O> " $mwin.mainfr.editfr.textarea insert insert {o}; incr dirtybit($myid) 1; break "

   bind $mwin.mainfr.editfr.textarea <Control-y> " $mwin.mainfr.editfr.textarea insert insert [format %c 14]; incr dirtybit($myid) 1; break "
   bind $mwin.mainfr.editfr.textarea <Control-r> " $mwin.mainfr.editfr.textarea insert insert [format %c 15]; incr dirtybit($myid) 1; break "

   # Mouse bindings
   menu $mwin.b2m -tearoff false -bg $appbg -fg $appfg
   $mwin.b2m add command -label " Cut " -command "cutBuffer $myid"
   $mwin.b2m add command -label " Copy " -command "copyBuffer $myid"
   $mwin.b2m add command -label " Paste " -command "pasteBuffer $myid"
   $mwin.b2m add separator
   $mwin.b2m add command -label " Normal " -command "normalSel $myid"
   $mwin.b2m add command -label " Underline " -command "ulSel $myid"
   $mwin.b2m add command -label " Superscript " -command "supSel $myid"
   $mwin.b2m add command -label " Supersuperscript " -command "supsupSel $myid"
   $mwin.b2m add command -label " Subsuperscript " -command "subsupSel $myid"
   $mwin.b2m add command -label " Subscript " -command "subSel $myid"
   $mwin.b2m add command -label " Subsubscript " -command "subsubSel $myid"
   $mwin.b2m add command -label " Supersubscript " -command "supsubSel $myid"
   $mwin.b2m add separator
   $mwin.b2m add command -label " Selection Font " -command "fontSel $myid"
   $mwin.b2m add command -label " Document Font " -command "chooseBaseFont"

   menu $mwin.b3m -tearoff false -bg $appbg -fg $appfg
   $mwin.b3m add command -label " Load file " -command "loadFile $myid"
   $mwin.b3m add command -label " Save file " -command "saveThisFile $myid"
   $mwin.b3m add command -label " Save as file " -command "saveFile $myid"
   $mwin.b3m add separator
   $mwin.b3m add command -label " Load Roman file " -command "importRoman $myid 0"
   $mwin.b3m add command -label " Insert Roman file " -command "importRoman $myid 1"
   $mwin.b3m add command -label " Append Roman file " -command "importRoman $myid 2"
   $mwin.b3m add separator
   $mwin.b3m add command -label " Load Tags " -command "loadTags $myid"
   $mwin.b3m add command -label " Save Tags " -command "saveTags $myid"
   $mwin.b3m add separator
   $mwin.b3m add command -label " Export to HTML " -command "exportHTML $myid"
   $mwin.b3m add command -label " Export to LaTeX " -command "exportLaTeX $myid"
   $mwin.b3m add command -label " Export to PostScript " -command "exportPS $myid"
   $mwin.b3m add separator
   $mwin.b3m add command -label " Send mail " -command "sendMail 1 $myid"
   $mwin.b3m add command -label " Read bwencoded file " -command "readBW 1 $myid"
   $mwin.b3m add command -label " Read MIME encoded file " -command "readMIME 1 $myid"
   $mwin.b3m add command -label " Read uuencoded file " -command "readUU 1 $myid"
   $mwin.b3m add separator
   $mwin.b3m add command -label " Close " -command "closeMain $myid"
   $mwin.b3m add command -label " Quit " -command "quitEditor"

   bind $mwin.mainfr.editfr.textarea <ButtonPress-2> "
      $mwin.b2m post %X %Y
      $mwin.b2m activate 0
      grab set -global $mwin.b2m
   "

   bind $mwin.mainfr.editfr.textarea <ButtonPress-3> "
      $mwin.b3m post %X %Y
      $mwin.b3m activate 0
      grab set -global $mwin.b3m
   "
}

proc activateFileMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.file]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.file]
   incr posy [winfo height $mwin.cmdfr.file]
   $mwin.cmdfr.file.m post $posx $posy
   $mwin.cmdfr.file.m activate 0
   grab set -global $mwin.cmdfr.file.m
   focus $mwin.cmdfr.file.m
}

proc activateEditMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.edit]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.edit]
   incr posy [winfo height $mwin.cmdfr.edit]
   $mwin.cmdfr.edit.m post $posx $posy
   $mwin.cmdfr.edit.m activate 0
   grab set -global $mwin.cmdfr.edit.m
   focus $mwin.cmdfr.edit.m
}

proc activateTagMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.tag]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.tag]
   incr posy [winfo height $mwin.cmdfr.tag]
   $mwin.cmdfr.tag.m post $posx $posy
   $mwin.cmdfr.tag.m activate 0
   grab set -global $mwin.cmdfr.tag.m
   focus $mwin.cmdfr.tag.m
}

proc activateOptionMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.option]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.option]
   incr posy [winfo height $mwin.cmdfr.option]
   $mwin.cmdfr.option.m post $posx $posy
   $mwin.cmdfr.option.m activate 0
   grab set -global $mwin.cmdfr.option.m
   focus $mwin.cmdfr.option.m
}

proc activateImportMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.import]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.import]
   incr posy [winfo height $mwin.cmdfr.import]
   $mwin.cmdfr.import.m post $posx $posy
   $mwin.cmdfr.import.m activate 0
   grab set -global $mwin.cmdfr.import.m
   focus $mwin.cmdfr.import.m
}

proc activateExportMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.export]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.export]
   incr posy [winfo height $mwin.cmdfr.export]
   $mwin.cmdfr.export.m post $posx $posy
   $mwin.cmdfr.export.m activate 0
   grab set -global $mwin.cmdfr.export.m
   focus $mwin.cmdfr.export.m
}

proc activateMailMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.mail]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.mail]
   incr posy [winfo height $mwin.cmdfr.mail]
   $mwin.cmdfr.mail.m post $posx $posy
   $mwin.cmdfr.mail.m activate 0
   grab set -global $mwin.cmdfr.mail.m
   focus $mwin.cmdfr.mail.m
}

proc activateHelpMenu { myid } {
   set mwin ".main$myid"
   set posx [winfo x $mwin]
   incr posx [winfo x $mwin.cmdfr.help]
   set posy [winfo y $mwin]
   incr posy [winfo y $mwin.cmdfr.help]
   incr posy [winfo height $mwin.cmdfr.help]
   $mwin.cmdfr.help.m post $posx $posy
   $mwin.cmdfr.help.m activate 0
   grab set -global $mwin.cmdfr.help.m
   focus $mwin.cmdfr.help.m
}

proc procKey { myid A } {
   global asciimode ascin dirtybit

   if ($asciimode($myid)) { set ascin($myid) "" ; set asciimode($myid) 0 }
   if { ([string compare $A " "] >= 0) && ([string compare $A "~"] <= 0) } {
      incr dirtybit($myid) 1
   }
   if {![string compare $A "\t"]} { incr dirtybit($myid) 1 }
   if {![string compare $A "\n"]} { incr dirtybit($myid) 1 }
   if {![string compare $A "\r"]} { incr dirtybit($myid) 1 }
   if {![string compare $A "\f"]} { incr dirtybit($myid) 1 }
}

proc procEsc { myid } {
   global asciimode ascin dirtybit

   set mwin ".main$myid"
   if {($asciimode($myid)) && ([string length $ascin($myid)] > 0)} {
      $mwin.mainfr.editfr.textarea insert insert [format "%c" $ascin($myid)]
      set ascin($myid) ""
      incr dirtybit($myid) 1
   }
   set asciimode($myid) [expr 1 - $asciimode($myid)]
}

proc markbegin { myid } {
   global selstart

   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {([llength $lsel] == 2)} {
      $mwin.mainfr.editfr.textarea tag remove sel [lindex $lsel 0] [lindex $lsel 1]
   }
   set selstart($myid) [$mwin.mainfr.editfr.textarea index insert]
}

proc markend { myid } {
   global selstart selend

   set mwin ".main$myid"
   if {[string length $selstart($myid)] > 0} {
      set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
      if {[llength $lsel] == 2} {
         $mwin.mainfr.editfr.textarea tag remove sel [lindex $lsel 0] [lindex $lsel 1]
      }
      set selend($myid) [$mwin.mainfr.editfr.textarea index insert]
      if {[$mwin.mainfr.editfr.textarea compare $selstart($myid) <= $selend($myid)]} {
         $mwin.mainfr.editfr.textarea tag add sel $selstart($myid) $selend($myid)
      } else {
         $mwin.mainfr.editfr.textarea tag add sel $selend($myid) $selstart($myid)
      }
   }
   set selstart($myid) ""
   set selend($myid) ""
}

proc puncsymb { ch } {
   switch -exact "$ch" {
       " " { return 1 }
      "\n" { return 1 }
      "\t" { return 1 }
      "." { return 1 }
      "<" { return 1 }
      "," { return 1 }
      ";" { return 1 }
      ":" { return 1 }
      "?" { return 1 }
      "!" { return 1 }
      "/" { return 1 }
      "%" { return 1 }
      "~" { return 1 }
      "`" { return 1 }
      "'" { return 1 }
      "\\" { return 1 }
      "\"" { return 1 }
      "#" { return 1 }
      "\$" { return 1 }
      "+" { return 1 }
      "-" { return 1 }
      "*" { return 1 }
      "=" { return 1 }
      "\{" { return 1 }
      "|" { return 1 }
      "(" { return 1 }
      ")" { return 1 }
      "\[" { return 1 }
      "\]" { return 1 }
      default { return 0 }
   }
}

proc delword { myid } {
   global dirtybit

   set mwin ".main$myid"
   incr dirtybit($myid) 1
   set ch [$mwin.mainfr.editfr.textarea get insert]
   $mwin.mainfr.editfr.textarea delete insert
   if {[puncsymb $ch]} { return }
   set ch [$mwin.mainfr.editfr.textarea get insert]
   while {![puncsymb $ch]} {
      $mwin.mainfr.editfr.textarea delete insert
      set ch [$mwin.mainfr.editfr.textarea get insert]
   }
}

proc bsword { myid } {
   global dirtybit

   set mwin ".main$myid"
   incr dirtybit($myid) 1
   set ch [$mwin.mainfr.editfr.textarea get "insert -1 chars"]
   $mwin.mainfr.editfr.textarea delete "insert -1 chars"
   if {[puncsymb $ch]} { return }
   set ch [$mwin.mainfr.editfr.textarea get "insert -1 chars"]
   while {[puncsymb $ch] == 0} {
      $mwin.mainfr.editfr.textarea delete "insert -1 chars"
      set ch [$mwin.mainfr.editfr.textarea get "insert -1 chars"]
   }
}

proc deltotalword { myid } {
   global dirtybit

   set mwin ".main$myid"
   incr dirtybit($myid) 1

   set ch [$mwin.mainfr.editfr.textarea get insert]
   $mwin.mainfr.editfr.textarea delete insert
   if {[puncsymb $ch]} { return }

   set ch [$mwin.mainfr.editfr.textarea get "insert -1 chars"]
   while {[puncsymb $ch] == 0} {
      $mwin.mainfr.editfr.textarea delete "insert -1 chars"
      set ch [$mwin.mainfr.editfr.textarea get "insert -1 chars"]
   }
   set ch [$mwin.mainfr.editfr.textarea get insert]
   while {![puncsymb $ch]} {
      $mwin.mainfr.editfr.textarea delete insert
      set ch [$mwin.mainfr.editfr.textarea get insert]
   }
   if {![string compare " " [$mwin.mainfr.editfr.textarea get insert]]} {
      $mwin.mainfr.editfr.textarea delete insert
   } elseif {![string compare "\t" [$mwin.mainfr.editfr.textarea get insert]]} {
      $mwin.mainfr.editfr.textarea delete insert
   }
}

proc joinword { myid } {
   global dirtybit

   set mwin ".main$myid"
   set i 0
   while {![puncsymb [$mwin.mainfr.editfr.textarea get "insert + $i chars"]]} {
      incr i 1
   }
   switch -exact [$mwin.mainfr.editfr.textarea get "insert + $i chars"] {
      "\n" {
         $mwin.mainfr.editfr.textarea delete "insert + $i chars"
         incr dirtybit($myid) 1
      }
      "\t" {
         $mwin.mainfr.editfr.textarea delete "insert + $i chars"
         incr dirtybit($myid) 1
      }
      " " {
         $mwin.mainfr.editfr.textarea delete "insert + $i chars"
         incr dirtybit($myid) 1
      }
   }
}

proc delline { myid } {
   global dirtybit

   set mwin ".main$myid"
   $mwin.mainfr.editfr.textarea delete insert "insert lineend" ; incr dirtybit($myid) 1
}

proc bsline { myid } {
   global dirtybit

   set mwin ".main$myid"
   $mwin.mainfr.editfr.textarea delete "insert linestart" "insert" ; incr dirtybit($myid) 1
}

proc deltotalline { myid } {
   global dirtybit

   set mwin ".main$myid"
   $mwin.mainfr.editfr.textarea delete "insert linestart" "insert + 1 lines linestart" ; incr dirtybit($myid) 1
}

proc joinline { myid } {
   global dirtybit

   set mwin ".main$myid"
   $mwin.mainfr.editfr.textarea delete "insert lineend" "insert + 1 lines linestart" ; incr dirtybit($myid) 1
}

set mavail 1
proc newMain { } {
   global mavail dirtybit fname customfontno

   set dirtybit($mavail) 0
   set fname($mavail) ""
   set customfontno($mavail) 0
   editMain $mavail
   incr mavail 1
   return [expr $mavail - 1]
}

proc loadMain { } {
   global mavail dirtybit fname customfontno

   set dirtybit($mavail) 0
   set fname($mavail) ""
   set customfontno($mavail) 0
   editMain $mavail [getFileName "Load file"]
   incr mavail 1
   return [expr $mavail - 1]
}

proc loadMain2 { fnm } {
   global mavail dirtybit fname customfontno

   set dirtybit($mavail) 0
   set fname($mavail) ""
   set customfontno($mavail) 0
   editMain $mavail $fnm
   incr mavail 1
   return [expr $mavail - 1]
}

proc closeMain { myid } {
   global dirtybit

   set mwin ".main$myid"
   saveConfirm $myid; if { $dirtybit($myid) != 0 } { return }
   destroy $mwin
   refreshAllWinList
}

proc newFile { myid } {
   global fname dirtybit

   set mwin ".main$myid"
   saveConfirm $myid; if {$dirtybit($myid) != 0} { return }
   clearTextArea $myid
   set fname($myid) ""
}

proc loadThisFile { myid fnm } {
   global dirtybit fname

   set mwin ".main$myid"
   saveConfirm $myid; if {$dirtybit($myid) != 0} { return }
   set fnm [string trim $fnm]
   if {![file readable $fnm]} {
      errmsg $myid "ERROR:\nI cannot load the file \"$fnm\". The file does not exist or does not have read permission."
      return
   }
   if {![file isfile $fnm]} {
      errmsg $myid "ERROR:\nI cannot load the file. \"$fnm\" is not a regular file."
      return
   }
   set f [open $fnm r]
   set x [read $f]
   clearTextArea $myid
   $mwin.mainfr.editfr.textarea insert 1.0 $x
   close $f
   focus $mwin.mainfr.editfr.textarea
   loadTags $myid "$fnm.tags"
   set fname($myid) $fnm
   $mwin.mainfr.editfr.textarea see insert
}

proc loadFile { myid } {
   global fname dirtybit

   set mwin ".main$myid"
   saveConfirm $myid; if {$dirtybit($myid) != 0} { return }
   set fn [getFileName "bwedit: Load"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      clearTextArea $myid
      $mwin.mainfr.editfr.textarea insert 1.0 $x
      close $f
      loadTags $myid "$fn.tags"
      set fname($myid) $fn
      $mwin.mainfr.editfr.textarea see insert
   }
}

proc insertFile { myid } {
   global dirtybit

   set mwin ".main$myid"
   set fn [getFileName "bwedit: Insert"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg $myid "ERROR:\nI cannot insert the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg $myid "ERROR:\nI cannot insert the file. \"$fn\" is not a regular file."
         return
      }
      set offset [$mwin.mainfr.editfr.textarea index insert]
      set dotidx [string first "." $offset]
      set offset [string range $offset 0 [expr $dotidx - 1]]
      set f [open $fn r]
      set x [read $f]
      $mwin.mainfr.editfr.textarea insert insert "\n$x"
      close $f
      loadTags $myid "$fn.tags" $offset
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($myid) 1
   }
}

proc appendFile { myid } {
   global dirtybit

   set mwin ".main$myid"
   set fn [getFileName "bwedit: Append"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg $myid "ERROR:\nI cannot append the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg $myid "ERROR:\nI cannot append the file. \"$fn\" is not a regular file."
         return
      }
      set offset [$mwin.mainfr.editfr.textarea index end]
      set dotidx [string first "." $offset]
      set offset [string range $offset 0 [expr $dotidx - 1]]
      incr offset -1
      set f [open $fn r]
      set x [read $f]
      $mwin.mainfr.editfr.textarea insert end "\n$x"
      close $f
      loadTags $myid "$fn.tags" $offset
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($myid) 1
   }
}

proc saveThisFile { myid } {
   global fname dirtybit

   set mwin ".main$myid"
   set fnm [string trim $fname($myid)]
   if {![string compare "" $fnm]} {
      errmsg $myid "ERROR:\nI cannot save file. No file name is given."
      return
   }
   set dnm [file dirname $fnm]
   if {![file isdirectory $dnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
      return
   }
   if {![file writable $dnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
      return
   }
   if {[file exists $fnm] && ![file isfile $fnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. \"$fnm\" is not a regular file."
      return
   }
   if {[file exists $fnm] && ![file writable $fnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fnm\""
      return
   }
   set f [open $fnm w]
   set x [$mwin.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   close $f
   saveTags $myid "$fnm.tags"
   set dirtybit($myid) 0
   errmsg $myid "$fnm saved"
}

proc saveFile { myid } {
   global fname dirtybit

   set mwin ".main$myid"
   set fnm [getFileName "bwedit: Save"]
   if {![string compare "" $fnm]} { return }
   set dnm [file dirname $fnm]
   if {![file isdirectory $dnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
      return
   }
   if {![file writable $dnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
      return
   }
   if {[file exists $fnm] && ![file isfile $fnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. \"$fnm\" is not a regular file."
      return
   }
   if {[file exists $fnm] && ![file writable $fnm]} {
      errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fnm\""
      return
   }
   set f [open $fnm w]
   set x [$mwin.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   close $f
   saveTags $myid "$fnm.tags"
   set dirtybit($myid) 0
   if {![string compare $fname($myid) ""]} { set fname($myid) $fnm }
   errmsg $myid "$fnm saved"
}

proc clearTextArea { myid } {
   .main$myid.mainfr.editfr.textarea delete 1.0 end
}

proc selectAll { myid } {
   .main$myid.mainfr.editfr.textarea tag add sel 1.0 end
}

set buffer ""
proc cutBuffer { myid } {
   global buffer dirtybit

   set mwin .main$myid
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   incr dirtybit($myid) 1
   set buffer [$mwin.mainfr.editfr.textarea get sel.first sel.last]
   $mwin.mainfr.editfr.textarea delete sel.first sel.last
   $mwin.mainfr.editfr.textarea see insert
}

proc copyBuffer { myid } {
   global buffer

   set mwin .main$myid
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   set buffer [$mwin.mainfr.editfr.textarea get sel.first sel.last]
}

proc pasteBuffer { myid } {
   global buffer dirtybit

   set mwin .main$myid
   $mwin.mainfr.editfr.textarea insert insert $buffer
   incr dirtybit($myid) 1
   $mwin.mainfr.editfr.textarea see insert
}

proc configTags { myid } {
   global off1 off2 off3 ptsize slant

   set mwin ".main$myid"

   switch -exact $ptsize {
      100 { set scriptsize 100; set scriptscriptsize 100 } 
      120 { set scriptsize 100; set scriptscriptsize 100 }
      150 { set scriptsize 120; set scriptscriptsize 100 }
      180 { set scriptsize 150; set scriptscriptsize 120 }
      210 { set scriptsize 180; set scriptscriptsize 150 }
      250 { set scriptsize 210; set scriptscriptsize 180 }
      300 { set scriptsize 250; set scriptscriptsize 210 }
      360 { set scriptsize 300; set scriptscriptsize 250 }
      default { set scriptsize 120; set scriptscriptsize 120 }
   }

   $mwin.mainfr.editfr.textarea tag config suptag -offset $off1 -font "-*-bengali-medium-$slant-*-*-*-$scriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config supsuptag -offset $off2 -font "-*-bengali-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config subsuptag -offset $off3 -font "-*-bengali-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config subtag -offset -$off1 -font "-*-bengali-medium-$slant-*-*-*-$scriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config subsubtag -offset -$off2 -font "-*-bengali-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config supsubtag -offset -$off3 -font "-*-bengali-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   $mwin.mainfr.editfr.textarea tag config ultag -underline true

   foreach point {100 120 150 180 210 250 300 360} {
      $mwin.mainfr.editfr.textarea tag config bengali${point}o -font "-*-bengali-medium-o-*-*-*-$point-*-*-*-*-*-fontspecific"
      $mwin.mainfr.editfr.textarea tag config bengali${point}r -font "-*-bengali-medium-r-*-*-*-$point-*-*-*-*-*-fontspecific"
   }
   $mwin.mainfr.editfr.textarea tag config english -font fixed
}

proc supSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag add suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc supsupSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag add supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subsupSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag add subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag add subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subsubSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag add subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc supsubSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag add supsubtag sel.first sel.last
}

proc ulSel { myid } {
   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag add ultag sel.first sel.last
}

proc normalSel { myid } {
   global customfontno

   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   $mwin.mainfr.editfr.textarea tag remove suptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
   $mwin.mainfr.editfr.textarea tag remove ultag sel.first sel.last
   foreach point {100 120 150 180 210 250 300 360} {
      $mwin.mainfr.editfr.textarea tag remove bengali${point}o sel.first sel.last
      $mwin.mainfr.editfr.textarea tag remove bengali${point}r sel.first sel.last
   }
   $mwin.mainfr.editfr.textarea tag remove english sel.first sel.last
   for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
      $mwin.mainfr.editfr.textarea tag remove customftag$i sel.first sel.last
   }
}

proc fontSel { myid } {
   global ptsize slant fseltype fselpt fselsl fswin fsgfname
   global fsok customfid customfontno lsel fontlist appbg appfg btnbg btnfg

   set mwin ".main$myid"
   set lsel [$mwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   set fswin [toplevel .fsel]
   set fseltype 0
   set fselpt $ptsize
   set fselsl $slant
   set fsgfname ""

   frame $fswin.bfr -bg $appbg -relief flat
   frame $fswin.efr -bg $appbg -relief flat
   frame $fswin.gfr -bg $appbg -relief flat
   frame $fswin.gfr.fr1 -bg $appbg -relief flat
   frame $fswin.gfr.fr2 -bg $appbg -relief flat
   frame $fswin.ofr -bg $appbg -relief flat
   radiobutton $fswin.bfr.rb  -text "Bengali: " -variable fseltype -value 0 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   menubutton $fswin.bfr.mb -text "Point size" -height 1 -width 10 \
      -relief raised -menu $fswin.bfr.mb.m -bg $appbg -fg #000000 \
      -activebackground $appbg -activeforeground #000000 -disabledforeground #A2A2A2
   menu $fswin.bfr.mb.m -tearoff false -bg $appbg -fg $appfg
   $fswin.bfr.mb.m add command -label " 100 " -command {$fswin.bfr.mb config -text 100; set fselpt 100}
   $fswin.bfr.mb.m add command -label " 120 " -command {$fswin.bfr.mb config -text 120; set fselpt 120}
   $fswin.bfr.mb.m add command -label " 150 " -command {$fswin.bfr.mb config -text 150; set fselpt 150}
   $fswin.bfr.mb.m add command -label " 180 " -command {$fswin.bfr.mb config -text 180; set fselpt 180}
   $fswin.bfr.mb.m add command -label " 210 " -command {$fswin.bfr.mb config -text 210; set fselpt 210}
   $fswin.bfr.mb.m add command -label " 250 " -command {$fswin.bfr.mb config -text 250; set fselpt 250}
   $fswin.bfr.mb.m add command -label " 300 " -command {$fswin.bfr.mb config -text 300; set fselpt 300}
   $fswin.bfr.mb.m add command -label " 360 " -command {$fswin.bfr.mb config -text 360; set fselpt 360}
   checkbutton $fswin.bfr.cb -text "Slanted" \
      -variable fselsl -onvalue "o" -offvalue "r" -relief flat \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground #000000 -activebackground $appbg -disabledforeground #A2A2A2
   label $fswin.bfr.space -text "" -relief flat -fg #000000 -bg $appbg
   radiobutton $fswin.efr.rb  -text "English: " -variable fseltype -value 1 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   label $fswin.efr.space -text "" -relief flat -fg #000000 -bg $appbg
   radiobutton $fswin.gfr.fr1.rb  -text "General: " -variable fseltype -value 2 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   entry $fswin.gfr.fr1.e -textvariable fsgfname -width 40 -bg #ddddaa -fg #000000 \
      -state disabled -selectbackground #000000 -selectforeground #ddddaa
   listbox $fswin.gfr.fr2.lbx -bg #ddddaa -fg #A2A2A2 -height 10 \
      -yscroll "$fswin.gfr.fr2.scr set" -relief sunken \
      -selectmode single -selectforeground #ddddaa -selectbackground #A2A2A2 \
      -selectborderwidth 0
   scrollbar $fswin.gfr.fr2.scr -command "$fswin.gfr.fr2.lbx yview" \
      -orient vertical -bg $appbg -width 12 -activebackground $appbg
   set fllen [llength $fontlist]
   for {set idx 0} {$idx < $fllen} {incr idx 1} {
      $fswin.gfr.fr2.lbx insert end [lindex $fontlist $idx]
   }
   bind $fswin.gfr.fr2.lbx <ButtonPress-1> {
      if {$fseltype == 2} {
         set fsgfname [$fswin.gfr.fr2.lbx get [$fswin.gfr.fr2.lbx nearest %y]]
      }
   }
   bind $fswin.gfr.fr2.lbx <ButtonRelease-1> "
      $mwin.mainfr.editfr.textarea tag add sel [lindex $lsel 0] [lindex $lsel 1]
   "
   bind $fswin.bfr.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #A2A2A2 -selectbackground #A2A2A2
      $fswin.bfr.mb config -state active
      $fswin.bfr.cb config -state active
   }
   bind $fswin.efr.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #A2A2A2 -selectbackground #A2A2A2
      $fswin.bfr.mb config -state disabled
      $fswin.bfr.cb config -state disabled
   }
   bind $fswin.gfr.fr1.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #000000 -selectbackground #000000
      $fswin.bfr.mb config -state disabled
      $fswin.bfr.cb config -state disabled
   }

   button $fswin.ofr.ok -text " Ok " -relief raised -fg $btnfg -bg $btnbg \
      -activebackground $btnbg -activeforeground $btnfg -command "set fsok 1"
   label $fswin.ofr.space -text "" -relief flat -fg $appfg -bg $appbg
   button $fswin.ofr.cancel -text " Cancel " -relief raised -fg $btnfg -bg $btnbg \
      -activebackground $btnbg -activeforeground $btnfg -command "set fsok 0"

   pack $fswin.bfr.rb $fswin.bfr.mb $fswin.bfr.cb -expand no -side left -padx 5 -pady 0
   pack $fswin.bfr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.efr.rb -expand no -side left -padx 5 -pady 0
   pack $fswin.efr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.gfr.fr1.rb -expand no -side left -padx 5 -pady 0
   pack $fswin.gfr.fr1.e -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.gfr.fr2.scr -side right -expand no -fill y -padx 0 -pady 0
   pack $fswin.gfr.fr2.lbx -side right -expand yes -fill x -padx 0 -pady 0
   pack $fswin.gfr.fr1 -expand yes -fill x -padx 0 -pady 0
   pack $fswin.gfr.fr2 -expand yes -fill x -padx 5 -pady 0
   pack $fswin.ofr.ok -expand no -side left -padx 5 -pady 0
   pack $fswin.ofr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.ofr.cancel -expand no -side left -padx 5 -pady 0
   pack $fswin.bfr $fswin.efr $fswin.gfr $fswin.ofr -padx 5 -pady 10 -expand yes -fill x
   $fswin config -bg $appbg

   wm title $fswin "Selection font"
   wm resizable $fswin false false

   bind $fswin <Escape> "set fsok 0"

   grab $fswin
   tkwait variable fsok
   destroy $fswin

   $mwin.mainfr.editfr.textarea tag add sel [lindex $lsel 0] [lindex $lsel 1]
   if {($fsok)} {
      foreach point {100 120 150 180 210 250 300 360} {
         $mwin.mainfr.editfr.textarea tag remove bengali${point}o sel.first sel.last
         $mwin.mainfr.editfr.textarea tag remove bengali${point}r sel.first sel.last
      }
      $mwin.mainfr.editfr.textarea tag remove english sel.first sel.last
      for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
         $mwin.mainfr.editfr.textarea tag remove customftag$i sel.first sel.last
      }
      switch -exact $fseltype {
         0 { $mwin.mainfr.editfr.textarea tag add bengali$fselpt$fselsl sel.first sel.last }
         1 { $mwin.mainfr.editfr.textarea tag add english sel.first sel.last }
         2 {
            set inserted 0
            for {set i 0} {($i < $customfontno($myid)) && (!$inserted)} {incr i 1} {
               if {![string comp $customfid("$myid:$i") $fsgfname]} {
                  $mwin.mainfr.editfr.textarea tag add customftag$i sel.first sel.last
                  set inserted 1
               }
            }
            if {!($inserted)} {
               $mwin.mainfr.editfr.textarea tag config customftag$customfontno($myid) -font $fsgfname
               $mwin.mainfr.editfr.textarea tag add customftag$customfontno($myid) sel.first sel.last
               set customfid("$myid:$customfontno($myid)") $fsgfname
               incr customfontno($myid) 1
            }
         }
      }
   }
}

proc loadTags { myid { tfname "" } { offset 0 } } {
   set mwin ".main$myid"
   if {![string compare $tfname ""]} {
      set fn [getFileName "bwedit: Load tags"]
   } else {
      set fn $tfname
   }
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         if {![string compare $tfname ""]} {
            errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         }
         return
      }
      if {![file isfile $fn]} {
         if {![string compare $tfname ""]} {
            errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         }
         return
      }
      set f [open $fn r]
      foreach line [split [read $f] "\n"] {
         addTag $myid $line $offset
      }
      close $f
      $mwin.mainfr.editfr.textarea see insert
   }
}

proc addTag { myid line { offset 0 } } {
   global customfontno customfid fontlist scriptlist

   set mwin ".main$myid"
   set endidx [$mwin.mainfr.editfr.textarea index end]
   set colonidx [ string first ":" $line ]
   if {$colonidx > 0} {
      set tagname [ string range $line 0 [expr $colonidx - 1] ]
      set tagranges [ string range $line [expr $colonidx + 1] [ expr [string length $line] - 1] ]
      set tagname [ string trim $tagname ]
      set tagranges [ string trim $tagranges ]
      set cfidx -1
      if {![string compare $tagname "customfont"]} {
         set tabidx [string first "\t" $tagranges]
         if {$tabidx > 0} {
            set tagname [string trim [string range $tagranges 0 [expr $tabidx - 1]]]
            set tagranges [string trim [string range $tagranges [expr $tabidx + 1] [expr [string length $tagranges] - 1]]]
            for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
               if {![string compare $tagname $customfid("$myid:$i")]} { set cfidx $i }
            }
            if {$cfidx == -1} {
               set cfidx $customfontno($myid)
               incr customfontno($myid) 1
               set customfid("$myid:$cfidx") $tagname
               if {[lsearch -exact $fontlist $tagname] < 0} {
                  puts "Unable to find font $tagname.. using fixed instead"
                  $mwin.mainfr.editfr.textarea tag config customftag$cfidx -font fixed
               } else {
                  $mwin.mainfr.editfr.textarea tag config customftag$cfidx -font $tagname
               }
            }
         } else { set cfidx -2 }
      }
      set tagranges [split $tagranges " "]
      if {$cfidx != -2} {
         while {[llength $tagranges] > 1} {
            set tagfirst [lindex $tagranges 0]
            set taglast [lindex $tagranges 1]
            set tagranges [lreplace $tagranges 0 1]
            if { [regexp {[0-9]+\.[0-9]+} $tagfirst] && [regexp {[0-9]+\.[0-9]+} $taglast] && ($tagfirst <= $taglast) && ($tagfirst >= 1.0) && ($taglast <= $endidx)} {
               set dotidx [string first "." $tagfirst]
               set tagfirst [expr $offset + [string range $tagfirst 0 [expr $dotidx - 1]]].[string range $tagfirst [expr $dotidx + 1] [expr [string length $tagfirst] - 1]]
               set dotidx [string first "." $taglast]
               set taglast [expr $offset + [string range $taglast 0 [expr $dotidx - 1]]].[string range $taglast [expr $dotidx + 1] [expr [string length $taglast] - 1]]
               if {[lsearch -exact $scriptlist $tagname] >= 0} {
                  $mwin.mainfr.editfr.textarea tag remove suptag $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove supsuptag $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove subsuptag $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove subtag $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove subsubtag $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove supsubtag $tagfirst $taglast
               }
               foreach point {100 120 150 180 210 250 300 360} {
                  $mwin.mainfr.editfr.textarea tag remove bengali${point}o $tagfirst $taglast
                  $mwin.mainfr.editfr.textarea tag remove bengali${point}r $tagfirst $taglast
               }
               $mwin.mainfr.editfr.textarea tag remove english $tagfirst $taglast
               for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
                  $mwin.mainfr.editfr.textarea tag remove customftag$i $tagfirst $taglast
               }
               if {$cfidx == -1} {
                  $mwin.mainfr.editfr.textarea tag add $tagname $tagfirst $taglast
               } else {
                  $mwin.mainfr.editfr.textarea tag add customftag$cfidx $tagfirst $taglast
               }
            }
         }
      }
   }
}

proc saveTags { myid { tfname "" } } {
   global customfontno customfid

   set mwin ".main$myid"
   if {![string compare $tfname ""]} {
      set fn [getFileName "bwedit: Save tags"]
   } else {
      set fn $tfname
   }
   if { [string compare $fn ""] != 0 } {
      set dnm [file dirname $fn]
      if {![file isdirectory $dnm]} {
         errmsg $myid "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
         return
      }
      if {![file writable $dnm]} {
         errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
        return
      }
      if {[file exists $fn] && ![file isfile $fn]} {
         errmsg $myid "ERROR:\nI cannot save the file. \"$fn\" is not a regular file."
         return
      }
      if {[file exists $fn] && ![file writable $fn]} {
         errmsg $myid "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fn\""
         return
      }

      set f [open $fn w]
      foreach tagname { ultag suptag supsuptag subsuptag subtag subsubtag supsubtag english } {
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} { puts $f "$tagname\t: $tagranges" }
      }
      foreach point {100 120 150 180 210 250 300 360} {
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges bengali${point}o ]
         if {[llength $tagranges] > 0} { puts $f "bengali${point}o\t: $tagranges" }
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges bengali${point}r ]
         if {[llength $tagranges] > 0} { puts $f "bengali${point}r\t: $tagranges" }
      }
      for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
         set tagname customftag$i
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} {
            set fid $customfid("$myid:$i")
            puts $f "customfont\t: $fid\t$tagranges"
         }
      }
      close $f
   }
}

set scwinid -1
proc saveConfirm { myid } {
   global scwin dirtybit btnbg btnfg scwinid sccancel

   set mwin ".main$myid"
   if {[winfo exists $scwinid]} {focus $scwinid; tkwait variable dirtybit($myid); return;}
   set sccancel 0
   while {($dirtybit($myid) != 0) && ($sccancel == 0)} {
      set scwin [toplevel .sc]
      set scwinid $scwin
      $scwin config -bg #004466
      label $scwin.l -text "Unsaved changes in main editor window $myid" -fg #ffffff -bg #006688
      frame $scwin.bfr -bg #004466
      button $scwin.bfr.b1 -text "Save" -command "saveThisFile $myid" -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $scwin.bfr.b2 -text "Save as" -command "saveFile $myid" -underline 5 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $scwin.bfr.b3 -text "Do not save" -command "set dirtybit($myid) 0" -underline 3 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $scwin.bfr.b4 -text "Cancel" -command "set dirtybit($myid) $dirtybit($myid); set sccancel 1" -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      pack $scwin.l -expand yes -fill both -padx 0 -pady 0
      pack $scwin.bfr.b1 $scwin.bfr.b2 $scwin.bfr.b3 $scwin.bfr.b4 -side left -padx 10 -pady 0
      pack $scwin.bfr -expand no -padx 0 -pady 10

      bind $scwin <Key-S> "saveThisFile $myid"
      bind $scwin <Key-A> "saveFile $myid"
      bind $scwin <Key-N> "set dirtybit($myid) 0"
      bind $scwin <Key-C> "set dirtybit($myid) $dirtybit($myid); set sccancel 1"
      bind $scwin <Key-s> "saveThisFile $myid"
      bind $scwin <Key-a> "saveFile $myid"
      bind $scwin <Key-n> "set dirtybit($myid) 0"
      bind $scwin <Key-c> "set dirtybit($myid) $dirtybit($myid); set sccancel 1"

      wm transient $scwin $mwin
      wm title $scwin "Options for unsaved changes"
      set posx [winfo x $mwin]
      set posy [winfo y $mwin]
      incr posx [winfo x $mwin.mainfr]
      incr posy [winfo y $mwin.mainfr]
      set twd [winfo width $mwin.mainfr.editfr.textarea]
      set tht [winfo height $mwin.mainfr.editfr.textarea]
      set ewd1 [winfo reqwidth $scwin.l]
      set ewd2 [expr [winfo reqwidth $scwin.bfr.b1] + \
                     [winfo reqwidth $scwin.bfr.b2] + \
                     [winfo reqwidth $scwin.bfr.b3] + \
                     [winfo reqwidth $scwin.bfr.b4] + 100]
      if {$ewd1 > $ewd2} { set ewd $ewd1 } else { set ewd $ewd2 }
      set eht [expr [winfo reqheight $scwin.l] + [winfo reqheight $scwin.bfr.b1] + 40]
      set posx [expr $posx + ($twd - $ewd) / 2]
      set posy [expr $posy + ($tht - $eht) / 2]
      if {$posx <= 0} { set posx 0 }
      if {$posy <= 0} { set posy 0 }
      wm geometry $scwin "${ewd}x${eht}+$posx+$posy"
      focus $scwin

      grab $scwin
      tkwait variable dirtybit($myid)
      grab release $scwin
      destroy $scwin
      set scwinid -1
   }
}

proc errmsg { myid msg } {
   global btnbg btnfg

   set mwin ".main$myid"
   set ewin [toplevel .error]

   message $ewin.msg -text $msg -relief flat -bg #006688 -fg #ffffff -width 250 -justify center
   button $ewin.btn -text "Ok" -relief raised -fg $btnfg -bg $btnbg \
          -activeforeground $btnfg -activebackground $btnbg \
          -command {set edone 1} -height 0

   pack $ewin.msg -padx 0 -pady 0 -expand yes -fill both
   pack $ewin.btn -pady 10

   bind $ewin <Escape> {set edone 1}
   bind $ewin <Return> {set edone 1}

   $ewin config -bg #004466

   wm transient $ewin $mwin
   set posx [winfo x $mwin]
   set posy [winfo y $mwin]
   incr posx [winfo x $mwin.mainfr]
   incr posy [winfo y $mwin.mainfr]
   set twd [winfo width $mwin.mainfr.editfr.textarea]
   set tht [winfo height $mwin.mainfr.editfr.textarea]
   set ewd [winfo reqwidth $ewin.msg]
   set eht [expr [winfo reqheight $ewin.msg] + [winfo reqheight $ewin.btn] + 40]
   set posx [expr $posx + ($twd - $ewd) / 2]
   set posy [expr $posy + ($tht - $eht) / 2]
   if {$posx <= 0} { set posx 0 }
   if {$posy <= 0} { set posy 0 }
   wm geometry $ewin "${ewd}x${eht}+$posx+$posy"
   wm title $ewin "Diagnostic message"

   grab $ewin
   tkwait variable edone
   grab release $ewin
   destroy $ewin
}

proc chooseBaseFont {} {
   global ptsize slant donef off1 off2 off3 appbg appfg btnbg btnfg mavail
  
   set fwin [toplevel .font]

   label $fwin.lbl -text "Choose font size" -relief flat -fg $appfg -bg $appbg

   radiobutton $fwin.rb1 -width 6 -text "10" -variable ptsize -value "100" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb2 -width 6 -text "12" -variable ptsize -value "120" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb3 -width 6 -text "15" -variable ptsize -value "150" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb4 -width 6 -text "18" -variable ptsize -value "180" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb5 -width 6 -text "21" -variable ptsize -value "210" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb6 -width 6 -text "25" -variable ptsize -value "250" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb7 -width 6 -text "30" -variable ptsize -value "300" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb8 -width 6 -text "36" -variable ptsize -value "360" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg

   checkbutton $fwin.cb -width 9 -text " slanted" -variable slant \
      -onvalue "o" -offvalue "r" -relief raised \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg

   button $fwin.done -text "Done" -command {set donef 1} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg
   button $fwin.cancel -text "Cancel" -command {set donef 0} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg

   pack $fwin.lbl -pady 5 -padx 5
   for {set i 1} {$i <= 8} {incr i 1} {
      pack $fwin.rb$i
   }
   pack $fwin.cb -padx 5 -pady 5
   pack $fwin.done $fwin.cancel -pady 5 -padx 5
   $fwin config -bg $appbg
   bind $fwin <Escape> {set donef 0}

   wm title $fwin "bwedit: select font"
   wm resizable $fwin false false

   grab $fwin
   tkwait variable donef
   grab release $fwin
   destroy $fwin

   if {$donef} {
      switch -exact $ptsize {
         100 {set spacing3 4; set off1 5; set off2 8; set off3 3;}
         120 {set spacing3 5; set off1 6; set off2 9; set off3 3;}
         150 {set spacing3 6; set off1 7; set off2 12; set off3 4;}
         180 {set spacing3 7; set off1 9; set off2 14; set off3 5;}
         210 {set spacing3 8; set off1 10; set off2 16; set off3 6;}
         250 {set spacing3 10; set off1 12; set off2 20; set off3 7;}
         300 {set spacing3 12; set off1 15; set off2 24; set off3 9;}
         360 {set spacing3 15; set off1 18; set off2 28; set off3 10;}
         default {set spacing3 5; set off1 6; set off2 9; set off3 3;}
      }
      for {set i 1} {$i < $mavail} {incr i 1} {
         if {[winfo exists .main$i]} {
            .main$i.mainfr.editfr.textarea config -font "-*-bengali-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific"
            .main$i.mainfr.editfr.textarea config -spacing3 $spacing3
            configTags $i
         }
      }
   }
}

proc putChar { i j bch btxt flag } {
   global targetWin dirtybit rdirtybit invencmap

   if {($targetWin > 0)} {
      if [ winfo exists .main$targetWin ] {
         .main$targetWin.mainfr.editfr.textarea insert insert $btxt
         incr dirtybit($targetWin) 1
      }
   } else {
      set twin [expr -$targetWin]
      if [ winfo exists .roman$twin ] {
         if {$flag} {
            switch -exact [string trim $bch] {
               "aA" { .roman$twin.mainfr.editfr.textarea insert insert "A" }
               "o" { .roman$twin.mainfr.editfr.textarea insert insert "ou" }
               "w" { .roman$twin.mainfr.editfr.textarea insert insert "^" }
               "^" { .roman$twin.mainfr.editfr.textarea insert insert "^r" }
               "_" { .roman$twin.mainfr.editfr.textarea insert insert "__" }
               default {
                  scan $bch "%c" asciival
                  if {$asciival == 15} {
                     .roman$twin.mainfr.editfr.textarea insert insert "^r"
                  } elseif {[info exists invencmap($asciival)]} {
                     .roman$twin.mainfr.editfr.textarea insert insert $invencmap($asciival)
                  } else {
                     .roman$twin.mainfr.editfr.textarea insert insert $bch
                  }
               }
            }
         } else {
            switch -exact $bch {
                 1 { .roman$twin.mainfr.editfr.textarea insert insert "i" }
                 2 { .roman$twin.mainfr.editfr.textarea insert insert "I" }
                 3 { .roman$twin.mainfr.editfr.textarea insert insert "u" }
                 4 { .roman$twin.mainfr.editfr.textarea insert insert "U" }
                 5 { .roman$twin.mainfr.editfr.textarea insert insert "R" }
                 6 { .roman$twin.mainfr.editfr.textarea insert insert "e" }
                 7 { .roman$twin.mainfr.editfr.textarea insert insert "oi" }
                 8 { .roman$twin.mainfr.editfr.textarea insert insert "o" }
                14 { .roman$twin.mainfr.editfr.textarea insert insert "^y" }
               105 { .roman$twin.mainfr.editfr.textarea insert insert "i" }
                73 { .roman$twin.mainfr.editfr.textarea insert insert "I" }
               117 { .roman$twin.mainfr.editfr.textarea insert insert "u" }
                85 { .roman$twin.mainfr.editfr.textarea insert insert "U" }
                87 { .roman$twin.mainfr.editfr.textarea insert insert "R" }
               101 { .roman$twin.mainfr.editfr.textarea insert insert "e" }
                69 { .roman$twin.mainfr.editfr.textarea insert insert "oi" }
               111 { .roman$twin.mainfr.editfr.textarea insert insert "o" }
               179 { .roman$twin.mainfr.editfr.textarea insert insert "^^tr" }
               193 { .roman$twin.mainfr.editfr.textarea insert insert "^^nt" }
               227 { .roman$twin.mainfr.editfr.textarea insert insert "^^lg" }
               254 { .roman$twin.mainfr.editfr.textarea insert insert "^^st" }
               default {
                  if {[info exists invencmap($bch)]} {
                     .roman$twin.mainfr.editfr.textarea insert insert $invencmap($bch)
                  } else {
                     .roman$twin.mainfr.editfr.textarea insert insert $bch
                  }
               }
            }
         }
         incr rdirtybit($twin) 1
         setbnstr $twin
      }
   }
}

proc setKbdText { i j bch etxt {flag 0} } {
   global appbg appfg dpyfont btnbg btnfg targetWin dirtybit

   set kwin .kbdmap
   frame $kwin.row$i.$j -relief raised -borderwidth 1 -bg $appbg -cursor hand2
   pack $kwin.row$i.$j -side left -expand no -padx 0 -pady 0 -expand yes -fill x
   if {$flag} {
      set btxt $bch
   } else {
      set btxt [format "%c" $bch]
   }
   label $kwin.row$i.$j.b -text $btxt -bg $appbg -fg #880088 -relief flat \
      -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
   label $kwin.row$i.$j.e -text $etxt -bg $appbg -fg $appfg -relief flat -font $dpyfont
   pack $kwin.row$i.$j.b $kwin.row$i.$j.e -padx 0 -pady 0 -side left -expand yes -fill x

   bind $kwin.row$i.$j <Enter> "
      $kwin.row$i.$j.b config -fg #0000ff
      $kwin.row$i.$j.e config -fg #0000ff
   "
   bind $kwin.row$i.$j <Leave> "
      $kwin.row$i.$j.b config -fg #880088
      $kwin.row$i.$j.e config -fg $appfg
   "
   bind $kwin.row$i.$j <ButtonPress-1> "putChar $i $j $bch $btxt $flag"
   bind $kwin.row$i.$j.b <ButtonPress-1> "putChar $i $j $bch $btxt $flag"
   bind $kwin.row$i.$j.e <ButtonPress-1> "putChar $i $j $bch $btxt $flag"
}

proc setKbdText2 { i j txt1 txt2 } {
   global appbg appfg dpyfont btnbg btnfg targetWin dirtybit

   set kwin .kbdmap
   frame $kwin.row$i.$j -relief raised -borderwidth 1 -bg $appbg -cursor hand2
   pack $kwin.row$i.$j -side left -expand no -padx 0 -pady 0 -expand yes -fill x
   label $kwin.row$i.$j.b -text $txt1 -bg $appbg -fg #880088 -relief flat \
      -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
   label $kwin.row$i.$j.e -text $txt1 -bg $appbg -fg $appfg -relief flat -font $dpyfont
   pack $kwin.row$i.$j.b $kwin.row$i.$j.e -padx 0 -pady 0 -side left -expand yes -fill x

   bind $kwin.row$i.$j <Enter> "
      $kwin.row$i.$j.b config -fg #0000ff
      $kwin.row$i.$j.e config -fg #0000ff
   "
   bind $kwin.row$i.$j <Leave> "
      $kwin.row$i.$j.b config -fg #880088
      $kwin.row$i.$j.e config -fg $appfg
   "
   bind $kwin.row$i.$j <ButtonPress-1> "putChar $i $j $txt2 $txt2 1"
   bind $kwin.row$i.$j.b <ButtonPress-1> "putChar $i $j $txt2 $txt2 1"
   bind $kwin.row$i.$j.e <ButtonPress-1> "putChar $i $j $txt2 $txt2 1"
}

proc setBindText { i j txt1 txt2 } {
   global appbg appfg dpyfont

   set kwin .kbdmap
   frame $kwin.row$i.$j -relief raised -borderwidth 1 -bg $appbg
   pack $kwin.row$i.$j -side left -expand no -padx 0 -pady 0 -expand yes -fill x
   label $kwin.row$i.$j.l1 -text $txt1 -bg $appbg -fg #660000 -relief flat -font $dpyfont
   label $kwin.row$i.$j.l2 -text $txt2 -bg $appbg -fg $appfg -relief flat -font $dpyfont
   pack $kwin.row$i.$j.l1 $kwin.row$i.$j.l2 -padx 0 -pady 0 -side left -expand yes -fill x -expand yes -fill x
}

proc setEnglishText { i j txt } {
   global appbg appfg btnbg dirtybit

   set kwin .kbdmap
   label $kwin.row$i.$j -relief raised -borderwidth 1 -bg $appbg -fg $appfg -text $txt -cursor hand1
   pack $kwin.row$i.$j -side left -expand no -padx 0 -pady 0 -expand yes -fill x
   bind $kwin.row$i.$j <Enter> "$kwin.row$i.$j config -fg #0000ff"
   bind $kwin.row$i.$j <Leave> "$kwin.row$i.$j config -fg $appfg"
   bind $kwin.row$i.$j <ButtonPress-1> "[list eval if \{ (\$targetWin > 0) && \[ winfo exists .main\$targetWin \] \} \{ .main\$targetWin.mainfr.editfr.textarea insert insert $txt english \; incr dirtybit(\$targetWin) 1 \} ]"
}

proc setEnglishText2 { i j txt1 txt2 } {
   global appbg appfg btnbg

   set kwin .kbdmap
   label $kwin.row$i.$j -relief raised -borderwidth 1 -bg $appbg -fg $appfg -text $txt1 -cursor hand1
   pack $kwin.row$i.$j -side left -expand no -padx 0 -pady 0 -expand yes -fill x
   bind $kwin.row$i.$j <Enter> "$kwin.row$i.$j config -fg #0000ff"
   bind $kwin.row$i.$j <Leave> "$kwin.row$i.$j config -fg $appfg"
   bind $kwin.row$i.$j <ButtonPress-1> "[list eval if \{ (\$targetWin > 0) && \[ winfo exists .main\$targetWin \] \} \{ .main\$targetWin.mainfr.editfr.textarea insert insert $txt2 english \; incr dirtybit(\$targetWin) 1 \} ]"
}

proc updateWinMenu { } {
   global targetWin mavail ravail

   .kbdmap.row0.target.m delete 0 last
   for {set i 0} {$i <= $mavail} {incr i 1} {
      if {[winfo exists ".main$i"]} {
         .kbdmap.row0.target.m add command -label "Target: Main window $i" \
            -command "
               set targetWin [list $i]
               .kbdmap.row0.target config -text { [list Target : Main window $i] } -underline 1
            "
      }
   }
   for {set i 0} {$i <= $ravail} {incr i 1} {
      if {[winfo exists ".roman$i"]} {
         .kbdmap.row0.target.m add command -label "Target: Transliterator window $i" \
            -command "
               set targetWin [list -$i]
               .kbdmap.row0.target config -text { [list Target : Transliterator window $i] } -underline 1
            "
      }
   }
   if {($targetWin > 0) && (![winfo exists .main$targetWin])} {
      set targetWin 0
      .kbdmap.row0.target config -text " Target window : (None) "
   }
   if {($targetWin < 0) && (![winfo exists .roman[expr -$targetWin]])} {
      set targetWin 0
      .kbdmap.row0.target config -text " Target window : (None) "
   }
}

proc postTargetList { } {
   set posx [winfo x .kbdmap]
   incr posx [winfo x .kbdmap.row0]
   incr posx [winfo x .kbdmap.row0.target]
   set posy [winfo y .kbdmap]
   incr posy [winfo y .kbdmap.row0]
   incr posy [winfo y .kbdmap.row0.target]
   incr posy [winfo height .kbdmap.row0.target]
   .kbdmap.row0.target.m post $posx $posy
   .kbdmap.row0.target.m activate 0
   grab set -global .kbdmap.row0.target.m
   focus .kbdmap.row0.target.m
}

proc viewKbdMap {} {
   global appbg appfg dpyfont hdrfont targetWin

   if {[winfo exists .kbdmap]} { focus .kbdmap ; return }
   set mapwin [toplevel .kbdmap]

   for {set i 0} {$i <= 23} {incr i 1} {
      frame $mapwin.row$i -bg $appbg
      pack $mapwin.row$i -padx 3 -pady 0 -expand yes -fill x
   }

   label $mapwin.row0.hdr -text "bwedit : Keyboard map" -font $hdrfont \
      -relief flat -bg $appbg -fg #006600
   label $mapwin.row0.spc -text "" -relief flat -bg $appbg -fg #006600
   menubutton $mapwin.row0.target -text " Target window : (None) " -height 1 \
      -relief raised -menu $mapwin.row0.target.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0 -underline 1
   menu $mapwin.row0.target.m -tearoff false -bg $appbg -fg $appfg
   updateWinMenu
   bind $mapwin <Alt-t> "postTargetList"
   bind $mapwin <Alt-T> "postTargetList"
   set targetWin 0
   button $mapwin.row0.done -text "Close window" -command "destroy $mapwin" \
      -bg $appbg -fg $appfg -activebackground $appbg -activeforeground $appfg \
      -underline 0
   bind $mapwin <Alt-c> "$mapwin.row0.done invoke; break"
   bind $mapwin <Alt-C> "$mapwin.row0.done invoke; break"

   pack $mapwin.row0.hdr -expand no -padx 0 -pady 5 -side left
   pack $mapwin.row0.spc -expand yes -fill x -padx 0 -pady 5 -side left
   pack $mapwin.row0.target -expand no -padx 0 -pady 5 -side left
   pack $mapwin.row0.done -expand no -padx 0 -pady 5 -side left

   setKbdText 1 1 "a" "a" 1
   setKbdText 1 2 "aA" "^A" 1
   setKbdText 1 3 1 "^i"
   setKbdText 1 4 2 "^I"
   setKbdText 1 5 3 "^u"
   setKbdText 1 6 4 "^U"
   setKbdText 1 7 5 "^R"
   setKbdText 1 8 6 "^e"
   setKbdText 1 9 7 "^E"
   setKbdText 1 10 8 "^o"
   setKbdText 1 11 "o" "o" 1
   setKbdText 1 12 "A" "A" 1
   setKbdText 1 13 "i " "i" 1
   setKbdText 1 14 " I" "I" 1
   setKbdText 1 15 " u" "u" 1
   setKbdText 1 16 " U" "U" 1
   setKbdText 1 17 " W" "W" 1
   setKbdText 1 18 "e" "e" 1
   setKbdText 1 19 "E" "E" 1
   setKbdText 1 20 " O" "O" 1

   setKbdText 2 1 "k" "k" 1
   setKbdText 2 2 "K" "K" 1
   setKbdText 2 3 "g" "g" 1
   setKbdText 2 4 "G" "G" 1
   setKbdText 2 5 "q" "q" 1
   setKbdText 2 6 "c" "c" 1
   setKbdText 2 7 "C" "C" 1
   setKbdText 2 8 "j" "j" 1
   setKbdText 2 9 "J" "J" 1
   setKbdText 2 10 "Q" "Q" 1
   setKbdText 2 11 "T" "T" 1
   setKbdText 2 12 "Z" "Z" 1
   setKbdText 2 13 "D" "D" 1
   setKbdText 2 14 "X" "X" 1
   setKbdText 2 15 "N" "N" 1
   setKbdText 2 16 "t" "t" 1
   setKbdText 2 17 "z" "z" 1
   setKbdText 2 18 "d" "d" 1
   setKbdText 2 19 "x" "x" 1
   setKbdText 2 20 "n" "n" 1

   setKbdText 3 1 "p" "p" 1
   setKbdText 3 2 "f" "f" 1
   setKbdText 3 3 "b" "b" 1
   setKbdText 3 4 "v" "v" 1
   setKbdText 3 5 "m" "m" 1
   setKbdText 3 6 "Y" "Y" 1
   setKbdText 3 7 "r" "r" 1
   setKbdText 3 8 "l" "l" 1
   setKbdText 3 9 "b" "b" 1
   setKbdText 3 10 "S" "S" 1
   setKbdText 3 11 "F" "F" 1
   setKbdText 3 12 "s" "s" 1
   setKbdText 3 13 "h" "h" 1
   setKbdText 3 14 "R" "R" 1
   setKbdText 3 15 "V" "V" 1
   setKbdText 3 16 "y" "y" 1
   setKbdText 3 17 "B" "B" 1
   setKbdText 3 18 "M" "M" 1
   setKbdText 3 19 "H" "H" 1
   setKbdText 3 20 " w" "w" 1

   setKbdText 4 1 25 "\[25\]"
   setKbdText 4 2 26 "\[26\]"
   setKbdText 4 3 27 "\[27\]"
   setKbdText 4 4 28 "\[28\]"
   setKbdText 4 5 29 "\[29\]"
   setKbdText 4 6 30 "\[30\]"
   for {set i 0} {$i < 10} {incr i 1} {
      setKbdText 4 [expr $i + 7] $i $i 1
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 5 $i [expr $i + 127] "\[[expr $i + 127]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 6 $i [expr $i + 140] "\[[expr $i + 140]\]"
   }

   for {set i 1} {$i <= 6} {incr i 1} {
      setKbdText 7 $i [expr $i + 153] "\[[expr $i + 153]\]"
   }
   setKbdText 7 7 80 "P"
   for {set i 8} {$i <= 13} {incr i 1} {
      setKbdText 7 $i [expr $i + 153] "\[[expr $i + 153]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 8 $i [expr $i + 166] "\[[expr $i + 166]\]"
   }

   setKbdText 9 1 38 "&"
   for {set i 2} {$i <= 13} {incr i 1} {
      setKbdText 9 $i [expr $i + 178] "\[[expr $i + 178]\]"
   }

   for {set i 1} {$i <= 6} {incr i 1} {
      setKbdText 10 $i [expr $i + 191] "\[[expr $i + 191]\]"
   }
   setKbdText 10 7 64 "@"
   for {set i 8} {$i <= 13} {incr i 1} {
      setKbdText 10 $i [expr $i + 190] "\[[expr $i + 190]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 11 $i [expr $i + 203] "\[[expr $i + 203]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 12 $i [expr $i + 216] "\[[expr $i + 216]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 13 $i [expr $i + 229] "\[[expr $i + 229]\]"
   }

   for {set i 1} {$i <= 13} {incr i 1} {
      setKbdText 14 $i [expr $i + 242] "\[[expr $i + 242]\]"
   }

   for {set i 1} {$i <= 9} {incr i 1} {
      setKbdText 15 $i [expr $i + 15] "\[[expr $i + 15]\]"
   }
   setKbdText 15 10 31 "\[31\]"
   setKbdText 15 11 62 ">"
   setKbdText 15 12 76 "L"
   setKbdText 15 13 125 "\}"
   setKbdText 15 14 14 "^y"
   set btxt " [format "%c" 15]"
   setKbdText 15 15 $btxt "^r" 1
   setKbdText 15 16 "^ " "^" 1
   setKbdText 15 17 "_ " "_" 1

   setKbdText2 16 1 "." "."
   setKbdText2 16 2 "<" "<"
   setKbdText2 16 3 "," ","
   setKbdText2 16 4 ";" "\\;"
   setKbdText2 16 5 ":" ":"
   setKbdText2 16 6 "?" "?"
   setKbdText2 16 7 "!" "!"
   setKbdText2 16 8 "/" "/"
   setKbdText2 16 9 "%" "%%"
   setKbdText2 16 10 "~" "~"
   setKbdText2 16 11 "`" "`"
   setKbdText2 16 12 "'" "'"
   setKbdText2 16 13 "\\" "\\\\"
   setKbdText2 16 14 "\"" "\\\""
   setKbdText2 16 15 "#" "#"
   setKbdText2 16 16 "$" "$"
   setKbdText2 16 17 "+" "+"
   setKbdText2 16 18 "-" "-"
   setKbdText2 16 19 "*" "*"
   setKbdText2 16 20 "=" "="
   setKbdText2 16 21 "\{" "\\\{"
   setKbdText2 16 22 "|" "|"
   setKbdText2 16 23 "(" "("
   setKbdText2 16 24 ")" ")"
   setKbdText2 16 25 "\[" "\\\["
   setKbdText2 16 26 "\]" "\\\]"

   for {set i 1} {$i <= 26} {incr i 1} {
      setEnglishText 17 $i [format "%c" [expr $i + 64]]
      setEnglishText 18 $i [format "%c" [expr $i + 96]]
   }

   setEnglishText 19 1 "."
   setEnglishText 19 2 "$"
   setEnglishText2 19 3 "\{" "\\\{"
   setEnglishText2 19 4 "\}" "\\\}"
   setEnglishText 19 5 "<"
   setEnglishText 19 6 ">"
   setEnglishText2 19 7 "\\" "\\\\"
   setEnglishText 19 8 "@"
   setEnglishText 19 9 "&"
   setEnglishText 19 10 "^"
   setEnglishText 19 11 "_"
   setEnglishText 19 12 "0"
   setEnglishText 19 13 "1"
   setEnglishText 19 14 "2"
   setEnglishText 19 15 "3"
   setEnglishText 19 16 "4"
   setEnglishText 19 17 "5"
   setEnglishText 19 18 "6"
   setEnglishText 19 19 "7"
   setEnglishText 19 20 "8"
   setEnglishText 19 21 "9"

   setBindText 20 1 "^DEL" "Delete from cursor to end of word"
   setBindText 20 2 "^BS" "Delete from start of word to cursor"
   setBindText 20 3 "^w" "Delete word"
   setBindText 20 4 "^j" "Join two words"

   setBindText 21 1 "^(DEL)" "Delete from cursor to end of line"
   setBindText 21 2 "^(BS)" "Delete from start of line to cursor"
   setBindText 21 3 "^L" "Delete line"
   setBindText 21 4 "^J" "Join two lines"

   setBindText 22 1 "F1" "Help"
   setBindText 22 2 "F2" "Load"
   setBindText 22 3 "F3" "Save"
   setBindText 22 4 "F4" "Cut"
   setBindText 22 5 "F5" "Copy"
   setBindText 22 6 "F6" "Paste"
   setBindText 22 7 "F7" "Start marking"
   setBindText 22 8 "F8" "End marking"
   setBindText 22 9 "F9" "Send mail"
   setBindText 22 10 "F10" "Menu"

   label $mapwin.row23.legend -relief flat -bg $appbg -fg #000088 \
      -text "Notations : ^ = CONTROL, \[<num>\] = ESCAPE<num>ESCAPE, DEL = DELETE, BS = BACKSPACE, (<key>) = SHIFT<key>"
   pack $mapwin.row23.legend -padx 0 -pady 5

   $mapwin config -bg $appbg
   bind $mapwin <Escape> "destroy $mapwin"

   wm title $mapwin "bwedit: character map"
   wm resizable $mapwin false false
}

proc readEnc { { flag 0 } { fnm "" } } {
   global encmap invencmap installdir

   if {$flag == 0} {
      set encfname "$installdir/lib/bn.enc"
   } elseif {$flag == 1} {
      set encfname [getFileName "bwedit: Encoding file"]
   } else {
      set encfname $fnm
   }
   if {[string length $encfname] == 0} { return }
   if {![file readable "$encfname"]} {
      puts "ERROR: I cannot read the encoding file."
      puts "The file $encfname"
      puts "does not exist or does not have read permission."
      puts "This means that you cannot use the Roman-to-Bengali transliterator."
      return
   }

   if [info exists encmap] { unset encmap }
   if [info exists invencmap] { unset invencmap }
   set encf [open "$encfname" r]
   while {[gets $encf line] >= 0} {
      set idx [ string first "#" $line ]
      if {$idx >= 0} { set line [string range $line 0 [expr $idx - 1]] }
      set idx [ string first ":" $line ]
      if {$idx >= 0} {
         set code [string range $line 0 [expr $idx - 1]]
         set char [string range $line [expr $idx + 1] [expr [string length $line] - 1]]
         set code [string trim $code]
         set char [string trim $char]
         if {([string length $code] >= 0) && ([string length $char] >= 0)} {
            if {![string compare "\\" [string index $char 0]]} {
               set ascval [string range $char 1 [expr [string length $char] - 1]]
            } else {
               scan $char "%c" ascval
            }
            set encmap($code) $ascval
            set invencmap($ascval) $code
         }
      }
   }
}

proc vowel { c } {
   if {![string compare $c "-"]} { return 0 }
   switch -exact $c {
      a { return 1 }
      e { return 1 }
      i { return 1 }
      o { return 1 }
      u { return 1 }
      A { return 1 }
      E { return 1 }
      I { return 1 }
      O { return 1 }
      U { return 1 }
      R { return 1 }
      L { return 1 }
      default { return 0 }
   }
}

proc consonant { c } {
   if {[vowel $c]} { return 0 }
   scan $c "%c" asciival
   if {($asciival == 94)} { return 1 }
   if {($asciival > 65) && ($asciival <= 90)} { return 1 }
   if {($asciival > 97) && ($asciival <= 122)} { return 1 }
   return 0
}

proc romanToBeng { txt tarea {cursor "insert"} } {
   global encmap

   set bngmode 1
   set idx 0
   set iplen [string length $txt]
   if {$iplen > 0} { set nextchar [string index $txt 0] }
   while {$idx < $iplen} {
      if {($bngmode == 0)} {
         if {![string compare $nextchar "#"]} {
            if {($idx <= $iplen - 2) && (![string compare "#" [string index $txt [expr $idx + 1]]])} {
               incr idx
               $tarea insert $cursor "#" english
            } else {
               set bngmode 1
            }
         } elseif {![string compare $nextchar "\n"]} {
            set bngmode 1
            $tarea insert $cursor "\n"
         } else {
            $tarea insert $cursor $nextchar english
         }
         incr idx 1
         if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
      } else {
         set bntxt ""
         if {[vowel $nextchar]} {
            set swar ""
            while {[vowel $nextchar] && ($idx < $iplen)} {
               set swar $swar$nextchar
               incr idx 1
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            }
            if [info exists encmap($swar)] {
               switch -exact $encmap($swar) {
                  97 { set bntxt "a" }
                  65 { set bntxt "aA" }
                   1 { set bntxt [format "%c" 1] }
                 105 { set bntxt [format "%c" 1] }
                   2 { set bntxt [format "%c" 2] }
                  73 { set bntxt [format "%c" 2] }
                   3 { set bntxt [format "%c" 3] }
                 117 { set bntxt [format "%c" 3] }
                   4 { set bntxt [format "%c" 4] }
                  85 { set bntxt [format "%c" 4] }
                   5 { set bntxt [format "%c" 5] }
                  87 { set bntxt [format "%c" 5] }
                   6 { set bntxt [format "%c" 6] }
                 101 { set bntxt [format "%c" 6] }
                   7 { set bntxt [format "%c" 7] }
                  69 { set bntxt [format "%c" 7] }
                   8 { set bntxt [format "%c" 8] }
                  79 { set bntxt "o" }
                 111 { set bntxt "o" }
                  14 { set bntxt a[format "%c" 14]A }
               }
            }
         } elseif {[consonant $nextchar]} {
            set swar ""
            set banjon ""
            while {[consonant $nextchar] && ($idx < $iplen)} {
               set banjon $banjon$nextchar
               incr idx 1
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            }
            while {[vowel $nextchar] && ($idx < $iplen)} {
               set swar $swar$nextchar
               incr idx 1
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            }
            if {[string compare "^" $banjon]} {
               set notdone 1
               set chandra ""
               set ref ""
               set jafala ""
               set rafala ""
               while {$notdone} {
                  set notdone 0
                  set len [string length $banjon]
                  if {![string compare [string index $banjon [expr $len - 1]] "^"]} {
                     set chandra "w"
                     set banjon [string range $banjon 0 [expr $len - 2]]
                     incr len -1
                     set notdone 1
                  }
                  if {![string compare [string index $banjon [expr $len - 2]] "^"]} {
                     if {![string compare [string index $banjon [expr $len - 1]] "r"]} {
                        set rafala [format "%c" 15]
                        set banjon [string range $banjon 0 [expr $len - 3]]
                        incr len -2
                        set notdone 1
                     }
                     if {![string compare [string index $banjon [expr $len - 1]] "y"]} {
                        set jafala [format "%c" 14]
                        set banjon [string range $banjon 0 [expr $len - 3]]
                        incr len -2
                        set notdone 1
                     }
                     if {![string compare [string index $banjon [expr $len - 1]] "Y"]} {
                        set jafala [format "%c" 14]
                        set banjon [string range $banjon 0 [expr $len - 3]]
                        incr len -2
                        set notdone 1
                     }
                  }
                  if {![string compare [string range $banjon 0 1] "^r"]} {
                     set ref "^"
                     set banjon [string range $banjon 2 [expr $len - 1]]
                     incr len -2
                     set notdone 1
                  }
               }
               if {[info exists encmap($banjon)]} {
                  set ban [format "%c" $encmap($banjon)]
               } else {
                  set notdone 1
                  while {$notdone} {
                     set notdone 0
                     if {![string compare $ref ""] && ![string compare [string index $banjon 0] "r"] } {
                        set ref "^"
                        set banjon [string range $banjon 1 [expr $len - 1]]
                        incr len -1
                        set notdone 1
                     }
                     if {($len > 1) && ![string compare $rafala ""]} {
                        set lastchar [string index $banjon [expr $len - 1]]
                        if {![string compare $lastchar "r"]} {
                           set rafala [format "%c" 15]
                           set banjon [string range $banjon 0 [expr $len - 2]]
                           incr len -1
                           set notdone 1
                        }
                     }
                     if {($len > 1) && ![string compare $jafala ""]} {
                        set lastchar [string index $banjon [expr $len - 1]]
                        if {![string compare $lastchar "y"] || ![string compare $lastchar "Y"]} {
                           set jafala [format "%c" 14]
                           set banjon [string range $banjon 0 [expr $len - 2]]
                           incr len -1
                           set notdone 1
                        }
                     }
                     if {($len > 1) && ![string compare $chandra ""]} {
                        set lastchar [string index $banjon [expr $len - 1]]
                        if {![string compare $lastchar "^"]} {
                           set chandra "w"
                           set banjon [string range $banjon 0 [expr $len - 2]]
                           incr len -1
                           set notdone 1
                        }
                     }
                  }
                  if {[info exists encmap($banjon)]} {
                     set ban [format "%c" $encmap($banjon)]
                  } else {
                     set ban " "
                  }
               }
               if {[info exists encmap($swar)]} { set swar $encmap($swar) } else { set swar 97 }
               if {(![string compare $ban "r"]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 25]
                  set swar 97
               }
               if {(![string compare $ban "r"]) && (($swar == 4) || ($swar == 85))} {
                  set ban [format "%c" 26]
                  set swar 97
               }
               if {(![string compare $ban "h"]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 27]
                  set swar 97
               }
               if {(![string compare $ban "h"]) && (($swar == 5) || ($swar == 87))} {
                  set ban [format "%c" 28]
                  set swar 97
               }
               if {(![string compare $ban "g"]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 29]
                  set swar 97
               }
               if {(![string compare $ban "S"]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 30]
                  set swar 97
               }
               if {(![string compare $ban [format "%c" 178]]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 179]
                  set swar 97
               }
               if {(![string compare $ban [format "%c" 192]]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 193]
                  set swar 97
               }
               if {(![string compare $ban [format "%c" 226]]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 227]
                  set swar 97
               }
               if {(![string compare $ban [format "%c" 253]]) && (($swar == 3) || ($swar == 117))} {
                  set ban [format "%c" 254]
                  set swar 97
               }
               set ban "$ban$ref$chandra$rafala$jafala"
            } else {
               set ban "w"
               set swar 97
            }
            switch -exact $swar {
               97 { set bntxt "$ban" }
               65 { set bntxt "${ban}A" }
                1 { set bntxt "i$ban" }
              105 { set bntxt "i$ban" }
                2 { set bntxt "${ban}I" }
               73 { set bntxt "${ban}I" }
                3 { set bntxt "${ban}u" }
              117 { set bntxt "${ban}u" }
                4 { set bntxt "${ban}U" }
               85 { set bntxt "${ban}U" }
                5 { set bntxt "${ban}W" }
               87 { set bntxt "${ban}W" }
                6 { set bntxt "e$ban" }
              101 { set bntxt "e$ban" }
                7 { set bntxt "E$ban" }
               69 { set bntxt "E$ban" }
                8 { set bntxt "e${ban}A" }
               79 { set bntxt "e${ban}O" }
              111 { set bntxt "e${ban}O" }
               14 { set bntxt "$ban[format "%c" 14]A" }
            }
         } else {
            if {![string compare $nextchar "#"]} {
               incr idx 1
               if {$idx < $iplen} { set nextnextchar [string index $txt $idx] } else { set nextnextchar "" }
               if {![string compare $nextnextchar "#"]} {
                  incr idx 1
                  set bntxt "#"
                  if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
               } else {
                  set nextchar $nextnextchar
                  set bngmode 0
               }
            } elseif {![string compare $nextchar "_"]} {
               incr idx 1
               if {$idx < $iplen} { set nextnextchar [string index $txt $idx] } else { set nextnextchar "" }
               if {![string compare $nextnextchar "_"]} {
                  incr idx 1
                  set bntxt "_"
                  if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
               } else { set nextchar $nextnextchar }
            } else {
               if {![string compare $nextchar "."]} {
                  incr idx 1
                  if {$idx < $iplen} { set nextnextchar [string index $txt $idx] } else { set nextnextchar "" }
                  if {![string compare $nextnextchar "."]} {
                     incr idx 1
                     set bntxt "<"
                     if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
                  } else {
                     set bntxt "."
                     set nextchar $nextnextchar
                  }
               } else {
                  set bntxt "$nextchar"
                  incr idx 1
                  if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
               }
            }
         }
         $tarea insert $cursor $bntxt
      }
   }
   return $bntxt
}

proc importRoman { myid flag } {
   global dirtybit

   set mwin ".main$myid"

   set fn [getFileName "bwedit: Import Roman file"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      if {$flag == 0} { $mwin.mainfr.editfr.textarea delete 1.0 end }
      set f [open $fn r]
      set txt [read $f]
      close $f
      if {$flag == 2} {
         romanToBeng $txt $mwin.mainfr.editfr.textarea end
      } else {
         romanToBeng $txt $mwin.mainfr.editfr.textarea
      }
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($myid) 1
   }
}

proc getExportFileName {} {
   global efname verbatim omithdr xfnok appbg appfg btnbg btnfg

   set dbox [toplevel .export]
   frame $dbox.fr1
   frame $dbox.fr2
   frame $dbox.fr3
   frame $dbox.fr4
   label $dbox.fr1.lbl -text "Export to file:" -relief flat -anchor e -bg $appbg -fg $appfg
   entry $dbox.fr1.ent -textvariable efname -bg #ddaaaa -fg #000000
   label $dbox.fr2.lbl -text "Document title:" -relief flat -anchor e -bg $appbg -fg $appfg
   entry $dbox.fr2.ent -textvariable doctitle -bg #ddaaaa -fg #000000
   checkbutton $dbox.fr3.cb -text "  Verbatim copy " -variable verbatim -onvalue 1 -offvalue 0 -relief raised -selectcolor #bbff00 -bg $appbg -fg $appfg -activebackground $appbg -activeforeground $appfg
   checkbutton $dbox.fr3.oh -text "  Omit headers " -variable omithdr -onvalue 1 -offvalue 0 -relief raised -selectcolor #bbff00 -bg $appbg -fg $appfg -activebackground $appbg -activeforeground $appfg
   button $dbox.fr4.obtn -text "OK" -command {set xfnok 1} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   button $dbox.fr4.cbtn -text "Cancel" -command {set xfnok 0} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   label $dbox.fr4.space -text "" -relief flat -bg $appbg -fg $appfg
   bind $dbox.fr1.ent <Return> "focus $dbox.fr2.ent"
   bind $dbox.fr2.ent <Return> {set xfnok 1}
   bind $dbox <Escape> {set xfnok 0}

   pack $dbox.fr1 $dbox.fr2 $dbox.fr3 -expand yes -fill x
   pack $dbox.fr4 -expand yes -fill both
   pack $dbox.fr1.lbl -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr1.ent -padx 5 -pady 5
   pack $dbox.fr2.lbl -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr2.ent -padx 5 -pady 5
   pack $dbox.fr3.cb  -padx 5 -pady 5
   pack $dbox.fr3.oh  -padx 5 -pady 5
   pack $dbox.fr4.obtn -padx 5 -pady 5 -fill y -side left
   pack $dbox.fr4.space -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr4.cbtn -padx 5 -pady 5 -fill y
   $dbox config -bg $appbg
   $dbox.fr1 config -bg $appbg
   $dbox.fr2 config -bg $appbg
   $dbox.fr3 config -bg $appbg
   $dbox.fr4 config -bg $appbg

   wm title $dbox "bwedit: export"
   wm resizable $dbox false false

   focus $dbox.fr1.ent
   grab $dbox
   tkwait variable xfnok
   grab release $dbox
   destroy $dbox

   if {$xfnok} { return [string trim $efname] } else { return "" }
}

proc exportLaTeX { myid } {
   global fname efname verbatim omithdr doctitle customfontno ptsize slant

   set mwin ".main$myid"

   if { [string compare $fname($myid) ""] != 0 } {
      set dotindex [string last "." $fname($myid)]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname($myid) 0 $dotindex]
      set efname "$efname.tex"
   } else {
      set efname "$fname($myid).tex"
   }
   set verbatim 0
   set omithdr 0
   set doctitle ""
   set efn [getExportFileName]
   if { [string compare $efn ""] != 0 } {
      switch -exact $ptsize {
         100 { set bndft "\\bn\\small" ; set ss "\\bn\\tiny" ; set sss "\\bn\\tiny" }
         150 { set bndft "\\bn\\large" ; set ss "\\bn" ; set sss "\\bn\\small" }
         180 { set bndft "\\bn\\Large" ; set ss "\\bn\\large" ; set sss "\\bn" }
         210 { set bndft "\\bn\\LARGE" ; set ss "\\bn\\Large" ; set sss "\\bn\\large" }
         250 { set bndft "\\bn\\huge" ; set ss "\\bn\\LARGE" ; set sss "\\bn\\Large" }
         300 { set bndft "\\bn\\Huge" ; set ss "\\bn\\huge" ; set sss "\\bn\\LARGE" }
         360 { set bndft "\\bn\\Huge" ; set ss "\\bn\\huge" ; set sss "\\bn\\LARGE" }
         default {set bndft "\\bn" ; set ss "\\bn\\small" ; set sss "\\bn\\tiny" }
      }
      if {![string compare "o" $slant]} { set bndft "$bndft\\sl" }
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [$mwin.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
         set englishrng [concat $englishrng [$mwin.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set smallrng [$mwin.mainfr.editfr.textarea tag ranges bengali100r]
      set normalsizerng [$mwin.mainfr.editfr.textarea tag ranges bengali120r]
      set largerng [$mwin.mainfr.editfr.textarea tag ranges bengali150r]
      set Largerng [$mwin.mainfr.editfr.textarea tag ranges bengali180r]
      set LARGErng [$mwin.mainfr.editfr.textarea tag ranges bengali210r]
      set hugerng [$mwin.mainfr.editfr.textarea tag ranges bengali250r]
      set Hugerng [lsort -real -increasing [concat \
         [$mwin.mainfr.editfr.textarea tag ranges bengali300r] \
         [$mwin.mainfr.editfr.textarea tag ranges bengali360r]]]
      set smallslrng [$mwin.mainfr.editfr.textarea tag ranges bengali100o]
      set normalsizeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali120o]
      set largeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali150o]
      set Largeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali180o]
      set LARGEslrng [$mwin.mainfr.editfr.textarea tag ranges bengali210o]
      set hugeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali250o]
      set Hugeslrng [lsort -real -increasing [concat \
         [$mwin.mainfr.editfr.textarea tag ranges bengali300o] \
         [$mwin.mainfr.editfr.textarea tag ranges bengali360o]]]

      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$normalsizerng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$englishrng \$normalsizeslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }

      set f [open $efn w]
      puts $f "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
      puts $f "%% Filename: $efname"
      puts $f "%% Original file: $fname($myid)"
      puts $f "%% Exported by: bwedit version 2.2"
      puts $f "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
      if {$omithdr == 0} {
         puts $f "\\documentstyle\[11pt,bengali\]\{article\}"
         puts $f "\\parindent 0pt"
         puts $f "\\parskip 10pt"
         puts $f "\\hbadness 10000"
         if { [string compare $doctitle ""] != 0 } {
            puts $f "\\pagestyle\{myheadings\}"
            puts $f "\\markboth\{$doctitle\}\{$doctitle\}"
         }
         puts $f "\\begin\{document\}"
      }
      puts $f "\\begingroup$bndft\\leavevmode"
      set ins [$mwin.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set englishmode 0
      set tagshere {}
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            foreach tagname { \$normalsizerng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$normalsizeslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f "\}" }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } {
            puts -nonewline $f "\}"
            incr englishmode -1
         }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } {
               if {[string length $tagname] == 6} {
                  puts -nonewline $f "\}\}\$"
               } else {
                  puts -nonewline $f "\}\}\}\$"
               }
            }
         }
         set tagshere [$mwin.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            switch -exact $tagname {
               suptag {
                  set ridx [lsearch -exact $suptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{\\hbox\{$ss " }
               }
               subtag {
                  set ridx [lsearch -exact $subtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{\\hbox\{$ss " }
               }
               supsuptag {
                  set ridx [lsearch -exact $supsuptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{^\{\\hbox\{$sss " }
               }
               subsuptag {
                  set ridx [lsearch -exact $subsuptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{_\{\\hbox\{$sss " }
               }
               subsubtag {
                  set ridx [lsearch -exact $subsubtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{_\{\\hbox\{$sss " }
               }
               subsubtag {
                  set ridx [lsearch -exact $supsubtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{^\{\\hbox\{$sss " }
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) } {
            if { !($ridx & 1) } {
               incr englishmode 1 ; puts -nonewline $f "\{\\rm "
            } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                  incr englishmode 1 ; puts -nonewline $f "\{\\rm "
               }
            }
         }
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            foreach tagname { normalsize small large Large LARGE huge Huge } {
               set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
               if { ($ridx >= 0) } {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "\{\\$tagname\\nsl "
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength  \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}rng $ridx]) } {
                        puts -nonewline $f "\{\\$tagname\\nsl "
                     }
                  }
               }
               set ridx [eval lsearch -exact \$${tagname}slrng $lineno.$charno]
               if { ($ridx >= 0) } {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "\{\\$tagname\\sl "
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength  \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}slrng $ridx]) } {
                        puts -nonewline $f "\{\\$tagname\\sl "
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         if {($englishmode & 1)} {
            switch -exact $asciival {
               10 { if {$verbatim} {
                       puts $f "\\null\\\\\\null"
                    } else {
                       puts $f ""
                    }
               }
               32 { if {$verbatim} {
                       puts -nonewline $f "\\ "
                    } else {
                       puts -nonewline $f " "
                    }
               }
               35 { puts -nonewline $f "\\#" }
               36 { puts -nonewline $f "\\\$" }
               37 { puts -nonewline $f "\\%" }
               38 { puts -nonewline $f "\\&" }
               60 { puts -nonewline $f "\$<\$" }
               62 { puts -nonewline $f "\$>\$" }
               91 { puts -nonewline $f "\$\[\$" }
               92 { puts -nonewline $f "\$\\backslash\$" }
               93 { puts -nonewline $f "\$\]\$" }
               94 { puts -nonewline $f "\{\\char94\}" }
               95 { puts -nonewline $f "\\_" }
               123 { puts -nonewline $f "\\\{" }
               124 { puts -nonewline $f "\$|\$" }
               125 { puts -nonewline $f "\\\}" }
               126 { puts -nonewline $f "\$\\tilde\{\\phantom\{1\}\}\$" }
               169 { puts -nonewline $f "\\copyright\{\}" }
               215 { puts -nonewline $f "\$\\times\$" }
               247 { puts -nonewline $f "\$\\div\$" }
               default { puts -nonewline $f $nextchar }
            }
         } else {
            switch -exact $asciival {
                9 { puts -nonewline $f "\t" }
               10 { if {$verbatim} {
                       puts $f "\\null\\\\\\null"
                    } else {
                       puts $f ""
                    }
                  }
               32 { if {$verbatim} {
                       puts -nonewline $f "\\ "
                    } else {
                       puts -nonewline $f " "
                    }
                  }
               35 { puts -nonewline $f "\\#" }
               36 { puts -nonewline $f "\{\\bucks\}" }
               37 { puts -nonewline $f "\\%" }
               38 { puts -nonewline $f "\{\\char38\}" }
               60 { puts -nonewline $f ".." }
               62 { puts -nonewline $f "\{\\char62\}" }
               64 { puts -nonewline $f "\{\\char64\}" }
               91 { puts -nonewline $f "\{\\char91\}" }
               92 { puts -nonewline $f "\{\\char92\}" }
               93 { puts -nonewline $f "\{\\char93\}" }
               94 { puts -nonewline $f "\{\\char94\}" }
               95 { puts -nonewline $f "\{\\char95\}" }
               default {
                  if { $asciival < 32 } {
                     puts -nonewline $f "\{\\char$asciival\}"
                  } elseif { $asciival >= 123 } {
                     puts -nonewline $f "\{\\char$asciival\}"
                  } else {
                     puts -nonewline $f $nextchar
                  }
               }
            }
         }
      }
      puts $f "\\endgroup"
      if {$omithdr == 0} { puts $f "\\end\{document\}" }
      puts $f "%% End of file"
      close $f
   }
}


proc exportHTML { myid } {
   global fname efname verbatim omithdr doctitle ptsize slant customfontno

   set mwin ".main$myid"
   if { [string compare $fname($myid) ""] != 0 } {
      set dotindex [string last "." $fname($myid)]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname($myid) 0 $dotindex]
      set efname "$efname.html"
   } else {
      set efname "$fname($myid).html"
   }
   set verbatim 0
   set omithdr 0
   set doctitle "untitled"
   set efn [getExportFileName]
   if { [string compare $efn ""] != 0 } {
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [$mwin.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
         set englishrng [concat $englishrng [$mwin.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set englishrng [lsort -real -increasing $englishrng]
      set size1rng [$mwin.mainfr.editfr.textarea tag ranges bengali100r]
      set size2rng [$mwin.mainfr.editfr.textarea tag ranges bengali120r]
      set size3rng [$mwin.mainfr.editfr.textarea tag ranges bengali150r]
      set size4rng [$mwin.mainfr.editfr.textarea tag ranges bengali180r]
      set size5rng [$mwin.mainfr.editfr.textarea tag ranges bengali210r]
      set size6rng [$mwin.mainfr.editfr.textarea tag ranges bengali250r]
      set size7rng [lsort -real -increasing [concat \
         [$mwin.mainfr.editfr.textarea tag ranges bengali300r] \
         [$mwin.mainfr.editfr.textarea tag ranges bengali360r]]]
      set size1slrng [$mwin.mainfr.editfr.textarea tag ranges bengali100o]
      set size2slrng [$mwin.mainfr.editfr.textarea tag ranges bengali120o]
      set size3slrng [$mwin.mainfr.editfr.textarea tag ranges bengali150o]
      set size4slrng [$mwin.mainfr.editfr.textarea tag ranges bengali180o]
      set size5slrng [$mwin.mainfr.editfr.textarea tag ranges bengali210o]
      set size6slrng [$mwin.mainfr.editfr.textarea tag ranges bengali250o]
      set size7slrng [lsort -real -increasing [concat \
         [$mwin.mainfr.editfr.textarea tag ranges bengali300o] \
         [$mwin.mainfr.editfr.textarea tag ranges bengali360o]]]
      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$englishrng \$size1rng \$size2rng \$size3rng \$size4rng \$size5rng \$size6rng \$size7rng \$size1slrng \$size2slrng \$size3slrng \$size4slrng \$size5slrng \$size6slrng \$size7slrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }

      set f [open $efn w]
      puts $f "<!--------------------------------------------------------->"
      puts $f "<!-- Filename: $efname -->"
      puts $f "<!-- Original file: $fname($myid) -->"
      puts $f "<!-- Exported by: bwedit version 2.2 -->"
      puts $f "<!--------------------------------------------------------->"
      if {$omithdr == 0} {
         puts $f "<HTML>"
         puts $f "<HEAD><TITLE>$doctitle</TITLE></HEAD>"
      }
      switch -exact $ptsize {
         100 { puts $f "<BASEFONT SIZE=2>" }
         150 { puts $f "<BASEFONT SIZE=4>" }
         180 { puts $f "<BASEFONT SIZE=5>" }
         210 { puts $f "<BASEFONT SIZE=6>" }
         250 { puts $f "<BASEFONT SIZE=7>" }
         300 { puts $f "<BASEFONT SIZE=7>" }
         360 { puts $f "<BASEFONT SIZE=7>" }
      }
      if {$omithdr == 0} { puts $f "<BODY>" }
      set ins [$mwin.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set tagshere {}
      set opsctg(sup) "<SUP>"
      set opsctg(sub) "<SUB>"
      set opsctg(supsup) "<SUP><SUP>"
      set opsctg(subsup) "<SUP><SUB>"
      set opsctg(subsub) "<SUB><SUB>"
      set opsctg(supsub) "<SUB><SUP>"
      set clsctg(sup) "</SUP>"
      set clsctg(sub) "</SUB>"
      set clsctg(supsup) "</SUP></SUP>"
      set clsctg(subsup) "</SUB></SUP>"
      set clsctg(subsub) "</SUB></SUB>"
      set clsctg(supsub) "</SUP></SUB>"
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            foreach tagname { \$size1rng \$size2rng \$size3rng \$size4rng \$size5rng \$size6rng \$size7rng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  puts -nonewline $f "</FONT>"
               }
            }
            foreach tagname { \$size1slrng \$size2slrng \$size3slrng \$size4slrng \$size5slrng \$size6slrng \$size7slrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  puts -nonewline $f "</I></FONT>"
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f "</TT>" }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f $clsctg($tagname) }
         }
         set tagshere [$mwin.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f $opsctg($tagname) }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if {($ridx >= 0)} {
            if { !($ridx & 1) } { puts -nonewline $f "<TT>" } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                   puts -nonewline $f "<TT>"
               }
            }
         }
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            for {set ftsz 1} {$ftsz <= 7} {incr ftsz 1} {
               set ridx [eval lsearch -exact \$size${ftsz}rng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "<FONT SIZE=$ftsz>"
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$size${ftsz}rng]) && ("$lineno.$charno" == [eval lindex \$size${ftsz}rng $ridx]) } {
                        puts -nonewline $f "<FONT SIZE=$ftsz>"
                     }
                  }
               }
               set ridx [eval lsearch -exact \$size${ftsz}slrng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "<FONT SIZE=$ftsz><I>"
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$size${ftsz}slrng]) && ("$lineno.$charno" == [eval lindex \$size${ftsz}slrng $ridx]) } {
                        puts -nonewline $f "<FONT SIZE=$ftsz><I>"
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         switch -exact $asciival {
            34 { puts -nonewline $f "&quot;" }
            38 { puts -nonewline $f "&amp;" }
            60 { puts -nonewline $f "&lt;" }
            62 { puts -nonewline $f "&gt;" }
             9 { if {$verbatim} {
                    puts -nonewline $f "&nbsp;"
                 } else {
                    puts  -nonewline $f "\t"
                 }
               }
            10 { if {$verbatim} {
                    puts $f "<BR>"
                 } else {
                    incr i 1
                    set nextnextchar [string range $ins $i $i]
                    if { [string compare $nextnextchar "\n"] == 0 } {
                       puts $f "\n<P>"
                    } else {
                       incr i -1
                       puts $f ""
                    }
                 }
               }
            32 { if {$verbatim} {
                    puts -nonewline $f "&nbsp;"
                 } else {
                    puts -nonewline $f " "
                 }
               }
            default {
               if { $asciival < 32 } {
                  puts -nonewline $f "&#$asciival;"
               } elseif { $asciival >= 128 } {
                  puts -nonewline $f "&#$asciival;"
               } else {
                  puts -nonewline $f $nextchar
               }
            }
         }
      }
      if {$omithdr == 0} {
         puts $f "</BODY>"
         puts $f "</HTML>"
      }
      puts $f "<!-- End of file -->"
      close $f
   }
}

proc getPSFileName {} {
   global efname pt pageheight textheight xoffset yoffset psfnok
   global btnbg btnfg appbg appfg

   set dbox [toplevel .export]
   frame $dbox.fr1
   frame $dbox.fr2
   frame $dbox.fr3
   frame $dbox.fr4
   frame $dbox.fr5
   frame $dbox.fr6
   frame $dbox.fr6a
   frame $dbox.fr7
   label $dbox.fr1.lbl -text "Export to file:" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr1.ent -textvariable efname -bg #ddaaaa -fg #000000
   label $dbox.fr2.lbl -text "Point size:" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr2.ent -textvariable pt -bg #ddaaaa -fg #000000
   label $dbox.fr3.lbl -text "Text height (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr3.ent -textvariable textheight -bg #ddaaaa -fg #000000
   label $dbox.fr4.lbl -text "X offset (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr4.ent -textvariable xoffset -bg #ddaaaa -fg #000000
   label $dbox.fr5.lbl -text "Y offset (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr5.ent -textvariable yoffset -bg #ddaaaa -fg #000000
   label $dbox.fr6.lbl -text "Page height (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr6.ent -textvariable pageheight -bg #ddaaaa -fg #000000
   label $dbox.fr6a.lbl -text "Paper" -relief flat -anchor e -fg $appfg -bg $appbg
   menubutton $dbox.fr6a.btn -text "A4" -height 1 -width 10 -relief raised \
      -menu $dbox.fr6a.btn.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $dbox.fr6a.btn.m -tearoff false -bg $appbg -fg $appfg
   $dbox.fr6a.btn.m add command -label "  A3" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 42.0; set textheight 37.0; $dbox.fr6a.btn config -text A3"
   $dbox.fr6a.btn.m add command -label "  A4" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 29.7; set textheight 24.7; $dbox.fr6a.btn config -text A4"
   $dbox.fr6a.btn.m add command -label "  A5" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 21.0; set textheight 16.0; $dbox.fr6a.btn config -text A5"
   $dbox.fr6a.btn.m add command -label "  B4" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 36.4; set textheight 31.4; $dbox.fr6a.btn config -text B4"
   $dbox.fr6a.btn.m add command -label "  B5" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 25.7; set textheight 20.7; $dbox.fr6a.btn config -text B5"
   $dbox.fr6a.btn.m add command -label "  Executive" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 25.4; set textheight 20.4; $dbox.fr6a.btn config -text Executive"
   $dbox.fr6a.btn.m add command -label "  Folio" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 33.0; set textheight 28.0; $dbox.fr6a.btn config -text Folio"
   $dbox.fr6a.btn.m add command -label "  Ledger" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.9; set textheight 22.9; $dbox.fr6a.btn config -text Ledger"
   $dbox.fr6a.btn.m add command -label "  Legal" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 35.6; set textheight 30.6; $dbox.fr6a.btn config -text Legal"
   $dbox.fr6a.btn.m add command -label "  Letter" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.9; set textheight 22.9; $dbox.fr6a.btn config -text Letter"
   $dbox.fr6a.btn.m add command -label "  Quarto" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.5; set textheight 22.5; $dbox.fr6a.btn config -text Quarto"
   $dbox.fr6a.btn.m add command -label "  Statement" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 21.6; set textheight 16.6; $dbox.fr6a.btn config -text Statement"
   $dbox.fr6a.btn.m add command -label "  Tabloid" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 43.2; set textheight 38.2; $dbox.fr6a.btn config -text Tabloid"
   button $dbox.fr7.obtn -text "OK" -command {set psfnok 1} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   button $dbox.fr7.cbtn -text "Cancel" -command {set psfnok 0} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   label $dbox.fr7.space -text "" -relief flat -fg $appfg -bg $appbg
   pack $dbox.fr1 $dbox.fr2 $dbox.fr3 $dbox.fr4 $dbox.fr5 $dbox.fr6 -expand yes -fill x
   pack $dbox.fr6a -expand no
   pack $dbox.fr7 -expand yes -fill x
   pack $dbox.fr1.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr1.ent -padx 5 -pady 5
   pack $dbox.fr2.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr2.ent -padx 5 -pady 5
   pack $dbox.fr3.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr3.ent -padx 5 -pady 5
   pack $dbox.fr4.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr4.ent -padx 5 -pady 5
   pack $dbox.fr5.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr5.ent -padx 5 -pady 5
   pack $dbox.fr6.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr6.ent -padx 5 -pady 5
   pack $dbox.fr6a.lbl -padx 5 -pady 5 -side left -expand no
   pack $dbox.fr6a.btn -padx 5 -pady 5
   pack $dbox.fr7.obtn -padx 5 -pady 5 -side left
   pack $dbox.fr7.space -padx 5 -pady 5  -side left -expand yes -fill x
   pack $dbox.fr7.cbtn -padx 5 -pady 5 -fill y
   $dbox config -bg $appbg
   $dbox.fr1 config -bg $appbg
   $dbox.fr2 config -bg $appbg
   $dbox.fr3 config -bg $appbg
   $dbox.fr4 config -bg $appbg
   $dbox.fr5 config -bg $appbg
   $dbox.fr6 config -bg $appbg
   $dbox.fr6a config -bg $appbg
   $dbox.fr7 config -bg $appbg
   bind $dbox <Escape> {set psfnok 0}
   bind $dbox.fr1.ent <Return>  "focus $dbox.fr2.ent"
   bind $dbox.fr2.ent <Return>  "focus $dbox.fr3.ent"
   bind $dbox.fr3.ent <Return>  "focus $dbox.fr4.ent"
   bind $dbox.fr4.ent <Return>  "focus $dbox.fr5.ent"
   bind $dbox.fr5.ent <Return>  "focus $dbox.fr6.ent"
   bind $dbox.fr6.ent <Return>  {set psfnok 1}

   wm title $dbox "bwedit: export"
   wm resizable $dbox false false

   focus $dbox.fr1.ent
   grab $dbox
   tkwait variable psfnok
   grab release $dbox
   destroy $dbox

   if {$psfnok} { return [string trim $efname] } else { return "" }
}

proc exportPS { myid } {
   global fname efname pt pageheight textheight xoffset yoffset psfontfile
   global customfontno ptsize slant appbg appfg

   set mwin ".main$myid"

   if { [string compare $fname($myid) ""] != 0 } {
      set dotindex [string last "." $fname($myid)]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname($myid) 0 $dotindex]
      set efname "$efname.ps"
   } else {
      set efname "$fname($myid).ps"
   }
   set pt 12
   set sl "normal"
   set pageheight 29.7
   set textheight 24.7
   set xoffset 2.5
   set yoffset 2.5

   set efn [getPSFileName]
   if { [string compare $efn ""] != 0 } {
      if {[string compare "o" $slant]} { set slflag 0 } else { set slflag 1 }
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [$mwin.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno($myid)} {incr i 1} {
         set englishrng [concat $englishrng [$mwin.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set englishrng [lsort -real -increasing $englishrng]
      set smallrng [$mwin.mainfr.editfr.textarea tag ranges bengali100r]
      set normalrng [$mwin.mainfr.editfr.textarea tag ranges bengali120r]
      set largerng [$mwin.mainfr.editfr.textarea tag ranges bengali150r]
      set Largerng [$mwin.mainfr.editfr.textarea tag ranges bengali180r]
      set LARGErng [$mwin.mainfr.editfr.textarea tag ranges bengali210r]
      set hugerng [$mwin.mainfr.editfr.textarea tag ranges bengali250r]
      set Hugerng [$mwin.mainfr.editfr.textarea tag ranges bengali300r]
      set HUGErng [$mwin.mainfr.editfr.textarea tag ranges bengali360r]
      set smallslrng [$mwin.mainfr.editfr.textarea tag ranges bengali100o]
      set normalslrng [$mwin.mainfr.editfr.textarea tag ranges bengali120o]
      set largeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali150o]
      set Largeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali180o]
      set LARGEslrng [$mwin.mainfr.editfr.textarea tag ranges bengali210o]
      set hugeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali250o]
      set Hugeslrng [$mwin.mainfr.editfr.textarea tag ranges bengali300o]
      set HUGEslrng [$mwin.mainfr.editfr.textarea tag ranges bengali360o]
      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$normalrng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$HUGErng \$englishrng \$normalslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng \$HUGEslrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }
      set pageno 1
      set f [open $efn w]
      puts $f "%!PS-Adobe-2.0"
      puts $f "%%Title: Exported from $fname($myid)"
      puts $f "%%Creator: bwedit version 2.2"
      puts $f "%%CreationDate: [exec date]"
      puts $f "%%Pages: (atend)"
      puts $f "%%PageOrder: Ascend"
      puts $f "%%BoundingBox: 0 0 596 842"
      puts $f "%%DocumentFonts: "
      puts $f "%%DocumentPaperSizes: a4"
      puts $f "%%EndComments"

      set ff [open $psfontfile r]
      set x [read $ff]
      puts $f $x
      close $ff

      set corr1 [expr 0.43 * $pt]
      set corr2 [expr 0.23 * $pt]
      set corr3 [expr 0.20 * $pt]
      set corr4 [expr 0.56 * $pt]
      set corr5 [expr 0.06 * $pt]
      set lineskip [expr 1.4 * $pt]
      set uly [expr ($pageheight - $yoffset) * 28.35 - (0.8 * $pt)]
      set lly [expr $uly - ($textheight * 28.35)]
      set xoffset [expr $xoffset * 28.35]
      set currenty $uly
      set off1 [expr 0.5 * $pt]
      set off2 [expr 0.8 * $pt]
      set off3 [expr 0.3 * $pt]
      puts $f "/bnnormal \{ /Bengali findfont $pt scalefont setfont \} def"
      set bnsize [expr 0.7 * $pt]
      puts $f "/bnsmall \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 0.5 * $pt]
      puts $f "/bntiny \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.2 * $pt]
      puts $f "/bnlarge \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.44 * $pt]
      puts $f "/bnLarge \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.728 * $pt]
      puts $f "/bnLARGE \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.074 * $pt]
      puts $f "/bnhuge \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.488 * $pt]
      puts $f "/bnHuge \{ /Bengali findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.986 * $pt]
      puts $f "/bnHUGE \{ /Bengali findfont $bnsize scalefont setfont \} def"
      puts $f "/english \{ /Times-Roman findfont $pt scalefont setfont \} def"

      puts $f "/bsup \{ 0 $off1 rmoveto \} def"
      puts $f "/bsub \{ 0 -$off1 rmoveto \} def"
      puts $f "/bsupsup \{ 0 $off2 rmoveto \} def"
      puts $f "/bsubsub \{ 0 -$off2 rmoveto \} def"
      puts $f "/bsubsup \{ 0 $off3 rmoveto \} def"
      puts $f "/bsupsub \{ 0 -$off3 rmoveto \} def"
      puts $f "/esup \{ 0 -$off1 rmoveto \} def"
      puts $f "/esub \{ 0 $off1 rmoveto \} def"
      puts $f "/esupsup \{ 0 -$off2 rmoveto \} def"
      puts $f "/esubsub \{ 0 $off2 rmoveto \} def"
      puts $f "/esubsup \{ 0 -$off3 rmoveto \} def"
      puts $f "/esupsub \{ 0 $off3 rmoveto \} def"

      puts $f "/M \{ dup 4 div neg /y0 exch def moveto \} def"
      puts $f "/S \{ show \} def"
      puts $f "/SS \{ dup stringwidth pop /xx exch def gsave \[1 0 0.25 1 y0 0\] concat show grestore xx 0 rmoveto \} def"
      puts $f "/N \{ $xoffset $uly M \} def"
      puts $f "/B \{ neg /corr exch def corr 0 rmoveto \} def /F \{ /corr exch def corr 0 rmoveto \} def"
      puts $f "/CH 1 string def"
      puts $f "/P \{ CH 0 3 -1 roll put CH S \} def"
      puts $f "/PP \{ CH 0 3 -1 roll put CH SS \} def"
      puts $f "bnnormal"
      set tos 0
      set fontstack(0) "bnnormal"

      puts $f "\n%%Page: $pageno $pageno\nN"
      set ins [$mwin.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set englishmode 0
      foreach tagname { sub sup subsup supsub supsup subsub large Large LARGE huge Huge HUGE } {
         set ${tagname}found 0
         set prevcorr 0
      }
      set acc ""
      set tagshere {}
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            foreach tagname { \$normalrng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$HUGErng \$normalslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng \$HUGEslrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
                  if {[string compare $slant "o"]} {set slflag 0} else {set slflag 1}
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } {
            incr englishmode -1
            incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
         }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } {
               set acc "$acc e$tagname"
               incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
            }
         }
         set tagshere [$mwin.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su.tag"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) && ([string length $tagname] == 3) } {
               set acc "$acc b$tagname"
               incr tos 1 ; set fontstack($tos) bnsmall ; set acc "$acc bnsmall"
               set ${tagname}found 1
            }
         }
         set suidx [lsearch -regexp $tagshere "su.su.tag"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) } {
               set acc "$acc b$tagname"
               incr tos 1 ; set fontstack($tos) bntiny ; set acc "$acc bntiny"
               set ${tagname}found 1
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if {($ridx >= 0)} {
            if { !($ridx & 1) } {
               incr englishmode 1
               incr tos 1 ; set fontstack($tos) english ; set acc "$acc english"
            } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                  incr englishmode 1
                  incr tos 1 ; set fontstack($tos) english ; set acc "$acc english"
               }
            }
         }
         if {[lsearch -regexp $tagshere "bengali"] >= 0} {
            foreach tagname { normal small large Large LARGE huge Huge HUGE } {
               set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     set acc "$acc bn$tagname" ; set slflag 0
                     incr tos 1 ; set fontstack($tos) bn$tagname
                     set ${tagname}found 1
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}rng $ridx]) } {
                        set acc "$acc bn$tagname" ; set slflag 0
                        incr tos 1 ; set fontstack($tos) bn$tagname
                        set ${tagname}found 1
                     }
                  }
               }
               set ridx [eval lsearch -exact \$${tagname}slrng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     set acc "$acc bn$tagname" ; set slflag 1
                     incr tos 1 ; set fontstack($tos) bn$tagname
                     set ${tagname}found 1
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$${tagname}slrng]) && ("$lineno.$charno" == [eval lindex \$${tagname}slrng $ridx]) } {
                        set acc "$acc bn$tagname" ; set slflag 1
                        incr tos 1 ; set fontstack($tos) bn$tagname
                        set ${tagname}found 1
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         if {($slflag) && !($englishmode)} {set P PP ; set S SS} else {set P P ; set S S}
         if {$asciival == 10} {
            set currenty [expr $currenty - $lineskip]
            if {$prevcorr != 0} { set currenty [expr $currenty - ( $prevcorr * $pt )] }
            set sosc 0
            if {$subsupfound} { set sosc 0.3 }
            if {$supfound} { set sosc 0.5 }
            if {$supsupfound} { set sosc 0.8 }
            set fosc 0
            if {$largefound} { set fosc 0.25 }
            if {$Largefound} { set fosc 0.5 }
            if {$LARGEfound} { set fosc 0.75 }
            if {$hugefound} { set fosc 1.08 }
            if {$Hugefound} { set fosc 1.5 }
            if {$HUGEfound} { set fosc 2 }
            set tosc [expr ( $sosc + $fosc ) * $pt]
            set currenty [expr $currenty - $tosc]
            set prevcorr 0
            if { $currenty <= $lly } {
               incr pageno 1
               puts $f "showpage\n\n%%Page: $pageno $pageno\nN"
               set currenty $uly
            } else {
               if {$supsubfound} {set prevcorr 0.3}
               if {$subfound} {set prevcorr 0.5}
               if {$subsubfound} {set prevcorr 0.8}
            }
            puts $f "$xoffset $currenty M"
            puts $f $acc
            set acc ""
            set taglist [$mwin.mainfr.editfr.textarea tag names "$lineno.0"]
            if {[lsearch -regexp $taglist "bengali150"] >= 0} { set largefound 1 } else { set largefound 0 }
            if {[lsearch -regexp $taglist "bengali180"] >= 0} { set Largefound 1 } else { set Largefound 0 }
            if {[lsearch -regexp $taglist "bengali210"] >= 0} { set LARGEfound 1 } else { set LARGEfound 0 }
            if {[lsearch -regexp $taglist "bengali250"] >= 0} { set hugefound 1 } else { set hugefound 0 }
            if {[lsearch -regexp $taglist "bengali300"] >= 0} { set Hugefound 1 } else { set Hugefound 0 }
            if {[lsearch -regexp $taglist "bengali360"] >= 0} { set HUGEfound 1 } else { set HUGEfound 0 }
            foreach tagname { sub sup subsup supsub supsup subsub } {
               if {[lsearch -exact $taglist "${tagname}tag"] >= 0} {
                  set ${tagname}found 1
               } else { set ${tagname}found 0 }
            }
         } elseif {$englishmode} {
            switch -exact $asciival {
               37 { set acc "$acc (\\$nextchar) S" }
               40 { set acc "$acc (\\$nextchar) S" }
               41 { set acc "$acc (\\$nextchar) S" }
               92 { set acc "$acc (\\$nextchar) S" }
               default {
                  if { ($asciival < 32) || ($asciival > 127) } {
                     set acc "$acc $asciival P"
                  } else {
                     set acc "$acc ($nextchar) S"
                  }
               }
            }
         } else {
            switch -exact $asciival {
                1 { set acc "$acc $corr5 B 1 $P $corr5 F" }
                3 { set acc "$acc $corr5 B 3 $P $corr5 F" }
                4 { set acc "$acc $corr5 B 4 $P $corr5 F" }
               15 { set acc "$acc $corr4 B 15 $P $corr4 F" }
               37 { set acc "$acc (\\$nextchar) $S" }
               40 { set acc "$acc (\\$nextchar) $S" }
               41 { set acc "$acc (\\$nextchar) $S" }
               46 { set acc "$acc $corr1 F (.) $S" }
               73 { set acc "$acc $corr1 B (I) $S $corr1 F" }
               79 { set acc "$acc $corr1 B (O) $S $corr1 F" }
               84 { set acc "$acc $corr5 B (T) $S $corr5 F" }
               85 { set acc "$acc $corr2 B (U) $S $corr2 F" }
               87 { set acc "$acc $corr2 B (W) $S $corr2 F" }
               92 { set acc "$acc (\\$nextchar) $S" }
              117 { set acc "$acc $corr2 B (u) $S $corr2 F" }
              119 { set acc "$acc $corr3 B (w) $S $corr3 F" }
               default {
                  if { ($asciival < 32) || ($asciival > 127) } {
                     set acc "$acc $asciival $P"
                  } else {
                     set acc "$acc ($nextchar) $S"
                  }
               }
            }
         }
      }
      puts $f "showpage\n"
      puts $f "%%Trailer"
      puts $f "%%Pages: $pageno"
      puts $f "%%EOF"
      close $f
   }
}


############ Transliterator window #############
proc editRoman { myid { rfnm "" } } {
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2
   global olbg olfg
   global bweditlogo rfname installdir dpyfont
   global rselstart rselend
   global rdirtybit
   global appbg appfg opttype

   set myname ".roman$myid"
   if {[winfo exists $myname]} {return}
   set rwin [toplevel $myname]
   $rwin config -bg $appbg
   wm title $rwin "bwedit: Transliterator window $myid"

   frame $rwin.cmdfr -relief raised -borderwidth 2 -bg $appbg
   frame $rwin.namefr -bg $appbg
   frame $rwin.mainfr -bg $appbg
   frame $rwin.mainfr.editfr -bg $appbg

   # Tool bar
   menubutton $rwin.cmdfr.file -text "File" -height 1 -relief flat \
      -menu $rwin.cmdfr.file.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rwin.cmdfr.edit -text "Edit" -height 1 -relief flat \
      -menu $rwin.cmdfr.edit.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rwin.cmdfr.transfer -text "Transfer" -height 1 -relief flat \
      -menu $rwin.cmdfr.transfer.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rwin.cmdfr.mail -text "Mail" -height 1 -relief flat \
      -menu $rwin.cmdfr.mail.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rwin.cmdfr.option -text "Option" -height 1 -relief flat \
      -menu $rwin.cmdfr.option.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rwin.cmdfr.help -text "Help" -height 1 -relief flat \
      -menu $rwin.cmdfr.help.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg

   menu $rwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.file.m add command -label "  New main window " -accelerator " Alt+1 " -command "newMain" -underline 6
   $rwin.cmdfr.file.m add command -label "  New transliterator window " -accelerator " Alt+2 " -command "newRoman" -underline 6
   $rwin.cmdfr.file.m add separator
   $rwin.cmdfr.file.m add command -label "  New file " -accelerator " Alt+N " -command "newRomanFile $myid" -underline 2
   $rwin.cmdfr.file.m add command -label "  Load file " -accelerator " F2 " -command "loadRomanFile $myid" -underline 2
   $rwin.cmdfr.file.m add command -label "  Insert file " -accelerator " Alt+I " -command "insertRomanFile $myid" -underline 2
   $rwin.cmdfr.file.m add command -label "  Append file " -accelerator " Alt+A " -command "appendRomanFile $myid" -underline 2
   $rwin.cmdfr.file.m add command -label "  Save file " -accelerator " F3 " -command "saveThisRomanFile $myid" -underline 4
   $rwin.cmdfr.file.m add command -label "  Save as file " -accelerator " Alt+S " -command "saveRomanFile $myid" -underline 2
   $rwin.cmdfr.file.m add separator
   $rwin.cmdfr.file.m add command -label "  Read encoding from file " -command "readEnc 1" -underline 2
   $rwin.cmdfr.file.m add separator
   $rwin.cmdfr.file.m add command -label "  Close " -accelerator " Alt+C " -command "closeRoman $myid" -underline 2
   $rwin.cmdfr.file.m add command -label "  Quit " -accelerator " Alt+Q " -command "quitEditor" -underline 2

   menu $rwin.cmdfr.edit.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.edit.m add command -label "  Clear  " -command "rclearTextArea $myid ; incr rdirtybit($myid) 1" -underline 2
   $rwin.cmdfr.edit.m add command -label "  Select all  " -command "rselectAll $myid " -underline 9
   $rwin.cmdfr.edit.m add separator
   $rwin.cmdfr.edit.m add command -label "  Cut  " -accelerator " F4 " -command "rcutBuffer $myid " -underline 4
   $rwin.cmdfr.edit.m add command -label "  Copy  " -accelerator " F5 " -command "rcopyBuffer $myid " -underline 5
   $rwin.cmdfr.edit.m add command -label "  Paste  " -accelerator " F6 " -command "rpasteBuffer $myid " -underline 2
   $rwin.cmdfr.edit.m add separator
   $rwin.cmdfr.edit.m add command -label "  Search  " -accelerator " F11 " -command "searchExpr $myid roman" -underline 2

   menu $rwin.cmdfr.transfer.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.transfer.m add cascade -label "  Select target window " -menu $rwin.cmdfr.transfer.m.m -underline 2
   menu $rwin.cmdfr.transfer.m.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.transfer.m add separator
   $rwin.cmdfr.transfer.m add command -label "  Transfer text to main window " -accelerator " Alt+T " -command "transferText $myid" -underline 2
   $rwin.cmdfr.transfer.m add command -label "  Transfer line to main window " -accelerator " Alt+F " -command "transferLine $myid" -underline 7
   $rwin.cmdfr.transfer.m add command -label "  Transfer selected text to main window " -accelerator " Alt+X " -command "transferSelText $myid" -underline 22

   menu $rwin.cmdfr.mail.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.mail.m add command -label "  Read mail  " -accelerator " F9 " -command "readMail" -underline 2
   $rwin.cmdfr.mail.m add command -label "  Send mail  " -accelerator " Shift+F9 " -command "sendMail 2 $myid" -underline 2
   $rwin.cmdfr.mail.m add separator
   $rwin.cmdfr.mail.m add command -label "  Read bwencoded text  " -accelerator "Alt+5" -command "readBW 2 $myid" -underline 7
   $rwin.cmdfr.mail.m add command -label "  Read MIME encoded text  " -accelerator "Alt+6" -command "readMIME 2 $myid" -underline 7
   $rwin.cmdfr.mail.m add command -label "  Read uuencoded text  " -accelerator "Alt+7" -command "readUU 2 $myid" -underline 7
   $rwin.cmdfr.mail.m add separator
   $rwin.cmdfr.mail.m add command -label "  Edit mail options  " -command "set opttype 3; editOptions 1 $myid" -underline 2

   menu $rwin.cmdfr.option.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.option.m add command -label "  Edit options " -accelerator " Alt+O " -command " set opttype 2 ; editOptions 2 $myid " -underline 7
   $rwin.cmdfr.option.m add command -label "  Save options  " -command " saveOptions 2 $myid " -underline 2

   menu $rwin.cmdfr.help.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.help.m add command -label "  Show Keyboard map " -accelerator " Alt+K " -command {viewKbdMap} -underline 7
   $rwin.cmdfr.help.m add separator
   $rwin.cmdfr.help.m add command -label "  About bwedit  " -accelerator " F1 " -command {helpWin} -underline 2
   $rwin.cmdfr.help.m add command -label "  Roman-to-Bengali conversion rules  " -accelerator " Shift+F1 " -command {helpWinRoman} -underline 2
   $rwin.cmdfr.help.m add command -label "  Copyright notice  " -command {copyInfo} -underline 2

   label $rwin.cmdfr.blank -text "" -relief flat -bg $appbg -fg $appfg
   label $rwin.cmdfr.logo -image "bweditlogo" -relief flat -bg $appbg -fg $appfg -cursor hand2
   bind $rwin.cmdfr.logo <Button-1> { copyInfo }

   # File name
   label $rwin.namefr.lbl -text " File name: " -relief flat -foreground $appfg -background $appbg
   entry $rwin.namefr.ent -textvariable "rfname($myid)" -relief sunken \
      -background #ffb6c1 -foreground #000000 \
      -selectbackground #000000 -selectforeground #ffb6c1 -selectborderwidth 0
   bind $rwin.namefr.ent <Return> "focus $rwin.mainfr.editfr.textarea"

   # Edit area
   text $rwin.mainfr.editfr.textarea -relief sunken -height $textht2 -width $textwd2 \
      -font $dpyfont -wrap none -relief flat \
      -xscroll "$rwin.mainfr.hscroll set" -yscroll "$rwin.mainfr.editfr.scrbar set" \
      -insertbackground $textibg2 -insertwidth 3 \
      -background $textbg2 -foreground $textfg2 -borderwidth 2 \
      -selectbackground $textsbg2 -selectforeground $textsfg2 -selectborderwidth 0
   scrollbar $rwin.mainfr.editfr.scrbar -relief sunken -orient vertical \
      -command "$rwin.mainfr.editfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   # Horizontal scrollbar
   scrollbar $rwin.mainfr.hscroll -relief sunken -orient horizontal \
      -command "$rwin.mainfr.editfr.textarea xview" -bg $appbg -width 12 \
      -activebackground $appbg

   # Online view
   text $rwin.mainfr.olview -bg $olbg -fg $olfg -state disabled \
      -height 1 -width 80 -relief flat -selectforeground $olfg \
      -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific" \
      -selectbackground $olbg -selectborder 0 -spacing3 3
   $rwin.mainfr.olview tag config english -font $dpyfont

   pack $rwin.cmdfr.file $rwin.cmdfr.edit $rwin.cmdfr.transfer \
      $rwin.cmdfr.mail $rwin.cmdfr.option $rwin.cmdfr.help \
      -side left -padx 4 -pady 0 -side left
   pack $rwin.cmdfr.blank -side left -expand yes -fill both
   pack $rwin.cmdfr.logo -side left -padx 5 -pady 0 -side left
   pack $rwin.namefr.lbl -side left -padx 0 -pady 0
   pack $rwin.namefr.ent -side left -padx 0 -pady 0 -expand yes -fill x
   pack $rwin.mainfr.editfr.scrbar -fill y -side right -padx 0 -pady 0
   pack $rwin.mainfr.editfr.textarea -expand yes -fill both -side right -padx 0 -pady 0
   pack $rwin.mainfr.olview -padx 0 -pady 0 -fill x -side bottom
   pack $rwin.mainfr.hscroll -padx 0 -pady 0 -fill x -side bottom
   pack $rwin.mainfr.editfr -padx 0 -pady 0 -expand yes -fill both -side bottom
   pack $rwin.cmdfr -padx 0 -pady 0 -fill x
   pack $rwin.namefr -padx 5 -pady 5 -fill x
   pack $rwin.mainfr -padx 0 -pady 0 -expand yes -fill both

   focus $rwin.mainfr.editfr.textarea

   tkwait visibility $rwin
   refreshAllWinList
   set rfnm [string trim $rfnm]
   if {[string length $rfnm] > 0} { loadThisRomanFile $myid $rfnm }

   bind $rwin.mainfr.editfr.textarea <Any-KeyRelease> "setbnstr $myid"
   bind $rwin.mainfr.editfr.textarea <ButtonRelease-1> "setbnstr $myid"

   # Function key bindings
   bind $rwin <F1> "helpWin"
   bind $rwin <Shift-F1> "helpWinRoman"
   bind $rwin <F2> "loadRomanFile $myid"
   bind $rwin <F3> "saveThisRomanFile $myid"
   bind $rwin <F4> "rcutBuffer $myid"
   bind $rwin <F5> "rcopyBuffer $myid"
   bind $rwin <F6> "rpasteBuffer $myid"
   set rselstart($myid) ""
   set rselend($myid) ""
   bind $rwin.mainfr.editfr.textarea <F7> "rmarkbegin $myid"
   bind $rwin.mainfr.editfr.textarea <F8> "rmarkend $myid"
   bind $rwin <F9> "readMail"
   bind $rwin <Shift-F9> "sendMail 2 $myid"
   bind $rwin <F10> "ractivateFileMenu $myid ; break"
   bind $rwin <F11> "searchExpr $myid roman"

   # Alt + key bindings
   bind $rwin <Alt-Key-1> "newMain"
   bind $rwin <Alt-Key-2> "newRoman"
   bind $rwin <Alt-Key-5> "readBW 2 $myid"
   bind $rwin <Alt-Key-6> "readMIME 2 $myid"
   bind $rwin <Alt-Key-7> "readUU 2 $myid"
   bind $rwin <Alt-a> "appendRomanFile $myid"
   bind $rwin <Alt-A> "appendRomanFile $myid"
   bind $rwin <Alt-c> "closeRoman $myid; break"
   bind $rwin <Alt-C> "closeRoman $myid; break"
   bind $rwin <Alt-f> "transferLine $myid"
   bind $rwin <Alt-F> "transferLine $myid"
   bind $rwin <Alt-i> "insertRomanFile $myid"
   bind $rwin <Alt-I> "insertRomanFile $myid"
   bind $rwin <Alt-k> "viewKbdMap"
   bind $rwin <Alt-K> "viewKbdMap"
   bind $rwin <Alt-n> "newFile $myid"
   bind $rwin <Alt-N> "newFile $myid"
   bind $rwin <Alt-o> "set opttype 2 ; editOptions 1 $myid"
   bind $rwin <Alt-O> "set opttype 2 ; editOptions 1 $myid"
   bind $rwin <Alt-q> "quitEditor; break"
   bind $rwin <Alt-Q> "quitEditor; break"
   bind $rwin <Alt-s> "saveRomanFile $myid"
   bind $rwin <Alt-S> "saveRomanFile $myid"
   bind $rwin <Alt-t> "transferText $myid"
   bind $rwin <Alt-T> "transferText $myid"
   bind $rwin <Alt-x> "transferSelText $myid"
   bind $rwin <Alt-X> "transferSelText $myid"

   # Dirty bit
   bind $rwin.mainfr.editfr.textarea <Any-Key> "rprocKey $myid %A"
   bind $rwin.mainfr.editfr.textarea <Alt-Key> { }
   bind $rwin.mainfr.editfr.textarea <Control-Key> { }
   bind $rwin.mainfr.editfr.textarea <BackSpace> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-h> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Delete> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-d> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Meta-d> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-k> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-o> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-w> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-x> " incr rdirtybit($myid) 1 "
   bind $rwin.mainfr.editfr.textarea <Control-t> " incr rdirtybit($myid) 1 "

   # Menu bindings
   bind $rwin.cmdfr.file.m <Right> " grab release $rwin.cmdfr.file.m; $rwin.cmdfr.file.m unpost; ractivateEditMenu $myid ; break "
   bind $rwin.cmdfr.edit.m <Right> " grab release $rwin.cmdfr.edit.m; $rwin.cmdfr.edit.m unpost; ractivateTransferMenu $myid ; break "
   bind $rwin.cmdfr.transfer.m <Right> " grab release $rwin.cmdfr.transfer.m; $rwin.cmdfr.transfer.m unpost; ractivateMailMenu $myid ; break "
   bind $rwin.cmdfr.mail.m <Right> " grab release $rwin.cmdfr.mail.m; $rwin.cmdfr.mail.m unpost; ractivateOptionMenu $myid ; break "
   bind $rwin.cmdfr.option.m <Right> " grab release $rwin.cmdfr.option.m; $rwin.cmdfr.option.m unpost; ractivateHelpMenu $myid ; break "
   bind $rwin.cmdfr.help.m <Right> " grab release $rwin.cmdfr.help.m; $rwin.cmdfr.help.m unpost; ractivateFileMenu $myid ; break "
   bind $rwin.cmdfr.file.m <Left> " grab release $rwin.cmdfr.file.m; $rwin.cmdfr.file.m unpost; ractivateHelpMenu $myid ; break "
   bind $rwin.cmdfr.edit.m <Left> " grab release $rwin.cmdfr.edit.m; $rwin.cmdfr.edit.m unpost; ractivateFileMenu $myid ; break "
   bind $rwin.cmdfr.transfer.m <Left> " grab release $rwin.cmdfr.transfer.m; $rwin.cmdfr.transfer.m unpost; ractivateEditMenu $myid ; break "
   bind $rwin.cmdfr.mail.m <Left> " grab release $rwin.cmdfr.mail.m; $rwin.cmdfr.mail.m unpost; ractivateTransferMenu $myid ; break "
   bind $rwin.cmdfr.option.m <Left> " grab release $rwin.cmdfr.option.m; $rwin.cmdfr.option.m unpost; ractivateMailMenu $myid ; break "
   bind $rwin.cmdfr.help.m <Left> " grab release $rwin.cmdfr.help.m; $rwin.cmdfr.help.m unpost; ractivateOptionMenu $myid ; break "

   # Control + key bindings
   bind $rwin.mainfr.editfr.textarea <Control-Delete> " rdelword $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-BackSpace> " rbsword $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-w> " rdeltotalword $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-j> " rjoinword $myid ; break "

   bind $rwin.mainfr.editfr.textarea <Control-Shift-Delete> " rdelline $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-Shift-BackSpace> " rbsline $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-L> " rdeltotalline $myid ; break "
   bind $rwin.mainfr.editfr.textarea <Control-J> " rjoinline $myid ; break "

   # Mouse bindings
   menu $rwin.b2m  -tearoff false -bg $appbg -fg $appfg
   $rwin.b2m add command -label " Cut " -command "rcutBuffer $myid"
   $rwin.b2m add command -label " Copy " -command "rcopyBuffer $myid"
   $rwin.b2m add command -label " Paste " -command "rpasteBuffer $myid"
   $rwin.b2m add separator
   $rwin.b2m add command -label " Transfer text " -command "transferText $myid"
   $rwin.b2m add command -label " Transfer line " -command "transferLine $myid"
   $rwin.b2m add command -label " Transfer selection " -command "transferSelText $myid"
   $rwin.b2m add separator
   $rwin.b2m add command -label " Conversion rules " -command {helpwinRoman}

   menu $rwin.b3m  -tearoff false -bg $appbg -fg $appfg
   $rwin.b3m add command -label " Load file " -command "loadRomanFile $myid"
   $rwin.b3m add command -label " Save file " -command "saveThisRomanFile $myid"
   $rwin.b3m add command -label " Save as file " -command "saveRomanFile $myid"
   $rwin.b3m add separator
   $rwin.b3m add command -label " Send mail " -command "sendMail 2 $myid"
   $rwin.b3m add command -label " Read bwencoded file " -command "readBW 2 $myid"
   $rwin.b3m add command -label " Read MIME encoded file " -command "readMIME 2 $myid"
   $rwin.b3m add command -label " Read uuencoded file " -command "readUU 2 $myid"
   $rwin.b3m add separator
   $rwin.b3m add command -label " Close " -command "closeRoman $myid"
   $rwin.b3m add command -label " Quit " -command "quitEditor"

   bind $rwin.mainfr.editfr.textarea <ButtonPress-2> "
      $rwin.b2m post %X %Y
      $rwin.b2m activate 0
      grab set -global $rwin.b2m
   "
   bind $rwin.mainfr.editfr.textarea <ButtonPress-3> "
      $rwin.b3m post %X %Y
      $rwin.b3m activate 0
      grab set -global $rwin.b3m
   "
}

proc rprocKey { myid A } {
   global rdirtybit

   if { ([string compare $A " "] >= 0) && ([string compare $A "~"] <= 0) } {
      incr rdirtybit($myid) 1
   }
   if {![string compare $A "\t"]} { incr rdirtybit($myid) 1 }
   if {![string compare $A "\n"]} { incr rdirtybit($myid) 1 }
   if {![string compare $A "\r"]} { incr rdirtybit($myid) 1 }
   if {![string compare $A "\f"]} { incr rdirtybit($myid) 1 }
}

proc rdelword { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert" "insert wordend"
   incr rdirtybit($myid) 1
}

proc rbsword { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert - 1 chars wordstart" "insert"
   incr rdirtybit($myid) 1
}

proc rdeltotalword { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert wordstart" "insert wordend"
   incr rdirtybit($myid) 1
}

proc rjoinword { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   switch -exact [$rwin.mainfr.editfr.textarea get [$rwin.mainfr.editfr.textarea index "insert wordend"]] {
      "\n" {
         $rwin.mainfr.editfr.textarea delete "insert wordend" "insert wordend + 1 chars"
         incr rdirtybit($myid) 1
      }
      "\t" {
         $rwin.mainfr.editfr.textarea delete "insert wordend" "insert wordend + 1 chars"
         incr rdirtybit($myid) 1
      }
      " " {
         $rwin.mainfr.editfr.textarea delete "insert wordend" "insert wordend + 1 chars"
         incr rdirtybit($myid) 1
      }
   }
}

proc rdelline { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert" "insert lineend"
   incr rdirtybit($myid) 1
}

proc rbsline { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert linestart" "insert"
   incr rdirtybit($myid) 1
}

proc rdeltotalline { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert linestart" "insert + 1 lines linestart"
   incr rdirtybit($myid) 1
}

proc rjoinline { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea delete "insert lineend" "insert + 1 lines linestart"
   incr rdirtybit($myid) 1
}

proc ractivateFileMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.file]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.file]
   incr posy [winfo height $rwin.cmdfr.file]
   $rwin.cmdfr.file.m post $posx $posy
   $rwin.cmdfr.file.m activate 0
   grab set -global $rwin.cmdfr.file.m
   focus $rwin.cmdfr.file.m
}

proc ractivateEditMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.edit]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.edit]
   incr posy [winfo height $rwin.cmdfr.edit]
   $rwin.cmdfr.edit.m post $posx $posy
   $rwin.cmdfr.edit.m activate 0
   grab set -global $rwin.cmdfr.edit.m
   focus $rwin.cmdfr.edit.m
}

proc ractivateTransferMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.transfer]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.transfer]
   incr posy [winfo height $rwin.cmdfr.transfer]
   $rwin.cmdfr.transfer.m post $posx $posy
   $rwin.cmdfr.transfer.m activate 0
   grab set -global $rwin.cmdfr.transfer.m
   focus $rwin.cmdfr.transfer.m
}

proc ractivateOptionMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.option]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.option]
   incr posy [winfo height $rwin.cmdfr.option]
   $rwin.cmdfr.option.m post $posx $posy
   $rwin.cmdfr.option.m activate 0
   grab set -global $rwin.cmdfr.option.m
   focus $rwin.cmdfr.option.m
}

proc ractivateMailMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.mail]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.mail]
   incr posy [winfo height $rwin.cmdfr.mail]
   $rwin.cmdfr.mail.m post $posx $posy
   $rwin.cmdfr.mail.m activate 0
   grab set -global $rwin.cmdfr.mail.m
   focus $rwin.cmdfr.mail.m
}

proc ractivateHelpMenu { myid } {
   set rwin ".roman$myid"
   set posx [winfo x $rwin]
   incr posx [winfo x $rwin.cmdfr.help]
   set posy [winfo y $rwin]
   incr posy [winfo y $rwin.cmdfr.help]
   incr posy [winfo height $rwin.cmdfr.help]
   $rwin.cmdfr.help.m post $posx $posy
   $rwin.cmdfr.help.m activate 0
   grab set -global $rwin.cmdfr.help.m
   focus $rwin.cmdfr.help.m
}

proc rmarkbegin { myid } {
   global rselstart

   set rwin ".roman$myid"
   set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
   if {([llength $lsel] == 2)} {
      $rwin.mainfr.editfr.textarea tag remove sel [lindex $lsel 0] [lindex $lsel 1]
   }
   set rselstart($myid) [$rwin.mainfr.editfr.textarea index insert]
}

proc rmarkend { myid } {
   global rselstart rselend

   set rwin ".roman$myid"
   if {[string length $rselstart($myid)] > 0} {
      set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
      if {[llength $lsel] == 2} {
         $rwin.mainfr.editfr.textarea tag remove sel [lindex $lsel 0] [lindex $lsel 1]
      }
      set rselend($myid) [$rwin.mainfr.editfr.textarea index insert]
      if {[$rwin.mainfr.editfr.textarea compare $rselstart($myid) <= $rselend($myid)]} {
         $rwin.mainfr.editfr.textarea tag add sel $rselstart($myid) $rselend($myid)
      } else {
         $rwin.mainfr.editfr.textarea tag add sel $rselend($myid) $rselstart($myid)
      }
   }
   set rselstart($myid) ""
   set rselend($myid) ""
}

proc newRomanFile { myid } {
   global rfname rdirtybit

   set rwin ".roman$myid"
   saveRomanConfirm $myid; if {$rdirtybit($myid) != 0} { return }
   rclearTextArea $myid
   set rfname($myid) ""
   setbnstr $myid
}

proc loadThisRomanFile { myid fn } {
   global rfname rdirtybit

   set rwin ".roman$myid"
   saveRomanConfirm $myid; if {$rdirtybit($myid) != 0} { return }
   set fn [string trim $fn]
   if {[string compare $fn ""] != 0} {
      if {![file readable $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      close $f
      $rwin.mainfr.editfr.textarea delete 1.0 end
      $rwin.mainfr.editfr.textarea insert 1.0 $x
      $rwin.mainfr.editfr.textarea see insert
      focus $rwin.mainfr.editfr.textarea
      set rfname($myid) $fn
      set rdirtybit($myid) 0
      setbnstr $myid
   }
}

proc loadRomanFile { myid } {
   global rfname rdirtybit

   set rwin ".roman$myid"
   saveRomanConfirm $myid; if {$rdirtybit($myid) != 0} { return }
   set fn [getFileName "bwedit: Load Roman file"]
   if {[string compare $fn ""] != 0} {
      if {![file readable $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      $rwin.mainfr.editfr.textarea delete 1.0 end
      $rwin.mainfr.editfr.textarea insert 1.0 $x
      close $f
      set rfname($myid) $fn
      $rwin.mainfr.editfr.textarea see insert
      set rdirtybit($myid) 0
      setbnstr $myid
   }
}

proc insertRomanFile { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   set fn [getFileName "bwedit: Insert Roman file"]
   if {[string compare $fn ""] != 0} {
      if {![file readable $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      close $f
      $rwin.mainfr.editfr.textarea insert insert $x
      $rwin.mainfr.editfr.textarea see insert
      incr rdirtybit($myid) 1
      setbnstr $myid
   }
}

proc appendRomanFile { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   set fn [getFileName "bwedit: Append Roman file"]
   if {[string compare $fn ""] != 0} {
      if {![file readable $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      close $f
      $rwin.mainfr.editfr.textarea insert end $x
      $rwin.mainfr.editfr.textarea see insert
      incr rdirtybit($myid) 1
      setbnstr $myid
   }
}

proc saveThisRomanFile { myid } {
   global rfname rdirtybit

   set rwin ".roman$myid"
   set rfname($myid) [string trim $rfname($myid)]
   set fnm $rfname($myid)
   if {![string compare "" $fnm]} {
      errmsg2 $myid "ERROR:\nI cannot save file. No file name is given."
      return
   }
   set dnm [file dirname $fnm]
   if {![file isdirectory $dnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
      return
   }
   if {![file writable $dnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
      return
   }
   if {[file exists $fnm] && ![file isfile $fnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. \"$fnm\" is not a regular file."
      return
   }
   if {[file exists $fnm] && ![file writable $fnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fnm\""
      return
   }
   set f [open $fnm w]
   set x [$rwin.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   close $f
   set rdirtybit($myid) 0
   errmsg2 $myid "$fnm saved"
}

proc saveRomanFile { myid } {
   global rfname rdirtybit

   set rwin ".roman$myid"
   set fnm [getFileName "bwedit: Save Roman file"]
   if {![string compare "" $fnm]} { return }
   set dnm [file dirname $fnm]
   if {![file isdirectory $dnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
      return
   }
   if {![file writable $dnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
      return
   }
   if {[file exists $fnm] && ![file isfile $fnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. \"$fnm\" is not a regular file."
      return
   }
   if {[file exists $fnm] && ![file writable $fnm]} {
      errmsg2 $myid "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fnm\""
      return
   }
   set f [open $fnm w]
   set x [$rwin.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   close $f
   set rdirtybit($myid) 0
   if {![string compare $rfname($myid) ""]} { set rfname($myid) $fnm }
   errmsg2 $myid "$fnm saved"
}

proc rclearTextArea { myid } {
   .roman$myid.mainfr.editfr.textarea delete 1.0 end
}

proc rselectAll { myid } {
   .roman$myid.mainfr.editfr.textarea tag add sel 1.0 end
}

set rbuffer ""

proc rcutBuffer { myid } {
   global rbuffer rdirtybit

   set rwin ".roman$myid"
   set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   incr rdirtybit($myid) 1
   set rbuffer [$rwin.mainfr.editfr.textarea get sel.first sel.last]
   $rwin.mainfr.editfr.textarea delete sel.first sel.last
   $rwin.mainfr.editfr.textarea see insert
   setbnstr $myid
}

proc rcopyBuffer { myid } {
   global rbuffer

   set rwin ".roman$myid"
   set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   set rbuffer [$rwin.mainfr.editfr.textarea get sel.first sel.last]
}

proc rpasteBuffer { myid } {
   global rbuffer rdirtybit

   set rwin ".roman$myid"
   $rwin.mainfr.editfr.textarea insert insert $rbuffer
   incr rdirtybit($myid) 1
   setbnstr $myid
   $rwin.mainfr.editfr.textarea see insert
}

set ttargetWin "0"
proc refreshTargetWinList { } {
   global mavail ravail ttargetWin

   for {set i 1} {$i < $ravail} {incr i 1} {
      if {[winfo exists .roman$i]} {
         .roman$i.cmdfr.transfer.m.m delete 0 last
         for {set j 1} {$j <= $mavail} {incr j 1} {
            if {[winfo exists .main$j]} {
               .roman$i.cmdfr.transfer.m.m add radio -label "Main window $j" -variable ttargetWin -value "$j"
            }
         }
      }
   }
}

proc transferText { myid } {
   global ttargetWin dirtybit

   set mwin ".main$ttargetWin"
   set rwin ".roman$myid"

   if {[winfo exists $mwin]} {
      set ipstr "[$rwin.mainfr.editfr.textarea get 1.0 end]"
      romanToBeng $ipstr $mwin.mainfr.editfr.textarea
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($ttargetWin) 1
   }
}

proc transferLine { myid } {
   global ttargetWin dirtybit

   set mwin ".main$ttargetWin"
   set rwin ".roman$myid"

   if {[winfo exists $mwin]} {
      set ipstr "[$rwin.mainfr.editfr.textarea get "insert linestart" "insert lineend"]\n"
      romanToBeng $ipstr $mwin.mainfr.editfr.textarea
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($ttargetWin) 1
   }
}

proc transferSelText { myid } {
   global ttargetWin dirtybit

   set mwin ".main$ttargetWin"
   set rwin ".roman$myid"
   set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 $myid "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }
   if {[winfo exists $mwin]} {
      set ipstr "[$rwin.mainfr.editfr.textarea get sel.first sel.last]\n"
      romanToBeng $ipstr $mwin.mainfr.editfr.textarea
      $mwin.mainfr.editfr.textarea see insert
      incr dirtybit($ttargetWin) 1
   }
}

proc setbnstr { myid } {
   set ipstr "[.roman$myid.mainfr.editfr.textarea get "insert linestart" "insert lineend"] "
   .roman$myid.mainfr.olview config -state normal
   .roman$myid.mainfr.olview delete 1.0 end
   romanToBeng $ipstr .roman$myid.mainfr.olview
   .roman$myid.mainfr.olview config -state disabled
}

set srcwinid -1
proc saveRomanConfirm { myid } {
   global srcwin rdirtybit btnbg btnfg srcwinid srccancel

   set rwin ".roman$myid"
   if {[winfo exists $srcwinid]} {focus $scrwinid; tkwait variable rdirtybit($myid); return}
   set srccancel 0
   while {($rdirtybit($myid) != 0) && ($srccancel == 0)} {
      set srcwin [toplevel .src]
      set srcwinid $srcwin
      $srcwin config -background #004466
      label $srcwin.l -text "Unsaved changes in transliterator window $myid" -fg #ffffff -bg #006688
      frame $srcwin.bfr -bg #004466
      button $srcwin.bfr.b1 -text "Save" -command "saveThisRomanFile $myid" -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $srcwin.bfr.b2 -text "Save as" -command "saveRomanFile $myid" -underline 5 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $srcwin.bfr.b3 -text "Do not save" -command "set rdirtybit($myid) 0" -underline 3 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $srcwin.bfr.b4 -text "Cancel" -command "set rdirtybit($myid) $rdirtybit($myid); set srccancel 1" -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      pack $srcwin.l -expand yes -fill both -padx 0 -pady 0
      pack $srcwin.bfr.b1 $srcwin.bfr.b2 $srcwin.bfr.b3 $srcwin.bfr.b4 -side left -padx 10 -pady 0
      pack $srcwin.bfr -expand no -padx 0 -pady 10

      bind $srcwin <Key-S> "saveThisRomanFile $myid"
      bind $srcwin <Key-A> "saveRomanFile $myid"
      bind $srcwin <Key-N> "set rdirtybit($myid) 0"
      bind $srcwin <Key-C> "set rdirtybit($myid) $rdirtybit($myid); set srccancel 1"
      bind $srcwin <Key-s> "saveThisRomanFile $myid"
      bind $srcwin <Key-a> "saveRomanFile $myid"
      bind $srcwin <Key-n> "set rdirtybit($myid) 0"
      bind $srcwin <Key-c> "set rdirtybit($myid) $rdirtybit($myid); set srccancel 1"

      wm transient $srcwin $rwin
      wm title $srcwin "Options for unsaved changes"
      set posx [winfo x $rwin]
      set posy [winfo y $rwin]
      incr posx [winfo x $rwin.mainfr]
      incr posy [winfo y $rwin.mainfr]
      set twd [winfo width $rwin.mainfr.editfr.textarea]
      set tht [winfo height $rwin.mainfr.editfr.textarea]
      set ewd1 [winfo reqwidth $srcwin.l]
      set ewd2 [expr [winfo reqwidth $srcwin.bfr.b1] + \
                     [winfo reqwidth $srcwin.bfr.b2] + \
                     [winfo reqwidth $srcwin.bfr.b3] + \
                     [winfo reqwidth $srcwin.bfr.b4] + 100]
      if {$ewd1 > $ewd2} { set ewd $ewd1 } else { set ewd $ewd2 }
      set eht [expr [winfo reqheight $srcwin.l] + [winfo reqheight $srcwin.bfr.b1] + 40]
      set posx [expr $posx + ($twd - $ewd) / 2]
      set posy [expr $posy + ($tht - $eht) / 2]
      if {$posx <= 0} { set posx 0 }
      if {$posy <= 0} { set posy 0 }
      wm geometry $srcwin "${ewd}x${eht}+$posx+$posy"
      focus $srcwin

      grab $srcwin
      tkwait variable rdirtybit($myid)
      grab release $srcwin
      destroy $srcwin
      set srcwinid -1
   }
}

proc errmsg2 { myid msg } {
   global btnbg btnfg

   set rwin ".roman$myid"
   set ewin [toplevel .error]

   message $ewin.msg -text $msg -relief flat -bg #006688 -fg #ffffff -width 250 -justify center
   button $ewin.btn -text "Ok" -relief raised -fg $btnfg -bg $btnbg \
          -activeforeground $btnfg -activebackground $btnbg \
          -command {set edone 1} -height 0

   pack $ewin.msg -padx 0 -pady 0 -expand yes -fill both
   pack $ewin.btn -pady 10

   bind $ewin <Escape> {set edone 1}
   bind $ewin <Return> {set edone 1}

   $ewin config -bg #004466

   wm transient $ewin $rwin
   set posx [winfo x $rwin]
   set posy [winfo y $rwin]
   incr posx [winfo x $rwin.mainfr]
   incr posy [winfo y $rwin.mainfr]
   set twd [winfo width $rwin.mainfr.editfr.textarea]
   set tht [winfo height $rwin.mainfr.editfr.textarea]
   set ewd [winfo reqwidth $ewin.msg]
   set eht [expr [winfo reqheight $ewin.msg] + [winfo reqheight $ewin.btn] + 40]
   set posx [expr $posx + ($twd - $ewd) / 2]
   set posy [expr $posy + ($tht - $eht) / 2]
   if {$posx <= 0} { set posx 0 }
   if {$posy <= 0} { set posy 0 }
   wm geometry $ewin "${ewd}x${eht}+$posx+$posy"
   wm title $ewin "Diagnostic message"

   grab $ewin
   tkwait variable edone
   grab release $ewin
   destroy $ewin
}

set ravail 1
proc newRoman { } {
   global ravail rdirtybit rfname

   set rdirtybit($ravail) 0
   set rfname($ravail) ""
   incr ravail 1
   editRoman [expr $ravail - 1]
   return [expr $ravail - 1]
}

proc loadRoman { } {
   global ravail rdirtybit rfname

   set rdirtybit($ravail) 0
   set rfname($ravail) ""
   incr ravail 1
   editRoman [expr $ravail - 1] [getFileName "Load Roman file"]
   return [expr $ravail - 1]
}

proc loadRoman2 { fnm } {
   global ravail rdirtybit rfname

   set rdirtybit($ravail) 0
   set rfname($ravail) ""
   incr ravail 1
   editRoman [expr $ravail - 1] $fnm
   return [expr $ravail - 1]
}

proc closeRoman { myid } {
   global rdirtybit

   set rwin ".roman$myid"
   saveRomanConfirm $myid; if { $rdirtybit($myid) != 0 } { return }
   destroy $rwin
   refreshAllWinList
}


############ Help windows ############
proc adddoc { twin fn } {
   global installdir

   $twin config -state normal
   $twin tag configure bntag -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
   set bngmode 0
   $twin delete 1.0 end
   if {![file readable "$installdir/help/$fn.hlp"]} {
      $twin insert end "ERROR:\nI am unable to read the help file\n$installdir/help/$fn.hlp\n"
   } else {
      set bngmode 0
      set f [open "$installdir/help/$fn.hlp" r]
      while {![eof $f]} {
         set nextchar [read $f 1]
         if {$bngmode == 0} {
            if {![string compare "#" $nextchar]} {
               set bngmode 1
               set bnstr ""
            } else { $twin insert end $nextchar }
         } else {
            if {![string compare "#" $nextchar]} {
               if {[string length $bnstr] > 0} {
                  if {![string compare [string index $bnstr 0] "\\"]} {
                     $twin insert end [format "%c" [string range $bnstr 1 [expr [string length $bnstr] - 1]]] bntag
                  } else {
                     $twin insert end $bnstr bntag
                  }
               }
               set bngmode 0
            } else { set bnstr "$bnstr$nextchar" }
         }
      }
   }
   $twin config -state disabled
}

proc addHelpBtn { btn txt } {
   global appbg appfg

   button .help.ctfr.$btn -text $txt -fg $appfg -bg $appbg \
      -activeforeground #0000ff -activebackground $appbg \
      -command "adddoc .help.dpyfr.textarea $btn" -anchor w \
      -relief flat -borderwidth -1 -highlightthickness 0 -cursor hand2
   pack .help.ctfr.$btn -side top -fill x -padx 0 -pady 0 -expand no
}

set hwinid -1
proc helpWin { } {
   global installdir bweditlogo dpyfont hdrfont appbg appfg hwinid

   if {[winfo exists $hwinid]} {focus $hwinid; return}
   set hwin [toplevel .help]
   set hwinid $hwin
   $hwin config -bg $appbg
   frame $hwin.ctfr -bg $appbg -borderwidth 2 -relief raised
   frame $hwin.dpyfr -bg $appbg
   label $hwin.ctfr.logo -image "bweditlogo" -bg $appbg -cursor hand2
   bind $hwin.ctfr.logo <Button-1> { copyInfo }
   label $hwin.ctfr.hdr -text "Help topics" -bg $appbg -fg #990099 -font $hdrfont
   pack $hwin.ctfr.logo -pady 5
   pack $hwin.ctfr.hdr -pady 5 -fill x
   addHelpBtn intro       "Introduction"
   addHelpBtn coordinator "Coordinator window"
   addHelpBtn main        "Main editor window"
   addHelpBtn toolbar     "    Toolbar"
   addHelpBtn file        "        File menu"
   addHelpBtn edit        "        Edit menu"
   addHelpBtn tag         "        Tag menu"
   addHelpBtn import      "        Import menu"
   addHelpBtn export      "        Export menu"
   addHelpBtn mail        "        Mail menu"
   addHelpBtn option      "        Option menu"
   addHelpBtn help        "        Help menu"
   addHelpBtn fname       "    File name"
   addHelpBtn textarea    "    Textarea"
   addHelpBtn editrmn     "Transliterator window"
   addHelpBtn rmntool     "    Toolbar"
   addHelpBtn rmntext     "    Text area"
   addHelpBtn rmnolview   "    Online view"
   addHelpBtn kbdmap      "Keyboard map"
   addHelpBtn readmail    "Read mails"
   addHelpBtn sendmail    "Send mails"
   addHelpBtn cmdline     "Command line options"
   addHelpBtn binding     "Keyboard / mouse bindings"
   addHelpBtn copyright   "Copyright info"

   label $hwin.ctfr.space -text "" -fg $appfg -bg $appbg
   pack $hwin.ctfr.space -side top -padx 0 -pady 0 -fill y -expand yes

   button $hwin.ctfr.transrule -text "Transliteration rules" -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg \
      -command "helpWinRoman" -underline 0
   pack $hwin.ctfr.transrule -side top -padx 2 -pady 1 -fill x

   button $hwin.ctfr.close -text "Close window" -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg \
      -command "destroy $hwin" -underline 0
   pack $hwin.ctfr.close -side top -padx 2 -pady 1 -fill x

   text $hwin.dpyfr.textarea -relief sunken -height 45 -width 60 \
      -yscroll "$hwin.dpyfr.vscroll set" -state disabled -spacing3 2 \
      -wrap none -relief flat -highlightthickness 0 -font $dpyfont \
      -background #000000 -foreground #ffffff -borderwidth 2 \
      -selectbackground #ffffff -selectforeground #000000 -selectborderwidth 0
   scrollbar $hwin.dpyfr.vscroll -relief sunken -orient vertical \
      -command "$hwin.dpyfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   pack $hwin.dpyfr.vscroll -side right -padx 0 -pady 0 -expand no -fill y
   pack $hwin.dpyfr.textarea -side right -padx 0 -pady 0 -expand yes -fill both
   pack $hwin.ctfr -side left -padx 0 -pady 0 -expand no -fill y
   pack $hwin.dpyfr -side left -padx 0 -pady 0 -expand yes -fill both

   bind $hwin <Escape> "destroy $hwin"
   bind $hwin <Alt-c> "destroy $hwin; break"
   bind $hwin <Alt-C> "destroy $hwin; break"
   bind $hwin <Alt-t> "helpWinRoman"
   bind $hwin <Alt-T> "helpWinRoman"
   adddoc $hwin.dpyfr.textarea intro
   wm title $hwin "bwedit: Help"
   focus $hwin.dpyfr.textarea
   bind $hwin.dpyfr.textarea <Up> {break}
   bind $hwin.dpyfr.textarea <Down> {break}
   bind $hwin.dpyfr.textarea <Left> {break}
   bind $hwin.dpyfr.textarea <Right> {break}
}

proc addHelpBtn2 { btn txt } {
   global appbg appfg

   button .rhelp.ctfr.$btn -text $txt -fg $appfg -bg $appbg \
      -activeforeground #0000ff -activebackground $appbg \
      -command "adddoc .rhelp.dpyfr.textarea $btn" -anchor w \
      -relief flat -borderwidth -1 -highlightthickness 0 -cursor hand2
   pack .rhelp.ctfr.$btn -side top -fill x -padx 0 -pady 0 -expand no
}

set hwinrid -1
proc helpWinRoman { } {
   global installdir bweditlogo hdrfont dpyfont appbg appfg hwinrid

   if {[winfo exists $hwinrid]} {focus $hwinrid; return}
   set hwin [toplevel .rhelp]
   set hwinrid $hwin
   $hwin config -bg $appbg
   frame $hwin.ctfr -bg $appbg -borderwidth 2 -relief raised
   frame $hwin.dpyfr -bg $appbg
   label $hwin.ctfr.logo -image "bweditlogo" -bg $appbg -cursor hand2
   bind $hwin.ctfr.logo <Button-1> { copyInfo }
   label $hwin.ctfr.hdr -text "Transliteration rules" -bg $appbg -fg #990099 -font $hdrfont
   pack $hwin.ctfr.logo -pady 5
   pack $hwin.ctfr.hdr -pady 5 -fill x

   addHelpBtn2 cr1     "1. Introduction"
   addHelpBtn2 cr2     "2. General rules"
   addHelpBtn2 cr3     "3. The default encoding"
   addHelpBtn2 cr3_1   "    3.1 Vowels"
   addHelpBtn2 cr3_2   "    3.2 Consonants"
   addHelpBtn2 cr3_3   "    3.3 Conjunct consonants"
   addHelpBtn2 cr3_4   "    3.4 Digits and punctuation"
   addHelpBtn2 cr4     "4. Customize encoding"
   addHelpBtn2 cr5     "5. Inserting text in Roman font"
   addHelpBtn2 cr6     "6. Conclusion"

   label $hwin.ctfr.space -text "" -fg $appfg -bg $appbg
   pack $hwin.ctfr.space -side top -padx 0 -pady 0 -fill y -expand yes

   button $hwin.ctfr.about -text "About bwedit" -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg \
      -command "helpWin" -underline 0
   pack $hwin.ctfr.about -side top -padx 2 -pady 1 -fill x

   button $hwin.ctfr.close -text "Close window" -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg \
      -command "destroy $hwin" -underline 0
   pack $hwin.ctfr.close -side top -padx 2 -pady 1 -fill x

   text $hwin.dpyfr.textarea -relief sunken -height 45 -width 60 \
      -yscroll "$hwin.dpyfr.vscroll set" -state disabled -spacing3 2 \
      -wrap none -relief flat -highlightthickness 0 -font $dpyfont \
      -background #ffffff -foreground #000000 -borderwidth 2 \
      -selectbackground #000000 -selectforeground #ffffff -selectborderwidth 0
   scrollbar $hwin.dpyfr.vscroll -relief sunken -orient vertical \
      -command "$hwin.dpyfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   pack $hwin.dpyfr.vscroll -side right -padx 0 -pady 0 -expand no -fill y
   pack $hwin.dpyfr.textarea -side right -padx 0 -pady 0 -expand yes -fill both
   pack $hwin.ctfr -side left -padx 0 -pady 0 -expand no -fill y
   pack $hwin.dpyfr -side left -padx 0 -pady 0 -expand yes -fill both

   bind $hwin <Escape> "destroy $hwin"
   bind $hwin <Alt-c> "destroy $hwin; break"
   bind $hwin <Alt-C> "destroy $hwin"
   bind $hwin <Alt-a> "helpWin"
   bind $hwin <Alt-A> "helpWin"
   adddoc $hwin.dpyfr.textarea cr1
   wm title $hwin "bwedit: Roman-to-Bengali transliteration scheme"
   focus $hwin.dpyfr.textarea
   bind $hwin.dpyfr.textarea <Up> {break}
   bind $hwin.dpyfr.textarea <Down> {break}
   bind $hwin.dpyfr.textarea <Left> {break}
   bind $hwin.dpyfr.textarea <Right> {break}
}


############ Mail functions ############
proc readInbox { {flag 0} } {
   global inbox mno mfrom msender mdate msubject mrepto mbody mcurr mailEditMode

   if {![string compare $mailEditMode "on"]} {return}
   if {$flag == 0} { set minbox $inbox } else {
      set minbox [getFileName "bwedit: Choose mail folder"]
      if {![string compare $minbox ""]} { return }
   }
   set f [open $minbox r]
   set mlines [split [read $f] "\n"]
   close $f 
   set mcurr 0
   set mno 0
   for {set i 0} {$i < [llength $mlines]} {incr i 1} {
      set nextline [lindex $mlines $i]
      if {![string compare "From " [string range $nextline 0 4]]} {
         incr mno 1
         set mbody($mno) ""
         set nextline [string trim [string range $nextline 5 [expr [string length $nextline] - 1]]]
         set spcidx [string first " " $nextline]
         if {$spcidx > 0} {
            set mfrom($mno) [string range $nextline 0 [expr $spcidx - 1]]
            set mdate($mno) [string trim [string range $nextline $spcidx [expr [string length $nextline] - 1]]]
         } else {
            set mfrom($mno) ""
            set mdate($mno) ""
         }
         set msubject($mno) ""
         set msender($mno) ""
         set mrepto($mno) ""
         set status 0
      } elseif {$mno > 0} {
         if {($status == 0)} {
            if {![string compare "" $nextline]} { set status 1 } else {
               if {![string compare "From: " [string range $nextline 0 5]] && ![string compare $msender($mno) ""]} {
                  set msender($mno) [string trim [string range $nextline 6 [expr [string length $nextline] - 1]]]
                  set ltidx [string first "<" $msender($mno)]
                  set gtidx [string first ">" $msender($mno)]
                  if { ($ltidx > 0) && ($gtidx > 0) && ($ltidx < $gtidx) } {
                     set msender($mno) [string trim [string range $msender($mno) 0 [expr $ltidx - 1]]]
                  } elseif { ($ltidx == 0) && ([expr $gtidx + 1] == [string length $msender($mno)])} {
                     set msender($mno) [string trim [string range $msender($mno) 1 [expr $gtidx - 1]]]
                  }
               } elseif {![string compare "Date: " [string range $nextline 0 5]] && ![string compare $mdate($mno) ""]} {
                  set mdate($mno) [string range $nextline 6 [expr [string length $nextline] - 1]]
               } elseif {![string compare "Subject: " [string range $nextline 0 8]] && ![string compare $msubject($mno) ""]} {
                  set msubject($mno) [string range $nextline 9 [expr [string length $nextline] - 1]]
               } elseif {![string compare "Reply-To: " [string range $nextline 0 9]] && ![string compare $mrepto($mno) ""]} {
                  set mrepto($mno) [string range $nextline 10 [expr [string length $nextline] - 1]]
               }
            }
         } else {
            set mbody($mno) "$mbody($mno)\n$nextline"
         }
      }
   }
   unset mlines
   .readmail.contfr.lbx delete 0 end
   for {set i 1} {$i <= $mno} {incr i 1} {
      .readmail.contfr.lbx insert 0 [formattedLine [expr $mno - $i + 1] $mdate($i) $msender($i) $msubject($i)]
   }
   .readmail.dpyfr.textfr.t config -state normal
   .readmail.dpyfr.textfr.t delete 1.0 end
   .readmail.dpyfr.textfr.t config -state disabled
   focus .readmail.dpyfr.textfr.t
   .readmail.fldrfr.h config -text "Current folder is  `$minbox'  with $mno messages"
   showMailNum 1
}

proc formattedLine { no date sender subject } {
   if {$no < 10} {
      set outp "   $no  "
   }  elseif {$no < 100} {
      set outp "  $no  "
   }  elseif {$no < 1000} {
      set outp " $no  "
   }  else {
      set outp "$no  "
   }
   set outp "${outp}[string range $date 4 9]  "
   if {[string length $sender] > 25} {
      set outp "${outp}[string range $sender 0 24] "
   } else {
      set outp "${outp}${sender}"
      while {[string length $outp] < 40} { set outp "$outp "  }
   }
   set outp "$outp $subject"
   return $outp
}

proc readMail { } {
   global appbg appfg btnbg btnfg bweditlogo dpyfont
   global inbox mno mfrom msender mdate msubject mrepto mbody mcurr mailEditMode msrcopt

   if {[winfo exists .readmail]} { focus .readmail ; return }

   set rmwin [toplevel .readmail]
   $rmwin config -bg $appbg
   wm title $rmwin "bwedit: Read mail"

   frame $rmwin.cmdfr -bg $appbg -relief raised -borderwidth 2
   frame $rmwin.fldrfr -bg $appbg -relief flat
   frame $rmwin.contfr -bg $appbg -relief flat
   frame $rmwin.dpyfr -bg $appbg -relief flat
   frame $rmwin.dpyfr.textfr -bg $appbg -relief flat

   menubutton $rmwin.cmdfr.file -text "File" -height 1 -relief flat \
      -menu $rmwin.cmdfr.file.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rmwin.cmdfr.mail -text "Mail" -height 1 -relief flat \
      -menu $rmwin.cmdfr.mail.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rmwin.cmdfr.option -text "Option" -height 1 -relief flat \
      -menu $rmwin.cmdfr.option.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg
   menubutton $rmwin.cmdfr.help -text "Help" -height 1 -relief flat \
      -menu $rmwin.cmdfr.help.m -bg $appbg -fg $appfg -highlightthickness 0 \
      -activeforeground $appfg -activebackground $appbg

   menu $rmwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg -disabledforeground #888888
   $rmwin.cmdfr.file.m add command -label "  New main window " -accelerator " Alt+1 " -command {newMain} -underline 6
   $rmwin.cmdfr.file.m add command -label "  New transliterator window " -accelerator " Alt+2 " -command {newRoman} -underline 6
   $rmwin.cmdfr.file.m add command -label "  Show mail in main window" -accelerator " Alt+3 " -command {loadMail} -underline 2
   $rmwin.cmdfr.file.m add command -label "  Show mail in transliterator window " -accelerator " Alt+4 " -command {loadMailRoman} -underline 3
   $rmwin.cmdfr.file.m add command -label "  BWdecode mail and show " -accelerator " Alt+5 " -command {decodeMail 1} -underline 2
   # $rmwin.cmdfr.file.m add command -label "  MIME decode mail and show " -accelerator " Alt+6 " -command {decodeMail 2} -underline 2
   $rmwin.cmdfr.file.m add command -label "  UUdecode mail and show " -accelerator " Alt+7 " -command {decodeMail 3} -underline 2
   $rmwin.cmdfr.file.m add command -label "  Save mail " -accelerator " F3 " -command {saveMail} -underline 4
   $rmwin.cmdfr.file.m add separator
   $rmwin.cmdfr.file.m add command -label "  Close " -accelerator " Alt+C " -command "set mcurr 0 ; set mailEditMode off ; if {$msrcopt == 3} { set msrcopt -1 } ; destroy $rmwin" -underline 2
   $rmwin.cmdfr.file.m add command -label "  Quit " -accelerator " Alt+Q " -command "quitEditor" -underline 2

   menu $rmwin.cmdfr.mail.m -tearoff false -bg $appbg -fg $appfg -disabledforeground #888888
   $rmwin.cmdfr.mail.m add command -label "  Reread inbox " -accelerator " Alt+R " -command "readInbox" -underline 9
   $rmwin.cmdfr.mail.m add command -label "  Read folder " -command "readInbox 1" -underline 2
   $rmwin.cmdfr.mail.m add separator
   $rmwin.cmdfr.mail.m add command -label "  Show next mail " -accelerator " Down / n / + " -command "showNextMail" -underline 7
   $rmwin.cmdfr.mail.m add command -label "  Show previous mail " -accelerator " Up / p / - " -command "showPrevMail" -underline 7
   $rmwin.cmdfr.mail.m add command -label "  Show first mail " -accelerator " Home " -command "showMailNum 1" -underline 11
   $rmwin.cmdfr.mail.m add command -label "  Show last mail " -accelerator " End " -command {showMailNum $mno} -underline 7
   $rmwin.cmdfr.mail.m add command -label "  Ten mails forward " -accelerator " Right / N " -command "tenForward" -underline 12
   $rmwin.cmdfr.mail.m add command -label "  Ten mails backward " -accelerator " Left / P " -command "tenBackward" -underline 12
   $rmwin.cmdfr.mail.m add command -label "  Goto mail " -accelerator " Hash " -command "gotoMail" -underline 2
   $rmwin.cmdfr.mail.m add separator
   $rmwin.cmdfr.mail.m add command -label "  Send mail " -accelerator " Shift+F9 " -command "sendMail 0" -underline 2
   $rmwin.cmdfr.mail.m add command -label "  Send reply " -accelerator " F9 " -command "sendReply" -underline 3
   $rmwin.cmdfr.mail.m add command -label "  Edit reply " -accelerator " Alt+E " -command "editMail" -underline 3

   menu $rmwin.cmdfr.option.m -tearoff false -bg $appbg -fg $appfg -disabledforeground #888888
   $rmwin.cmdfr.option.m add command -label "  Edit mail options " -accelerator " Alt+O " -command "set opttype 3; editOptions 0" -underline 2
   $rmwin.cmdfr.option.m add command -label "  Save options " -accelerator "" -command "saveOptions 3" -underline 2

   menu $rmwin.cmdfr.help.m -tearoff false -bg $appbg -fg $appfg -disabledforeground #888888
   $rmwin.cmdfr.help.m add command -label "  About bwedit  " -accelerator " F1 " -command {helpWin} -underline 2
   $rmwin.cmdfr.help.m add command -label "  Roman-to-Bengali conversion rules  " -accelerator " Shift+F1 " -command {helpWinRoman} -underline 2
   $rmwin.cmdfr.help.m add command -label "  Copyright notice  " -command {copyInfo} -underline 2

   label $rmwin.cmdfr.blank -text "" -relief flat -bg $appbg -fg $appfg
   label $rmwin.cmdfr.logo -image "bweditlogo" -relief flat -bg $appbg -fg $appfg -cursor hand2
   bind $rmwin.cmdfr.logo <Button-1> { copyInfo }

   label $rmwin.fldrfr.h -text "" -relief flat -fg #ffffff -bg #000000 \
      -font $dpyfont

   listbox $rmwin.contfr.lbx -width 80 -height 10 -bg #ffffff -fg #000000 \
      -yscroll "$rmwin.contfr.vscroll set" -relief flat -highlightthickness 0 \
      -selectmode single -selectforeground #ffffff -selectbackground #000000 \
      -selectborderwidth 0 -font fixed
   scrollbar $rmwin.contfr.vscroll -command "$rmwin.contfr.lbx yview" \
      -troughcolor $appbg -orient vertical -bg $appbg -width 12 \
      -activebackground $appbg

   text $rmwin.dpyfr.textfr.t -relief sunken -height 30 -width 80 \
      -xscroll "$rmwin.dpyfr.hscroll set" -yscroll "$rmwin.dpyfr.textfr.vscroll set" \
      -wrap none -relief flat -font fixed -fg $appfg -bg $appbg \
      -selectborderwidth 0 -selectbackground $appfg -selectforeground $appbg \
      -highlightthickness 0 -state disabled
   scrollbar $rmwin.dpyfr.textfr.vscroll -relief sunken -orient vertical -width 12 \
      -command "$rmwin.dpyfr.textfr.t yview" -bg $appbg -activebackground $appbg
   scrollbar $rmwin.dpyfr.hscroll -relief sunken -orient horizontal -width 12 \
      -command "$rmwin.dpyfr.textfr.t xview" -bg $appbg -activebackground $appbg

   pack $rmwin.cmdfr.file $rmwin.cmdfr.mail $rmwin.cmdfr.option $rmwin.cmdfr.help \
      -side left -padx 4 -pady 0 -side left
   pack $rmwin.cmdfr.blank -side left -expand yes -fill both
   pack $rmwin.cmdfr.logo -side left -padx 5 -pady 0 -side left

   pack $rmwin.fldrfr.h -expand yes -fill x -padx 0 -pady 0 -side left

   pack $rmwin.contfr.vscroll -expand no -fill y -padx 0 -pady 0 -side right
   pack $rmwin.contfr.lbx -expand yes -fill both -padx 0 -pady 0 -side right

   pack $rmwin.dpyfr.textfr.vscroll -side right -padx 0 -pady 0 -expand no -fill y
   pack $rmwin.dpyfr.textfr.t -side right -padx 0 -pady 0 -expand yes -fill both
   pack $rmwin.dpyfr.hscroll -side bottom -padx 0 -pady 0 -expand no -fill x
   pack $rmwin.dpyfr.textfr -side bottom -expand yes -fill both -padx 0 -pady 0

   pack $rmwin.cmdfr -expand no -fill x -padx 0 -pady 0
   pack $rmwin.fldrfr -expand no -fill x -padx 5 -pady 0
   pack $rmwin.contfr -expand no -fill x -padx 5 -pady 0
   pack $rmwin.dpyfr -expand yes -fill both -padx 5 -pady 5

   bind $rmwin.contfr.lbx <ButtonRelease-1> "showMail %Y"
   bind $rmwin.contfr.lbx <KeyRelease-space> "showMail %Y"

   set mailEditMode "off"
   readInbox
   focus $rmwin.dpyfr.textfr.t
   bind $rmwin.dpyfr.textfr.t <Up> {
      if {![string compare $mailEditMode "off"]} {showPrevMail; break}
   }
   bind $rmwin.dpyfr.textfr.t <Down> {
      if {![string compare $mailEditMode "off"]} {showNextMail; break}
   }
   bind $rmwin.dpyfr.textfr.t <Left> {
      if {![string compare $mailEditMode "off"]} {tenBackward; break}
   }
   bind $rmwin.dpyfr.textfr.t <Right> {
      if {![string compare $mailEditMode "off"]} {tenForward; break}
   }

   # Key bindings
   bind $rmwin <Key-plus> {showNextMail}
   bind $rmwin <Key-minus> {showPrevMail}
   bind $rmwin <Key-n> {showNextMail}
   bind $rmwin <Key-p> {showPrevMail}
   bind $rmwin <Key-N> {tenForward}
   bind $rmwin <Key-P> {tenBackward}
   bind $rmwin <Key-numbersign> {gotoMail}
   bind $rmwin <Home> {showMailNum 1}
   bind $rmwin <End> {showMailNum [expr $mno]}

   # Alt-key bindings
   bind $rmwin <Alt-Key-1> {newMain}
   bind $rmwin <Alt-Key-2> {newRoman}
   bind $rmwin <Alt-Key-3> {loadMail}
   bind $rmwin <Alt-Key-4> {loadMailRoman}
   bind $rmwin <Alt-Key-5> {decodeMail 1}
   bind $rmwin <Alt-Key-7> {decodeMail 3}
   bind $rmwin <Alt-c> "set mcurr 0 ; destroy $rmwin ; break"
   bind $rmwin <Alt-C> "set mcurr 0 ; destroy $rmwin ; break"
   bind $rmwin <Alt-e> {editMail}
   bind $rmwin <Alt-E> {editMail}
   bind $rmwin <Alt-o> {set opttype 3; editOptions 0}
   bind $rmwin <Alt-O> {set opttype 3; editOptions 0}
   bind $rmwin <Alt-q> {quitEditor; break}
   bind $rmwin <Alt-Q> {quitEditor; break}
   bind $rmwin <Alt-r> {readInbox}
   bind $rmwin <Alt-R> {readInbox}

   # Function key bindings
   bind $rmwin <F1> {helpWin}
   bind $rmwin <Shift-F1> {helpWinRoman}
   bind $rmwin <F3> {saveMail}
   bind $rmwin <F9> {sendReply}
   bind $rmwin <Shift-F9> {sendMail 0}
   bind $rmwin <F10> {mpostFileMenu ; break}

   # Menu bindings
   bind $rmwin.cmdfr.file.m <Right> "grab release $rmwin.cmdfr.file.m; $rmwin.cmdfr.file.m unpost; mpostMailMenu; break"
   bind $rmwin.cmdfr.mail.m <Right> "grab release $rmwin.cmdfr.mail.m; $rmwin.cmdfr.mail.m unpost; mpostOptionMenu; break"
   bind $rmwin.cmdfr.option.m <Right> "grab release $rmwin.cmdfr.option.m; $rmwin.cmdfr.option.m unpost; mpostHelpMenu; break"
   bind $rmwin.cmdfr.help.m <Right> "grab release $rmwin.cmdfr.help.m; $rmwin.cmdfr.help.m unpost; mpostFileMenu; break"
   bind $rmwin.cmdfr.file.m <Left> "grab release $rmwin.cmdfr.file.m; $rmwin.cmdfr.file.m unpost; mpostHelpMenu; break"
   bind $rmwin.cmdfr.mail.m <Left> "grab release $rmwin.cmdfr.mail.m; $rmwin.cmdfr.mail.m unpost; mpostFileMenu; break"
   bind $rmwin.cmdfr.option.m <Left> "grab release $rmwin.cmdfr.option.m; $rmwin.cmdfr.option.m unpost; mpostMailMenu; break"
   bind $rmwin.cmdfr.help.m <Left> "grab release $rmwin.cmdfr.help.m; $rmwin.cmdfr.help.m unpost; mpostOptionMenu; break"
}

proc mpostFileMenu { } {
   set posx [winfo x .readmail]
   incr posx [winfo x .readmail.cmdfr.file]
   set posy [winfo y .readmail]
   incr posy [winfo y .readmail.cmdfr.file]
   incr posy [winfo height .readmail.cmdfr.file]
   .readmail.cmdfr.file.m post $posx $posy
   .readmail.cmdfr.file.m activate 0
   grab set -global .readmail.cmdfr.file.m
   focus .readmail.cmdfr.file.m
}

proc mpostMailMenu { } {
   set posx [winfo x .readmail]
   incr posx [winfo x .readmail.cmdfr.mail]
   set posy [winfo y .readmail]
   incr posy [winfo y .readmail.cmdfr.mail]
   incr posy [winfo height .readmail.cmdfr.mail]
   .readmail.cmdfr.mail.m post $posx $posy
   .readmail.cmdfr.mail.m activate 0
   grab set -global .readmail.cmdfr.mail.m
   focus .readmail.cmdfr.mail.m
}

proc mpostOptionMenu { } {
   set posx [winfo x .readmail]
   incr posx [winfo x .readmail.cmdfr.option]
   set posy [winfo y .readmail]
   incr posy [winfo y .readmail.cmdfr.option]
   incr posy [winfo height .readmail.cmdfr.option]
   .readmail.cmdfr.option.m post $posx $posy
   .readmail.cmdfr.option.m activate 0
   grab set -global .readmail.cmdfr.option.m
   focus .readmail.cmdfr.option.m
}

proc mpostHelpMenu { } {
   set posx [winfo x .readmail]
   incr posx [winfo x .readmail.cmdfr.help]
   set posy [winfo y .readmail]
   incr posy [winfo y .readmail.cmdfr.help]
   incr posy [winfo height .readmail.cmdfr.help]
   .readmail.cmdfr.help.m post $posx $posy
   .readmail.cmdfr.help.m activate 0
   grab set -global .readmail.cmdfr.help.m
   focus .readmail.cmdfr.help.m
}

proc showMail { Y } {
   global mbody mdate msender msubject mrepto mno mcurr mailEditMode

   if {![string compare $mailEditMode "on"]} {return}
   set mi 0
   foreach si [.readmail.contfr.lbx curselection] { set mi [expr $mno - $si] }
   if {$mi != 0} {
      set mcurr $mi
      .readmail.dpyfr.textfr.t config -state normal
      .readmail.dpyfr.textfr.t delete 1.0 end
      .readmail.dpyfr.textfr.t insert insert "    From: $msender($mi)\n"
      .readmail.dpyfr.textfr.t insert insert "    Date: $mdate($mi)\n"
      .readmail.dpyfr.textfr.t insert insert " Subject: $msubject($mi)\n"
      if {[string compare $mrepto($mi) ""]} {
         .readmail.dpyfr.textfr.t insert insert "Reply-to: $mrepto($mi)\n"
      }
      .readmail.dpyfr.textfr.t insert insert $mbody($mi)
      .readmail.dpyfr.textfr.t config -state disabled
   }
}

proc showMailNum { n } {
   global mbody mdate msender mrepto msubject mno mcurr mailEditMode

   if {![string compare $mailEditMode "on"]} {return}
   if {($n < 1) || ($n > $mno)} {return}
   set mcurr [expr $mno - $n + 1]
   .readmail.dpyfr.textfr.t config -state normal
   .readmail.dpyfr.textfr.t delete 1.0 end
   .readmail.dpyfr.textfr.t insert insert "    From: $msender($mcurr)\n"
   .readmail.dpyfr.textfr.t insert insert "    Date: $mdate($mcurr)\n"
   .readmail.dpyfr.textfr.t insert insert " Subject: $msubject($mcurr)\n"
   if {[string compare $mrepto($mcurr) ""]} {
      .readmail.dpyfr.textfr.t insert insert "Reply-to: $mrepto($mcurr)\n"
   }
   .readmail.dpyfr.textfr.t insert insert $mbody($mcurr)
   .readmail.dpyfr.textfr.t config -state disabled
   .readmail.contfr.lbx select clear 0 end
   .readmail.contfr.lbx select set [expr $n - 1]
   .readmail.contfr.lbx see [expr $n - 1]
}

proc showNextMail { } {
   global mno mcurr

   showMailNum [expr $mno - $mcurr + 2]
}

proc showPrevMail { } {
   global mno mcurr

   showMailNum [expr $mno - $mcurr]
}

proc tenForward { } {
   global mno mcurr

   showMailNum [expr $mno - $mcurr + 11]
}

proc tenBackward { } {
   global mno mcurr

   showMailNum [expr $mno - $mcurr - 9]
}

proc gotoMail { } {
   global appbg appfg btnbg btnfg dpyfont gtmok mcurr mno mailEditMode

   if {![string compare $mailEditMode "on"]} {return}
   set gtmok 0
   set gtmbox [toplevel .gotomail]
   $gtmbox config -bg $appbg
   label $gtmbox.hdr -relief flat -fg $appfg -bg $appbg -text "Goto mail" -font $dpyfont
   frame $gtmbox.fr1 -relief flat -bg $appbg
   frame $gtmbox.fr2 -relief flat -bg $appbg
   frame $gtmbox.fr3 -relief flat -bg $appbg
   frame $gtmbox.fr4 -relief flat -bg $appbg

   label $gtmbox.fr1.l -text "Mail no:" -fg $appfg -bg $appbg -font $dpyfont
   entry $gtmbox.fr1.e -width 10 -bg #88ddff -fg #000000 \
      -selectforeground #88ddff -selectbackground #000000 -selectborderwidth 0
   $gtmbox.fr1.e insert insert [expr $mno - $mcurr + 1]
   button $gtmbox.fr1.b -text "Goto" -command { set gtmok [expr round([string trim [.gotomail.fr1.e get]])] } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $gtmbox.fr2.n -text "Next" -command { set gtmok [expr $mno - $mcurr + 2] } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0
   button $gtmbox.fr2.p -text "Previous" -command { set gtmok [expr $mno - $mcurr] } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0
   button $gtmbox.fr2.f -text "First" -command { set gtmok 1 } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 4
   button $gtmbox.fr2.l -text "Last" -command { set gtmok $mno } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   button $gtmbox.fr4.b -text "Cancel" -command { set gtmok 0 } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   label $gtmbox.fr3.l -text "Shift:" -fg $appfg -bg $appbg -font $dpyfont
   entry $gtmbox.fr3.e -width 10 -bg #88ddff -fg #000000 \
      -selectforeground #88ddff -selectbackground #000000 -selectborderwidth 0
   $gtmbox.fr3.e insert insert "10"
   button $gtmbox.fr3.f -text "Forward" -command { set gtmok [expr $mno - $mcurr + 1 + round([string trim [.gotomail.fr3.e get]])] } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0
   button $gtmbox.fr3.b -text "Backward" -command { set gtmok [expr $mno - $mcurr + 1 - round([string trim [.gotomail.fr3.e get]])] } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0

   pack $gtmbox.fr1.l $gtmbox.fr1.e -expand no -padx 0 -pady 0 -side left
   pack $gtmbox.fr1.b -expand no -padx 10 -pady 0 -side left
   pack $gtmbox.fr2.n $gtmbox.fr2.p $gtmbox.fr2.f $gtmbox.fr2.l -expand no -padx 5 -pady 0 -side left
   pack $gtmbox.fr3.l $gtmbox.fr3.e -expand no -padx 0 -pady 0 -side left
   pack $gtmbox.fr3.f -expand no -padx 10 -pady 0 -side left
   pack $gtmbox.fr3.b -expand no -padx 0 -pady 0 -side left
   pack $gtmbox.fr4.b -expand no -padx 0 -pady 0
   pack $gtmbox.hdr $gtmbox.fr1 $gtmbox.fr2 $gtmbox.fr3 $gtmbox.fr4 \
      -expand no -padx 5 -pady 5

   wm resizable $gtmbox false false
   wm title $gtmbox "bwedit: Goto mail"
   focus $gtmbox.fr1.e
   bind $gtmbox.fr1.e <Return> { focus .gotomail.fr3.e }
   bind $gtmbox.fr3.e <Return> { focus .gotomail.fr1.e }
   bind $gtmbox <Alt-B> { .gotomail.fr3.b invoke }
   bind $gtmbox <Alt-C> { .gotomail.fr4.b invoke }
   bind $gtmbox <Alt-F> { .gotomail.fr3.f invoke }
   bind $gtmbox <Alt-G> { .gotomail.fr1.b invoke }
   bind $gtmbox <Alt-L> { .gotomail.fr2.l invoke }
   bind $gtmbox <Alt-N> { .gotomail.fr2.n invoke }
   bind $gtmbox <Alt-P> { .gotomail.fr2.p invoke }
   bind $gtmbox <Alt-T> { .gotomail.fr2.f invoke }
   bind $gtmbox <Alt-b> { .gotomail.fr3.b invoke }
   bind $gtmbox <Alt-c> { .gotomail.fr4.b invoke }
   bind $gtmbox <Alt-f> { .gotomail.fr3.f invoke }
   bind $gtmbox <Alt-g> { .gotomail.fr1.b invoke }
   bind $gtmbox <Alt-l> { .gotomail.fr2.l invoke }
   bind $gtmbox <Alt-n> { .gotomail.fr2.n invoke }
   bind $gtmbox <Alt-p> { .gotomail.fr2.p invoke }
   bind $gtmbox <Alt-t> { .gotomail.fr2.f invoke }
   bind $gtmbox <Escape> { .gotomail.fr2.p invoke }

   grab $gtmbox
   tkwait variable gtmok
   grab release $gtmbox
   destroy $gtmbox
   showMailNum $gtmok
}

proc editMail { } {
   global mailEditMode mno mcurr mrepto

   if {![string compare $mailEditMode "off"]} {
      set mlines [split [.readmail.dpyfr.textfr.t get 1.0 end] "\n"]
      .readmail.dpyfr.textfr.t config -state normal
      .readmail.dpyfr.textfr.t delete 1.0 end
      if {[string compare $mrepto($mcurr) ""]} { set fline 4 } else { set fline 3 }
      for {set i $fline} {$i < [llength $mlines]} {incr i 1} {
         .readmail.dpyfr.textfr.t insert end "> [lindex $mlines $i]\n"
      }
      unset mlines
      set mailEditMode "on"
      .readmail.dpyfr.textfr.t see insert
      .readmail.cmdfr.mail.m entryconfigure 0 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 1 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 3 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 4 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 5 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 6 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 7 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 8 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 9 -state disabled
      .readmail.cmdfr.mail.m entryconfigure 13 -label "  Done editing " -underline 2
   } else {
      set mailEditMode "off"
      showMailNum [expr $mno - $mcurr + 1]
      .readmail.cmdfr.mail.m entryconfigure 0 -state active
      .readmail.cmdfr.mail.m entryconfigure 1 -state active
      .readmail.cmdfr.mail.m entryconfigure 3 -state active
      .readmail.cmdfr.mail.m entryconfigure 4 -state active
      .readmail.cmdfr.mail.m entryconfigure 5 -state active
      .readmail.cmdfr.mail.m entryconfigure 6 -state active
      .readmail.cmdfr.mail.m entryconfigure 7 -state active
      .readmail.cmdfr.mail.m entryconfigure 8 -state active
      .readmail.cmdfr.mail.m entryconfigure 9 -state active
      .readmail.cmdfr.mail.m entryconfigure 13 -label "  Edit reply " -underline 3
   }
}

proc loadMail { } {
   global mno mbody dirtybit mcurr

   set myid [newMain]
   if {$mcurr == 0} {
      .main$myid.mainfr.editfr.textarea insert insert [.readmail.dpyfr.textfr.t get 1.0 end]
   } else {
      .main$myid.mainfr.editfr.textarea insert insert $mbody($mcurr)
   }
   .main$myid.mainfr.editfr.textarea see insert
   set dirtybit($myid) 1
}

proc loadMailRoman { } {
   global mno mbody rdirtybit mcurr

   set myid [newRoman]
   if {$mcurr == 0} {
      .roman$myid.mainfr.editfr.textarea insert insert [.readmail.dpyfr.textfr.t get 1.0 end]
   } else {
      .roman$myid.mainfr.editfr.textarea insert insert $mbody($mcurr)
   }
   .roman$myid.mainfr.editfr.textarea see insert
   set rdirtybit($myid) 1
}

proc decodeMail { type } {
   global bwmaildir mbody mno mcurr

   if {$mcurr == 0} { return }
   if {![file exists $bwmaildir]} {
      exec mkdir $bwmaildir
      exec chmod 700 $bwmaildir
   }
   if {!([file exists $bwmaildir] && [file isdirectory $bwmaildir] && [file writable $bwmaildir])} {
      return
   }
   set f [open "$bwmaildir/tmp.mail" w]
   puts -nonewline $f $mbody($mcurr)
   close $f
   switch -exact $type {
      "1" {
         readBW 0 0 "$bwmaildir/tmp.mail"
      }
      "2" {
         readMIME 0 0 "$bwmaildir/tmp.mail"
      }
      "3" {
         readUU 0 0 "$bwmaildir/tmp.mail"
      }
   }
   exec rm "$bwmaildir/tmp.mail"
}

proc saveMail { } {
   global mbody mno mcurr

   set fnm [getFileName "bwedit: Save mail"]
   if {![string compare "" $fnm]} { return }
   set dnm [file dirname $fnm]
   if {![file isdirectory $dnm]} { return }
   if {![file writable $dnm]} { return }
   if {[file exists $fnm] && ![file isfile $fnm]} { return }
   if {[file exists $fnm] && ![file writable $fnm]} { return }
   set f [open $fnm w]
   if {$mcurr > 0} {
      puts -nonewline $f $mbody($mcurr)
   } else {
      puts -nonewline $f [.readmail.dpyfr.textfr.t get 1.0 end]
   }
   close $f
}

proc sendReply { } {
   global mbody mno mfrom mrepto mcurr msubject mailEditMode

   if {$mcurr > 0} {
      if {![string compare $mailEditMode "off"]} {editMail}
      sendMail 3
      .sendmail.fr1.ent delete 0 end
      if {[string compare $mrepto($mcurr) "" ]} {
         .sendmail.fr1.ent insert end $mrepto($mcurr)
      } else {
         .sendmail.fr1.ent insert end $mfrom($mcurr)
      }
      .sendmail.fr2.ent delete 0 end
      if {[string length $msubject($mcurr)] == 0} {
         .sendmail.fr2.ent insert end "Re: Your mail"
      } elseif {![string compare "Re:" [string range $msubject($mcurr) 0 2]]} {
         .sendmail.fr2.ent insert end "$msubject($mcurr)"
      } else {
         .sendmail.fr2.ent insert end "Re: $msubject($mcurr)"
      }
   }
}

set msrcopt -1
set mfname ""
proc sendMail { option { myid 0 } } {
   global btnbg btnfg appbg appfg
   global msrcopt mfname mtwin rmtwin mailEditMode

   if {[winfo exists .sendmail]} {
      if {$option == 1} {
         set msrcopt 1
         set mtwin $myid
         .sendmail.fr6.rad config -text "Main window $myid" -fg $appfg -activeforeground $appfg
         .sendmail.fr6.btn config -state active
         .sendmail.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr5.btn config -state disabled
         .sendmail.fr5.ent config -state disabled -fg #A2A2A2
         .sendmail.fr7.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr7.btn config -state disabled
         .sendmail.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      } elseif {$option == 2} {
         set msrcopt 2
         set rmtwin $myid
         .sendmail.fr7.rad config -text "Transliterator window $myid" -fg $appfg -activeforeground $appfg
         .sendmail.fr7.btn config -state active
         .sendmail.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr5.btn config -state disabled
         .sendmail.fr5.ent config -state disabled -fg #A2A2A2
         .sendmail.fr6.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr6.btn config -state disabled
         .sendmail.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      } elseif {$option == 3} {
         set msrcopt 3
         .sendmail.fr8.rad config -fg $appfg -activeforeground $appfg
         .sendmail.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr5.btn config -state disabled
         .sendmail.fr6.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr6.btn config -state disabled
         .sendmail.fr7.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         .sendmail.fr7.btn config -state disabled
      }
      mupdateMenus
      focus .sendmail
      return
   }

   set mtwin 0
   set rmtwin 0

   set mwin [toplevel .sendmail]
   $mwin config -bg $appbg
   wm title $mwin "bwedit: Send mail"
   wm resizable $mwin false false

   frame $mwin.fr1 -bg $appbg
   frame $mwin.fr2 -bg $appbg
   frame $mwin.fr3 -bg $appbg
   frame $mwin.fr4 -bg $appbg
   frame $mwin.fr5 -bg $appbg
   frame $mwin.fr6 -bg $appbg
   frame $mwin.fr7 -bg $appbg
   frame $mwin.fr8 -bg $appbg
   frame $mwin.frA -bg $appbg

   label $mwin.fr1.lbl -text "To:" -relief flat -anchor w -fg $appfg -bg $appbg
   entry $mwin.fr1.ent -bg #ddaaaa -fg #000000 -width 40
   label $mwin.fr2.lbl -text "Subject:" -relief flat -anchor w -fg $appfg -bg $appbg
   entry $mwin.fr2.ent -bg #ddaaaa -fg #000000 -width 40
   label $mwin.fr3.lbl -text "Encoding:" -relief flat -anchor w -fg $appfg -bg $appbg
   menubutton $mwin.fr3.btn -text "Plain text" -height 1 -width 15 \
      -relief raised -menu $mwin.fr3.btn.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg
   menu $mwin.fr3.btn.m -tearoff false -bg $appbg -fg $appfg
   $mwin.fr3.btn.m add command -label " Plain text " -command "$mwin.fr3.btn config -text {Plain text}"
   $mwin.fr3.btn.m add command -label " bwencode " -command "$mwin.fr3.btn config -text {bwencode}"
   $mwin.fr3.btn.m add command -label " MIME encoding " -command "$mwin.fr3.btn config -text {MIME encoding}"
   $mwin.fr3.btn.m add command -label " uuencode " -command "$mwin.fr3.btn config -text {uuencode}"
   label $mwin.fr4.lbl -text "Read mail body from: " -relief flat -anchor w -fg $appfg -bg $appbg
   radiobutton $mwin.fr5.rad  -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg #A2A2A2 -bg $appbg \
      -activebackground $appbg -activeforeground #A2A2A2 \
      -variable msrcopt -value 0 -text "File"
   entry $mwin.fr5.ent -textvariable mfname -bg #ddaaaa -fg #A2A2A2 -width 20 -state disabled
   button $mwin.fr5.btn -text "Browse" -relief raised -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg \
      -command {set mfname [getFileName "bwedit: Choose file to mail"]} \
      -state disabled -disabledforeground #A2A2A2
   radiobutton $mwin.fr6.rad  -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg #A2A2A2 -bg $appbg \
      -activebackground $appbg -activeforeground #A2A2A2 \
      -variable msrcopt -value 1 -text "Main window" -width 25 -anchor w
   menubutton $mwin.fr6.btn -text "Select window" -height 1 -width 15 \
      -relief raised -menu $mwin.fr6.btn.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg \
      -state disabled -disabledforeground #A2A2A2
   menu $mwin.fr6.btn.m -tearoff false -bg $appbg -fg $appfg
   radiobutton $mwin.fr7.rad  -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg #A2A2A2 -bg $appbg \
      -activebackground $appbg -activeforeground #A2A2A2 \
      -variable msrcopt -value 2 -text "Transliterator window" -width 25 -anchor w
   menubutton $mwin.fr7.btn -text "Select window" -height 1 -width 15 \
      -relief raised -menu $mwin.fr7.btn.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg \
      -state disabled -disabledforeground #A2A2A2
   menu $mwin.fr7.btn.m -tearoff false -bg $appbg -fg $appfg
   radiobutton $mwin.fr8.rad  -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg #A2A2A2 -bg $appbg \
      -activebackground $appbg -activeforeground #A2A2A2 \
      -variable msrcopt -value 3 -text "Edited mail in read mail window" -anchor w
   button $mwin.frA.send -text "Send" -relief raised -command "sendThisMail" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0
   button $mwin.frA.close -text "Close" -relief raised -command "destroy $mwin" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg -underline 0
   label $mwin.frA.space -text "" -fg $appfg -bg $appbg -relief flat

   pack $mwin.fr1.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $mwin.fr1.ent -padx 5 -pady 5
   pack $mwin.fr2.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $mwin.fr2.ent -padx 5 -pady 5
   pack $mwin.fr3.lbl $mwin.fr3.btn -padx 5 -pady 5 -expand no -side left
   pack $mwin.fr4.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $mwin.fr5.rad -expand no -side left -padx 5 -pady 5
   pack $mwin.fr5.ent -expand yes -fill x -side left -padx 5 -pady 5
   pack $mwin.fr5.btn -expand no -side left -padx 5 -pady 5
   pack $mwin.fr6.rad -expand no -side left -padx 5 -pady 5
   pack $mwin.fr6.btn -expand yes -fill x -side left -padx 5 -pady 5
   pack $mwin.fr7.rad -expand no -side left -padx 5 -pady 5
   pack $mwin.fr7.btn -expand yes -fill x -side left -padx 5 -pady 5
   pack $mwin.fr8.rad -expand no -side left -padx 5 -pady 5
   pack $mwin.frA.send -padx 5 -pady 5 -expand no -side left
   pack $mwin.frA.space -padx 5 -pady 5 -expand yes -fill x -side left
   pack $mwin.frA.close -padx 5 -pady 5 -expand no -side left
   pack $mwin.fr1 $mwin.fr2 -expand yes -fill x
   pack $mwin.fr3 -expand no
   pack $mwin.fr4 $mwin.fr5 $mwin.fr6 $mwin.fr7 $mwin.fr8 -expand yes -fill x
   pack $mwin.frA -expand yes -fill x

   mupdateMenus

   if {$option == 0} {
      if {$msrcopt == 0} {
         $mwin.fr5.btn config -state active
         $mwin.fr5.ent config -state normal -fg $appfg
         $mwin.fr5.rad config -fg $appfg -activeforeground $appfg
      } elseif {$msrcopt == 1} {
         $mwin.fr6.btn config -state active
         $mwin.fr6.rad config -fg $appfg -activeforeground $appfg
      } elseif {$msrcopt == 2} {
         $mwin.fr7.btn config -state active
         $mwin.fr7.rad config -fg $appfg -activeforeground $appfg
      } elseif {$msrcopt == 3} {
         $mwin.fr8.rad config -fg $appfg -activeforeground $appfg
      }
   } elseif {$option == 1} {
      $mwin.fr6.btn config -state active
      $mwin.fr6.rad config -text "Main window $myid"
      $mwin.fr6.rad config -fg $appfg -activeforeground $appfg
      set mtwin $myid
      set msrcopt 1
   } elseif {$option == 2} {
      $mwin.fr7.btn config -state active
      $mwin.fr7.rad config -text "Transliterator window $myid"
      $mwin.fr7.rad config -fg $appfg -activeforeground $appfg
      set rmtwin "$myid"
      set msrcopt 2
   } elseif {$option == 3} {
      $mwin.fr8.rad config -fg $appfg -activeforeground $appfg
      set msrcopt 3
   }

   bind $mwin.fr5.rad <ButtonPress-1> "
      $mwin.fr5.rad config -fg $appfg -activeforeground $appfg
      $mwin.fr5.btn config -state active
      $mwin.fr5.ent config -state normal -fg $appfg
      $mwin.fr6.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr6.btn config -state disabled
      $mwin.fr7.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr7.btn config -state disabled
      $mwin.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
   "
   bind $mwin.fr6.rad <ButtonPress-1> "
      $mwin.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr5.btn config -state disabled
      $mwin.fr5.ent config -state disabled -fg #A2A2A2
      $mwin.fr6.rad config -fg $appfg -activeforeground $appfg
      $mwin.fr6.btn config -state active
      $mwin.fr7.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr7.btn config -state disabled
      $mwin.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
   "
   bind $mwin.fr7.rad <ButtonPress-1> "
      $mwin.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr5.btn config -state disabled
      $mwin.fr5.ent config -state disabled -fg #A2A2A2
      $mwin.fr6.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      $mwin.fr6.btn config -state disabled
      $mwin.fr7.rad config -fg $appfg -activeforeground $appfg
      $mwin.fr7.btn config -state active
      $mwin.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
   "
   bind $mwin.fr8.rad <ButtonPress-1> {
      .sendmail.fr5.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      .sendmail.fr5.btn config -state disabled
      .sendmail.fr5.ent config -state disabled -fg #A2A2A2
      .sendmail.fr6.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      .sendmail.fr6.btn config -state disabled
      .sendmail.fr7.rad config -fg #A2A2A2 -activeforeground #A2A2A2
      .sendmail.fr7.btn config -state disabled
      if {[winfo exists .readmail]} {
         .sendmail.fr8.rad config -fg $appfg -activeforeground $appfg
         if {![string compare $mailEditMode "off"]} {editMail}
      } else {
         set msrcopt -1
         .sendmail.fr8.rad config -fg #A2A2A2 -activeforeground #A2A2A2
         break
      }
   }

   bind $mwin.fr1.ent <Return> "focus $mwin.fr2.ent"
   bind $mwin.fr2.ent <Return> "focus $mwin.fr1.ent"
   bind $mwin <Alt-s> "$mwin.frA.send invoke"
   bind $mwin <Alt-S> "$mwin.frA.send invoke"
   bind $mwin <Alt-c> "$mwin.frA.close invoke; break"
   bind $mwin <Alt-C> "$mwin.frA.close invoke; break"
   bind $mwin <Escape> "$mwin.frA.close invoke; break"
}

proc mupdateMenus { } {
   global mavail ravail mtwin rmtwin

   .sendmail.fr6.btn.m delete 0 last
   .sendmail.fr7.btn.m delete 0 last
   for {set i 1} {$i <= $mavail} {incr i 1} {
      if {[winfo exists .main$i]} {
         .sendmail.fr6.btn.m add command -label "Main window $i" \
            -command ".sendmail.fr6.rad config -text {Main window $i}; set mtwin {$i}"
      }
   }
   for {set i 1} {$i <= $ravail} {incr i 1} {
      if {[winfo exists .roman$i]} {
         .sendmail.fr7.btn.m add command -label "Transliterator window $i" \
            -command ".sendmail.fr7.rad config -text {Transliterator window $i}; set rmtwin {$i}"
      }
   }
   set radtxt [.sendmail.fr6.rad cget -text]
   set twin [string range $radtxt 12 [expr [string length $radtxt] - 1]]
   if {([string length $twin] > 0) && (![winfo exists .main$twin])} {
      set mtwin 0
      .sendmail.fr6.rad config -text "Main window"
   }
   set radtxt [.sendmail.fr7.rad cget -text]
   set twin [string range $radtxt 22 [expr [string length $radtxt] - 1]]
   if {([string length $twin] > 0) && (![winfo exists .roman$twin])} {
      set rmtwin 0
      .sendmail.fr7.rad config -text "Transliterator window"
   }
}

proc sendThisMail { } {
   global bwmaildir mailcmd mimen mimed uun uud
   global msrcopt mtwin rmtwin mfname mailEditMode

   if {![file exists $bwmaildir]} {
      exec mkdir $bwmaildir
      exec chmod 700 $bwmaildir
   }
   if {!([file exists $bwmaildir] && [file isdirectory $bwmaildir] && [file writable $bwmaildir])} {
      if {$msrcopt == 1} { errmsg $mtwin "Unable to access mail directory $bwmaildir" }
      if {$msrcopt == 2} { errmsg2 $rmtwin "Unable to access mail directory $bwmaildir" }
      return
   }

   set fno 1
   while {[file exists $bwmaildir/raw.$fno]} { incr fno 1 }

   if {$msrcopt == 0} {
      if {[string length $mfname] == 0} { return }
      if {[file exists $mfname] && [file isfile $mfname] && [file readable $mfname]} {
         exec cp $mfname $bwmaildir/raw.$fno
      } else { return }
   } elseif {$msrcopt == 1} {
      if {$mtwin <= 0} { return }
      if {![winfo exists ".main$mtwin"]} { return }
      set t [.main$mtwin.mainfr.editfr.textarea get 1.0 end]
      set rawfile [open $bwmaildir/raw.$fno w]
      puts -nonewline $rawfile $t
      close $rawfile
   } elseif {$msrcopt == 2} {
      if {$rmtwin <= 0} { return }
      if {![winfo exists ".roman$rmtwin"]} { return }
      set t [.roman$rmtwin.mainfr.editfr.textarea get 1.0 end]
      set rawfile [open $bwmaildir/raw.$fno w]
      puts -nonewline $rawfile $t
      close $rawfile
   } elseif {$msrcopt == 3} {
      if {![winfo exists .readmail]} {return}
      if {![string compare $mailEditMode "off"]} {return}
      set t [.readmail.dpyfr.textfr.t get 1.0 end]
      set rawfile [open $bwmaildir/raw.$fno w]
      puts -nonewline $rawfile $t
      close $rawfile
   } else { return }

   set mailto [.sendmail.fr1.ent get]
   set mailsub [.sendmail.fr2.ent get]
   set enctype [.sendmail.fr3.btn cget -text]
   if {![string compare $enctype "Plain text"]} {
      exec cp $bwmaildir/raw.$fno $bwmaildir/snd.$fno
   } elseif {![string compare $enctype "MIME encoding"]} {
      regsub -all "%f" $mimen $bwmaildir/raw.$fno enccmd
      set t [eval exec $enccmd]
      set sndfile [open $bwmaildir/snd.$fno w]
      puts $sndfile $t
      close $sndfile
   } elseif {![string compare $enctype "uuencode"]} {
      regsub -all "%f" $uun $bwmaildir/raw.$fno enccmd
      set t [eval exec $enccmd]
      set sndfile [open $bwmaildir/snd.$fno w]
      puts $sndfile $t
      close $sndfile
   } elseif {![string compare $enctype "bwencode"]} {
      if {$msrcopt == 1} {
         bwenc $bwmaildir/raw.$fno $bwmaildir/snd.$fno 0
      } else {
         bwenc $bwmaildir/raw.$fno $bwmaildir/snd.$fno 1
      }
   }
   regsub -all "%f" $mailcmd  $bwmaildir/snd.$fno emc
   regsub -all "%s" $emc "\"$mailsub\"" emc
   regsub -all "%r" $emc "\"$mailto\"" emc
   set mailto [string trim $mailto]
   if {[string length $mailto] > 0} {
      eval exec $emc
   } else {
      if {$msrcopt == 1} { errmsg $mtwin "No recipient given" }
      if {$msrcopt == 2} { errmsg2 $rmtwin "No recipient given" }
   }
}

proc hexdigit { decimal } {
   if { ($decimal < 0) || ($decimal >= 16) } {
      return "?";
   }
   if { $decimal < 10 } { return "$decimal" }
   if { $decimal == 10 } { return "A" }
   if { $decimal == 11 } { return "B" }
   if { $decimal == 12 } { return "C" }
   if { $decimal == 13 } { return "D" }
   if { $decimal == 14 } { return "E" }
   return "F";
}

proc bwenc { inf outf option } {
   global customfontno customfid mtwin

   set f [open $inf r]
   set t [read $f]
   close $f
   set f [open $outf w]
   set tt "begin bwenc\n$option\n"
   set len [string length $t]
   for {set i 0} {$i < $len} {incr i 1} {
      set nextch [string range $t $i $i]
      if {![string compare $nextch "\n"]} {
         set tt "$tt\n"
      } else {
         scan $nextch "%c" asciival
         set tt "$tt[hexdigit [expr $asciival / 16]][hexdigit [expr $asciival % 16]]"
      }
   }
   puts $f $tt
   puts $f "end bwenc"
   if {($option == 0)} {
      set mwin ".main$mtwin"
      foreach tagname { ultag suptag supsuptag subsuptag subtag subsubtag supsubtag english } {
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} { puts $f "$tagname\t: $tagranges" }
      }
      foreach point {100 120 150 180 210 250 300 360} {
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges bengali${point}o ]
         if {[llength $tagranges] > 0} { puts $f "bengali${point}o\t: $tagranges" }
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges bengali${point}r ]
         if {[llength $tagranges] > 0} { puts $f "bengali${point}r\t: $tagranges" }
      }
      for {set i 0} {$i < $customfontno($mtwin)} {incr i 1} {
         set tagname customftag$i
         set tagranges [$mwin.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} {
            set fid $customfid("$mtwin:$i")
            puts $f "customfont\t: $fid\t$tagranges"
         }
      }
   }
   close $f
}

proc readBW { option {myid 0} {fn ""} } {
   global dirtybit rdirtybit

   if {![string compare $fn ""]} {
      set fn [getFileName "bwedit: read bwencoded file"]
   }
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         if {$option == 1} {
            errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         } elseif {$option == 2} {
            errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         }
         return
      }
      if {![file isfile $fn]} {
         if {$option == 1} {
            errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         } elseif {$option == 2} {
            errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         }
         return
      }
      set f [open $fn r]
      set status 0
      set x ""
      while { [gets $f line] >= 0 } {
         switch -exact $status {
            "0" {
               if {![string compare $line "begin bwenc"]} {set status 1}
            }
            "1" {
               set status 2
               if {![string compare $line "0"]} {incr status 2}
            }
            "2" {
               if {![string compare $line "end bwenc"]} {
                  if {($option == 0) || ($option == 1)} { set myid [newRoman] }
                  set rwin ".roman$myid"
                  saveRomanConfirm $myid; if ($rdirtybit($myid)) { return }
                  $rwin.mainfr.editfr.textarea delete 1.0 end
                  $rwin.mainfr.editfr.textarea insert 1.0 $x
                  $rwin.mainfr.editfr.textarea see insert
                  set rdirtybit($myid) 1
                  set rfname($myid) ""
                  setbnstr $myid
                  set status 3
               } else {
                  set len [expr [string length $line] - 1]
                  for {set i 0} {$i < $len} {incr i 2} {
                     set x "$x[hextochar [string range $line $i [expr $i + 1]]]"
                  }
                  set x "$x\n"
               }
            }
            "3" { }
            "4" {
               if {![string compare $line "end bwenc"]} {
                  if {($option == 0) || ($option == 2)} { set myid [newMain] }
                  set mwin ".main$myid"
                  saveConfirm $myid; if ($dirtybit($myid)) { return }
                  $mwin.mainfr.editfr.textarea delete 1.0 end
                  $mwin.mainfr.editfr.textarea insert 1.0 $x
                  $mwin.mainfr.editfr.textarea see insert
                  set dirtybit($myid) 1
                  set fname($myid) ""
                  set status 5
               } else {
                  set len [expr [string length $line] - 1]
                  for {set i 0} {$i < $len} {incr i 2} {
                     set x "$x[hextochar [string range $line $i [expr $i + 1]]]"
                  }
                  set x "$x\n"
               }
            }
            "5" {
               addTag $myid $line
            }
         }
      }
      if {$status >= 4} { $mwin.mainfr.editfr.textarea see insert }
   }
}

proc hextochar { hexval } {
   set hhex [string range $hexval 0 0]
   set lhex [string range $hexval 1 1]
   switch -exact $hhex {
      "A" { set hval 10 }
      "B" { set hval 11 }
      "C" { set hval 12 }
      "D" { set hval 13 }
      "E" { set hval 14 }
      "F" { set hval 15 }
      default { set hval $hhex }
   }
   switch -exact $lhex {
      "A" { set lval 10 }
      "B" { set lval 11 }
      "C" { set lval 12 }
      "D" { set lval 13 }
      "E" { set lval 14 }
      "F" { set lval 15 }
      default { set lval $lhex }
   }
   return [format "%c" [expr 16 * $hval + $lval]]
}

proc readMIME { option { myid 0 } { fn "" } } {
   global mimed dirtybit rdirtybit

   if {$option == 1} {
      saveConfirm $myid
      if {$dirtybit($myid)} { return }
   } elseif {$option == 2} {
      saveRomanConfirm $myid
      if {$rdirtybit($myid)} { return }
   }

   if {![string compare $fn ""]} {
      set fn [getFileName "bwedit: read MIME encoded file"]
   }
   if {![string compare $fn ""]} { return }
   if {![file readable $fn]} {
      if {$option == 1} { errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission." }
      elseif {$option == 2} { errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission." }
      return
   }
   if {![file isfile $fn]} {
      if {$option == 1} { errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file." }
      elseif {$option == 2} { errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file." }
      return
   }

   if {$option == 0} {
      set myid [newMain]
      set twin ".main$myid"
      set dirtybit($myid) 1
   } elseif {$option == 1} {
      set twin ".main$myid"
      set dirtybit($myid) 1
      clearTextArea $myid
   } elseif {$option == 2} {
      set twin ".roman$myid"
      set rdirtybit($myid) 1
      rclearTextArea $myid
   } else { return }

   regsub -all "%f" $mimed $fn deccmd
   set x [eval exec $deccmd]
   $twin.mainfr.editfr.textarea insert 1.0 $x
   if {$option == 2} { setbnstr $myid }
   $twin.mainfr.editfr.textarea see insert
}

proc readUU { option { myid 0 } { fn "" } } {
   global uud dirtybit rdirtybit

   if {$option == 1} {
      saveConfirm $myid
      if {$dirtybit($myid)} { return }
   } elseif {$option == 2} {
      saveRomanConfirm $myid
      if {$rdirtybit($myid)} { return }
   }

   if {![string compare $fn ""]} {
      set fn [getFileName "bwedit: read uuencoded file"]
   }
   if {![string compare $fn ""]} { return }
   if {![file readable $fn]} {
      if {$option == 1} { errmsg $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission." }
      elseif {$option == 2} { errmsg2 $myid "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission." }
      return
   }
   if {![file isfile $fn]} {
      if {$option == 1} { errmsg $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file." }
      elseif {$option == 2} { errmsg2 $myid "ERROR:\nI cannot load the file. \"$fn\" is not a regular file." }
      return
   }

   if {$option == 0} {
      set myid [newMain]
      set twin ".main$myid"
      set dirtybit($myid) 1
   } elseif {$option == 1} {
      set twin ".main$myid"
      set dirtybit($myid) 1
      clearTextArea $myid
   } elseif {$option == 2} {
      set twin ".roman$myid"
      set rdirtybit($myid) 1
      rclearTextArea $myid
   } else { return }

   regsub -all "%f" $uud $fn deccmd
   set x [eval exec $deccmd]
   $twin.mainfr.editfr.textarea insert 1.0 $x
   if {$option == 2} { setbnstr $myid }
   $twin.mainfr.editfr.textarea see insert
}


############ Coordinator window ############
. config -bg $appbg

frame .toolfr -bg $appbg -relief raised -borderwidth 2

menubutton .toolfr.file -text "File" -height 1 -relief flat \
   -menu .toolfr.file.m -bg $appbg -fg $appfg \
   -activeforeground $appfg -activebackground $appbg \
   -highlightthickness 0
menu .toolfr.file.m -tearoff false -bg $appbg -fg $appfg
.toolfr.file.m add command -label "New main window" -accelerator "Alt+1" -command "newMain" -underline 0
.toolfr.file.m add command -label "Load file in main window" -accelerator "Alt+3" -command "loadMain" -underline 0
.toolfr.file.m add separator
.toolfr.file.m add command -label "New transliterator window" -accelerator "Alt+2" -command "newRoman" -underline 4
.toolfr.file.m add command -label "Load file in transliterator window" -accelerator "Alt+4" -command "loadRoman" -underline 1
.toolfr.file.m add separator
.toolfr.file.m add command -label "Read bwencoded file" -accelerator "Alt+5" -command "readBW 0" -underline 5
.toolfr.file.m add command -label "Read MIME encoded file" -accelerator "Alt+6" -command "readMIME 0" -underline 5
.toolfr.file.m add command -label "Read uuencoded file" -accelerator "Alt+7" -command "readUU 0" -underline 5
.toolfr.file.m add separator
.toolfr.file.m add command -label "Read mail" -accelerator "F9" -command "readMail" -underline 0
.toolfr.file.m add command -label "Send mail" -accelerator "Shift+F9" -command "sendMail 0" -underline 0
.toolfr.file.m add separator
.toolfr.file.m add command -label "Quit bwedit" -accelerator "Alt+Q" -command quitEditor -underline 0

menubutton .toolfr.option -text "Option" -height 1 -relief flat \
   -menu .toolfr.option.m -bg $appbg -fg $appfg \
   -activeforeground $appfg -activebackground $appbg \
   -highlightthickness 0
menu .toolfr.option.m -tearoff false -bg $appbg -fg $appfg
.toolfr.option.m add command -label "Select document font" -accelerator "Alt+D" -command "chooseBaseFont" -underline 7
.toolfr.option.m add separator
.toolfr.option.m add command -label "Edit main window options" -command "set opttype 1 ; editOptions 0" -underline 0
.toolfr.option.m add command -label "Edit transliterator window options" -command "set opttype 2 ; editOptions 0" -underline 5
.toolfr.option.m add command -label "Edit mail options" -command "set opttype 3 ; editOptions 0" -underline 5
.toolfr.option.m add separator
.toolfr.option.m add command -label "Save options" -command "saveOptions 0" -underline 0

menubutton .toolfr.help -text "Help" -height 1 -relief flat \
   -menu .toolfr.help.m -bg $appbg -fg $appfg \
   -activeforeground $appfg -activebackground $appbg \
   -highlightthickness 0
menu .toolfr.help.m -tearoff false -bg $appbg -fg $appfg
.toolfr.help.m add command -label "View keyboard map" -accelerator "Alt+K" -command "viewKbdMap" -underline 5
.toolfr.help.m add separator
.toolfr.help.m add command -label "About bwedit" -accelerator "F1" -command "helpWin" -underline 0
.toolfr.help.m add command -label "Roman-to-Bengali transliteration rules" -accelerator "Shift+F1" -command "helpWinRoman" -underline 0
.toolfr.help.m add command -label "Copyright notice" -command "copyInfo" -underline 0

label .toolfr.space -text "" -relief flat -borderwidth 0 -bg $appbg -fg $appfg

pack .toolfr.file -side left -padx 0 -pady 0
pack .toolfr.option -side left -padx 0 -pady 0
pack .toolfr.help -side left -padx 0 -pady 0
pack .toolfr.space -side left -expand yes -fill both

label .logo -image "bweditlogo" -relief flat -bg $appbg -fg $appfg -cursor hand2
bind .logo <Button-1> { copyInfo }

frame .btnfr -bg $appbg -relief flat
frame .btnfr.row1 -bg $appbg -relief flat
frame .btnfr.row2 -bg $appbg -relief flat
frame .btnfr.row3 -bg $appbg -relief flat
frame .btnfr.row4 -bg $appbg -relief flat
frame .btnfr.row5 -bg $appbg -relief flat

image create photo btnimg11 -file "$installdir/images/new1.gif"
button .btnfr.row1.b1 -image "btnimg11" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "newMain"
image create photo btnimg12 -file "$installdir/images/load1.gif"
button .btnfr.row1.b2 -image "btnimg12" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "loadMain"
image create photo btnimg13 -file "$installdir/images/option1.gif"
button .btnfr.row1.b3 -image "btnimg13" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "set opttype 1 ; editOptions 0"

image create photo btnimg21 -file "$installdir/images/new2.gif"
button .btnfr.row2.b1 -image "btnimg21" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "newRoman"
image create photo btnimg22 -file "$installdir/images/load2.gif"
button .btnfr.row2.b2 -image "btnimg22" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "loadRoman"
image create photo btnimg23 -file "$installdir/images/option2.gif"
button .btnfr.row2.b3 -image "btnimg23" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "set opttype 2 ; editOptions 0"

image create photo btnimg31 -file "$installdir/images/readBW.gif"
button .btnfr.row3.b1 -image "btnimg31" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "readBW 0"
image create photo btnimg32 -file "$installdir/images/readMIME.gif"
button .btnfr.row3.b2 -image "btnimg32" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "readMIME 0"
image create photo btnimg33 -file "$installdir/images/readUU.gif"
button .btnfr.row3.b3 -image "btnimg33" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "readUU 0"

image create photo btnimg41 -file "$installdir/images/mail.gif"
button .btnfr.row4.b1 -image "btnimg41" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "readMail"
image create photo btnimg42 -file "$installdir/images/option3.gif"
button .btnfr.row4.b2 -image "btnimg42" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "set opttype 3 ; editOptions 0"
image create photo btnimg43 -file "$installdir/images/font.gif"
button .btnfr.row4.b3 -image "btnimg43" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "chooseBaseFont"

image create photo btnimg51 -file "$installdir/images/kbdmap.gif"
button .btnfr.row5.b1 -image "btnimg51" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "viewKbdMap"
image create photo btnimg52 -file "$installdir/images/help1.gif"
button .btnfr.row5.b2 -image "btnimg52" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "helpWin"
image create photo btnimg53 -file "$installdir/images/help2.gif"
button .btnfr.row5.b3 -image "btnimg53" -relief raised -bg $btnbg \
   -borderwidth 3 -activebackground $btnbg -highlightthickness 0 \
   -command "helpWinRoman"

pack .btnfr.row1.b1 .btnfr.row1.b2 .btnfr.row1.b3 -side left -padx 6 -pady 0
pack .btnfr.row2.b1 .btnfr.row2.b2 .btnfr.row2.b3 -side left -padx 6 -pady 0
pack .btnfr.row3.b1 .btnfr.row3.b2 .btnfr.row3.b3 -side left -padx 6 -pady 0
pack .btnfr.row4.b1 .btnfr.row4.b2 .btnfr.row4.b3 -side left -padx 6 -pady 0
pack .btnfr.row5.b1 .btnfr.row5.b2 .btnfr.row5.b3 -side left -padx 6 -pady 0
pack .btnfr.row1 .btnfr.row2 .btnfr.row3 .btnfr.row4 .btnfr.row5 -side top -padx 0 -pady 6
pack .toolfr -side top -padx 0 -pady 0 -fill x
pack .logo -side top -padx 0 -pady 2
pack .btnfr -side top -padx 6 -pady 6

proc quitEditor {} {
   global mavail ravail dirtybit rdirtybit

   for {set i 1} {$i < $mavail} {incr i 1} {
      if { [winfo exists .main$i] } {
         saveConfirm $i
         if {$dirtybit($i) != 0} { return } else { destroy .main$i }
         refreshAllWinList
      }
   }

   for {set i 1} {$i < $ravail} {incr i 1} {
      if { [winfo exists .roman$i] } {
         saveRomanConfirm $i
         if {$rdirtybit($i) != 0} { return } else { destroy .roman$i }
         refreshAllWinList
      }
   }

   if {[winfo exists .kbdmap]} { destroy .kbdmap }
   if {[winfo exists .help]} { destroy .help }
   if {[winfo exists .rhelp]} { destroy .rhelp }
   if {[winfo exists .copyright]} { destroy .copyright }
   if {[winfo exists .option]} { destroy .option }
   if {[winfo exists .readmail]} { destroy .readmail }
   if {[winfo exists .sendmail]} { destroy .sendmail }

   destroy .
   exit 0
}

bind . <Alt-Key-1> {newMain}
bind . <Alt-Key-2> {newRoman}
bind . <Alt-Key-3> {loadMain}
bind . <Alt-Key-4> {loadRoman}
bind . <Alt-Key-5> {readBW 0}
bind . <Alt-Key-6> {readMIME 0}
bind . <Alt-Key-7> {readUU 0}
bind . <Alt-d> {chooseBaseFont}
bind . <Alt-D> {chooseBaseFont}
bind . <Alt-k> {viewKbdMap}
bind . <Alt-K> {viewKbdMap}
bind . <Alt-q> {quitEditor; break}
bind . <Alt-Q> {quitEditor; break}
bind . <F1> {helpWin}
bind . <Shift-F1> {helpWinRoman}
bind . <F9> {readMail}
bind . <Shift-F9> {sendMail 0}
bind . <F10> {postFileMenu; break}

proc postFileMenu { } {
   set posx [winfo x .]
   incr posx [winfo x .toolfr.file]
   set posy [winfo y .]
   incr posy [winfo y .toolfr.file]
   incr posy [winfo height .toolfr.file]
   .toolfr.file.m post $posx $posy
   .toolfr.file.m activate 0
   focus .toolfr.file.m
   grab set -global .toolfr.file.m
}

proc postOptionMenu { } {
   set posx [winfo x .]
   incr posx [winfo x .toolfr.option]
   set posy [winfo y .]
   incr posy [winfo y .toolfr.option]
   incr posy [winfo height .toolfr.option]
   .toolfr.option.m post $posx $posy
   .toolfr.option.m activate 0
   focus .toolfr.option.m
   grab set -global .toolfr.option.m
}

proc postHelpMenu { } {
   set posx [winfo x .]
   incr posx [winfo x .toolfr.help]
   set posy [winfo y .]
   incr posy [winfo y .toolfr.help]
   incr posy [winfo height .toolfr.help]
   .toolfr.help.m post $posx $posy
   .toolfr.help.m activate 0
   focus .toolfr.help.m
   grab set -global .toolfr.help.m
}

bind .toolfr.file.m <Right> { grab release .toolfr.file.m; .toolfr.file.m unpost; postOptionMenu; break}
bind .toolfr.option.m <Right> { grab release .toolfr.option.m; .toolfr.option.m unpost; postHelpMenu; break}
bind .toolfr.help.m <Right> { grab release .toolfr.help.m; .toolfr.help.m unpost; postFileMenu; break}
bind .toolfr.file.m <Left> { grab release .toolfr.file.m; .toolfr.file.m unpost; postHelpMenu; break}
bind .toolfr.option.m <Left> { grab release .toolfr.option.m; .toolfr.option.m unpost; postFileMenu; break}
bind .toolfr.help.m <Left> { grab release .toolfr.help.m; .toolfr.help.m unpost; postOptionMenu; break}

wm resizable . false false
wm title . "bwedit 2.2"

set globalb ""
proc showhint { row col msg } {
   global blnbg blnfg globalb dpyfont

   if {[winfo exists $globalb]} { destroy $globalb }

   set b [toplevel .bln]
   set globalb $b

   frame $b.f1 -bg $blnfg -height 1
   frame $b.f2 -bg $blnbg
   frame $b.f3 -bg $blnfg -height 1
   label $b.f2.l -text $msg -relief flat -fg $blnfg -bg $blnbg -font $dpyfont
   frame $b.f2.lb -bg $blnfg -width 1
   frame $b.f2.rb -bg $blnfg -width 1
   pack $b.f2.lb $b.f2.l $b.f2.rb -expand yes -fill both -side left
   pack $b.f1 $b.f2 $b.f3 -expand yes -fill both

   set x [winfo x .]
   set y [winfo y .]
   incr x [winfo x .btnfr]
   incr y [winfo y .btnfr]
   incr x [winfo x .btnfr.row$row]
   incr y [winfo y .btnfr.row$row]
   incr x [winfo x .btnfr.row$row.b$col]
   incr y [winfo y .btnfr.row$row.b$col]
   incr x [expr [winfo width .btnfr.row$row.b$col] / 2]
   incr y [winfo height .btnfr.row$row.b$col]
   incr y 2

   set wd [winfo reqwidth $b.f2.l]
   incr wd 2
   set ht [winfo reqheight $b.f2.l]
   incr ht 2
   wm geometry $b "${wd}x${ht}+$x+$y"
   wm overrideredirect $b true
}

proc hidehint { } {
   global globalb

   if [winfo exists $globalb] {destroy $globalb}
}

proc addballoon { i j msg } {
   bind .btnfr.row$i.b$j <Enter> "showhint $i $j \"$msg\""
   bind .btnfr.row$i.b$j <Leave> {hidehint}
}

addballoon 1 1 "New main window"
addballoon 1 2 "Open file in main window"
addballoon 1 3 "Edit main window options"

addballoon 2 1 "New transliterator window"
addballoon 2 2 "Open file in transliterator window"
addballoon 2 3 "Edit transliterator window options"

addballoon 3 1 "Read BW encoded text"
addballoon 3 2 "Read MIME encoded text"
addballoon 3 3 "Read UU encoded text"

addballoon 4 1 "Read and send e-mail"
addballoon 4 2 "Edit mail options"
addballoon 4 3 "Select document font"

addballoon 5 1 "Show keyboard map"
addballoon 5 2 "Launch help window"
addballoon 5 3 "Roman-to-Bengali conversion rules"

# Handle the command line arguments

proc printerrmsg { option } {
   puts "No argument specified for option \"$option\""
   puts "Type \"bwedit -h\" to list the command line options"
   exit
}

proc printVersion { } {
   puts "bwedit: Version 2.2"
   puts "Copyright 1998 - 1999 by Abhijit Das (abhij@csa.iisc.ernet.in)"
   exit
}

proc printHelp { } {
   puts "Usage: bwedit \[options\]\nThe options are"
   puts "   -m <file>      Open <file> in main window"
   puts "   -t <file>      Open <file> in transliterator window"
   puts "   -nm <num>      Open <num> blank main windows (Maximum 5)"
   puts "   -nt <num>      Open <num> blank transliterator windows (Maximum 5)"
   puts "   -bw <file>     Open bwencoded <file>"
   puts "   -uu <file>     Open uuencoded <file>"
   puts "   -mime <file>   Open MIME encoded <file>"
   puts "   -e <file>      Read Roman-to-Bengali encoding from <file>"
   puts "   -rm            Open read mail window"
   puts "   -k             Open Keyboard map window"
   puts "   -f <size>      Set default font size to <size> points"
   puts "   -hl <num>      Set help level (0, 1, 2 or 3)"
   puts "   -h             Print this help message and quit"
   puts "   -v             Print version info and quit"
   destroy .
   exit
}

set mflist [list]
set tflist [list]
set bwlist [list]
set uulist [list]
set mimelist [list]
set helplvl 0
set dfltptsize $ptsize

set narg [llength $argv]
if {![string compare [lindex $argv 0] "-h"]} {
   printHelp
}
for {set i 0} {$i < $narg} {incr i 1} {
   set thisarg [lindex $argv $i]
   if {![string compare $thisarg "-h"]} {
      printHelp
   } elseif {![string compare $thisarg "-v"]} {
      printVersion
   } elseif {![string compare $thisarg "-m"]} {
      if {$i == $narg - 1} { printerrmsg "-m" }
      incr i 1
      lappend mflist [lindex $argv $i]
   } elseif {![string compare $thisarg "-t"]} {
      if {$i == $narg - 1} { printerrmsg "-t" }
      incr i 1
      lappend tflist [lindex $argv $i]
   } elseif {![string compare $thisarg "-nm"]} {
      if {$i == $narg - 1} { printerrmsg "-nm" }
      incr i 1
      set mwno [lindex $argv $i]
   } elseif {![string compare $thisarg "-nt"]} {
      if {$i == $narg - 1} { printerrmsg "-nt" }
      incr i 1
      set twno [lindex $argv $i]
   } elseif {![string compare $thisarg "-e"]} {
      if {$i == $narg - 1} { printerrmsg "-e" }
      incr i 1
      set readencopt 2
      set encfnm [lindex $argv $i]
   } elseif {![string compare $thisarg "-bw"]} {
      if {$i == $narg - 1} { printerrmsg "-bw" }
      incr i 1
      lappend bwlist [lindex $argv $i]
   } elseif {![string compare $thisarg "-uu"]} {
      if {$i == $narg - 1} { printerrmsg "-uu" }
      incr i 1
      lappend uulist [lindex $argv $i]
   } elseif {![string compare $thisarg "-mime"]} {
      if {$i == $narg - 1} { printerrmsg "-mime" }
      incr i 1
      lappend mimelist [lindex $argv $i]
   } elseif {![string compare $thisarg "-f"]} {
      if {$i == $narg - 1} { printerrmsg "-f" }
      incr i 1
      set ptsize [lindex $argv $i]
   } elseif {![string compare $thisarg "-rm"]} {
      set openmail 1
   } elseif {![string compare $thisarg "-k"]} {
      set openkbdmap 1
   } elseif {![string compare $thisarg "-hl"]} {
      if {$i == $narg - 1} { printerrmsg "-hl" }
      incr i 1
      set helplvl [lindex $argv $i]
   } else {
      if {![string compare "-" [string range $thisarg 0 0]]} {
         puts "Unknown option: [lindex $argv $i]"
         puts "Type \"bwedit -h\" to list the command line options"
         exit
      }
      lappend mflist [lindex $argv $i]
   }
}

if {($ptsize != 100) && ($ptsize != 120) && ($ptsize != 150) && ($ptsize != 180) && ($ptsize != 210) && ($ptsize != 250) && ($ptsize != 300) && ($ptsize != 360) } {
   puts "Font size should be one of 100, 120, 150, 180, 210, 250, 300 and 360"
   set ptsize $dfltptsize
}
switch -exact $ptsize {
   100 {set textsp3 4; set off1 5; set off2 8; set off3 3;}
   120 {set textsp3 5; set off1 6; set off2 9; set off3 3;}
   150 {set textsp3 6; set off1 7; set off2 12; set off3 4;}
   180 {set textsp3 7; set off1 9; set off2 14; set off3 5;}
   210 {set textsp3 8; set off1 10; set off2 16; set off3 6;}
   250 {set textsp3 10; set off1 12; set off2 20; set off3 7;}
   300 {set textsp3 12; set off1 15; set off2 24; set off3 9;}
   360 {set textsp3 15; set off1 18; set off2 28; set off3 10;}
   default {set textsp3 5; set off1 6; set off2 9; set off3 3;}
}
for {set i 0} {$i < [llength $mflist]} {incr i 1} {
   loadMain2 [lindex $mflist $i]
}
for {set i 0} {$i < [llength $tflist]} {incr i 1} {
   loadRoman2 [lindex $tflist $i]
}
if {$readencopt == 2} { readEnc 2 $encfnm } else { readEnc }
if {$mwno > 5} {set mwno 5}
if {$twno > 5} {set twno 5}
for {set i 0} {$i < $mwno} {incr i 1} { newMain }
for {set i 0} {$i < $twno} {incr i 1} { newRoman }
for {set i 0} {$i < [llength $bwlist]} {incr i 1} {
   readBW 0 -1 [lindex $bwlist $i]
}
for {set i 0} {$i < [llength $uulist]} {incr i 1} {
   readUU 0 -1 [lindex $uulist $i]
}
for {set i 0} {$i < [llength $mimelist]} {incr i 1} {
   readMIME 0 -1 [lindex $mimelist $i]
}
if {$openmail} { readMail }
if {$openkbdmap} { viewKbdMap }

switch -exact $helplvl {
   1 { helpWin }
   2 { helpWinRoman }
   3 { helpWin; helpWinRoman }
}

proc searchExpr { myid {wintype main} } {
   global appbg appfg btnbg btnfg hdrfont dpyfont dirtybit
   global srchdirn srchcase findok sstring rstring lsidx sasciimode sascin rasciimode rascin

   if {[winfo exists .find]} {return}

   set sstring ""
   set rstring ""
   set findwin [toplevel .find]
   .find config -bg $appbg
   label .find.h -font $hdrfont -relief flat -fg $appfg -bg $appbg \
      -text "Search in transliterator window $myid"
   if {![string compare $wintype "main"]} {
      .find.h config -text "Search in main window $myid"
   }
   frame .find.s -bg $appbg -relief flat
   label .find.s.l -font $dpyfont -relief flat -fg $appfg -bg $appbg \
      -text "Search string  " -anchor e
   entry .find.s.e -textvariable sstring -bg #ddddaa -fg #000000 -width 50 \
      -selectforeground #ddddaa -selectbackground #000000 -selectborderwidth 0
   if {![string compare $wintype "main"]} {
      .find.s.e config -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific" -width 40
   }
   frame .find.r -bg $appbg -relief flat
   label .find.r.l -font $dpyfont -relief flat -fg $appfg -bg $appbg \
      -text "Replace string  " -anchor e
   entry .find.r.e -textvariable rstring -bg #ddddaa -fg #000000 -width 50 \
      -selectforeground #ddddaa -selectbackground #000000 -selectborderwidth 0
   if {![string compare $wintype "main"]} {
      .find.r.e config -font "-*-bengali-medium-r-*-*-*-120-*-*-*-*-*-fontspecific" -width 40
   }
   frame .find.c -bg $appbg -relief flat
   checkbutton .find.c.b -text " Search backward " -relief ridge \
      -onvalue "-back" -offvalue "-forw" -variable "srchdirn" \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg
   set srchdirn "-forw"
   checkbutton .find.c.c -text " Case sensitive " -relief ridge \
      -onvalue "1" -offvalue "0" -variable "srchcase" \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg
   set srchcase 1
   frame .find.b -bg $appbg -relief flat
   button .find.b.l -text "Clear" -relief raised -command {
         set sstring ""
         set rstring ""
      } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg \
      -underline 1
   button .find.b.s -text "Search" -relief raised -command "doSearch $myid $wintype" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg \
      -underline 0
   button .find.b.r -text "Replace" -relief raised -command "doReplace $myid $wintype" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg \
      -underline 0
   button .find.b.g -text "Replace all" -relief raised -command "doGlobalReplace $myid $wintype" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg \
      -underline 8
   button .find.b.c -text "Close" -relief raised -command { set findok 1 } \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg \
      -underline 0

   pack .find.h -padx 5 -pady 5 -expand yes -fill x
   pack .find.s.l -expand yes -fill x -anchor e -padx 0 -side left
   pack .find.s.e -expand no -padx 0 -side left
   pack .find.r.l -expand yes -fill x -anchor e -padx 0 -side left
   pack .find.r.e -expand no -padx 0 -side left
   pack .find.s .find.r -expand yes -fill x -padx 5 -pady 5
   pack .find.c.b -expand no -padx 10 -pady 0 -side left
   if {![string compare "roman" $wintype]} {
      pack .find.c.c -expand no -padx 10 -pady 0 -side left
   }
   pack .find.c -expand no -padx 5 -pady 5
   pack .find.b.l .find.b.s .find.b.r .find.b.g .find.b.c -padx 10 -pady 0 -side left
   pack .find.b -expand no -padx 5 -pady 5

   set lsidx ""

   bind $findwin <Alt-A> {.find.b.g invoke}
   bind $findwin <Alt-C> {.find.b.c invoke}
   bind $findwin <Alt-L> {.find.b.l invoke}
   bind $findwin <Alt-R> {.find.b.r invoke}
   bind $findwin <Alt-S> {.find.b.s invoke}
   bind $findwin <Alt-a> {.find.b.g invoke}
   bind $findwin <Alt-c> {.find.b.c invoke}
   bind $findwin <Alt-l> {.find.b.l invoke}
   bind $findwin <Alt-r> {.find.b.r invoke}
   bind $findwin <Alt-s> {.find.b.s invoke}
   bind .find.s.e <Return> {focus .find.r.e}
   bind .find.r.e <Return> {focus .find.s.e}

   if {![string compare $wintype "main"]} {
      bind .find.s.e <Control-a> ".find.s.e insert insert {a}; break"
      bind .find.s.e <Control-A> ".find.s.e insert insert {aA}; break"
      bind .find.s.e <Control-i> ".find.s.e insert insert [format %c 1]; break"
      bind .find.s.e <Control-I> ".find.s.e insert insert [format %c 2]; break"
      bind .find.s.e <Control-u> ".find.s.e insert insert [format %c 3]; break"
      bind .find.s.e <Control-U> ".find.s.e insert insert [format %c 4]; break"
      bind .find.s.e <Control-R> ".find.s.e insert insert [format %c 5]; break"
      bind .find.s.e <Control-e> ".find.s.e insert insert [format %c 6]; break"
      bind .find.s.e <Control-E> ".find.s.e insert insert [format %c 7]; break"
      bind .find.s.e <Control-o> ".find.s.e insert insert [format %c 8]; break"
      bind .find.s.e <Control-O> ".find.s.e insert insert {o}; break"
      bind .find.s.e <Control-y> ".find.s.e insert insert [format %c 14]; break"
      bind .find.s.e <Control-r> ".find.s.e insert insert [format %c 15]; break"

      bind .find.r.e <Control-a> ".find.r.e insert insert {a}; break"
      bind .find.r.e <Control-A> ".find.r.e insert insert {aA}; break"
      bind .find.r.e <Control-i> ".find.r.e insert insert [format %c 1]; break"
      bind .find.r.e <Control-I> ".find.r.e insert insert [format %c 2]; break"
      bind .find.r.e <Control-u> ".find.r.e insert insert [format %c 3]; break"
      bind .find.r.e <Control-U> ".find.r.e insert insert [format %c 4]; break"
      bind .find.r.e <Control-R> ".find.r.e insert insert [format %c 5]; break"
      bind .find.r.e <Control-e> ".find.r.e insert insert [format %c 6]; break"
      bind .find.r.e <Control-E> ".find.r.e insert insert [format %c 7]; break"
      bind .find.r.e <Control-o> ".find.r.e insert insert [format %c 8]; break"
      bind .find.r.e <Control-O> ".find.r.e insert insert {o}; break"
      bind .find.r.e <Control-y> ".find.r.e insert insert [format %c 14]; break"
      bind .find.r.e <Control-r> ".find.r.e insert insert [format %c 15]; break"

      set sasciimode 0
      set sascin ""
      for {set i 0} {$i < 10} {incr i 1} {
         bind .find.s.e <Key-$i> {
            if {$sasciimode} {set sascin "${sascin}%A"; break }
         }
      }
      bind .find.s.e <Escape> {sprocEsc}
      bind .find.s.e <Any-Key> {if {$sasciimode} {set sasciimode 0; set sascin ""}}

      set rasciimode 0
      set rascin ""
      for {set i 0} {$i < 10} {incr i 1} {
         bind .find.r.e <Key-$i> {
            if {$rasciimode} {set rascin "${rascin}%A"; break }
         }
      }
      bind .find.r.e <Escape> {rprocEsc}
      bind .find.r.e <Any-Key> {if {$rasciimode} {set rasciimode 0; set rascin ""}}
   }

   wm resizable $findwin false false
   wm title $findwin "bwedit: search"
   focus .find.s.e

   grab $findwin
   tkwait variable findok
   grab release $findwin
   destroy $findwin
}

proc sprocEsc { } {
   global sasciimode sascin

   if {($sasciimode == 1) && ([string length $sascin] > 0)} {
      .find.s.e insert insert [format "%c" $sascin]
      set sascin ""
   }
   set sasciimode [expr 1 - $sasciimode]
}

proc rprocEsc { } {
   global rasciimode rascin

   if {($rasciimode == 1) && ([string length $rascin] > 0)} {
      .find.r.e insert insert [format "%c" $rascin]
      set rascin ""
   }
   set rasciimode [expr 1 - $rasciimode]
}

proc doSearch { myid wintype } {
   global sstring rstring lsidx lsnum srchdirn srchcase

   if {[string length $sstring] == 0} {return}
   if {[string length $lsidx] == 0} {
      set lsidx "1.0"
   } elseif {![string compare $srchdirn "-forw"]} {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea index "$lsidx + 1 char"]
   } else {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea index "$lsidx"]
   }
   if {$srchcase} {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea search $srchdirn $sstring $lsidx]
   } else {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea search $srchdirn -nocase $sstring $lsidx]
   }
   if {[string length $lsidx] != 0} {
      .$wintype$myid.mainfr.editfr.textarea tag remove sel 1.0 end
      .$wintype$myid.mainfr.editfr.textarea tag add sel $lsidx "$lsidx + [string length $sstring] chars"
      .$wintype$myid.mainfr.editfr.textarea see $lsidx
   } else {
      if {![string compare $wintype "main"]} {
         errmsg $myid "     Search failed     "
      } else {
         errmsg2 $myid "     Search failed     "
      }
      grab .find
   }
}

proc doReplace { myid wintype } {
   global sstring rstring lsidx lsnum srchdirn srchcase dirtybit rdirtybit

   if {[string length $sstring] == 0} {return}
   if {[string length $lsidx] == 0} {
      set lsidx "1.0"
   } elseif {![string compare $srchdirn "-forw"]} {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea index "$lsidx + 1 char"]
   } else {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea index "$lsidx"]
   }
   if {$srchcase} {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea search $srchdirn $sstring $lsidx]
   } else {
      set lsidx [.$wintype$myid.mainfr.editfr.textarea search $srchdirn -nocase $sstring $lsidx]
   }
   if {[string length $lsidx] != 0} {
      .$wintype$myid.mainfr.editfr.textarea tag remove sel 1.0 end
      .$wintype$myid.mainfr.editfr.textarea delete $lsidx "$lsidx + [string length $sstring] chars"
      .$wintype$myid.mainfr.editfr.textarea insert $lsidx $rstring
      .$wintype$myid.mainfr.editfr.textarea tag add sel $lsidx "$lsidx + [string length $rstring] chars"
      .$wintype$myid.mainfr.editfr.textarea see $lsidx
      if {![string compare $wintype "main"]} {
         incr dirtybit($myid)
      } else {
         incr rdirtybit($myid)
      }
   } else {
      if {![string compare $wintype "main"]} {
         errmsg $myid "     Search failed     "
      } else {
         errmsg2 $myid "     Search failed     "
      }
      grab .find
   }
}

proc doGlobalReplace { myid wintype } {
   global sstring rstring lsidx lsnum srchcase dirtybit rdirtybit

   if {[string length $sstring] == 0} {return}
   set lsidx 1.0
   set nrepl 0
   .$wintype$myid.mainfr.editfr.textarea tag remove sel 1.0 end
   while {[string length $lsidx] > 0} {
      if {$srchcase} {
         set lsidx [.$wintype$myid.mainfr.editfr.textarea search $sstring $lsidx end]
      } else {
         set lsidx [.$wintype$myid.mainfr.editfr.textarea search -nocase $sstring $lsidx end]
      }
      if {[string length $lsidx] > 0} {
         .$wintype$myid.mainfr.editfr.textarea delete $lsidx "$lsidx + [string length $sstring] chars"
         .$wintype$myid.mainfr.editfr.textarea insert $lsidx $rstring
         .$wintype$myid.mainfr.editfr.textarea tag add sel $lsidx "$lsidx + [string length $rstring] chars"
         set lsidx [.$wintype$myid.mainfr.editfr.textarea index "$lsidx + [string length $rstring] chars"]
         incr nrepl
      }
   }

   if {![string compare $wintype "main"]} {
      incr dirtybit($myid) $nrepl
   } else {
      incr rdirtybit($myid) $nrepl
   }

   if {![string compare $wintype "main"]} {
      errmsg $myid "   $nrepl replacements done   "
   } else {
      setbnstr $myid
      errmsg2 $myid "   $nrepl replacements done   "
   }
   grab .find
}

###########################################################################
# Copyright 1998 - 1999 by Abhijit Das (abhij@csa.iisc.ernet.in).
# bwedit is a freeware. Permission is hereby granted to distribute and
# mirror it free of charge as long as the original author gets credit
# and this copyright notice remains intact.
###########################################################################
#
# End of bwedit
