#!/bin/sh
# the next line restarts using wish \
exec /usr/local/bin/wish8.4 "$0" "$@"

#    Copyright 2003 Regis Damongeot

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


#window title
wm title . "TkDVD 4.0.4"
wm geometry . 700x550
wm protocol . WM_DELETE_WINDOW { save_options; destroy . }
set burn_type "burn_dvd"
set v_create_iso "no"
set burning_device "/dev/rcd0c"
#used when creating ISO to save CD/DVD device
set temp_burning_device ""
set burn_command "growisofs"
set volume_id ""
set volume_id_o ""
set option_udf_ext ""
set option_joliet_ext "-J"
set option_rr_ext "-r"
set option_pad "-pad"
set file_list ""
set excluded_file_list ""
set only_one_file ""
set input ""
set total_file_size_f "0 KB"
set space_left_f "4.377 GB"
set dvd_size "4589850"
set selected_directory "[pwd]"
set iso_file ""
set t_session "-use-the-force-luke=tty -Z"
set option_dvd_compat "-dvd-compat"
set option_auto_refresh_space "1"
set option_overburn ""
set option_eject_cd ""
set option_tao_dao_cd "-tao"
set cd_session_type ""
set burn_speed ""
set language "English"
set i18n_language_list ""
set command_line "growisofs $t_session $burning_device $option_joliet_ext $option_rr_ext $burn_speed $option_dvd_compat $option_pad -graft-points"
#needed to not have too large precision when showing total files size
set tcl_precision 4

#set fullpath to source scripts (if TkDVD not launch from it install direcotory)
set source_directory "[info script]"
if { [file pathtype $source_directory] == "absolute" } {
	set source_directory [file dirname $source_directory]
} else {
	set source_directory "[file dirname [pwd]/[info script]]"
}

#we need to set a variable to fix compatibility problems between tcl 8.4 and 8.5
# 8.5 has a tristate value for checkbuttons which is by default "" that conflits with offvalue for TkDVD advanced options
# so we need to set a different tristate value with -tristatevalue option but, as tk 8.4 doesn't have this option, we must not set this option in this case. So a global variable set to "" when tk 8.4 is detected and set to "-tristatevalue "tristate"" will do the job.
set tristatecompatibility "no"
if { [string equal -length 3 $tk_patchLevel "8.5"] == 1 } {
  set tristatecompatibility "yes"
}

#source combobox code
if { [catch { package require combobox 2.3 } ] } {
#do not leave space before the following line or install.tcl will not work
# Copyright (c) 1998-2003, Bryan Oakley
# All Rights Reservered
#
# Bryan Oakley
# oakley@bardo.clearlight.com
#
# combobox v2.3 August 16, 2003
#
# a combobox / dropdown listbox (pick your favorite name) widget 
# written in pure tcl
#
# this code is freely distributable without restriction, but is 
# provided as-is with no warranty expressed or implied. 
#
# thanks to the following people who provided beta test support or
# patches to the code (in no particular order):
#
# Scott Beasley     Alexandre Ferrieux      Todd Helfter
# Matt Gushee       Laurent Duperval        John Jackson
# Fred Rapp         Christopher Nelson
# Eric Galluzzo     Jean-Francois Moine	    Oliver Bienert
#
# A special thanks to Martin M. Hunt who provided several good ideas, 
# and always with a patch to implement them. Jean-Francois Moine, 
# Todd Helfter and John Jackson were also kind enough to send in some 
# code patches.
#
# ... and many others over the years.

package require Tk 8.0
package provide combobox 2.3

namespace eval ::combobox {

    # this is the public interface
    namespace export combobox

    # these contain references to available options
    variable widgetOptions

    # these contain references to available commands and subcommands
    variable widgetCommands
    variable scanCommands
    variable listCommands
}

# ::combobox::combobox --
#
#     This is the command that gets exported. It creates a new
#     combobox widget.
#
# Arguments:
#
#     w        path of new widget to create
#     args     additional option/value pairs (eg: -background white, etc.)
#
# Results:
#
#     It creates the widget and sets up all of the default bindings
#
# Returns:
#
#     The name of the newly create widget

proc ::combobox::combobox {w args} {
    variable widgetOptions
    variable widgetCommands
    variable scanCommands
    variable listCommands

    # perform a one time initialization
    if {![info exists widgetOptions]} {
	Init
    }

    # build it...
    eval Build $w $args

    # set some bindings...
    SetBindings $w

    # and we are done!
    return $w
}


# ::combobox::Init --
#
#     Initialize the namespace variables. This should only be called
#     once, immediately prior to creating the first instance of the
#     widget
#
# Arguments:
#
#    none
#
# Results:
#
#     All state variables are set to their default values; all of 
#     the option database entries will exist.
#
# Returns:
# 
#     empty string

proc ::combobox::Init {} {
    variable widgetOptions
    variable widgetCommands
    variable scanCommands
    variable listCommands
    variable defaultEntryCursor

    array set widgetOptions [list \
	    -background          {background          Background} \
	    -bd                  -borderwidth \
	    -bg                  -background \
	    -borderwidth         {borderWidth         BorderWidth} \
	    -buttonbackground    {buttonBackground    Background} \
	    -command             {command             Command} \
	    -commandstate        {commandState        State} \
	    -cursor              {cursor              Cursor} \
	    -disabledbackground  {disabledBackground  DisabledBackground} \
	    -disabledforeground  {disabledForeground  DisabledForeground} \
            -dropdownwidth       {dropdownWidth       DropdownWidth} \
	    -editable            {editable            Editable} \
	    -elementborderwidth  {elementBorderWidth  BorderWidth} \
	    -fg                  -foreground \
	    -font                {font                Font} \
	    -foreground          {foreground          Foreground} \
	    -height              {height              Height} \
	    -highlightbackground {highlightBackground HighlightBackground} \
	    -highlightcolor      {highlightColor      HighlightColor} \
	    -highlightthickness  {highlightThickness  HighlightThickness} \
	    -image               {image               Image} \
	    -listvar             {listVariable        Variable} \
	    -maxheight           {maxHeight           Height} \
	    -opencommand         {opencommand         Command} \
	    -relief              {relief              Relief} \
	    -selectbackground    {selectBackground    Foreground} \
	    -selectborderwidth   {selectBorderWidth   BorderWidth} \
	    -selectforeground    {selectForeground    Background} \
	    -state               {state               State} \
	    -takefocus           {takeFocus           TakeFocus} \
	    -textvariable        {textVariable        Variable} \
	    -value               {value               Value} \
	    -width               {width               Width} \
	    -xscrollcommand      {xScrollCommand      ScrollCommand} \
    ]


    set widgetCommands [list \
	    bbox      cget     configure    curselection \
	    delete    get      icursor      index        \
	    insert    list     scan         selection    \
	    xview     select   toggle       open         \
            close    subwidget  \
    ]

    set listCommands [list \
	    delete       get      \
            index        insert       size \
    ]

    set scanCommands [list mark dragto]

    # why check for the Tk package? This lets us be sourced into 
    # an interpreter that doesn't have Tk loaded, such as the slave
    # interpreter used by pkg_mkIndex. In theory it should have no
    # side effects when run 
    if {[lsearch -exact [package names] "Tk"] != -1} {

	##################################################################
	#- this initializes the option database. Kinda gross, but it works
	#- (I think). 
	##################################################################

	# the image used for the button...
	if {$::tcl_platform(platform) == "windows"} {
	    image create bitmap ::combobox::bimage -data {
		#define down_arrow_width 12
		#define down_arrow_height 12
		static char down_arrow_bits[] = {
		    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		    0xfc,0xf1,0xf8,0xf0,0x70,0xf0,0x20,0xf0,
		    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;
		}
	    }
	} else {
	    image create bitmap ::combobox::bimage -data  {
		#define down_arrow_width 15
		#define down_arrow_height 15
		static char down_arrow_bits[] = {
		    0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,
		    0x00,0x80,0xf8,0x8f,0xf0,0x87,0xe0,0x83,
		    0xc0,0x81,0x80,0x80,0x00,0x80,0x00,0x80,
		    0x00,0x80,0x00,0x80,0x00,0x80
		}
	    }
	}

	# compute a widget name we can use to create a temporary widget
	set tmpWidget ".__tmp__"
	set count 0
	while {[winfo exists $tmpWidget] == 1} {
	    set tmpWidget ".__tmp__$count"
	    incr count
	}

	# get the scrollbar width. Because we try to be clever and draw our
	# own button instead of using a tk widget, we need to know what size
	# button to create. This little hack tells us the width of a scroll
	# bar.
	#
	# NB: we need to be sure and pick a window  that doesn't already
	# exist... 
	scrollbar $tmpWidget
	set sb_width [winfo reqwidth $tmpWidget]
	set bbg [$tmpWidget cget -background]
	destroy $tmpWidget

	# steal options from the entry widget
	# we want darn near all options, so we'll go ahead and do
	# them all. No harm done in adding the one or two that we
	# don't use.
	entry $tmpWidget 
	foreach foo [$tmpWidget configure] {
	    # the cursor option is special, so we'll save it in
	    # a special way
	    if {[lindex $foo 0] == "-cursor"} {
		set defaultEntryCursor [lindex $foo 4]
	    }
	    if {[llength $foo] == 5} {
		set option [lindex $foo 1]
		set value [lindex $foo 4]
		option add *Combobox.$option $value widgetDefault

		# these options also apply to the dropdown listbox
		if {[string compare $option "foreground"] == 0 \
			|| [string compare $option "background"] == 0 \
			|| [string compare $option "font"] == 0} {
		    option add *Combobox*ComboboxListbox.$option $value \
			    widgetDefault
		}
	    }
	}
	destroy $tmpWidget

	# these are unique to us...
	option add *Combobox.elementBorderWidth  1	widgetDefault
	option add *Combobox.buttonBackground    $bbg	widgetDefault
	option add *Combobox.dropdownWidth       {}     widgetDefault
	option add *Combobox.openCommand         {}     widgetDefault
	option add *Combobox.cursor              {}     widgetDefault
	option add *Combobox.commandState        normal widgetDefault
	option add *Combobox.editable            1      widgetDefault
	option add *Combobox.maxHeight           10     widgetDefault
	option add *Combobox.height              0
    }

    # set class bindings
    SetClassBindings
}

# ::combobox::SetClassBindings --
#
#    Sets up the default bindings for the widget class
#
#    this proc exists since it's The Right Thing To Do, but
#    I haven't had the time to figure out how to do all the
#    binding stuff on a class level. The main problem is that
#    the entry widget must have focus for the insertion cursor
#    to be visible. So, I either have to have the entry widget
#    have the Combobox bindtag, or do some fancy juggling of
#    events or some such. What a pain.
#
# Arguments:
#
#    none
#
# Returns:
#
#    empty string

proc ::combobox::SetClassBindings {} {

    # make sure we clean up after ourselves...
    bind Combobox <Destroy> [list ::combobox::DestroyHandler %W]

    # this will (hopefully) close (and lose the grab on) the
    # listbox if the user clicks anywhere outside of it. Note
    # that on Windows, you can click on some other app and
    # the listbox will still be there, because tcl won't see
    # that button click
    set this {[::combobox::convert %W -W]}
    bind Combobox <Any-ButtonPress>   "$this close"
    bind Combobox <Any-ButtonRelease> "$this close"

    # this helps (but doesn't fully solve) focus issues. The general
    # idea is, whenever the frame gets focus it gets passed on to
    # the entry widget
    bind Combobox <FocusIn> {::combobox::tkTabToWindow \
				 [::combobox::convert %W -W].entry}

    # this closes the listbox if we get hidden
    bind Combobox <Unmap> {[::combobox::convert %W -W] close}

    return ""
}

# ::combobox::SetBindings --
#
#    here's where we do most of the binding foo. I think there's probably
#    a few bindings I ought to add that I just haven't thought
#    about...
#
#    I'm not convinced these are the proper bindings. Ideally all
#    bindings should be on "Combobox", but because of my juggling of
#    bindtags I'm not convinced thats what I want to do. But, it all
#    seems to work, its just not as robust as it could be.
#
# Arguments:
#
#    w    widget pathname
#
# Returns:
#
#    empty string

proc ::combobox::SetBindings {w} {
    upvar ::combobox::${w}::widgets  widgets
    upvar ::combobox::${w}::options  options

    # juggle the bindtags. The basic idea here is to associate the
    # widget name with the entry widget, so if a user does a bind
    # on the combobox it will get handled properly since it is
    # the entry widget that has keyboard focus.
    bindtags $widgets(entry) \
	    [concat $widgets(this) [bindtags $widgets(entry)]]

    bindtags $widgets(button) \
	    [concat $widgets(this) [bindtags $widgets(button)]]

    # override the default bindings for tab and shift-tab. The
    # focus procs take a widget as their only parameter and we
    # want to make sure the right window gets used (for shift-
    # tab we want it to appear as if the event was generated
    # on the frame rather than the entry. 
    bind $widgets(entry) <Tab> \
	    "::combobox::tkTabToWindow \[tk_focusNext $widgets(entry)\]; break"
    bind $widgets(entry) <Shift-Tab> \
	    "::combobox::tkTabToWindow \[tk_focusPrev $widgets(this)\]; break"
    
    # this makes our "button" (which is actually a label)
    # do the right thing
    bind $widgets(button) <ButtonPress-1> [list $widgets(this) toggle]

    # this lets the autoscan of the listbox work, even if they
    # move the cursor over the entry widget.
    bind $widgets(entry) <B1-Enter> "break"

    bind $widgets(listbox) <ButtonRelease-1> \
        "::combobox::Select [list $widgets(this)] \
         \[$widgets(listbox) nearest %y\]; break"

    bind $widgets(vsb) <ButtonPress-1>   {continue}
    bind $widgets(vsb) <ButtonRelease-1> {continue}

    bind $widgets(listbox) <Any-Motion> {
	%W selection clear 0 end
	%W activate @%x,%y
	%W selection anchor @%x,%y
	%W selection set @%x,%y @%x,%y
	# need to do a yview if the cursor goes off the top
	# or bottom of the window... (or do we?)
    }

    # these events need to be passed from the entry widget
    # to the listbox, or otherwise need some sort of special
    # handling. 
    foreach event [list <Up> <Down> <Tab> <Return> <Escape> \
	    <Next> <Prior> <Double-1> <1> <Any-KeyPress> \
	    <FocusIn> <FocusOut>] {
	bind $widgets(entry) $event \
            [list ::combobox::HandleEvent $widgets(this) $event]
    }

    # like the other events, <MouseWheel> needs to be passed from
    # the entry widget to the listbox. However, in this case we
    # need to add an additional parameter
    catch {
	bind $widgets(entry) <MouseWheel> \
	    [list ::combobox::HandleEvent $widgets(this) <MouseWheel> %D]
    }
}

# ::combobox::Build --
#
#    This does all of the work necessary to create the basic
#    combobox. 
#
# Arguments:
#
#    w        widget name
#    args     additional option/value pairs
#
# Results:
#
#    Creates a new widget with the given name. Also creates a new
#    namespace patterened after the widget name, as a child namespace
#    to ::combobox
#
# Returns:
#
#    the name of the widget

proc ::combobox::Build {w args } {
    variable widgetOptions

    if {[winfo exists $w]} {
	error "window name \"$w\" already exists"
    }

    # create the namespace for this instance, and define a few
    # variables
    namespace eval ::combobox::$w {

	variable ignoreTrace 0
	variable oldFocus    {}
	variable oldGrab     {}
	variable oldValue    {}
	variable options
	variable this
	variable widgets

	set widgets(foo) foo  ;# coerce into an array
	set options(foo) foo  ;# coerce into an array

	unset widgets(foo)
	unset options(foo)
    }

    # import the widgets and options arrays into this proc so
    # we don't have to use fully qualified names, which is a
    # pain.
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    # this is our widget -- a frame of class Combobox. Naturally,
    # it will contain other widgets. We create it here because
    # we need it in order to set some default options.
    set widgets(this)   [frame  $w -class Combobox -takefocus 0]
    set widgets(entry)  [entry  $w.entry -takefocus 1]
    set widgets(button) [label  $w.button -takefocus 0] 

    # this defines all of the default options. We get the
    # values from the option database. Note that if an array
    # value is a list of length one it is an alias to another
    # option, so we just ignore it
    foreach name [array names widgetOptions] {
	if {[llength $widgetOptions($name)] == 1} continue

	set optName  [lindex $widgetOptions($name) 0]
	set optClass [lindex $widgetOptions($name) 1]

	set value [option get $w $optName $optClass]
	set options($name) $value
    }

    # a couple options aren't available in earlier versions of
    # tcl, so we'll set them to sane values. For that matter, if
    # they exist but are empty, set them to sane values.
    if {[string length $options(-disabledforeground)] == 0} {
        set options(-disabledforeground) $options(-foreground)
    }
    if {[string length $options(-disabledbackground)] == 0} {
        set options(-disabledbackground) $options(-background)
    }

    # if -value is set to null, we'll remove it from our
    # local array. The assumption is, if the user sets it from
    # the option database, they will set it to something other
    # than null (since it's impossible to determine the difference
    # between a null value and no value at all).
    if {[info exists options(-value)] \
	    && [string length $options(-value)] == 0} {
	unset options(-value)
    }

    # we will later rename the frame's widget proc to be our
    # own custom widget proc. We need to keep track of this
    # new name, so we'll define and store it here...
    set widgets(frame) ::combobox::${w}::$w

    # gotta do this sooner or later. Might as well do it now
    pack $widgets(button) -side right -fill y    -expand no
    pack $widgets(entry)  -side left  -fill both -expand yes

    # I should probably do this in a catch, but for now it's
    # good enough... What it does, obviously, is put all of
    # the option/values pairs into an array. Make them easier
    # to handle later on...
    array set options $args

    # now, the dropdown list... the same renaming nonsense
    # must go on here as well...
    set widgets(dropdown)   [toplevel  $w.top]
    set widgets(listbox) [listbox   $w.top.list]
    set widgets(vsb)     [scrollbar $w.top.vsb]

    pack $widgets(listbox) -side left -fill both -expand y

    # fine tune the widgets based on the options (and a few
    # arbitrary values...)

    # NB: we are going to use the frame to handle the relief
    # of the widget as a whole, so the entry widget will be 
    # flat. This makes the button which drops down the list
    # to appear "inside" the entry widget.

    $widgets(vsb) configure \
	    -borderwidth 1 \
	    -command "$widgets(listbox) yview" \
	    -highlightthickness 0

    $widgets(button) configure \
	    -background $options(-buttonbackground) \
	    -highlightthickness 0 \
	    -borderwidth $options(-elementborderwidth) \
	    -relief raised \
	    -width [expr {[winfo reqwidth $widgets(vsb)] - 2}]

    $widgets(entry) configure \
	    -borderwidth 0 \
	    -relief flat \
	    -highlightthickness 0 

    $widgets(dropdown) configure \
	    -borderwidth $options(-elementborderwidth) \
	    -relief sunken

    $widgets(listbox) configure \
	    -selectmode browse \
	    -background [$widgets(entry) cget -bg] \
	    -yscrollcommand "$widgets(vsb) set" \
	    -exportselection false \
	    -borderwidth 0


#    trace variable ::combobox::${w}::entryTextVariable w \
#	    [list ::combobox::EntryTrace $w]
	
    # do some window management foo on the dropdown window
    wm overrideredirect $widgets(dropdown) 1
    wm transient        $widgets(dropdown) [winfo toplevel $w]
    wm group            $widgets(dropdown) [winfo parent $w]
    wm resizable        $widgets(dropdown) 0 0
    wm withdraw         $widgets(dropdown)
    
    # this moves the original frame widget proc into our
    # namespace and gives it a handy name
    rename ::$w $widgets(frame)

    # now, create our widget proc. Obviously (?) it goes in
    # the global namespace. All combobox widgets will actually
    # share the same widget proc to cut down on the amount of
    # bloat. 
    proc ::$w {command args} \
        "eval ::combobox::WidgetProc $w \$command \$args"


    # ok, the thing exists... let's do a bit more configuration. 
    if {[catch "::combobox::Configure [list $widgets(this)] [array get options]" error]} {
	catch {destroy $w}
	error "internal error: $error"
    }

    return ""

}

# ::combobox::HandleEvent --
#
#    this proc handles events from the entry widget that we want
#    handled specially (typically, to allow navigation of the list
#    even though the focus is in the entry widget)
#
# Arguments:
#
#    w       widget pathname
#    event   a string representing the event (not necessarily an
#            actual event)
#    args    additional arguments required by particular events

proc ::combobox::HandleEvent {w event args} {
    upvar ::combobox::${w}::widgets  widgets
    upvar ::combobox::${w}::options  options
    upvar ::combobox::${w}::oldValue oldValue

    # for all of these events, if we have a special action we'll
    # do that and do a "return -code break" to keep additional 
    # bindings from firing. Otherwise we'll let the event fall
    # on through. 
    switch $event {

        "<MouseWheel>" {
	    if {[winfo ismapped $widgets(dropdown)]} {
                set D [lindex $args 0]
                # the '120' number in the following expression has
                # it's genesis in the tk bind manpage, which suggests
                # that the smallest value of %D for mousewheel events
                # will be 120. The intent is to scroll one line at a time.
                $widgets(listbox) yview scroll [expr {-($D/120)}] units
            }
        } 

	"<Any-KeyPress>" {
	    # if the widget is editable, clear the selection. 
	    # this makes it more obvious what will happen if the 
	    # user presses <Return> (and helps our code know what
	    # to do if the user presses return)
	    if {$options(-editable)} {
		$widgets(listbox) see 0
		$widgets(listbox) selection clear 0 end
		$widgets(listbox) selection anchor 0
		$widgets(listbox) activate 0
	    }
	}

	"<FocusIn>" {
	    set oldValue [$widgets(entry) get]
	}

	"<FocusOut>" {
	    if {![winfo ismapped $widgets(dropdown)]} {
		# did the value change?
		set newValue [$widgets(entry) get]
		if {$oldValue != $newValue} {
		    CallCommand $widgets(this) $newValue
		}
	    }
	}

	"<1>" {
	    set editable [::combobox::GetBoolean $options(-editable)]
	    if {!$editable} {
		if {[winfo ismapped $widgets(dropdown)]} {
		    $widgets(this) close
		    return -code break;

		} else {
		    if {$options(-state) != "disabled"} {
			$widgets(this) open
			return -code break;
		    }
		}
	    }
	}

	"<Double-1>" {
	    if {$options(-state) != "disabled"} {
		$widgets(this) toggle
		return -code break;
	    }
	}

	"<Tab>" {
	    if {[winfo ismapped $widgets(dropdown)]} {
		::combobox::Find $widgets(this) 0
		return -code break;
	    } else {
		::combobox::SetValue $widgets(this) [$widgets(this) get]
	    }
	}

	"<Escape>" {
#	    $widgets(entry) delete 0 end
#	    $widgets(entry) insert 0 $oldValue
	    if {[winfo ismapped $widgets(dropdown)]} {
		$widgets(this) close
		return -code break;
	    }
	}

	"<Return>" {
	    # did the value change?
	    set newValue [$widgets(entry) get]
	    if {$oldValue != $newValue} {
		CallCommand $widgets(this) $newValue
	    }

	    if {[winfo ismapped $widgets(dropdown)]} {
		::combobox::Select $widgets(this) \
			[$widgets(listbox) curselection]
		return -code break;
	    } 

	}

	"<Next>" {
	    $widgets(listbox) yview scroll 1 pages
	    set index [$widgets(listbox) index @0,0]
	    $widgets(listbox) see $index
	    $widgets(listbox) activate $index
	    $widgets(listbox) selection clear 0 end
	    $widgets(listbox) selection anchor $index
	    $widgets(listbox) selection set $index

	}

	"<Prior>" {
	    $widgets(listbox) yview scroll -1 pages
	    set index [$widgets(listbox) index @0,0]
	    $widgets(listbox) activate $index
	    $widgets(listbox) see $index
	    $widgets(listbox) selection clear 0 end
	    $widgets(listbox) selection anchor $index
	    $widgets(listbox) selection set $index
	}

	"<Down>" {
	    if {[winfo ismapped $widgets(dropdown)]} {
		::combobox::tkListboxUpDown $widgets(listbox) 1
		return -code break;

	    } else {
		if {$options(-state) != "disabled"} {
		    $widgets(this) open
		    return -code break;
		}
	    }
	}
	"<Up>" {
	    if {[winfo ismapped $widgets(dropdown)]} {
		::combobox::tkListboxUpDown $widgets(listbox) -1
		return -code break;

	    } else {
		if {$options(-state) != "disabled"} {
		    $widgets(this) open
		    return -code break;
		}
	    }
	}
    }

    return ""
}

# ::combobox::DestroyHandler {w} --
# 
#    Cleans up after a combobox widget is destroyed
#
# Arguments:
#
#    w    widget pathname
#
# Results:
#
#    The namespace that was created for the widget is deleted,
#    and the widget proc is removed.

proc ::combobox::DestroyHandler {w} {

    catch {
	# if the widget actually being destroyed is of class Combobox,
	# remove the namespace and associated proc.
	if {[string compare [winfo class $w] "Combobox"] == 0} {
	    # delete the namespace and the proc which represents
	    # our widget
	    namespace delete ::combobox::$w
	    rename $w {}
	}   
    }
    return ""
}

# ::combobox::Find
#
#    finds something in the listbox that matches the pattern in the
#    entry widget and selects it
#
#    N.B. I'm not convinced this is working the way it ought to. It
#    works, but is the behavior what is expected? I've also got a gut
#    feeling that there's a better way to do this, but I'm too lazy to
#    figure it out...
#
# Arguments:
#
#    w      widget pathname
#    exact  boolean; if true an exact match is desired
#
# Returns:
#
#    Empty string

proc ::combobox::Find {w {exact 0}} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    ## *sigh* this logic is rather gross and convoluted. Surely
    ## there is a more simple, straight-forward way to implement
    ## all this. As the saying goes, I lack the time to make it
    ## shorter...

    # use what is already in the entry widget as a pattern
    set pattern [$widgets(entry) get]

    if {[string length $pattern] == 0} {
	# clear the current selection
	$widgets(listbox) see 0
	$widgets(listbox) selection clear 0 end
	$widgets(listbox) selection anchor 0
	$widgets(listbox) activate 0
	return
    }

    # we're going to be searching this list...
    set list [$widgets(listbox) get 0 end]

    # if we are doing an exact match, try to find,
    # well, an exact match
    set exactMatch -1
    if {$exact} {
	set exactMatch [lsearch -exact $list $pattern]
    }

    # search for it. We'll try to be clever and not only
    # search for a match for what they typed, but a match for
    # something close to what they typed. We'll keep removing one
    # character at a time from the pattern until we find a match
    # of some sort.
    set index -1
    while {$index == -1 && [string length $pattern]} {
	set index [lsearch -glob $list "$pattern*"]
	if {$index == -1} {
	    regsub {.$} $pattern {} pattern
	}
    }

    # this is the item that most closely matches...
    set thisItem [lindex $list $index]

    # did we find a match? If so, do some additional munging...
    if {$index != -1} {

	# we need to find the part of the first item that is 
	# unique WRT the second... I know there's probably a
	# simpler way to do this... 

	set nextIndex [expr {$index + 1}]
	set nextItem [lindex $list $nextIndex]

	# we don't really need to do much if the next
	# item doesn't match our pattern...
	if {[string match $pattern* $nextItem]} {
	    # ok, the next item matches our pattern, too
	    # now the trick is to find the first character
	    # where they *don't* match...
	    set marker [string length $pattern]
	    while {$marker <= [string length $pattern]} {
		set a [string index $thisItem $marker]
		set b [string index $nextItem $marker]
		if {[string compare $a $b] == 0} {
		    append pattern $a
		    incr marker
		} else {
		    break
		}
	    }
	} else {
	    set marker [string length $pattern]
	}
	
    } else {
	set marker end
	set index 0
    }

    # ok, we know the pattern and what part is unique;
    # update the entry widget and listbox appropriately
    if {$exact && $exactMatch == -1} {
	# this means we didn't find an exact match
	$widgets(listbox) selection clear 0 end
	$widgets(listbox) see $index

    } elseif {!$exact}  {
	# this means we found something, but it isn't an exact
	# match. If we find something that *is* an exact match we
	# don't need to do the following, since it would merely 
	# be replacing the data in the entry widget with itself
	set oldstate [$widgets(entry) cget -state]
	$widgets(entry) configure -state normal
	$widgets(entry) delete 0 end
	$widgets(entry) insert end $thisItem
	$widgets(entry) selection clear
	$widgets(entry) selection range $marker end
	$widgets(listbox) activate $index
	$widgets(listbox) selection clear 0 end
	$widgets(listbox) selection anchor $index
	$widgets(listbox) selection set $index
	$widgets(listbox) see $index
	$widgets(entry) configure -state $oldstate
    }
}

# ::combobox::Select --
#
#    selects an item from the list and sets the value of the combobox
#    to that value
#
# Arguments:
#
#    w      widget pathname
#    index  listbox index of item to be selected
#
# Returns:
#
#    empty string

proc ::combobox::Select {w index} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    # the catch is because I'm sloppy -- presumably, the only time
    # an error will be caught is if there is no selection. 
    if {![catch {set data [$widgets(listbox) get [lindex $index 0]]}]} {
	::combobox::SetValue $widgets(this) $data

	$widgets(listbox) selection clear 0 end
	$widgets(listbox) selection anchor $index
	$widgets(listbox) selection set $index

    }
    $widgets(entry) selection range 0 end
    $widgets(entry) icursor end

    $widgets(this) close

    return ""
}

# ::combobox::HandleScrollbar --
# 
#    causes the scrollbar of the dropdown list to appear or disappear
#    based on the contents of the dropdown listbox
#
# Arguments:
#
#    w       widget pathname
#    action  the action to perform on the scrollbar
#
# Returns:
#
#    an empty string

proc ::combobox::HandleScrollbar {w {action "unknown"}} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    if {$options(-height) == 0} {
	set hlimit $options(-maxheight)
    } else {
	set hlimit $options(-height)
    }		    

    switch $action {
	"grow" {
	    if {$hlimit > 0 && [$widgets(listbox) size] > $hlimit} {
		pack forget $widgets(listbox)
		pack $widgets(vsb) -side right -fill y -expand n
		pack $widgets(listbox) -side left -fill both -expand y
	    }
	}

	"shrink" {
	    if {$hlimit > 0 && [$widgets(listbox) size] <= $hlimit} {
		pack forget $widgets(vsb)
	    }
	}

	"crop" {
	    # this means the window was cropped and we definitely 
	    # need a scrollbar no matter what the user wants
	    pack forget $widgets(listbox)
	    pack $widgets(vsb) -side right -fill y -expand n
	    pack $widgets(listbox) -side left -fill both -expand y
	}

	default {
	    if {$hlimit > 0 && [$widgets(listbox) size] > $hlimit} {
		pack forget $widgets(listbox)
		pack $widgets(vsb) -side right -fill y -expand n
		pack $widgets(listbox) -side left -fill both -expand y
	    } else {
		pack forget $widgets(vsb)
	    }
	}
    }

    return ""
}

# ::combobox::ComputeGeometry --
#
#    computes the geometry of the dropdown list based on the size of the
#    combobox...
#
# Arguments:
#
#    w     widget pathname
#
# Returns:
#
#    the desired geometry of the listbox

proc ::combobox::ComputeGeometry {w} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options
    
    if {$options(-height) == 0 && $options(-maxheight) != "0"} {
	# if this is the case, count the items and see if
	# it exceeds our maxheight. If so, set the listbox
	# size to maxheight...
	set nitems [$widgets(listbox) size]
	if {$nitems > $options(-maxheight)} {
	    # tweak the height of the listbox
	    $widgets(listbox) configure -height $options(-maxheight)
	} else {
	    # un-tweak the height of the listbox
	    $widgets(listbox) configure -height 0
	}
	update idletasks
    }

    # compute height and width of the dropdown list
    set bd [$widgets(dropdown) cget -borderwidth]
    set height [expr {[winfo reqheight $widgets(dropdown)] + $bd + $bd}]
    if {[string length $options(-dropdownwidth)] == 0 || 
        $options(-dropdownwidth) == 0} {
        set width [winfo width $widgets(this)]
    } else {
        set m [font measure [$widgets(listbox) cget -font] "m"]
        set width [expr {$options(-dropdownwidth) * $m}]
    }

    # figure out where to place it on the screen, trying to take into
    # account we may be running under some virtual window manager
    set screenWidth  [winfo screenwidth $widgets(this)]
    set screenHeight [winfo screenheight $widgets(this)]
    set rootx        [winfo rootx $widgets(this)]
    set rooty        [winfo rooty $widgets(this)]
    set vrootx       [winfo vrootx $widgets(this)]
    set vrooty       [winfo vrooty $widgets(this)]

    # the x coordinate is simply the rootx of our widget, adjusted for
    # the virtual window. We won't worry about whether the window will
    # be offscreen to the left or right -- we want the illusion that it
    # is part of the entry widget, so if part of the entry widget is off-
    # screen, so will the list. If you want to change the behavior,
    # simply change the if statement... (and be sure to update this
    # comment!)
    set x  [expr {$rootx + $vrootx}]
    if {0} { 
	set rightEdge [expr {$x + $width}]
	if {$rightEdge > $screenWidth} {
	    set x [expr {$screenWidth - $width}]
	}
	if {$x < 0} {set x 0}
    }

    # the y coordinate is the rooty plus vrooty offset plus 
    # the height of the static part of the widget plus 1 for a 
    # tiny bit of visual separation...
    set y [expr {$rooty + $vrooty + [winfo reqheight $widgets(this)] + 1}]
    set bottomEdge [expr {$y + $height}]

    if {$bottomEdge >= $screenHeight} {
	# ok. Fine. Pop it up above the entry widget isntead of
	# below.
	set y [expr {($rooty - $height - 1) + $vrooty}]

	if {$y < 0} {
	    # this means it extends beyond our screen. How annoying.
	    # Now we'll try to be real clever and either pop it up or
	    # down, depending on which way gives us the biggest list. 
	    # then, we'll trim the list to fit and force the use of
	    # a scrollbar

	    # (sadly, for windows users this measurement doesn't
	    # take into consideration the height of the taskbar,
	    # but don't blame me -- there isn't any way to detect
	    # it or figure out its dimensions. The same probably
	    # applies to any window manager with some magic windows
	    # glued to the top or bottom of the screen)

	    if {$rooty > [expr {$screenHeight / 2}]} {
		# we are in the lower half of the screen -- 
		# pop it up. Y is zero; that parts easy. The height
		# is simply the y coordinate of our widget, minus
		# a pixel for some visual separation. The y coordinate
		# will be the topof the screen.
		set y 1
		set height [expr {$rooty - 1 - $y}]

	    } else {
		# we are in the upper half of the screen --
		# pop it down
		set y [expr {$rooty + $vrooty + \
			[winfo reqheight $widgets(this)] + 1}]
		set height [expr {$screenHeight - $y}]

	    }

	    # force a scrollbar
	    HandleScrollbar $widgets(this) crop
	}	   
    }

    if {$y < 0} {
	# hmmm. Bummer.
	set y 0
	set height $screenheight
    }

    set geometry [format "=%dx%d+%d+%d" $width $height $x $y]

    return $geometry
}

# ::combobox::DoInternalWidgetCommand --
#
#    perform an internal widget command, then mung any error results
#    to look like it came from our megawidget. A lot of work just to
#    give the illusion that our megawidget is an atomic widget
#
# Arguments:
#
#    w           widget pathname
#    subwidget   pathname of the subwidget 
#    command     subwidget command to be executed
#    args        arguments to the command
#
# Returns:
#
#    The result of the subwidget command, or an error

proc ::combobox::DoInternalWidgetCommand {w subwidget command args} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    set subcommand $command
    set command [concat $widgets($subwidget) $command $args]
    if {[catch $command result]} {
	# replace the subwidget name with the megawidget name
	regsub $widgets($subwidget) $result $widgets(this) result

	# replace specific instances of the subwidget command
	# with our megawidget command
	switch $subwidget,$subcommand {
	    listbox,index  {regsub "index"  $result "list index"  result}
	    listbox,insert {regsub "insert" $result "list insert" result}
	    listbox,delete {regsub "delete" $result "list delete" result}
	    listbox,get    {regsub "get"    $result "list get"    result}
	    listbox,size   {regsub "size"   $result "list size"   result}
	}
	error $result

    } else {
	return $result
    }
}


# ::combobox::WidgetProc --
#
#    This gets uses as the widgetproc for an combobox widget. 
#    Notice where the widget is created and you'll see that the
#    actual widget proc merely evals this proc with all of the
#    arguments intact.
#
#    Note that some widget commands are defined "inline" (ie:
#    within this proc), and some do most of their work in 
#    separate procs. This is merely because sometimes it was
#    easier to do it one way or the other.
#
# Arguments:
#
#    w         widget pathname
#    command   widget subcommand
#    args      additional arguments; varies with the subcommand
#
# Results:
#
#    Performs the requested widget command

proc ::combobox::WidgetProc {w command args} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options
    upvar ::combobox::${w}::oldFocus oldFocus
    upvar ::combobox::${w}::oldFocus oldGrab

    set command [::combobox::Canonize $w command $command]

    # this is just shorthand notation...
    set doWidgetCommand \
	    [list ::combobox::DoInternalWidgetCommand $widgets(this)]

    if {$command == "list"} {
	# ok, the next argument is a list command; we'll 
	# rip it from args and append it to command to
	# create a unique internal command
	#
	# NB: because of the sloppy way we are doing this,
	# we'll also let the user enter our secret command
	# directly (eg: listinsert, listdelete), but we
	# won't document that fact
	set command "list-[lindex $args 0]"
	set args [lrange $args 1 end]
    }

    set result ""

    # many of these commands are just synonyms for specific
    # commands in one of the subwidgets. We'll get them out
    # of the way first, then do the custom commands.
    switch $command {
	bbox -
	delete -
	get -
	icursor -
	index -
	insert -
	scan -
	selection -
	xview {
	    set result [eval $doWidgetCommand entry $command $args]
	}
	list-get 	{set result [eval $doWidgetCommand listbox get $args]}
	list-index 	{set result [eval $doWidgetCommand listbox index $args]}
	list-size 	{set result [eval $doWidgetCommand listbox size $args]}

	select {
	    if {[llength $args] == 1} {
		set index [lindex $args 0]
		set result [Select $widgets(this) $index]
	    } else {
		error "usage: $w select index"
	    }
	}

	subwidget {
	    set knownWidgets [list button entry listbox dropdown vsb]
	    if {[llength $args] == 0} {
		return $knownWidgets
	    }

	    set name [lindex $args 0]
	    if {[lsearch $knownWidgets $name] != -1} {
		set result $widgets($name)
	    } else {
		error "unknown subwidget $name"
	    }
	}

	curselection {
	    set result [eval $doWidgetCommand listbox curselection]
	}

	list-insert {
	    eval $doWidgetCommand listbox insert $args
	    set result [HandleScrollbar $w "grow"]
	}

	list-delete {
	    eval $doWidgetCommand listbox delete $args
	    set result [HandleScrollbar $w "shrink"]
	}

	toggle {
	    # ignore this command if the widget is disabled...
	    if {$options(-state) == "disabled"} return

	    # pops down the list if it is not, hides it
	    # if it is...
	    if {[winfo ismapped $widgets(dropdown)]} {
		set result [$widgets(this) close]
	    } else {
		set result [$widgets(this) open]
	    }
	}

	open {

	    # if this is an editable combobox, the focus should
	    # be set to the entry widget
	    if {$options(-editable)} {
		focus $widgets(entry)
		$widgets(entry) select range 0 end
		$widgets(entry) icursor end
	    }

	    # if we are disabled, we won't allow this to happen
	    if {$options(-state) == "disabled"} {
		return 0
	    }

	    # if there is a -opencommand, execute it now
	    if {[string length $options(-opencommand)] > 0} {
		# hmmm... should I do a catch, or just let the normal
		# error handling handle any errors? For now, the latter...
		uplevel \#0 $options(-opencommand)
	    }

	    # compute the geometry of the window to pop up, and set
	    # it, and force the window manager to take notice
	    # (even if it is not presently visible).
	    #
	    # this isn't strictly necessary if the window is already
	    # mapped, but we'll go ahead and set the geometry here
	    # since its harmless and *may* actually reset the geometry
	    # to something better in some weird case.
	    set geometry [::combobox::ComputeGeometry $widgets(this)]
	    wm geometry $widgets(dropdown) $geometry
	    update idletasks

	    # if we are already open, there's nothing else to do
	    if {[winfo ismapped $widgets(dropdown)]} {
		return 0
	    }

	    # save the widget that currently has the focus; we'll restore
	    # the focus there when we're done
	    set oldFocus [focus]

	    # ok, tweak the visual appearance of things and 
	    # make the list pop up
	    $widgets(button) configure -relief sunken
	    wm deiconify $widgets(dropdown) 
	    update idletasks
	    raise $widgets(dropdown) 

	    # force focus to the entry widget so we can handle keypress
	    # events for traversal
	    focus -force $widgets(entry)

	    # select something by default, but only if its an
	    # exact match...
	    ::combobox::Find $widgets(this) 1

	    # save the current grab state for the display containing
	    # this widget. We'll restore it when we close the dropdown
	    # list
	    set status "none"
	    set grab [grab current $widgets(this)]
	    if {$grab != ""} {set status [grab status $grab]}
	    set oldGrab [list $grab $status]
	    unset grab status

	    # *gasp* do a global grab!!! Mom always told me not to
	    # do things like this, but sometimes a man's gotta do
	    # what a man's gotta do.
	    grab -global $widgets(this)

	    # fake the listbox into thinking it has focus. This is 
	    # necessary to get scanning initialized properly in the
	    # listbox.
	    event generate $widgets(listbox) <B1-Enter>

	    return 1
	}

	close {
	    # if we are already closed, don't do anything...
	    if {![winfo ismapped $widgets(dropdown)]} {
		return 0
	    }

	    # restore the focus and grab, but ignore any errors...
	    # we're going to be paranoid and release the grab before
	    # trying to set any other grab because we really really
	    # really want to make sure the grab is released.
	    catch {focus $oldFocus} result
	    catch {grab release $widgets(this)}
	    catch {
		set status [lindex $oldGrab 1]
		if {$status == "global"} {
		    grab -global [lindex $oldGrab 0]
		} elseif {$status == "local"} {
		    grab [lindex $oldGrab 0]
		}
		unset status
	    }

	    # hides the listbox
	    $widgets(button) configure -relief raised
	    wm withdraw $widgets(dropdown) 

	    # select the data in the entry widget. Not sure
	    # why, other than observation seems to suggest that's
	    # what windows widgets do.
	    set editable [::combobox::GetBoolean $options(-editable)]
	    if {$editable} {
		$widgets(entry) selection range 0 end
		$widgets(button) configure -relief raised
	    }


	    # magic tcl stuff (see tk.tcl in the distribution 
	    # lib directory)
	    ::combobox::tkCancelRepeat

	    return 1
	}

	cget {
	    if {[llength $args] != 1} {
		error "wrong # args: should be $w cget option"
	    }
	    set opt [::combobox::Canonize $w option [lindex $args 0]]

	    if {$opt == "-value"} {
		set result [$widgets(entry) get]
	    } else {
		set result $options($opt)
	    }
	}

	configure {
	    set result [eval ::combobox::Configure {$w} $args]
	}

	default {
	    error "bad option \"$command\""
	}
    }

    return $result
}

# ::combobox::Configure --
#
#    Implements the "configure" widget subcommand
#
# Arguments:
#
#    w      widget pathname
#    args   zero or more option/value pairs (or a single option)
#
# Results:
#    
#    Performs typcial "configure" type requests on the widget

proc ::combobox::Configure {w args} {
    variable widgetOptions
    variable defaultEntryCursor

    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options

    if {[llength $args] == 0} {
	# hmmm. User must be wanting all configuration information
	# note that if the value of an array element is of length
	# one it is an alias, which needs to be handled slightly
	# differently
	set results {}
	foreach opt [lsort [array names widgetOptions]] {
	    if {[llength $widgetOptions($opt)] == 1} {
		set alias $widgetOptions($opt)
		set optName $widgetOptions($alias)
		lappend results [list $opt $optName]
	    } else {
		set optName  [lindex $widgetOptions($opt) 0]
		set optClass [lindex $widgetOptions($opt) 1]
		set default [option get $w $optName $optClass]
		if {[info exists options($opt)]} {
		    lappend results [list $opt $optName $optClass \
			    $default $options($opt)]
		} else {
		    lappend results [list $opt $optName $optClass \
			    $default ""]
		}
	    }
	}

	return $results
    }
    
    # one argument means we are looking for configuration
    # information on a single option
    if {[llength $args] == 1} {
	set opt [::combobox::Canonize $w option [lindex $args 0]]

	set optName  [lindex $widgetOptions($opt) 0]
	set optClass [lindex $widgetOptions($opt) 1]
	set default [option get $w $optName $optClass]
	set results [list $opt $optName $optClass \
		$default $options($opt)]
	return $results
    }

    # if we have an odd number of values, bail. 
    if {[expr {[llength $args]%2}] == 1} {
	# hmmm. An odd number of elements in args
	error "value for \"[lindex $args end]\" missing"
    }
    
    # Great. An even number of options. Let's make sure they 
    # are all valid before we do anything. Note that Canonize
    # will generate an error if it finds a bogus option; otherwise
    # it returns the canonical option name
    foreach {name value} $args {
	set name [::combobox::Canonize $w option $name]
	set opts($name) $value
    }

    # process all of the configuration options
    # some (actually, most) options require us to
    # do something, like change the attributes of
    # a widget or two. Here's where we do that...
    #
    # note that the handling of disabledforeground and
    # disabledbackground is a little wonky. First, we have
    # to deal with backwards compatibility (ie: tk 8.3 and below
    # didn't have such options for the entry widget), and
    # we have to deal with the fact we might want to disable
    # the entry widget but use the normal foreground/background
    # for when the combobox is not disabled, but not editable either.

    set updateVisual 0
    foreach option [array names opts] {
	set newValue $opts($option)
	if {[info exists options($option)]} {
	    set oldValue $options($option)
	}

	switch -- $option {
	    -buttonbackground {
		$widgets(button) configure -background $newValue
	    }
	    -background {
		set updateVisual 1
		set options($option) $newValue
	    }

	    -borderwidth {
		$widgets(frame) configure -borderwidth $newValue
		set options($option) $newValue
	    }

	    -command {
		# nothing else to do...
		set options($option) $newValue
	    }

	    -commandstate {
		# do some value checking...
		if {$newValue != "normal" && $newValue != "disabled"} {
		    set options($option) $oldValue
		    set message "bad state value \"$newValue\";"
		    append message " must be normal or disabled"
		    error $message
		}
		set options($option) $newValue
	    }

	    -cursor {
		$widgets(frame) configure -cursor $newValue
		$widgets(entry) configure -cursor $newValue
		$widgets(listbox) configure -cursor $newValue
		set options($option) $newValue
	    }

	    -disabledforeground {
		set updateVisual 1
		set options($option) $newValue
	    }

	    -disabledbackground {
		set updateVisual 1
		set options($option) $newValue
	    }

            -dropdownwidth {
                set options($option) $newValue
            }

	    -editable {
		set updateVisual 1
 		if {$newValue} {
 		    # it's editable...
 		    $widgets(entry) configure \
 			    -state normal \
 			    -cursor $defaultEntryCursor
 		} else {
 		    $widgets(entry) configure \
 			    -state disabled \
 			    -cursor $options(-cursor)
 		}
		set options($option) $newValue
	    }

	    -elementborderwidth {
		$widgets(button) configure -borderwidth $newValue
		$widgets(vsb) configure -borderwidth $newValue
		$widgets(dropdown) configure -borderwidth $newValue
		set options($option) $newValue
	    }

	    -font {
		$widgets(entry) configure -font $newValue
		$widgets(listbox) configure -font $newValue
		set options($option) $newValue
	    }

	    -foreground {
		set updateVisual 1
		set options($option) $newValue
	    }

	    -height {
		$widgets(listbox) configure -height $newValue
		HandleScrollbar $w
		set options($option) $newValue
	    }

	    -highlightbackground {
		$widgets(frame) configure -highlightbackground $newValue
		set options($option) $newValue
	    }

	    -highlightcolor {
		$widgets(frame) configure -highlightcolor $newValue
		set options($option) $newValue
	    }

	    -highlightthickness {
		$widgets(frame) configure -highlightthickness $newValue
		set options($option) $newValue
	    }
	    
	    -image {
		if {[string length $newValue] > 0} {
		    puts "old button width: [$widgets(button) cget -width]"
		    $widgets(button) configure \
			-image $newValue \
			-width [expr {[image width $newValue] + 2}]
		    puts "new button width: [$widgets(button) cget -width]"
		    
		} else {
		    $widgets(button) configure -image ::combobox::bimage
		}
		set options($option) $newValue
	    }

	    -listvar {
		if {[catch {$widgets(listbox) cget -listvar}]} {
		    return -code error \
			"-listvar not supported with this version of tk"
		}
		$widgets(listbox) configure -listvar $newValue
		set options($option) $newValue
	    }

	    -maxheight {
		# ComputeGeometry may dork with the actual height
		# of the listbox, so let's undork it
		$widgets(listbox) configure -height $options(-height)
		HandleScrollbar $w
		set options($option) $newValue
	    }

	    -opencommand {
		# nothing else to do...
		set options($option) $newValue
	    }

	    -relief {
		$widgets(frame) configure -relief $newValue
		set options($option) $newValue
	    }

	    -selectbackground {
		$widgets(entry) configure -selectbackground $newValue
		$widgets(listbox) configure -selectbackground $newValue
		set options($option) $newValue
	    }

	    -selectborderwidth {
		$widgets(entry) configure -selectborderwidth $newValue
		$widgets(listbox) configure -selectborderwidth $newValue
		set options($option) $newValue
	    }

	    -selectforeground {
		$widgets(entry) configure -selectforeground $newValue
		$widgets(listbox) configure -selectforeground $newValue
		set options($option) $newValue
	    }

	    -state {
		if {$newValue == "normal"} {
		    set updateVisual 1
		    # it's enabled

		    set editable [::combobox::GetBoolean \
			    $options(-editable)]
		    if {$editable} {
			$widgets(entry) configure -state normal
			$widgets(entry) configure -takefocus 1
		    }

                    # note that $widgets(button) is actually a label,
                    # not a button. And being able to disable labels
                    # wasn't possible until tk 8.3. (makes me wonder
		    # why I chose to use a label, but that answer is
		    # lost to antiquity)
                    if {[info patchlevel] >= 8.3} {
                        $widgets(button) configure -state normal
                    }

		} elseif {$newValue == "disabled"}  {
		    set updateVisual 1
		    # it's disabled
		    $widgets(entry) configure -state disabled
		    $widgets(entry) configure -takefocus 0
                    # note that $widgets(button) is actually a label,
                    # not a button. And being able to disable labels
                    # wasn't possible until tk 8.3. (makes me wonder
		    # why I chose to use a label, but that answer is
		    # lost to antiquity)
                    if {$::tcl_version >= 8.3} {
                        $widgets(button) configure -state disabled 
                    }

		} else {
		    set options($option) $oldValue
		    set message "bad state value \"$newValue\";"
		    append message " must be normal or disabled"
		    error $message
		}

		set options($option) $newValue
	    }

	    -takefocus {
		$widgets(entry) configure -takefocus $newValue
		set options($option) $newValue
	    }

	    -textvariable {
		$widgets(entry) configure -textvariable $newValue
		set options($option) $newValue
	    }

	    -value {
		::combobox::SetValue $widgets(this) $newValue
		set options($option) $newValue
	    }

	    -width {
		$widgets(entry) configure -width $newValue
		$widgets(listbox) configure -width $newValue
		set options($option) $newValue
	    }

	    -xscrollcommand {
		$widgets(entry) configure -xscrollcommand $newValue
		set options($option) $newValue
	    }
	}	    

	if {$updateVisual} {UpdateVisualAttributes $w}
    }
}

# ::combobox::UpdateVisualAttributes --
#
# sets the visual attributes (foreground, background mostly) 
# based on the current state of the widget (normal/disabled, 
# editable/non-editable)
#
# why a proc for such a simple thing? Well, in addition to the
# various states of the widget, we also have to consider the 
# version of tk being used -- versions from 8.4 and beyond have
# the notion of disabled foreground/background options for various
# widgets. All of the permutations can get nasty, so we encapsulate
# it all in one spot.
#
# note also that we don't handle all visual attributes here; just
# the ones that depend on the state of the widget. The rest are 
# handled on a case by case basis
#
# Arguments:
#    w		widget pathname
#
# Returns:
#    empty string

proc ::combobox::UpdateVisualAttributes {w} {

    upvar ::combobox::${w}::widgets     widgets
    upvar ::combobox::${w}::options     options

    if {$options(-state) == "normal"} {

	set foreground $options(-foreground)
	set background $options(-background)
	
    } elseif {$options(-state) == "disabled"} {

	set foreground $options(-disabledforeground)
	set background $options(-disabledbackground)
    }

    $widgets(entry)   configure -foreground $foreground -background $background
    $widgets(listbox) configure -foreground $foreground -background $background
    $widgets(button)  configure -foreground $foreground 
    $widgets(vsb)     configure -background $background -troughcolor $background
    $widgets(frame)   configure -background $background

    # we need to set the disabled colors in case our widget is disabled. 
    # We could actually check for disabled-ness, but we also need to 
    # check whether we're enabled but not editable, in which case the 
    # entry widget is disabled but we still want the enabled colors. It's
    # easier just to set everything and be done with it.
    
    if {$::tcl_version >= 8.4} {
	$widgets(entry) configure \
	    -disabledforeground $foreground \
	    -disabledbackground $background
	$widgets(button)  configure -disabledforeground $foreground
	$widgets(listbox) configure -disabledforeground $foreground
    }
}

# ::combobox::SetValue --
#
#    sets the value of the combobox and calls the -command, 
#    if defined
#
# Arguments:
#
#    w          widget pathname
#    newValue   the new value of the combobox
#
# Returns
#
#    Empty string

proc ::combobox::SetValue {w newValue} {

    upvar ::combobox::${w}::widgets     widgets
    upvar ::combobox::${w}::options     options
    upvar ::combobox::${w}::ignoreTrace ignoreTrace
    upvar ::combobox::${w}::oldValue    oldValue

    if {[info exists options(-textvariable)] \
	    && [string length $options(-textvariable)] > 0} {
	set variable ::$options(-textvariable)
	set $variable $newValue
    } else {
	set oldstate [$widgets(entry) cget -state]
	$widgets(entry) configure -state normal
	$widgets(entry) delete 0 end
	$widgets(entry) insert 0 $newValue
	$widgets(entry) configure -state $oldstate
    }

    # set our internal textvariable; this will cause any public
    # textvariable (ie: defined by the user) to be updated as
    # well
#    set ::combobox::${w}::entryTextVariable $newValue

    # redefine our concept of the "old value". Do it before running
    # any associated command so we can be sure it happens even
    # if the command somehow fails.
    set oldValue $newValue


    # call the associated command. The proc will handle whether or 
    # not to actually call it, and with what args
    CallCommand $w $newValue

    return ""
}

# ::combobox::CallCommand --
#
#   calls the associated command, if any, appending the new
#   value to the command to be called.
#
# Arguments:
#
#    w         widget pathname
#    newValue  the new value of the combobox
#
# Returns
#
#    empty string

proc ::combobox::CallCommand {w newValue} {
    upvar ::combobox::${w}::widgets widgets
    upvar ::combobox::${w}::options options
    
    # call the associated command, if defined and -commandstate is
    # set to "normal"
    if {$options(-commandstate) == "normal" && \
	    [string length $options(-command)] > 0} {
	set args [list $widgets(this) $newValue]
	uplevel \#0 $options(-command) $args
    }
}


# ::combobox::GetBoolean --
#
#     returns the value of a (presumably) boolean string (ie: it should
#     do the right thing if the string is "yes", "no", "true", 1, etc
#
# Arguments:
#
#     value       value to be converted 
#     errorValue  a default value to be returned in case of an error
#
# Returns:
#
#     a 1 or zero, or the value of errorValue if the string isn't
#     a proper boolean value

proc ::combobox::GetBoolean {value {errorValue 1}} {
    if {[catch {expr {([string trim $value])?1:0}} res]} {
	return $errorValue
    } else {
	return $res
    }
}

# ::combobox::convert --
#
#     public routine to convert %x, %y and %W binding substitutions.
#     Given an x, y and or %W value relative to a given widget, this
#     routine will convert the values to be relative to the combobox
#     widget. For example, it could be used in a binding like this:
#
#     bind .combobox <blah> {doSomething [::combobox::convert %W -x %x]}
#
#     Note that this procedure is *not* exported, but is intended for
#     public use. It is not exported because the name could easily 
#     clash with existing commands. 
#
# Arguments:
#
#     w     a widget path; typically the actual result of a %W 
#           substitution in a binding. It should be either a
#           combobox widget or one of its subwidgets
#
#     args  should one or more of the following arguments or 
#           pairs of arguments:
#
#           -x <x>      will convert the value <x>; typically <x> will
#                       be the result of a %x substitution
#           -y <y>      will convert the value <y>; typically <y> will
#                       be the result of a %y substitution
#           -W (or -w)  will return the name of the combobox widget
#                       which is the parent of $w
#
# Returns:
#
#     a list of the requested values. For example, a single -w will
#     result in a list of one items, the name of the combobox widget.
#     Supplying "-x 10 -y 20 -W" (in any order) will return a list of
#     three values: the converted x and y values, and the name of 
#     the combobox widget.

proc ::combobox::convert {w args} {
    set result {}
    if {![winfo exists $w]} {
	error "window \"$w\" doesn't exist"
    }

    while {[llength $args] > 0} {
	set option [lindex $args 0]
	set args [lrange $args 1 end]

	switch -exact -- $option {
	    -x {
		set value [lindex $args 0]
		set args [lrange $args 1 end]
		set win $w
		while {[winfo class $win] != "Combobox"} {
		    incr value [winfo x $win]
		    set win [winfo parent $win]
		    if {$win == "."} break
		}
		lappend result $value
	    }

	    -y {
		set value [lindex $args 0]
		set args [lrange $args 1 end]
		set win $w
		while {[winfo class $win] != "Combobox"} {
		    incr value [winfo y $win]
		    set win [winfo parent $win]
		    if {$win == "."} break
		}
		lappend result $value
	    }

	    -w -
	    -W {
		set win $w
		while {[winfo class $win] != "Combobox"} {
		    set win [winfo parent $win]
		    if {$win == "."} break;
		}
		lappend result $win
	    }
	}
    }
    return $result
}

# ::combobox::Canonize --
#
#    takes a (possibly abbreviated) option or command name and either 
#    returns the canonical name or an error
#
# Arguments:
#
#    w        widget pathname
#    object   type of object to canonize; must be one of "command",
#             "option", "scan command" or "list command"
#    opt      the option (or command) to be canonized
#
# Returns:
#
#    Returns either the canonical form of an option or command,
#    or raises an error if the option or command is unknown or
#    ambiguous.

proc ::combobox::Canonize {w object opt} {
    variable widgetOptions
    variable columnOptions
    variable widgetCommands
    variable listCommands
    variable scanCommands

    switch $object {
	command {
	    if {[lsearch -exact $widgetCommands $opt] >= 0} {
		return $opt
	    }

	    # command names aren't stored in an array, and there
	    # isn't a way to get all the matches in a list, so
	    # we'll stuff the commands in a temporary array so
	    # we can use [array names]
	    set list $widgetCommands
	    foreach element $list {
		set tmp($element) ""
	    }
	    set matches [array names tmp ${opt}*]
	}

	{list command} {
	    if {[lsearch -exact $listCommands $opt] >= 0} {
		return $opt
	    }

	    # command names aren't stored in an array, and there
	    # isn't a way to get all the matches in a list, so
	    # we'll stuff the commands in a temporary array so
	    # we can use [array names]
	    set list $listCommands
	    foreach element $list {
		set tmp($element) ""
	    }
	    set matches [array names tmp ${opt}*]
	}

	{scan command} {
	    if {[lsearch -exact $scanCommands $opt] >= 0} {
		return $opt
	    }

	    # command names aren't stored in an array, and there
	    # isn't a way to get all the matches in a list, so
	    # we'll stuff the commands in a temporary array so
	    # we can use [array names]
	    set list $scanCommands
	    foreach element $list {
		set tmp($element) ""
	    }
	    set matches [array names tmp ${opt}*]
	}

	option {
	    if {[info exists widgetOptions($opt)] \
		    && [llength $widgetOptions($opt)] == 2} {
		return $opt
	    }
	    set list [array names widgetOptions]
	    set matches [array names widgetOptions ${opt}*]
	}

    }

    if {[llength $matches] == 0} {
	set choices [HumanizeList $list]
	error "unknown $object \"$opt\"; must be one of $choices"

    } elseif {[llength $matches] == 1} {
	set opt [lindex $matches 0]

	# deal with option aliases
	switch $object {
	    option {
		set opt [lindex $matches 0]
		if {[llength $widgetOptions($opt)] == 1} {
		    set opt $widgetOptions($opt)
		}
	    }
	}

	return $opt

    } else {
	set choices [HumanizeList $list]
	error "ambiguous $object \"$opt\"; must be one of $choices"
    }
}

# ::combobox::HumanizeList --
#
#    Returns a human-readable form of a list by separating items
#    by columns, but separating the last two elements with "or"
#    (eg: foo, bar or baz)
#
# Arguments:
#
#    list    a valid tcl list
#
# Results:
#
#    A string which as all of the elements joined with ", " or 
#    the word " or "

proc ::combobox::HumanizeList {list} {

    if {[llength $list] == 1} {
	return [lindex $list 0]
    } else {
	set list [lsort $list]
	set secondToLast [expr {[llength $list] -2}]
	set most [lrange $list 0 $secondToLast]
	set last [lindex $list end]

	return "[join $most {, }] or $last"
    }
}

# This is some backwards-compatibility code to handle TIP 44
# (http://purl.org/tcl/tip/44.html). For all private tk commands
# used by this widget, we'll make duplicates of the procs in the
# combobox namespace. 
#
# I'm not entirely convinced this is the right thing to do. I probably
# shouldn't even be using the private commands. Then again, maybe the
# private commands really should be public. Oh well; it works so it
# must be OK...
foreach command {TabToWindow CancelRepeat ListboxUpDown} {
    if {[llength [info commands ::combobox::tk$command]] == 1} break;

    set tmp [info commands tk$command]
    set proc ::combobox::tk$command
    if {[llength [info commands tk$command]] == 1} {
        set command [namespace which [lindex $tmp 0]]
        proc $proc {args} "uplevel $command \$args"
    } else {
        if {[llength [info commands ::tk::$command]] == 1} {
            proc $proc {args} "uplevel ::tk::$command \$args"
        }
    }
}

# end of combobox.tcl


}
#source save/load config options procedure
 #    Copyright 2003 Regis Damongeot

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

set current_version "4.0.4"

proc save_options {} {
	global current_version dvd_size env burning_device option_auto_refresh_space language option_eject_cd burn_speed
	#puts "saving ver $current_version and dvdsize $dvd_size"
	check_config_file_exist
	set config_file [open $env(HOME)/.tkdvd/config w]
	puts $config_file "version = $current_version"
	puts $config_file "dvd_size = $dvd_size"
	puts $config_file "option_auto_refresh_space = $option_auto_refresh_space"
	puts $config_file "language = $language"
	if { $option_eject_cd != "" } { puts $config_file "option_eject_cd = $option_eject_cd" }
	if { $burn_speed != "" } { puts $config_file "burn_speed = $burn_speed" }
	#when "create iso image" is selected, burning_device is equal to the path of the image and so it should not be saved
	if {![string compare -length 3 $burning_device "/dev"]} {
		puts $config_file "burning_device = $burning_device"
	} else {
		puts $config_file "burning_device = /dev/rcd0c"
	}
	close $config_file
}

proc load_options {} {
	global env current_version space_left_f dvd_size burning_device temp_burning_device option_auto_refresh_space language option_eject_cd burn_speed
	set string_temp ""
	check_config_file_exist
	set config_file [open $env(HOME)/.tkdvd/config r]
	while { ! [eof $config_file] } {
		gets $config_file string_temp
		if { [lindex $string_temp 0] == "version" } {
			if {([lindex $string_temp end] != $current_version) } {
				#we need to update config file and check that there is no change that can break loading
				update_version_config_file [lindex $string_temp end]
			}
		}
		if {[lindex $string_temp 0] == "dvd_size"} {
			set dvd_size [lindex $string_temp end]
			#puts "dvd size found when loading settings: $dvd_size"
		}
		if {[lindex $string_temp 0] == "burning_device"} {
			set burning_device [lindex $string_temp end]
			set temp_burning_device "$burning_device"
		}
		if {[lindex $string_temp 0] == "option_auto_refresh_space"} {
			set option_auto_refresh_space [lindex $string_temp end]
		}
		if {[lindex $string_temp 0] == "language"} {
			set language [lindex $string_temp end]
		}
		if {[lindex $string_temp 0] == "option_eject_cd"} {
			set option_eject_cd [lindex $string_temp end]
		}
		if {[lindex $string_temp 0] == "burn_speed"} {
			set burn_speed [lindex $string_temp end]
		}
	}
	if { [eof $config_file] && (($dvd_size != "4589850") && ($dvd_size != "8300790") && ($dvd_size != "665600") && ($dvd_size != "716800") ) } {
		#puts "cant find dvd_size variable in config file, setting to default"
		set dvd_size "4589850"
	}
	#puts "found tkdvd config ver $config_version and dvdsize $dvd_size"

	close $config_file
}

proc check_config_file_exist {} {
	global env current_version
	if { ! [file exists "$env(HOME)/.tkdvd/config"] } {
		if { ! [file isdirectory "$env(HOME)/.tkdvd"] } {
			#puts "creating ~/.tkdvd"
			exec mkdir $env(HOME)/.tkdvd
		}
		if { ! [file exists "$env(HOME)/.tkdvd/config"] } {
			#puts "tkdvd config file doesnt exist, creating it"
			exec touch $env(HOME)/.tkdvd/config
		}
		save_options
		#set config_file [open $env(HOME)/.tkdvd/config w]
		#puts $config_file "version = $current_version"
		#puts $config_file "dvd_size = 4589850"
		#close $config_file
	}
}

proc update_version_config_file { old_version } {
	global current_version env dvd_size
	#puts "updating config file from $old_version to $current_version"
	#for updating, just load previous version options and call save_options proc
	if { $old_version == "2.8" } {
		set config_file [open $env(HOME)/.tkdvd/config r]
		set string_temp ""
		while {! [eof $config_file]} {
			gets $config_file string_temp
			#puts "$string_temp"
			if {[lindex $string_temp 0] == "dvd_size"} {
				set dvd_size [lindex $string_temp end]
			}
		}
		close $config_file
		save_options
	} else {
		#no special change for later versions so we load option classically
	}
}
#load user default options
load_options
#change command line variable according to loaded values
set command_line "growisofs $t_session $burning_device $option_joliet_ext $option_rr_ext $option_dvd_compat $option_pad -graft-points"
#source internationalisation variables
 #    Copyright 2003 Regis Damongeot

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


# If you want to add your langage, just add langage name to i18n_langage_list and repeat what is done for french langage


lset i18n_language_list "English"

set i18n_step1 "Step 1: Select Files and Folders"
set i18n_step2 "Customize Burning"
set i18n_burn_files_and_folders_on_a_dvd "Burn files and folders on a CD/DVD"
set i18n_only_create_iso9660_image "Only create iso9660 image"
set i18n_burn_iso9660_image "Burn iso9660 image"
set i18n_add_files "Add Files..."
set i18n_add_directory "Add Directory..."
set i18n_delete_file_dir "Delete File/Dir"
set i18n_clear_list "Clear List"
set i18n_excluded_files_dir "Excluded Files..."
set i18n_close "Close"
set i18n_used_space "Used space:"
set i18n_free_space "Free space:"
set i18n_burning_device "Burning device:"
set i18n_volume_name "Volume name:"
set i18n_command "Command:"
set i18n_erase_dvdrw "Erase DVD RW"
set i18n_erase_cdrw "Erase CD-RW"
set i18n_advanced_options_b "Advanced Options..."
set i18n_advanced_options_t "Advanced Options"
set i18n_burn "Burn"
set i18n_filesystem_extensions "Filesystem extensions:"
set i18n_add_joliet_extensions "Add Joliet extensions (-J)"
set i18n_rock_ridge_extensions "Rock Ridge extensions:"
set i18n_off "Off"
set i18n_rr_extensions "RR extensions (-R)"
set i18n_anonymous_rr_extensions "Anonymous RR extensions (all files set to r--r--r-- or +x if executable) (-r)"
set i18n_udf_extensions "UDF extensions:"
set i18n_udf_extensions_radiobutton "UDF extensions (-udf)"
set i18n_dvd_video_compliant_udf_filesystem "DVD Video complient UDF filesystem (-dvd-video)"
set i18n_dvd_size "CD/DVD size:"
set i18n_other_options "Other options:"
set i18n_burning_speed "Burning speed, leave blank for maximum speed (-speed=X):"
set i18n_overburn "Overburn (-overburn)"
set i18n_pad "Pad (-pad)"
set i18n_add_session_to_disc "Add session to disc (-M)"
set i18n_maximum_media_compatibility "Maximum media compatibility (if DVD R => create single session closed disc) (-dvd-compat)"
set i18n_monosession_cd "Create monosession CD/Close multisession CD"
set i18n_multisession_cd "Create multisession CD/append session to CD (-multi)"
set i18n_eject_cd_after_burning "Eject CD after burning"
set i18n_automaticaly_refresh_used_space "Automaticaly refresh used space (may take a lot of time)"
set i18n_open "Open..."
set i18n_growisofs_mkisofs_output "growisofs/mkisofs/cdrecord output"
set i18n_update "Update"
set i18n_select_iso_image "Select ISO Image"
set i18n_erase "Erase"
set i18n_full_format "Full format (-blank=full)"
set i18n_full_format_cd "Full format (blank=all)"
set i18n_normal_format "Normal format (-force)"
set i18n_quick_format "Quick format"
set i18n_quick_format_cd "Quick format (blank=fast)"
set i18n_writing_finished "Writing finished"
set i18n_load_file_list "Load file list"
set i18n_save_file_list "Save file list"
set i18n_error_filelist_empty "File list is empty"
set i18n_error "Error"
set i18n_dvd_copy "DVD Copy"
set i18n_cd_copy "CD Copy"
set i18n_copy "Copy"
set i18n_choose_source_device "Choose source device:"
set i18n_quit "Quit"
set i18n_create_iso_from_dvd "Create ISO image from DVD"
set i18n_create_iso_from_cd "Create ISO image from CD"
set i18n_choose_target_file "Choose target file..."
set i18n_create "Create"
set i18n_error_target_file_ns "Target file not specified"
set i18n_error_directory_already_present "This directory is already present in file list"
set i18n_quest_directory_contained "This directory is already contained in another directory in the file list. Add it anyway?"
set i18n_quest_directory_contains "This directory contains files or directorys already present in file list. Add it anyway?"
set i18n_error_file_already_present "The following file is already present in file list"
set i18n_quest_file_contained "The following file is already contained in a directory of the file list. Add it anyway?"
set i18n_error_directory_not_present "This directory is not present in file list"
set i18n_error_file_not_present "This file is not present in file list"
set i18n_error_adding_ef "This file or directory  is already in excluded file list, contains already added files or directory in this list or is contained by an already added directory"



lappend i18n_language_list "French"
if { "$language" == "French" } {
	set i18n_step1 "Etape 1: Selection des fichiers et des dossiers"
	set i18n_step2 "Options de gravure"
	set i18n_burn_files_and_folders_on_a_dvd "Graver les fichiers et les dossiers sur un CD/DVD"
	set i18n_only_create_iso9660_image "Crer une image ISO"
	set i18n_burn_iso9660_image "Graver une image ISO"
	set i18n_add_files "Ajouter fichiers..."
	set i18n_add_directory "Ajouter dossier..."
	set i18n_delete_file_dir "Supprimer"
	set i18n_clear_list "Vider la liste"
	set i18n_excluded_files_dir "Fichiers exclus..."
	set i18n_close "Fermer"
	set i18n_used_space "Espace utilis:"
	set i18n_free_space "Espace libre:"
	set i18n_burning_device "Priphrique:"
	set i18n_volume_name "Nom de volume:"
	set i18n_command "Commande:"
	set i18n_erase_dvdrw "Effacer un DVD RW"
	set i18n_erase_cdrw "Effacer un CD-RW"
	set i18n_advanced_options_b "Options avances..."
	set i18n_advanced_options_t "Options avances"
	set i18n_burn "Graver"
	set i18n_filesystem_extensions "Extensions du systme de fichier:"
	set i18n_add_joliet_extensions "Ajouter les extensions Joliet (-J)"
	set i18n_rock_ridge_extensions "Extensions Rock Ridge:"
	set i18n_off "Dsactiver"
	set i18n_rr_extensions "Extensions RR (-R)"
	set i18n_anonymous_rr_extensions "Extensions RR anonymes (droits r--r--r-- ou +x si executable) (-r)"
	set i18n_udf_extensions "Extensions UDF:"
	set i18n_udf_extensions_radiobutton "Extensions UDF (-udf)"
	set i18n_dvd_video_compliant_udf_filesystem "Extensions UDF en conformance avec le standard DVD Video (-dvd-video)"
	set i18n_dvd_size "Taille des CD/DVD:"
	set i18n_other_options "Autres options:"
	set i18n_burning_speed "Vitesse de gravure, laisser vide pour vitesse maximum (-speed=X):"
	set i18n_overburn "Overburn (-overburn)"
	set i18n_pad "Pad (-pad)"
	set i18n_add_session_to_disc "Ajouter une session au disque courant (-M)"
	set i18n_maximum_media_compatibility "Compatibilit maximum (si DVD R => cration d'un disque monosession ferm) (-dvd-compat)"
	set i18n_monosession_cd "Crer un CD monosession/Fermer un CD multisession"
	set i18n_multisession_cd "Crer un CD multisession/ajouter une session au CD (-multi)"
	set i18n_eject_cd_after_burning "Ejecter le CD aprs la gravure"
	set i18n_automaticaly_refresh_used_space "Rafraichissement automatique de l'espace disque utilis (peut prendre beaucoup de temps)"
	set i18n_open "Ouvrir..."
	set i18n_growisofs_mkisofs_output "Sortie de growisofs/mkisofs/cdrecord"
	set i18n_update "Rafraichir"
	set i18n_select_iso_image "Selectionner l'image ISO"
	set i18n_erase "Effacer"
	set i18n_full_format "Formattage complet (-blank=full)"
	set i18n_full_format_cd "Formattage complet (blank=all)"
	set i18n_normal_format "Formattage normal (-force)"
	set i18n_quick_format "Formattage rapide"
	set i18n_quick_format_cd "Formattage rapide (blank=fast)"
	set i18n_writing_finished "Opration termine"
	set i18n_load_file_list "Charger une liste de fichiers"
	set i18n_save_file_list "Sauvegarder la liste de fichiers"
	set i18n_error_filelist_empty "La liste des fichiers  graver est vide"
	set i18n_error "Erreur"
	set i18n_dvd_copy "Copier un DVD"
	set i18n_cd_copy "Copier un CD"
	set i18n_copy "Copier"
	set i18n_choose_source_device "Choisissez le priphrique source:"
	set i18n_quit "Quitter"
	set i18n_create_iso_from_dvd "Crer une image ISO  partir d'un DVD"
	set i18n_create_iso_from_cd "Crer une image ISO  partir d'un CD"
	set i18n_choose_target_file "Choisir le fichier cible..."
	set i18n_create "Crer"
	set i18n_error_target_file_ns "Fichier cible non prcis"
	set  i18n_error_directory_already_present "Ce dossier est dj prsent dans la liste des fichiers"
	set  i18n_quest_directory_contained "Ce dossier est dj contenu dans un autre dossier de la liste des fichiers. Voulez-vous l'ajouter tout de mme?"
	set  i18n_quest_directory_contains "Ce dossier contient certains fichiers ou dossiers dj prsent dans la liste des fichiers. Voulez-vous l'ajouter tout de mme?"
	set  i18n_error_file_already_present "Le fichier suivant est dj prsent dans la liste des fichiers"
	set  i18n_quest_file_contained "Le fichier suivant est dj contenu dans un dossier de la liste des fichiers. Voulez-vous l'ajouter tout de mme?"
	set i18n_error_directory_not_present "Ce fichier n'est pas prsent dans la liste"
	set i18n_error_file_not_present "Ce fichier n'est pas prsent dans la liste"
	set i18n_error_adding_ef "Ce fichier/dossier est dj dans la liste des fichiers exclus, ou bien contient des fichiers dj ajout  cette liste, ou alors est contenu dans un dossier dj prcedement ajout"
}

lappend i18n_language_list "Italian"
if { "$language" == "Italian" } {
	set i18n_step1 "Passo 1: Selezionare File e Directory"
	set i18n_step2 "Personalizza Scrittura"
	set i18n_burn_files_and_folders_on_a_dvd "Scrive file e directory sul CD/DVD"
	set i18n_only_create_iso9660_image "Crea solo immagine iso9660"
	set i18n_burn_iso9660_image "Scrivi immagine iso9660"
	set i18n_add_files "Aggiungi File..."
	set i18n_add_directory "Aggiungi Dir..."
	set i18n_delete_file_dir "Elimina File/Dir"
	set i18n_clear_list "Cancella Lista"
	set i18n_excluded_files_dir "Escludi Files..."
	set i18n_close "Chiudi"
	set i18n_used_space "Spazio Usato:"
	set i18n_free_space "Spazio Libero:"
	set i18n_burning_device "Dispositivo di scrittura:"
	set i18n_volume_name "Nome Volume:"
	set i18n_command "Comando:"
	set i18n_erase_dvdrw "Cancella DVD RW"
	set i18n_erase_cdrw "Cancella CD-RW"
	set i18n_advanced_options_b "Opzioni Avanzate..."
	set i18n_advanced_options_t "Opzioni Avanzate"
	set i18n_burn "Scrivi"
	set i18n_filesystem_extensions "Estensioni del Filesystem:"
	set i18n_add_joliet_extensions "Aggiungi Estesioni Joliet (-J)"
	set i18n_rock_ridge_extensions "Estensioni Rock Ridge:"
	set i18n_off "Inattivo"
	set i18n_rr_extensions "Estensioni RR (-R)"
	set i18n_anonymous_rr_extensions "Estensioni RR Anonime (tutti i file impostati a r--r--r-- o +x se eseguibile) (-r)"
	set i18n_udf_extensions "Estensioni UDF:"
	set i18n_udf_extensions_radiobutton "Estensioni UDF (-udf)"
	set i18n_dvd_video_compliant_udf_filesystem "Filesystem DVD Video compatibile UDF (-dvd-video)"
	set i18n_dvd_size "Dimensione CD/DVD:"
	set i18n_other_options "Altre Opzioni:"
	set i18n_overburn "Overburn (-overburn)"
	set i18n_pad "Pad (-pad)"
	set i18n_add_session_to_disc "Aggiungi sessione al disco (-M)"
	set i18n_maximum_media_compatibility "Massima compatibilita' con i supporti (se DVD R => crea un disco con una sola sessione) (-dvd-compat)"
	set i18n_monosession_cd "Crea CD monosessione/chiudi CD multisessione"
	set i18n_multisession_cd "Crea CD multisessione/aggiungi sessione ad un CD (-multi)" 
	set i18n_eject_cd_after_burning "Espelli CD al termine"
	set i18n_automaticaly_refresh_used_space "Aggiorna automaticamente lo spazio usato (puo' richiedere molto tempo)"
	set i18n_open "Apri..."
	set i18n_growisofs_mkisofs_output "Output di growisofs/mkisofs/cdrecord"
	set i18n_update "Aggiorna"
	set i18n_select_iso_image "Seleziona un'immagine ISO"
	set i18n_erase "Cancella"
	set i18n_full_format "Formattazione completa (-blank=full)"
	set i18n_full_format_cd "Formattazione completa (blank=all)"
	set i18n_normal_format "Formattazione normale (-force)"
	set i18n_quick_format "Formattazione rapida"
	set i18n_quick_format_cd "Formattazione rapida (blank=fast)"
	set i18n_writing_finished "Scrittura Completata"
	set i18n_load_file_list "Carica lista file"
	set i18n_save_file_list "Salva lista file"
	set i18n_error_filelist_empty "lista file vuota"
	set i18n_error "Errore"
	set i18n_dvd_copy "Copia DVD"
	set i18n_cd_copy "Copia CD"
	set i18n_copy "Copia"
	set i18n_choose_source_device "Scegli periferica di origine:"
	set i18n_quit "Esci"
	set i18n_create_iso_from_dvd "Crea immagineISO da un DVD"
	set i18n_create_iso_from_cd "Crea immagineISO da un CD"
	set i18n_choose_target_file "Scegli file destinazione..."
	set i18n_create "Crea"
	set i18n_error_target_file_ns "File destinazioen non specificato"
	set i18n_error_directory_already_present "Questa direcotry e' gia' presente nella lista"
	set i18n_quest_directory_contained "Questa directory e' gia' contenuta in un'altra presente nella lista. Continuare lo stesso?"
	set i18n_quest_directory_contains "Questa directory contiene file o directory gia' presenti nella lista. Aggiungerla lo stesso?"
	set i18n_error_file_already_present "Il file seguente e' gia' presente nella lista"
	set i18n_quest_file_contained "Il file seguente e' gia' contenuto in una directry della lista. Aggiugnerlo lo stesso?"
	set i18n_error_directory_not_present "Questa directory non e' presente nella lista"
	set i18n_error_file_not_present "Questo file non e' presente nella lista"
	set i18n_error_adding_ef "Questo file/directory e' gia' nella lista delle esclusioni, contiene dei file/directory gia' aggiunti a questa lista o e' contenuto in una directory gia' inserita"
}

lappend i18n_language_list "Spanish"
if { "$language" == "Spanish" } {
	set i18n_step1 "Paso 1: Seleccionar archivos y directorios"
	set i18n_step2 "Paso 2: Grabacin personalizada"
	set i18n_burn_files_and_folders_on_a_dvd "Grabar archivos y directorios en el CD/DVD"
	set i18n_only_create_iso9660_image "Solamente crear la imagen ISO9660"
	set i18n_burn_iso9660_image "Grabar la imagen ISO9660"
	set i18n_add_files "Aadir archivos"
	set i18n_add_directory "Aadir directorios"
	set i18n_delete_file_dir "Borrar archivo"
	set i18n_clear_list "Limpiar lista"
	set i18n_excluded_files_dir "Excluir archivos"
	set i18n_close "Cerrar"
	set i18n_used_space "Espacio usado:"
	set i18n_free_space "Espacio libre:"
	set i18n_burning_device "Dispositivo grabacin:"
	set i18n_volume_name "Nombre del volumen:"
	set i18n_command "Orden:"
	set i18n_erase_dvdrw "Borrar DVD RW"
	set i18n_erase_cdrw "Borrar CD-RW"
	set i18n_advanced_options_b "Opciones avanzadas"
	set i18n_advanced_options_t "Opciones avanzadas"
	set i18n_burn "Grabar"
	set i18n_filesystem_extensions "Opciones detalladas:"
	set i18n_add_joliet_extensions "Aadir Joliet (para Windows) (-J)"
	set i18n_rock_ridge_extensions "Rock Ridge:"
	set i18n_off "Apagado"
	set i18n_rr_extensions "RR (-R)"
	set i18n_anonymous_rr_extensions "Annimo RR (todos archivos son lecture fija o ejecutable) (-r)"
	set i18n_udf_extensions "UDF:"
	set i18n_udf_extensions_radiobutton "UDF (-udf)"
	set i18n_dvd_video_compliant_udf_filesystem "DVD video UDF (-dvd-video)"
	set i18n_dvd_size "Tamao de CD/DVD:"
	set i18n_other_options "Otras opciones:"
	set i18n_overburn "Permitir overburning (-overburn)"
	set i18n_pad "Pad (-pad)"
	set i18n_add_session_to_disc "Aadir sesin a disco (-M)"
	set i18n_maximum_media_compatibility "Mximo tamao del medio (si DVD R => crear unisesin disco cerrado) (-dvd-compat)"
	set i18n_open "Abrir..."
	set i18n_select_iso_image "Seleccionar la imagen ISO"
	set i18n_erase "Borrar"
	set i18n_full_format "Formato completo (-blank=full)"
	set i18n_full_format_cd "Formato completo (blank=all)"
	set i18n_normal_format "Formato normal (-force)"
	set i18n_quick_format "Formato rpido"
	set i18n_quick_format_cd "Formato rpido (blank=fast)"
	set i18n_writing_finished "Grabando completo"
}
#source of the total file size count procedure
#    Copyright 2003 Regis Damongeot

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

 
proc refresh_total_file_size {} {
	global file_list total_file_size_f space_left_f command_line t_session excluded_file_list dvd_size 
	#set local var total_file_size_type cause if total_file_size < 1024 octets, total_file_size isnt set
	set total_file_size_type "KB"
	#set local var total_file_size cause if llength $file_list > 1 then $total_file_size is not set for the fisrt iteration of "for"
	set total_file_size 0
	#attention: $total_file_size is in KB to prevent overflow if $total_file_size > 2go
	if {[llength $file_list] == 0} {
		set total_file_size 0
	} elseif { [llength $file_list] == 1 } {
		if {[file isdirectory [lindex $file_list 0]]} {
			set total_file_size [expr [lindex [exec du -ks -- [lindex $file_list 0]] 0] - [file size [lindex $file_list 0]]/1024]
		} else { set total_file_size [expr [file size [lindex $file_list 0]]/1024.] }
	} else {
		for { set i 0 } {$i < [llength $file_list]} {incr i} {
			if {[file isdirectory [lindex $file_list $i]]} {
				set total_file_size [expr $total_file_size + [expr [lindex [exec du -ks -- [lindex $file_list $i]] 0] - [file size [lindex $file_list 0]]/1024]]
			} else { set total_file_size [expr ($total_file_size + [expr ([file size [lindex $file_list $i]])/1024.])] }
		}
	}
	
	
	foreach i $excluded_file_list {
		if { [file isdirectory $i] } {
			set total_file_size [expr $total_file_size - [exec du -ks $i | cut -f1 ] ]
		} elseif { [file isfile $i] } {
			set total_file_size [expr $total_file_size - ([ file size $i ] / 1024.) ]
		}
	}
	
	
	# save total_file_size in order to reuse it to calculate space_left more easily
	set space_left $total_file_size
	if { $total_file_size > 1048576 } {
		set total_file_size [expr (($total_file_size)/1024.)/1024.]
		set total_file_size_type "GB"
	} elseif { $total_file_size > 1024 } {
		set total_file_size [expr ($total_file_size)/1024.]
		set total_file_size_type "MB"
	} else {
		set total_file_size $total_file_size
		set total_file_size_type "KB"
	}
	set total_file_size_f "$total_file_size $total_file_size_type"
	switch $total_file_size_type  {
		GB {
			set space_left [expr ($dvd_size - $space_left)/1024.]
			set space_left_type "MB"
		}
		MB {
			#if we burn CD we don't want space left to be in GB
			if { $dvd_size == "665600" || $dvd_size == "716800"} {
				set space_left [expr ($dvd_size - $space_left)/1024.]
				set space_left_type "MB"
			} else {
				set space_left [expr (($dvd_size - $space_left)/1024.)/1024.]
				set space_left_type "GB"
			}
		}
		KB {
			#if we burn CD we don't want space left to be in GB
			if { $dvd_size == "665600" || $dvd_size == "716800"} {
				set space_left [expr ($dvd_size - $space_left)/1024.]
				set space_left_type "MB"
			} else {
				set space_left [expr (($dvd_size - $space_left)/1024.)/1024.]
				set space_left_type "GB"
			}
		}
	}
	#if {$t_session == "-use-the-force-luke=tty -Z"} {set space_left_f "$space_left $space_left_type"
	#} else {set space_left_f "N/A"}
	set space_left_f "$space_left $space_left_type"
}
#source of the refresh command line procedure (main procedure)
#    Copyright 2003 Regis Damongeot

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

 
proc refresh_cmd_line {} {
	global total_file_size_f option_udf_ext option_joliet_ext option_rr_ext burn_speed file_list volume_id option_pad burn_type command_line t_session burning_device iso_file space_left_f burn_command option_dvd_compat option_overburn excluded_file_list dvd_size v_create_iso option_eject_cd option_tao_dao_cd cd_session_type
	refresh_burning_variables
	set_visible_options
	if { [catch { exec ps -A | grep -v "grep -E" | grep -E "growisofs|cdrecord" }] != 0} {
		if { ($burn_type == "burn_dvd") || ($v_create_iso == "yes") } {
			check_volume_id
			if { [lindex $space_left_f 0] <0 && $option_overburn == "" && $burn_type == "burn_dvd" && $v_create_iso == "no" } {
				#exact maximum size: 4.37721610069. Although it should be oversized because "du" return > real file size due to indirect blocks its undersized to prevent disallowing burning when beleving overburn is needed while its no the case (anyway growisofs check it)
				set command_line "You need to enable overburning if you want to burn all theses files"
				.f_burn.go_button configure -state disabled
			} else {
				#create list containing excluded files and directories prefixed with -m option
				set excluded_file_list_t ""
				foreach i $excluded_file_list {
					append excluded_file_list_t "-m {$i} "
					
				}

				#create local variable that are copy of global ones, used to remove unused option
				#for exemple, when creating ISO, no need of overburn option
				#we create local variables to prevent using a lot of "if/else" that only remove theses options when needed because there is already a lot of if else only for CD/DVDs :-(
				set local_option_overburn "$option_overburn"
				set local_t_session "$t_session"
				set local_burn_speed "$burn_speed"
				set local_option_dvd_compat "$option_dvd_compat"
				if { $v_create_iso == "yes" } {
					set local_option_overburn ""
					set local_t_session ""
					set local_burn_speed ""
					set local_option_dvd_compat ""
				} else {
					if { $burn_speed != "" } {
						#for growisofs there is a "-" before speed option while cdrecord doesn't take one
						if { $dvd_size > 716800 } {
							set local_burn_speed "-speed=$burn_speed"
						} else {
							set local_burn_speed "speed=$burn_speed"
						}
					} else {
						set local_burn_speed ""
					}
				}

				#if we burn a DVD-Video UDF complient we need to not modify directory with graft points
				if {$option_udf_ext != "-dvd-video" } {
					#if burning a CD, command line is different (pipe between mkisofs and cdrecord)
					if { $dvd_size <= 716800 &&  $v_create_iso == "no" } {
						set command_line "[concat $burn_command $volume_id $option_udf_ext $option_joliet_ext $option_rr_ext $option_pad -graft-points $excluded_file_list_t [file_list_w_modif_dir $file_list]] | cdrecord dev=$burning_device $local_burn_speed $option_overburn $option_eject_cd $cd_session_type -"
					} else {
						set command_line "[concat $burn_command $local_t_session $burning_device $volume_id $option_udf_ext $option_joliet_ext $option_rr_ext $local_burn_speed $local_option_dvd_compat $local_option_overburn $option_pad -graft-points $excluded_file_list_t [file_list_w_modif_dir $file_list]]"
					}
				} else {
					if { $dvd_size <= 716800  && $v_create_iso == "no" } {
						set command_line "[concat $burn_command $volume_id $option_udf_ext $excluded_file_list_t $file_list] | cdrecord dev=$burning_device $local_burn_speed $option_overburn $option_eject_cd $cd_session_type -"
					} else {
						set command_line "[concat $burn_command $local_t_session $burning_device $volume_id $option_udf_ext $local_burn_speed $local_option_dvd_compat $local_option_overburn $excluded_file_list_t $file_list]"
					}
				}
				#enable burn button if all OK
				if { [.f_burn.go_button cget -state] == "disabled" } { .f_burn.go_button configure -state normal }
			}
		} elseif { $burn_type == "burn_iso" } {
			if { $burn_speed != "" } {
				#for growisofs there is a "-" before speed option while cdrecord doesn't take one
				if { $dvd_size > 716800 } {
					set local_burn_speed "-speed=$burn_speed"
				} else {
					set local_burn_speed "speed=$burn_speed"
				}
			} else {
				set local_burn_speed ""
			}
			if { $dvd_size <= 716800 } {
				set command_line "$burn_command $option_overburn $local_burn_speed $option_eject_cd  $option_tao_dao_cd dev=$burning_device $iso_file"
			} else {
				set command_line "$burn_command $option_dvd_compat $local_burn_speed $option_overburn $t_session $burning_device=$iso_file"
			}
			if { [.f_burn.go_button cget -state] == "disabled" } { .f_burn.go_button configure -state normal }
		}
	} else { set command_line "growisofs/cdrecord is currently working" }
	if {($t_session == "-M" && $space_left_f != "N/A") || ($t_session == "-use-the-force-luke=tty -Z" && $space_left_f == "N/A") } { refresh_total_file_size }
	return 1
}
#source of excluded file window and its needed procedures
#    Copyright 2003 Regis Damongeot

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

proc proc_add_excluded_f_d { files_list } {
	global excluded_file_list option_auto_refresh_space i18n_error i18n_error_file_not_present i18n_error_directory_not_present i18n_error_adding_ef
	#if user click on cancel, returned list = ""
	if { $files_list != "" } {
		#foreach needed for multiple files selection
		foreach i $files_list {
			set file_present [file_is_present_or_conatained "$i"]
			set file_present_efl [file_is_present_or_conatained_in_efl "$i"]
			if { $file_present == "no" } {
				if { [file isfile $i] } {
					tk_messageBox -icon error -message "$i18n_error_file_not_present" -type ok -title $i18n_error
				} elseif { [file isdirectory $i] } {
					tk_messageBox -icon error -message "$i18n_error_directory_not_present" -type ok -title $i18n_error
				}
			} else {
				#check if file is not already in excluded file list or contains/contained in (see ile_is_present_or_conatained_in_efl procedure)
				if { $file_present_efl != "no" } {
					tk_messageBox -icon error -message "$i18n_error_adding_ef: $i" -type ok -title $i18n_error
				} else {
					lappend excluded_file_list $i
				}
			}
		}
		
		if { $option_auto_refresh_space == "1" } {
			refresh_total_file_size
		}
		refresh_cmd_line
	} else {
	#puts "No file or dir chosen"
	}
}

proc delete_excluded_files {} {
	global excluded_file_list option_auto_refresh_space
	if { "[.excluded_file_window.file_list.list curselection]" == "" } {
	} else {
		set excluded_file_list [lreplace $excluded_file_list [.excluded_file_window.file_list.list curselection] [.excluded_file_window.file_list.list curselection]]
		#refresh command line entry after checking space used to check overburn condition
		if { $option_auto_refresh_space == "1" } {
			refresh_total_file_size
		}
		refresh_cmd_line
	}
}

proc excluded_file_window {} {
	global excluded_file_list
	#i18n
	global i18n_add_files i18n_add_directory i18n_delete_file_dir i18n_clear_list i18n_close
if { ! [winfo exists .excluded_file_window] } {
	toplevel .excluded_file_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
	wm title .excluded_file_window "Excluded Files And Directories"
	frame .excluded_file_window.f_buttons
	button .excluded_file_window.f_buttons.b_add_files -highlightbackground red -width 13 -text "$i18n_add_files" -command { proc_add_excluded_f_d [tk_getOpenFile -multiple 1] }
	button .excluded_file_window.f_buttons.b_add_dir -highlightbackground red -width 13 -text "$i18n_add_directory" -command { proc_add_excluded_f_d "{[tk_chooseDirectory -mustexist true]}" }
	button .excluded_file_window.f_buttons.b_del -highlightbackground red -width 13 -text "$i18n_delete_file_dir" -command { delete_excluded_files }
	button .excluded_file_window.f_buttons.b_clear -highlightbackground red -width 13 -text "$i18n_clear_list" -command { set excluded_file_list ""; refresh_total_file_size; refresh_cmd_line }
	button .excluded_file_window.f_buttons.b_close -highlightbackground red -width 13 -text "$i18n_close" -command {destroy .excluded_file_window}
	pack .excluded_file_window.f_buttons.b_add_files .excluded_file_window.f_buttons.b_add_dir .excluded_file_window.f_buttons.b_del .excluded_file_window.f_buttons.b_clear .excluded_file_window.f_buttons.b_close -side left
	pack .excluded_file_window.f_buttons -side top
	
	frame .excluded_file_window.file_list
	listbox .excluded_file_window.file_list.list -bg #f5f5f5 -listvariable excluded_file_list -heigh 15 -yscrollcommand { .excluded_file_window.file_list.scroll_bar set }
	scrollbar .excluded_file_window.file_list.scroll_bar -command { .file_list.list yview }
	pack .excluded_file_window.file_list.scroll_bar -side right -fill y
	pack .excluded_file_window.file_list.list -fill x
	pack .excluded_file_window.file_list -fill both -expand false -side bottom
}
}

#source advanced options window procedure
#    Copyright 2003 Regis Damongeot

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

proc advanced_options_window {} {
	global burn_type v_create_iso dvd_size option_auto_refresh_space burn_speed langage tristatecompatibility option_tao_dao_cd cd_session_type
	#i18n variables
	global i18n_filesystem_extensions i18n_add_joliet_extensions i18n_rock_ridge_extensions i18n_off i18n_rr_extensions i18n_anonymous_rr_extensions i18n_udf_extensions i18n_udf_extensions_radiobutton i18n_dvd_video_compliant_udf_filesystem i18n_dvd_size i18n_other_options i18n_burning_speed i18n_overburn i18n_pad i18n_add_session_to_disc i18n_maximum_media_compatibility i18n_automaticaly_refresh_used_space i18n_close i18n_advanced_options_t i18n_eject_cd_after_burning i18n_monosession_cd i18n_multisession_cd
if { ! [winfo exists .advanced_options_window] } {
	toplevel .advanced_options_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
	wm title .advanced_options_window "$i18n_advanced_options_t"
	
	#create frame for options buttons
	frame .advanced_options_window.f_fs_ext -background #f5f5f5
	frame .advanced_options_window.options_fs -background #f5f5f5
	frame .advanced_options_window.f_options_rr -background #f5f5f5
	frame .advanced_options_window.f_options_udf -background #f5f5f5
	frame .advanced_options_window.rr_radiobuttons -background #f5f5f5
	frame .advanced_options_window.udf_radiobuttons -background #f5f5f5
	frame .advanced_options_window.f_opts_dvd_size -background #f5f5f5
	frame .advanced_options_window.f_dvd_size -background #f5f5f5
	frame .advanced_options_window.f_opts_dvd -background #f5f5f5
	frame .advanced_options_window.f_opts_cd -background #f5f5f5
	frame .advanced_options_window.f_opts_cd.f_cd_burn_type -background #f5f5f5
	frame .advanced_options_window.f_oth_opts -background #f5f5f5
	frame .advanced_options_window.options_oth -background #f5f5f5
	frame .advanced_options_window.f_langage -background #f5f5f5
	
	label .advanced_options_window.f_fs_ext.label_fs_ext -bg #f5f5f5 -text "$i18n_filesystem_extensions"
	label .advanced_options_window.f_options_rr.label_fs_rr -bg #f5f5f5 -text "$i18n_rock_ridge_extensions"
	label .advanced_options_window.f_options_udf.label_fs_udf -bg #f5f5f5 -text "$i18n_udf_extensions"
	label .advanced_options_window.f_opts_dvd_size.label_dvd_size -bg #f5f5f5 -text "$i18n_dvd_size"
	label .advanced_options_window.f_oth_opts.label_oth_opts -bg #f5f5f5 -text "$i18n_other_options"
	label .advanced_options_window.f_langage.label_langage -bg #f5f5f5 -text "Langage:"

	label .advanced_options_window.f_opts_dvd.label_dvd -bg #f5f5f5 -text "DVD:"
	label .advanced_options_window.f_opts_cd.label_cd -bg #f5f5f5 -text "CD:"
	
	checkbutton .advanced_options_window.options_fs.joliet_ext -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_add_joliet_extensions" -variable option_joliet_ext -offvalue "" -onvalue "-J" -command refresh_cmd_line
	
	checkbutton .advanced_options_window.options_oth.pad -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_pad" -variable option_pad -offvalue "" -onvalue "-pad"  -command refresh_cmd_line

	radiobutton .advanced_options_window.rr_radiobuttons.rr_ext_off -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_off" -variable option_rr_ext -value "" -command refresh_cmd_line

	radiobutton .advanced_options_window.rr_radiobuttons.rr_ext -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_rr_extensions" -variable option_rr_ext -value "-R"  -command refresh_cmd_line
	
	radiobutton .advanced_options_window.rr_radiobuttons.rra_ext -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_anonymous_rr_extensions" -variable option_rr_ext -value "-r" -command refresh_cmd_line
	
	radiobutton .advanced_options_window.udf_radiobuttons.udf_ext_off -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_off" -variable option_udf_ext -value "" -command refresh_cmd_line
	
	radiobutton .advanced_options_window.udf_radiobuttons.udf_ext -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_udf_extensions_radiobutton" -variable option_udf_ext -value "-udf" -command refresh_cmd_line
	
	radiobutton .advanced_options_window.udf_radiobuttons.dvd_video_ext -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_dvd_video_compliant_udf_filesystem" -variable option_udf_ext -value "-dvd-video" -command refresh_cmd_line
	
	label .advanced_options_window.options_oth.label_burn_speed -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_burning_speed"

	entry .advanced_options_window.options_oth.entry_burn_speed -relief flat -bg white -highlightbackground blue -highlightcolor blue -disabledbackground #f5f5f5 -state normal -textvariable burn_speed -width 3

	checkbutton .advanced_options_window.options_oth.overburn -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_overburn" -variable option_overburn -offvalue "" -onvalue "-overburn" -command refresh_cmd_line
	
	checkbutton .advanced_options_window.f_opts_dvd.multisession -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_add_session_to_disc" -variable t_session -offvalue "-use-the-force-luke=tty -Z" -onvalue "-use-the-force-luke=tty -Z -M"  -command refresh_cmd_line
	
	checkbutton .advanced_options_window.f_opts_dvd.monosession -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_maximum_media_compatibility" -variable option_dvd_compat -offvalue "" -onvalue "-dvd-compat"  -command refresh_cmd_line
	
	radiobutton .advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_cmd_line } -text "Track at once (-tao)" -variable option_tao_dao_cd  -value "-tao"

	radiobutton .advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_cmd_line } -text "Disk/Session at once (-dao)" -variable option_tao_dao_cd  -value "-dao"

	radiobutton .advanced_options_window.f_opts_cd.monosession  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_cmd_line } -text $i18n_monosession_cd -variable cd_session_type  -value ""

	radiobutton .advanced_options_window.f_opts_cd.multisession  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_cmd_line } -text $i18n_multisession_cd -variable cd_session_type  -value "-multi"

	checkbutton .advanced_options_window.f_opts_cd.eject_cd -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_eject_cd_after_burning" -variable option_eject_cd -offvalue "" -onvalue "-eject"  -command refresh_cmd_line

	checkbutton .advanced_options_window.options_oth.auto_refresh_space -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_automaticaly_refresh_used_space" -variable option_auto_refresh_space -offvalue "0" -onvalue "1" -command {if { $option_auto_refresh_space == "1" } { pack forget .f_upper_file_list.b_update }  else { pack .f_upper_file_list.b_update -side left } }
	
	radiobutton .advanced_options_window.f_dvd_size.cd6  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_total_file_size; refresh_cmd_line } -text "650 MB" -variable dvd_size -value 665600

	radiobutton .advanced_options_window.f_dvd_size.cd7 -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_total_file_size; refresh_cmd_line } -text "700 MB" -variable dvd_size -value 716800

	radiobutton .advanced_options_window.f_dvd_size.single_layer  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_total_file_size; refresh_cmd_line } -text "4.7 GB" -variable dvd_size -value 4589850
	
	radiobutton .advanced_options_window.f_dvd_size.dual_layer  -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -command { refresh_total_file_size; refresh_cmd_line }  -text "8.5 GB (DL)" -variable dvd_size -value 8300790

	::combobox::combobox .advanced_options_window.f_langage.langage_list -listvar i18n_language_list -editable false -textvariable language
	
	
	#button .advanced_options_window.f_dvd_size.b_save -highlightbackground red -text "Save" -command { save_options }
	
	button .advanced_options_window.b_close -highlightbackground red -text "$i18n_close" -command { destroy .advanced_options_window; refresh_cmd_line }
	
	#see TkDVD.sh comments about Tk 8.4/8.5 compatibility and tristate option
	if { $tristatecompatibility == yes } {
	  #checkbuttons
	  .advanced_options_window.options_fs.joliet_ext configure -tristatevalue "tristate"
	  .advanced_options_window.options_oth.pad configure -tristatevalue "tristate"
	  .advanced_options_window.options_oth.overburn configure -tristatevalue "tristate"
	  .advanced_options_window.f_opts_dvd.multisession configure -tristatevalue "tristate"
	  .advanced_options_window.f_opts_dvd.monosession configure -tristatevalue "tristate"
	  .advanced_options_window.f_opts_cd.eject_cd configure -tristatevalue "tristate"
	  .advanced_options_window.options_oth.auto_refresh_space configure -tristatevalue "tristate"
	  #radiobuttons
	  .advanced_options_window.rr_radiobuttons.rr_ext_off configure -tristatevalue "tristate"
	  .advanced_options_window.rr_radiobuttons.rr_ext configure -tristatevalue "tristate"
	  .advanced_options_window.rr_radiobuttons.rra_ext configure -tristatevalue "tristate"
	  .advanced_options_window.udf_radiobuttons.udf_ext_off configure -tristatevalue "tristate"
	  .advanced_options_window.udf_radiobuttons.udf_ext configure -tristatevalue "tristate"
	  .advanced_options_window.udf_radiobuttons.dvd_video_ext configure -tristatevalue "tristate"
	  .advanced_options_window.f_opts_cd.monosession configure -tristatevalue "tristate"
	  .advanced_options_window.f_opts_cd.multisession configure -tristatevalue "tristate"
	}

	set_visible_options
	
	
	#pack buttons and labels
	pack .advanced_options_window.f_fs_ext.label_fs_ext -side left
	pack .advanced_options_window.f_options_rr.label_fs_rr -side left
	pack .advanced_options_window.f_options_udf.label_fs_udf -side left
	pack .advanced_options_window.f_opts_dvd_size.label_dvd_size -side left
	pack .advanced_options_window.f_oth_opts.label_oth_opts -side left
	pack .advanced_options_window.options_fs.joliet_ext -side top -anchor w -padx {12 0}
	pack .advanced_options_window.f_dvd_size.cd6 .advanced_options_window.f_dvd_size.cd7 .advanced_options_window.f_dvd_size.single_layer .advanced_options_window.f_dvd_size.dual_layer -side left -anchor w -padx {12 0}
	#DVD section
	pack .advanced_options_window.f_opts_dvd.label_dvd -side top -anchor w
	pack .advanced_options_window.f_opts_dvd.multisession .advanced_options_window.f_opts_dvd.monosession -side top -anchor w -padx {12 0}
	#CD section
	pack .advanced_options_window.f_opts_cd.label_cd -side top -anchor w
	pack .advanced_options_window.f_opts_cd.eject_cd -side top -anchor w -padx {12 0}
	pack .advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao .advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao -side left -anchor w -padx {12 0}
	pack .advanced_options_window.f_opts_cd.f_cd_burn_type -side top -anchor w
	pack .advanced_options_window.f_opts_cd.monosession .advanced_options_window.f_opts_cd.multisession -side left -anchor w -padx {12 0}
	#other options
	pack .advanced_options_window.options_oth.overburn .advanced_options_window.options_oth.pad -side top -anchor w -padx {12 0}
	pack .advanced_options_window.options_oth.auto_refresh_space  -side top -anchor w -padx {12 0}
	pack .advanced_options_window.options_oth.label_burn_speed .advanced_options_window.options_oth.entry_burn_speed -side left -anchor w -padx {12 0}
	#langage
	pack .advanced_options_window.f_langage.label_langage -side top -anchor w
	pack .advanced_options_window.f_langage.langage_list -side top -anchor w -padx {12 0}  -pady {6 0}
	#pack .advanced_options_window.f_dvd_size.b_save -side right -padx {0 12}
	pack .advanced_options_window.rr_radiobuttons.rr_ext_off -side left -padx {24 0}
	pack .advanced_options_window.rr_radiobuttons.rr_ext .advanced_options_window.rr_radiobuttons.rra_ext  -side left
	pack .advanced_options_window.udf_radiobuttons.udf_ext_off .advanced_options_window.udf_radiobuttons.udf_ext .advanced_options_window.udf_radiobuttons.dvd_video_ext -side left -padx {24 0}
	#packing frames
	pack .advanced_options_window.f_fs_ext -fill x
	pack .advanced_options_window.options_fs -fill x
	pack .advanced_options_window.f_options_rr -fill x -padx {12 0}
	pack .advanced_options_window.rr_radiobuttons -fill x
	pack .advanced_options_window.f_options_udf -fill x -padx {12 0}
	pack .advanced_options_window.udf_radiobuttons -fill x
	pack .advanced_options_window.f_opts_dvd_size -fill x -pady {6 0}
	pack .advanced_options_window.f_dvd_size -fill x
	pack .advanced_options_window.f_opts_dvd -fill x -pady {6 0}
	pack .advanced_options_window.f_opts_cd -fill x -pady {6 0}
	pack .advanced_options_window.f_oth_opts -fill x -pady {6 0}
	pack .advanced_options_window.options_oth -fill x
	pack .advanced_options_window.f_langage -fill x -pady {6 0}
	pack .advanced_options_window.b_close -side right -padx {0 12} -pady {0 6}
}
}

#source main TkDVD window
#    Copyright 2003 Regis Damongeot

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

. configure -background #f5f5f5

#fill the  top menu
frame .f_menubar
menubutton .f_menubar.file -text File -underline 0 -menu .f_menubar.file.menu
menubutton .f_menubar.cd -text CD -underline 0 -menu .f_menubar.cd.menu
menubutton .f_menubar.dvd -text DVD -underline 0 -menu .f_menubar.dvd.menu
menu .f_menubar.file.menu -tearoff 0
menu .f_menubar.cd.menu -tearoff 0
menu .f_menubar.dvd.menu -tearoff 0
.f_menubar.file.menu add command -label "$i18n_load_file_list" -command {load_file_list }
.f_menubar.file.menu add command -label "$i18n_save_file_list" -command {save_file_list }
.f_menubar.file.menu add command -label "$i18n_quit" -command {save_options ; exit }
.f_menubar.cd.menu add command -label "$i18n_cd_copy" -command { disc_copy "cd" }
.f_menubar.cd.menu add command -label "$i18n_create_iso_from_cd" -command { disc_to_iso "cd" }
.f_menubar.cd.menu add command -label "$i18n_erase_cdrw" -command { cd_choose_format }
.f_menubar.dvd.menu add command -label "$i18n_dvd_copy" -command { disc_copy "dvd" }
.f_menubar.dvd.menu add command -label "$i18n_create_iso_from_dvd" -command { disc_to_iso "dvd" }
.f_menubar.dvd.menu add command -label "$i18n_erase_dvdrw" -command { dvd_choose_format }
pack .f_menubar.file .f_menubar.cd .f_menubar.dvd -side left
pack .f_menubar -fill x

frame .f_label_first_step -background #c7d1d1
label .f_label_first_step.l_first_step -bg #c7d1d1 -text "$i18n_step1"

frame .f_first_step -background #f5f5f5
radiobutton .f_first_step.burn_dvd -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_burn_files_and_folders_on_a_dvd" -command refresh_cmd_line -variable burn_type -value burn_dvd
.f_first_step.burn_dvd select

frame .f_first_step_b -background #f5f5f5
button .f_first_step_b.add -highlightbackground blue -text "$i18n_add_files" -width 12 -command { add_file [tk_getOpenFile -multiple 1] }
button .f_first_step_b.add_d -highlightbackground blue -text "$i18n_add_directory" -width 12 -command add_d
button .f_first_step_b.delete -highlightbackground blue -text "$i18n_delete_file_dir" -width 12 -command delete_files
button .f_first_step_b.clear -highlightbackground blue -text "$i18n_clear_list" -width 12 -command { set file_list ""; refresh_total_file_size; refresh_cmd_line }
button .f_first_step_b.excluded_files -highlightbackground blue -width 12 -text "$i18n_excluded_files_dir" -command { excluded_file_window }

frame .f_upper_file_list -background #f5f5f5
label .f_upper_file_list.l_file_size -bg #f5f5f5 -text "$i18n_used_space"
entry .f_upper_file_list.show_file_size -relief flat -highlightbackground #f5f5f5 -highlightcolor #f5f5f5 -readonlybackground #f5f5f5 -state readonly -textvariable total_file_size_f -width 10
label .f_upper_file_list.l_space_left -bg #f5f5f5 -text "$i18n_free_space"
entry .f_upper_file_list.show_space_left -relief flat -highlightbackground #f5f5f5 -highlightcolor #f5f5f5 -readonlybackground #f5f5f5 -state readonly -textvariable space_left_f -width 10
button .f_upper_file_list.b_update -highlightbackground blue -text "$i18n_update" -command { refresh_total_file_size }

frame .file_list -bg #f5f5f5
#seems to be necessary to fix an height (for Puppy a least)
listbox .file_list.file_list -bg white -height 8 -listvariable file_list -yscrollcommand { .file_list.scroll_bar set }
scrollbar .file_list.scroll_bar -command { .file_list.file_list yview }

frame .f_only_create_iso -bg #f5f5f5
checkbutton .f_only_create_iso.only_create_iso -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_only_create_iso9660_image" -command refresh_cmd_line -variable v_create_iso -onvalue "yes" -offvalue "no"

frame .f_first_step_iso -background #f5f5f5
radiobutton .f_first_step_iso.b_burn_iso -activebackground #f5f5f5 -background #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_burn_iso9660_image" -command refresh_cmd_line -variable burn_type -value burn_iso
button  .f_first_step_iso.b_open_iso -highlightbackground blue -text "$i18n_open" -state disabled -command choose_iso_file -width 7
entry .f_first_step_iso.iso_file -relief flat -highlightbackground blue -highlightcolor blue -readonlybackground #f5f5f5 -state readonly -textvariable iso_file -width 57

frame .f_label_second_step -background #c7d1d1
label .f_label_second_step.l_second_step -bg #c7d1d1 -text "$i18n_step2"

frame .f_burn_dev -background #f5f5f5
label .f_burn_dev.l_burn_device -bg #f5f5f5 -width 20 -anchor w -text "$i18n_burning_device"
entry .f_burn_dev.burn_device -relief flat -bg white -highlightbackground blue -highlightcolor blue -disabledbackground #f5f5f5 -state normal -textvariable burning_device
.f_burn_dev.burn_device configure -validate focus -validatecommand refresh_cmd_line

frame .f_vol_name -background #f5f5f5
label .f_vol_name.label_vname -bg #f5f5f5 -width 20 -anchor w -text "$i18n_volume_name"
entry .f_vol_name.volume_name -relief flat -bg white -highlightbackground blue -highlightcolor blue  -disabledbackground #f5f5f5 -state normal -textvariable volume_id_o
button .f_vol_name.b_advanced_options -highlightbackground blue -width 15 -text "$i18n_advanced_options_b" -command { advanced_options_window }

frame .f_cmd_line -background #f5f5f5
label .f_cmd_line.label_vid -bg #f5f5f5 -width 20 -anchor w -text "$i18n_command"
entry .f_cmd_line.cmd_line -relief flat -highlightbackground blue -highlightcolor blue -readonlybackground #f5f5f5 -state readonly -textvariable command_line -width 150

frame .f_burn -background #c7d1d1
button .f_burn.go_button -text "$i18n_burn" -highlightbackground red -command { refresh_total_file_size; refresh_cmd_line; launch "burn" "" } -width 7


pack .f_label_first_step.l_first_step -side left
pack .f_label_first_step -fill x

pack .f_first_step.burn_dvd -side left
pack .f_first_step -fill x

pack .f_first_step_b.add -side left -padx {0 10}
pack .f_first_step_b.add_d .f_first_step_b.delete .f_first_step_b.clear .f_first_step_b.excluded_files -side left -padx {10 10} -expand 0
pack .f_first_step_b.excluded_files -side right -padx {10 0}
pack .f_first_step_b -fill x -padx {50 15} -pady {7 3}

pack .f_upper_file_list.l_file_size .f_upper_file_list.show_file_size .f_upper_file_list.l_space_left .f_upper_file_list.show_space_left -side left
if { $option_auto_refresh_space == "0" } { pack .f_upper_file_list.b_update -side left }
pack .f_upper_file_list -fill x -padx {50 0}

pack .file_list.scroll_bar -fill y -side right
pack .file_list.file_list -fill both -expand 1
pack .file_list -fill both -padx {50 15} -expand 1

pack .f_only_create_iso.only_create_iso -side left
pack .f_only_create_iso -fill x -padx {50 0} -pady {0 4}

pack .f_first_step_iso.b_burn_iso -side left
pack .f_first_step_iso.iso_file -side right -padx {12 0}
pack .f_first_step_iso.b_open_iso -side right
pack .f_first_step_iso -fill x -padx {0 15}

pack .f_label_second_step.l_second_step -side left
pack .f_label_second_step -fill x  -pady {12 12}

pack .f_burn_dev.l_burn_device -side left
pack .f_burn_dev.burn_device -side left -padx {0 0}
pack .f_burn_dev -fill x -padx {20 15} -pady {0 10}

pack .f_vol_name.label_vname -side left
pack .f_vol_name.volume_name -side left -padx {0 0}
pack .f_vol_name.b_advanced_options -side right -padx {0 0}
pack .f_vol_name -fill x -padx {20 15} -pady {0 10}

pack .f_cmd_line.label_vid -side left
pack .f_cmd_line.cmd_line -side left -padx {0 0}
pack .f_cmd_line -fill x  -pady {0 10} -padx {20 15}

pack .f_burn.go_button -pady {2 2}
pack .f_burn -fill x

#source all procedures left
 #    Copyright 2003 Regis Damongeot

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

proc file_list_w_modif_dir { file_list_to_modif } {
	#puts "$file_list_to_modif"
	set file_list_to_modif_f ""
	#set modified false
	for { set i 0 } { $i < [llength $file_list_to_modif]} { incr i } {
		if { [file isdirectory [lindex $file_list_to_modif $i]] } {
			set file_list_to_modif [lreplace $file_list_to_modif $i $i "[lindex [split [lindex $file_list_to_modif $i] /] end]/=[lindex $file_list_to_modif $i]"]
		} else {
		}
	}
	#if { $modified == true } { return [eval concat $file_list_to_modif] } else { return $file_list_to_modif }
	return $file_list_to_modif
}



proc choose_iso_file {} {
	global iso_file burn_type burning_device i18n_select_iso_image
	set iso_file_o ""
	if { $burn_type == "burn_iso" } {
		set iso_file_o [tk_getOpenFile -defaultextension .iso -title "$i18n_select_iso_image"]
		if { [llength $iso_file_o] > 1} {
			set iso_file [lindex $iso_file_o 0]
			for { set i 1} {$i < [llength $iso_file_o]} {incr i} {
				set iso_file "$iso_file\\ [lindex $iso_file_o $i]"
			}
		} else {
			set iso_file $iso_file_o
		}
	} else {
		set burning_device ""
		#set iso_file [tk_chooseDirectory -mustexist 0]
		set iso_file [tk_getSaveFile]
		set burning_device "-o"
		lappend burning_device $iso_file
	}
	refresh_cmd_line
}

proc check_volume_id {} {
	global volume_id volume_id_o
	set volume_id ""
	if { $volume_id_o == "" } {
		set volume_id ""
	} elseif { [llength $volume_id_o] > 1} {
			set volume_id [lindex $volume_id_o 0]
			for { set i 1} {$i < [llength $volume_id_o]} {incr i} {
				set volume_id "$volume_id\\ [lindex $volume_id_o $i]"
			}
			set volume_id "-V $volume_id"
		} else { set volume_id "-V $volume_id_o" }
}

proc add_file {files} {
	global file_list option_auto_refresh_space i18n_error i18n_error_file_already_present i18n_quest_file_contained
	
	if { $files != "" } {
		#foreach needed for multiple files selection
		foreach i $files {
			set answer "yes"
			set file_present [file_is_present_or_conatained "$i"]
			if { "$file_present" == "yes" } {
				set answer "no"
				tk_messageBox -icon error -message "$i18n_error_file_already_present: $i" -type ok -title $i18n_error
			} elseif { "$file_present" == "yes_c" } {
				set answer [tk_messageBox -icon error -message "$i18n_quest_file_contained $i" -type yesno -default no -title $i18n_error]
			}
		
			if { $answer == "yes" } {
				lappend file_list $i
			}
		}
		if { $option_auto_refresh_space == "1" } {
			refresh_total_file_size
		}
		refresh_cmd_line
	}
}

proc add_d {} {
	global file_list option_auto_refresh_space i18n_error i18n_error_directory_already_present i18n_quest_directory_contained i18n_quest_directory_contains
	set temp [tk_chooseDirectory]
	set answer "yes"
	if { $temp != "" } {
		set file_present [file_is_present_or_conatained "$temp"]
		if { "$file_present" == "yes" } {
			set answer "no"
			tk_messageBox -icon error -message "$i18n_error_directory_already_present" -type ok -title $i18n_error
		} elseif { "$file_present" == "yes_c" } {
			set answer [tk_messageBox -icon error -message "$i18n_quest_directory_contained" -type yesno -default no -title $i18n_error]
		} elseif { "$file_present" == "will_contains" } {
			set answer [tk_messageBox -icon error -message "$i18n_quest_directory_contains" -type yesno -default no -title $i18n_error]
		}
		
		if { $answer == "yes" } {
			lappend file_list $temp
			#refresh command line entry after checking space used to check overburn condition
			if { $option_auto_refresh_space == "1" } {
				refresh_total_file_size
			}
			refresh_cmd_line
		}
	}
}

proc delete_files {} {
	global file_list option_auto_refresh_space
	if { "[.file_list.file_list curselection]" == "" } {
	} else {
		set file_list [lreplace $file_list [.file_list.file_list curselection] [.file_list.file_list curselection]]
		#refresh command line entry after checking space used to check overburn condition
		if { $option_auto_refresh_space == "1" } {
			refresh_total_file_size
		}
		refresh_cmd_line
	}
}

proc launch {burn_type burn_opt} {
	global input command_line burning_device i18n_growisofs_mkisofs_output i18n_close burn_speed option_overburn
	#if output window not already created, we create it
	if { ! [winfo exists .output_window] } {
		toplevel .output_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
		wm title .output_window "$i18n_growisofs_mkisofs_output"
		frame .output_window.f_main
		text .output_window.f_main.log -heigh 10 -bg #f5f5f5 -relief ridge -setgrid true -yscrollcommand { .output_window.f_main.scroll_bar set }
		scrollbar .output_window.f_main.scroll_bar -command { .output_window.f_main.log yview }
		button .output_window.b_close -highlightbackground blue -width 7 -text "$i18n_close" -command { destroy .output_window; refresh_cmd_line }
		
		pack .output_window.f_main.log -fill both -side left -expand 1
		pack .output_window.f_main.scroll_bar -fill y -side right
		pack .output_window.f_main -fill both -expand 1
		pack .output_window.b_close
	}
	.f_burn.go_button configure -state disabled
	if { $burn_type == "burn" } {
		if {[catch {open "|$command_line |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "$command_line\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "$command_line\n\n"
		}
	} elseif { $burn_type == "dvd_copy" } {
		#burn_opt contains source device from which we copy
		if {[catch {open "|growisofs -Z $burning_device=$burn_opt |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "growisofs -Z $burning_device=$burn_opt\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "growisofs -Z $burning_device=$burn_opt\n\n"
		}
	} elseif { $burn_type == "cd_copy" } {
		#burn_opt contains source device from which we copy
		if {[catch {open "|cdrecord dev=$burning_device $burn_speed $option_overburn -isosize $burn_opt |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "cdrecord dev=$burning_device $burn_speed $option_overburn -isosize $burn_opt\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "cdrecord dev=$burning_device $burn_speed $option_overburn -isosize $burn_opt\n\n"
		}
	} elseif { $burn_type == "create_iso" } {
		# burn_opt contains destination file for ISO image
		if {[catch {open "|dd bs=2048 if=$burning_device of=$burn_opt |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "dd bs=2048 if=$burning_device of=$burn_opt\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "dd bs=2048 if=$burning_device of=$burn_opt\n\n"
		}
	} elseif { $burn_type == "erase_dvd" } {
		# $burn_opt= "" or "force" or "blank"
		if {[catch {open "|dvd+rw-format $burn_opt $burning_device |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "dvd+rw-format $burn_type $burning_device\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "dvd+rw-format $burn_type $burning_device\n\n"
		}
	} elseif { $burn_type == "erase_cd" } {
		# $burn_opt= "blank=fast" or "blank=full"
		if {[catch {open "|cdrecord $burn_opt dev=$burning_device |& cat"} input]} {
			#one blank line to increase readability
			.output_window.f_main.log insert end "cdrecord $burn_opt dev=$burning_device\n\n"
		} else {
			fileevent $input readable log_proc
			#one blank line to increase readability
			.output_window.f_main.log insert end "cdrecord $burn_opt dev=$burning_device\n\n"
		}
	}
	catch {fconfigure $input -blocking 0}
	after 4000 refresh_cmd_line
}

proc dvd_choose_format {} {
#i18n
global i18n_erase i18n_close i18n_full_format i18n_normal_format i18n_quick_format i18n_erase_dvdrw
	if { ! [winfo exists .format_window] } {
		
		toplevel .format_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
		wm title .format_window "$i18n_erase_dvdrw"
		
		frame .format_window.f_format_type -background #f5f5f5
		
		radiobutton .format_window.f_format_type.options_full_f -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_full_format" -variable format_type -value "-blank"
		radiobutton .format_window.f_format_type.options_normal_f -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_normal_format" -variable format_type -value "-force"
		radiobutton .format_window.f_format_type.options_quick_f -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_quick_format" -variable format_type -value ""
		
		button .format_window.b_erase -highlightbackground red -text "$i18n_erase" -command { launch "erase_dvd" $format_type; destroy .format_window}
		button .format_window.b_close -highlightbackground red -text "$i18n_close" -command { destroy .format_window}
		
		pack .format_window.f_format_type.options_quick_f -side left
		pack .format_window.f_format_type.options_normal_f -side left
		pack .format_window.f_format_type.options_full_f -side left
		pack .format_window.f_format_type -fill x -padx {0 12}
		pack .format_window.b_close .format_window.b_erase -fill x -side right -padx {0 12} -pady {6 6}
		
		.format_window.f_format_type.options_quick_f select
	}
}

proc cd_choose_format {} {
#i18n
global i18n_erase i18n_close i18n_full_format_cd i18n_quick_format_cd i18n_erase_cdrw
	if { ! [winfo exists .format_window] } {
		
		toplevel .format_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
		wm title .format_window "$i18n_erase_cdrw"
		
		frame .format_window.f_format_type -background #f5f5f5
		
		radiobutton .format_window.f_format_type.options_full_f -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_full_format_cd" -variable format_type -value "blank=all"
		radiobutton .format_window.f_format_type.options_quick_f -bg #f5f5f5 -activebackground #f5f5f5 -highlightbackground #f5f5f5 -text "$i18n_quick_format_cd" -variable format_type -value "blank=fast"
		
		button .format_window.b_erase -highlightbackground red -text "$i18n_erase" -command { launch "erase_cd" $format_type; destroy .format_window}
		button .format_window.b_close -highlightbackground red -text "$i18n_close" -command { destroy .format_window}
		
		pack .format_window.f_format_type.options_quick_f -side left
		pack .format_window.f_format_type.options_full_f -side left
		pack .format_window.f_format_type -fill x -padx {0 12}
		pack .format_window.b_close .format_window.b_erase -fill x -side right -padx {0 12} -pady {6 6}
		
		.format_window.f_format_type.options_quick_f select
	}
}

proc log_proc {} {
	global input i18n_writing_finished
	if { [gets $input line] > 0 } {
		if { [winfo exists .output_window] } {
			.output_window.f_main.log insert end $line\n
			.output_window.f_main.log see end
		}
	} elseif { [eof $input] } {
		catch { close $input }
		if { [winfo exists .output_window] } {
			.output_window.f_main.log insert end "$i18n_writing_finished"
			.output_window.f_main.log see end
		}
	}
}

proc set_visible_options {} {
	global burn_type v_create_iso dvd_size
	if { $burn_type == "burn_dvd" &&  $v_create_iso == "no" } {
		.f_first_step_iso.b_open_iso configure -state disabled
		.f_only_create_iso.only_create_iso configure -state normal
		.f_vol_name.label_vname configure -state normal
		.f_vol_name.volume_name configure -state normal
		.f_first_step_b.add configure -state normal
		.f_first_step_b.add_d configure -state normal
		.f_first_step_b.delete configure -state normal
		.f_first_step_b.clear configure -state normal
		.f_first_step_b.excluded_files configure -state normal
		.file_list.file_list configure -state normal
		.f_upper_file_list.l_file_size configure -state normal
		.f_upper_file_list.l_space_left configure -state normal
		.f_burn_dev.l_burn_device configure -state normal
		.f_burn_dev.burn_device configure -state normal
		if { [winfo exists .advanced_options_window] } {
			.advanced_options_window.options_oth.pad configure -state normal
			.advanced_options_window.udf_radiobuttons.udf_ext configure -state normal
			.advanced_options_window.udf_radiobuttons.dvd_video_ext configure -state normal
			.advanced_options_window.udf_radiobuttons.udf_ext_off configure -state normal
			.advanced_options_window.rr_radiobuttons.rr_ext_off configure -state normal
			.advanced_options_window.rr_radiobuttons.rra_ext configure -state normal
			.advanced_options_window.rr_radiobuttons.rr_ext configure -state normal
			.advanced_options_window.options_fs.joliet_ext configure -state normal
			.advanced_options_window.options_oth.label_burn_speed configure -state normal
			.advanced_options_window.options_oth.entry_burn_speed configure -state normal
			.advanced_options_window.options_oth.overburn configure -state normal
			.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao configure -state disabled
			.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao configure -state disabled
			if { $dvd_size <= 716800 } {
				.advanced_options_window.f_opts_dvd.multisession configure -state disabled
				.advanced_options_window.f_opts_dvd.monosession configure -state disabled
				.advanced_options_window.f_opts_cd.eject_cd configure -state normal
				.advanced_options_window.f_opts_cd.monosession configure -state normal
				.advanced_options_window.f_opts_cd.multisession configure -state normal
			} else {
				.advanced_options_window.f_opts_dvd.multisession configure -state normal
				.advanced_options_window.f_opts_dvd.monosession configure -state normal
				.advanced_options_window.f_opts_cd.eject_cd configure -state disabled
				.advanced_options_window.f_opts_cd.monosession configure -state disabled
				.advanced_options_window.f_opts_cd.multisession configure -state disabled
			}
			.advanced_options_window.options_oth.auto_refresh_space configure -state normal
		}
	} elseif { $burn_type == "burn_dvd" && $v_create_iso == "yes" } {
		.f_first_step_iso.b_open_iso configure -state normal
		.f_burn_dev.l_burn_device configure -state disabled
		.f_burn_dev.burn_device configure -state disabled
		if { [winfo exists .advanced_options_window] } {
			.advanced_options_window.options_oth.pad configure -state normal
			.advanced_options_window.options_fs.joliet_ext configure -state normal
			.advanced_options_window.udf_radiobuttons.udf_ext configure -state normal
			.advanced_options_window.udf_radiobuttons.udf_ext_off configure -state normal
			.advanced_options_window.udf_radiobuttons.dvd_video_ext configure -state normal
			.advanced_options_window.rr_radiobuttons.rr_ext_off configure -state normal
			.advanced_options_window.rr_radiobuttons.rr_ext configure -state normal
			.advanced_options_window.rr_radiobuttons.rra_ext configure -state normal
			.advanced_options_window.options_oth.label_burn_speed configure -state disabled
			.advanced_options_window.options_oth.entry_burn_speed configure -state disabled
			.advanced_options_window.options_oth.overburn configure -state disabled
			.advanced_options_window.f_opts_dvd.multisession configure -state disabled
			.advanced_options_window.f_opts_dvd.monosession configure -state disabled
			.advanced_options_window.f_opts_cd.eject_cd configure -state disabled
			.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao configure -state disabled
			.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao configure -state disabled
			.advanced_options_window.f_opts_cd.monosession configure -state disabled
			.advanced_options_window.f_opts_cd.multisession configure -state disabled
			.advanced_options_window.options_oth.auto_refresh_space configure -state normal
		}
	} elseif { $burn_type == "burn_iso" } {
		.f_first_step_iso.b_open_iso configure -state normal
		.f_only_create_iso.only_create_iso configure -state disabled
		.f_vol_name.label_vname configure -state disabled
		.f_vol_name.volume_name configure -state disabled
		.f_first_step_b.add configure -state disabled
		.f_first_step_b.add_d configure -state disabled
		.f_first_step_b.delete configure -state disabled
		.f_first_step_b.clear configure -state disabled
		.f_first_step_b.excluded_files configure -state disabled
		.file_list.file_list configure -state disabled
		.f_upper_file_list.l_file_size configure -state disabled
		.f_upper_file_list.l_space_left configure -state disabled
		.f_burn_dev.l_burn_device configure -state normal
		.f_burn_dev.burn_device configure -state normal
		if { [winfo exists .advanced_options_window] } {
			.advanced_options_window.options_oth.pad configure -state disabled
			.advanced_options_window.udf_radiobuttons.udf_ext configure -state disabled
			.advanced_options_window.udf_radiobuttons.udf_ext_off configure -state disabled
			.advanced_options_window.udf_radiobuttons.dvd_video_ext configure -state disabled
			.advanced_options_window.rr_radiobuttons.rr_ext_off configure -state disabled
			.advanced_options_window.rr_radiobuttons.rra_ext configure -state disabled
			.advanced_options_window.rr_radiobuttons.rr_ext configure -state disabled
			.advanced_options_window.options_fs.joliet_ext configure -state disabled
			.advanced_options_window.options_oth.label_burn_speed configure -state normal
			.advanced_options_window.options_oth.entry_burn_speed configure -state normal
			.advanced_options_window.options_oth.overburn configure -state normal
			.advanced_options_window.f_opts_dvd.multisession configure -state disabled
			.advanced_options_window.f_opts_dvd.monosession configure -state disabled
			.advanced_options_window.f_opts_cd.monosession configure -state disabled
			.advanced_options_window.f_opts_cd.multisession configure -state disabled
			.advanced_options_window.options_oth.auto_refresh_space configure -state disabled
			if { $dvd_size <= 716800 } {
				.advanced_options_window.f_opts_cd.eject_cd configure -state normal
				.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao configure -state normal
				.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao configure -state normal
			} else {
				.advanced_options_window.f_opts_cd.eject_cd configure -state disabled
				.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_tao configure -state disabled
				.advanced_options_window.f_opts_cd.f_cd_burn_type.radio_dao configure -state disabled
			}
		}
	}
}

proc refresh_burning_variables {} {
	global burn_command t_session burning_device temp_burning_device option_dvd_compat option_overburn v_create_iso v_create_iso dvd_size burn_type iso_file
	if { "$burn_type" == "burn_iso" } {
		#burning of an ISO image
		if { $temp_burning_device != "" } {
			#in this case, we just changed burning type to burning ISO, so we restore burning device
			set burning_device "$temp_burning_device"
			set temp_burning_device ""
		}
		if { $dvd_size <= 716800 } {
			set burn_command "cdrecord"
		} else {
			set burn_command "growisofs"
		}
		set v_create_iso "no"
		set volume_id ""
	} elseif {$burn_type == "burn_dvd" && $v_create_iso == "no"} {
		#DVD burning without ISO creation
		if { $temp_burning_device != "" } {
			#in this case, we just changed burning type to burning CD/DVD, so we restore burning device
			set burning_device "$temp_burning_device"
			set temp_burning_device ""
		}
		if { $dvd_size <= 716800 } {
			set burn_command "mkisofs"
		} else {
			set burn_command "growisofs"
		}
		set iso_file ""
	} else {
		#ISO creation
		set burn_command "mkisofs"
		if { $temp_burning_device == "" } {
			#in this case, we just change burning type to ISO creation so we need to save the previous real burning device
			set temp_burning_device "$burning_device"
			set burning_device ""
		}
	}
}



proc disc_copy { disc_type } {
	#disc_type == "dvd" or "cd"
	global i18n_dvd_copy i18n_cd_copy i18n_copy i18n_close i18n_choose_source_device
	#seems necessary to declare a second variable for -command launch and not with "set", only variable works...
	variable disc_type_g "$disc_type"
	if { ! [winfo exists .dvd_copy_window] } {
		toplevel .dvd_copy_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
		if { $disc_type == "dvd" } {
			wm title .dvd_copy_window "$i18n_dvd_copy"
		} else {
			wm title .dvd_copy_window "$i18n_cd_copy"
		}

		frame .dvd_copy_window.f_source_device -background #f5f5f5
		label .dvd_copy_window.f_source_device.l_mess -bg #f5f5f5 -text "$i18n_choose_source_device"
		entry .dvd_copy_window.f_source_device.e_bd -relief flat -bg white -highlightbackground blue -highlightcolor blue -disabledbackground #f5f5f5 -state normal -textvariable source_device
		
		button .dvd_copy_window.b_copy -highlightbackground red -text "$i18n_copy" -command { launch "${disc_type_g}_copy" "$source_device"; destroy .dvd_copy_window}
		button .dvd_copy_window.b_close -highlightbackground red -text "$i18n_close" -command { destroy .dvd_copy_window}
	
		pack .dvd_copy_window.f_source_device.l_mess -side left
		pack .dvd_copy_window.f_source_device.e_bd -side left
		pack  .dvd_copy_window.f_source_device -fill x -padx {0 12} -pady {12 12}
		pack .dvd_copy_window.b_close .dvd_copy_window.b_copy -fill x -side right -padx {0 12} -pady {6 6}
	}	
}

proc disc_to_iso { disc_type } {
	#disc_type == "dvd" or "cd"
	global i18n_close i18n_create_iso_from_dvd i18n_create_iso_from_cd i18n_create i18n_choose_target_file i18n_error i18n_error_target_file_ns
	set dest_file ""
	if { ! [winfo exists .create_iso_window] } {
	
		toplevel .create_iso_window -highlightthickness 1 -highlightcolor blue -background #f5f5f5
		if { $disc_type == "dvd" } {
			wm title .create_iso_window "$i18n_create_iso_from_dvd"
		} else {
			wm title .create_iso_window "$i18n_create_iso_from_cd"
		}

		frame .create_iso_window.f_dest_file -background #f5f5f5
		button .create_iso_window.f_dest_file.b_mess -highlightbackground blue -text "$i18n_choose_target_file" -command { set dest_file [tk_getSaveFile -filetypes {{ {ISO Image} { .iso } } {{All Files}  * } } -defaultextension .iso] }
		entry .create_iso_window.f_dest_file.e_fp  -relief flat -highlightbackground blue -highlightcolor blue -readonlybackground #f5f5f5 -state readonly -textvariable dest_file -width 57
	
		button .create_iso_window.b_create -highlightbackground red -text "$i18n_create" -command { if { $dest_file == "" } { tk_messageBox -icon error -message $i18n_error_target_file_ns -type ok -title $i18n_error } else {launch "create_iso" "$dest_file"; destroy .create_iso_window} }
		button .create_iso_window.b_close -highlightbackground red -text "$i18n_close" -command { destroy .create_iso_window}
	
		pack .create_iso_window.f_dest_file.b_mess -side left -padx {12 12}
		pack .create_iso_window.f_dest_file.e_fp -side left
		pack  .create_iso_window.f_dest_file -fill x -padx {0 12} -pady {12 12}
		pack .create_iso_window.b_close .create_iso_window.b_create -fill x -side right -padx {0 12} -pady {6 6}
	}	
}

proc save_file_list {} {
	global file_list excluded_file_list i18n_error_filelist_empty i18n_error
	#we first check that file list is not empty
	if { $file_list == "" } {
		tk_messageBox -icon error -message $i18n_error_filelist_empty -type ok -title $i18n_error
		return
	}
	set output_file_s [tk_getSaveFile -filetypes {{ {TkDVD file list} { .tkdvd } } {{All Files}  * } } -defaultextension .tkdvd]
	if { $output_file_s != "" } {
		set output_file [open $output_file_s w]
		puts $output_file $file_list
		puts $output_file $excluded_file_list
		close $output_file
	}
}

proc load_file_list {} {
	global file_list excluded_file_list option_auto_refresh_space
	set temp_fl ""
	set temp_efl ""
	set input_file_s [tk_getOpenFile -filetypes {{ {TkDVD file list} { .tkdvd } } {{All Files}  * } } -defaultextension .tkdvd]
	if { $input_file_s != "" } {
		set input_file [open $input_file_s r]
		gets $input_file temp_fl
		gets $input_file temp_efl
		#check if each file/dir loaded is not already in file list
		foreach i $temp_fl {
			if { [file_is_present_or_conatained "$i"] == "no"} {
				lappend file_list $i
			}
		}
		#same check for excluded file
		foreach i $temp_efl {
			if { ([file_is_present_or_conatained "$i"] != "no") && ([file_is_present_or_conatained_in_efl "$i"] == "no")} {
				lappend excluded_file_list $i
			}
		}
		close $input_file
		if { $option_auto_refresh_space == "1" } {
			refresh_total_file_size
		}
		refresh_cmd_line
	}
}

proc file_is_present_or_conatained { this_file } {
	#return "yes" if $this_file is already in file list or "yes_c" if it is contained, returns "will_contains" if this_file will contains other files already present, else return "no"
	global file_list
	if { [file isfile "$this_file"] } {
		#in this case we check that file given in parameter is not equal to another file already in FL or contains in a directory in FL
		foreach i $file_list {
			if { [file isfile "$i"] } {
				#same file
				if { "$i" == "$this_file" } { return "yes" }
			} elseif { [file isdirectory "$i"] } {
				#file contained in already present directory
				if { [string compare -length [string length $i] "$i" "$this_file"] == 0 } { return "yes_c" }
			}
		}
	} elseif { [file isdirectory "$this_file"] } {
		foreach i $file_list {
			if { [file isdirectory "$i"] } {
				#same directory
				if { "$i" == "$this_file" } { return "yes" }
				#new directory will contains another already rpesent in FL
				if { [string compare -length [string length $this_file] "$this_file" "$i"] == 0} { return "will_contains" }
				#new directory is contained by another directory in FL
				if { [string compare -length [string length $i] "$i" "$this_file"]==0 } { return "yes_c" }
			} elseif { [file isfile "$i"] } {
				#check that new directory doesnt contains files already present
				if { [string compare -length [string length $this_file] "$this_file" "$i"] == 0} { return "will_contains" }
			}
		}
	}
	return "no"
}

proc file_is_present_or_conatained_in_efl { this_file } {
	#return "yes" if $this_file is already in excluded file list or "yes_c" if it is contained, returns "will_contains" if this_file will contains other files already present, else return "no"
	global excluded_file_list
	if { [file isfile "$this_file"] } {
		#in this case we check that file given in parameter is not equal to another file already in FL or contains in a directory in FL
		foreach i $excluded_file_list {
			if { [file isfile "$i"] } {
				#same file
				if { "$i" == "$this_file" } { return "yes" }
			} elseif { [file isdirectory "$i"] } {
				#file contained in already present directory
				if { [string compare -length [string length $i] "$i" "$this_file"] == 0 } { return "yes_c" }
			}
		}
	} elseif { [file isdirectory "$this_file"] } {
		foreach i $excluded_file_list {
			if { [file isdirectory "$i"] } {
				#same directory
				if { "$i" == "$this_file" } { return "yes" }
				#new directory will contains another already rpesent in FL
				if { [string compare -length [string length $this_file] "$this_file" "$i"] == 0} { return "will_contains" }
				#new directory is contained by another directory in FL
				if { [string compare -length [string length $i] "$i" "$this_file"]==0 } { return "yes_c" }
			} elseif { [file isfile "$i"] } {
				#check that new directory doesnt contains files already present
				if { [string compare -length [string length $this_file] "$this_file" "$i"] == 0} { return "will_contains" }
			}
		}
	}
	return "no"
}
#refresh space left for initial DVD size loaded from config file
refresh_total_file_size
#refresh cmd line (mkisofs for exemple if dvd size == CD size
refresh_cmd_line


