# SRTtoASS3D.tcl v0.8 (July 27, 2019)
# This file is part of BD3D2MK3D (c) r0lZ 2016 - 2023
# (c) 2012-2023 r0lZ - Open source

# TODO:
# - Accept SUP or SUB file as guide
# - Convert XML twice when subtitles are fullscreen
# - Retrieve and verify video resolution and frame rate from XML guide
# - How to get the right metrics for the SSA fonts?
# - Implement Alignment of the 2-lines subtitles
# - Add "Title" ASS parameter in GUI ?
# - What encoding to use? (last param of the "style" line in the ASS file)
# - The frame margin for GetPositions should be modifiable by the user

# - DONE in v0.6: Requested by konikpolny https://forum.doom9.org/showthread.php?p=1874468#post1874468 :
# -- Fix bug bad X placement when converting with the margins option (Done in v0.6 to v0.8)
# -- Add possibility to provide a fixed Y placement when using a guide (v0.6)
# -- Add an option to ignore these 2 last options for all subs located in the upper half of the screen (v0.6)

namespace eval ::s2a {

proc Srt2Ass3D_GUI {} {
	set ::status ""

	set w .srt2ass3d
	if {! [winfo exists $w]} {

		# set default values
		set ::s2a::insrtfile ""
		set ::s2a::inencoding "utf-8"
		set ::s2a::keepformatting 1
		if {$::stereomode == 2} {
			# frame sequential in main program: assumes Half-SBS
			set ::s2a::half 1
			set ::s2a::sbs 1
		} else {
			set ::s2a::half $::half
			set ::s2a::sbs  $::stereomode
		}
		set ::s2a::leftfirst 1
		set ::s2a::ofsfile ""
		set ::s2a::searchalt3dp 0
		set ::s2a::adddepth $::additionaldepth
		set ::s2a::fontname "Arial"
		set ::s2a::fontsize 50
		set ::s2a::color "#C0C0C0"
		set ::s2a::outline 4
		set ::s2a::shadow 2
		set ::s2a::shadowtr 192
		set ::s2a::margin 40
		set ::s2a::ignoreguidey 0
		set ::s2a::excepttop 1
		set ::s2a::guidefile ""
		set ::s2a::topaligned 0
		set ::s2a::usepostags 0
# 		set ::s2a::saveutf8 0
		set ::s2a::outass ""

		menu ${w}_menu
		${w}_menu add cascade -label "Presets" -menu ${w}_menu.presets
		menu ${w}_menu.presets
		${w}_menu.presets add command -label "1.78:1 (Full 16:9)" \
			-command {::s2a::SetPreset 40 0 4 2 #D0D0D0 -1}
		${w}_menu.presets add command -label "1.85:1 (Thin black borders)" \
			-command {::s2a::SetPreset 56 0 4 2 #D0D0D0 -1}
		${w}_menu.presets add command -label "2.40:1 (Cinemascope), subtitles in picture" \
			-command {::s2a::SetPreset 150 0 4 2 #D0D0D0 -1}
		${w}_menu.presets add command -label "2.40:1 (Cinemascope), subtitles in black borders" \
			-command {::s2a::SetPreset 20 1 2 0 #A0A0A0 57}
		${w}_menu add cascade -label "Settings" -menu ${w}_menu.settings
		menu ${w}_menu.settings
		${w}_menu.settings add command -label "Save default settings" \
				-command {::s2a::SaveS2ASettings "Default.srt2ass.cfg"}
		${w}_menu.settings add command -label "Save settings as..." \
				-command ::s2a::SaveS2ASettings
		${w}_menu.settings add separator
		${w}_menu.settings add command -label "Load default settings" \
				-command {::s2a::LoadS2ASettings "Default.srt2ass.cfg"}
		${w}_menu.settings add command -label "Load settings file..." \
				-command ::s2a::LoadS2ASettings
		${w}_menu add command -label "Help" -command ::s2a::MainHelp
		
		toplevel $w -menu ${w}_menu
		wm withdraw $w
		wm transient $w .
		wm title $w "BD3D2MK3D - Convert subtitles from SRT 2D to ASS 3D"

		pack [::ttk::labelframe $w.f1 -text "Input SRT (SubRip) file"] -padx 4 -pady 4 -fill x -expand 1
		pack [frame $w.f1.f1] -padx 2 -fill x -expand 1
		pack [::ttk::entry $w.f1.f1.e -textvariable ::s2a::insrtfile -width 40] -side left -padx 2 -fill x -expand 1
		pack [::ttk::button $w.f1.f1.b -text "..." -width 3 -command ::s2a::OpenSrt] -side left -padx 2

		pack [frame $w.f1.f2] -padx 2 -fill x -expand 1
		pack [label $w.f1.f2.l -text "Character encoding:"] -side left
		pack [::ttk::combobox $w.f1.f2.e -textvariable ::s2a::inencoding -values \
				[concat [list "utf-8" "unicode" [encoding system]] [lsort -dictionary [encoding names]]] \
				-state readonly -width 15] -side left -padx 2
		pack [::ttk::button $w.f1.f2.b -text " Check character encoding " -command ::s2a::CheckEncoding] -side left -padx 2
		pack [::ttk::button $w.f1.f2.b2 -text "?" -width 3 -command "::s2a::CharEncHelp"] -side right -padx 2 -pady 1
		pack [::ttk::checkbutton $w.f1.cb -text "Keep text formatting (bold, italic, underline and colours of individual SRT subtitles)" -variable ::s2a::keepformatting] -anchor w -padx 4

		pack [::ttk::labelframe $w.f2 -text "Output 3D format and depth"] -padx 4 -pady 4 -fill x -expand 1
		pack [frame $w.f2.f1] -padx 2 -fill x -expand 1
		pack [label $w.f2.f1.l1 -text "Stereoscopy:"] -side left
		pack [ttk::radiobutton  $w.f2.f1.r11 -text "Half"  -variable ::s2a::half -value 1] -side left
		pack [ttk::radiobutton  $w.f2.f1.r12 -text "Full"  -variable ::s2a::half -value 0] -side left
		pack [label $w.f2.f1.l13 -text "-"] -side left
		pack [ttk::radiobutton  $w.f2.f1.r21 -text "SBS"   -variable ::s2a::sbs -value 1] -side left
		pack [ttk::radiobutton  $w.f2.f1.r22 -text "T&B"   -variable ::s2a::sbs -value 0] -side left
		pack [label $w.f2.f1.l23 -text ", "] -side left
		pack [ttk::radiobutton  $w.f2.f1.r31 -text "Left view first"  -variable ::s2a::leftfirst -value 1] -side left
		pack [ttk::radiobutton  $w.f2.f1.r32 -text "Right view first" -variable ::s2a::leftfirst -value 0] -side left

		pack [frame $w.f2.f1b] -padx 2 -fill x -expand 1
		pack [label $w.f2.f1b.l11 -text "Additional or fixed depth:"] -side left
		pack [spinbox $w.f2.f1b.s11 -textvariable ::s2a::adddepth -from -30 -to 30 -state readonly -width 3 -justify right] -side left
		pack [scale $w.f2.f1b.s12 -sliderlength 18 -length 50 -orient h -showvalue 0 -variable ::s2a::adddepth -from -30 -to 30] -side left -fill x -expand 1
		pack [::ttk::button $w.f2.f1b.b11 -text "?" -width 3 -command "AdditionalDepthHelp $w"] -side left -padx 2

		pack [label $w.f2.l2 -text "Input 3D-Plane (OFS) file to extract the correct depths from:"] -anchor w -padx 2
		pack [frame $w.f2.f2] -fill x -expand 1 -padx 2
		pack [::ttk::entry $w.f2.f2.e -textvariable ::s2a::ofsfile -width 40] -side left -padx 2 -fill x -expand 1
		pack [::ttk::button $w.f2.f2.b -text "..." -width 3 -command ::s2a::OpenOfs] -side left -padx 2

		pack [frame $w.f2.cbf] -fill x -padx 2 -expand 1
		pack [::ttk::checkbutton $w.f2.cbf.l -text "When a subtitle has no depth value defined in the 3D-Plane,\nsearch for valid depth value in the other 3D-Planes in the same directory" -variable ::s2a::searchalt3dp] -side left -padx 2
		pack [ttk::button $w.f2.cbf.b -width 3 -text "?" -command "HelpSearchAlt3Dp $w false"] -side right -padx 2


		pack [::ttk::labelframe $w.f3 -text "Subtitle Font"] -padx 4 -pady 4 -fill x -expand 1
		pack [frame $w.f3.f1] -fill x -expand 1

		pack [frame $w.f3.f1.pad1] -padx 1 -side left
		pack [::ttk::menubutton $w.f3.f1.b1 -menu $w.f3.f1.b1.menu -width 22 -text $::s2a::fontname] -padx 2 -fill y -side left
		menu $w.f3.f1.b1.menu -tearoff false
		$w.f3.f1.b1.menu add command -label "Arial" -command {::s2a::SelFont "Arial"} -font {Arial 16}
		$w.f3.f1.b1.menu add command -label "Verdana" -command {::s2a::SelFont "Verdana"} -font {Verdana 14}
		$w.f3.f1.b1.menu add command -label "Times New Roman" -command {::s2a::SelFont "Times New Roman"} -font {{Times New Roman} 13}
		$w.f3.f1.b1.menu add separator
		$w.f3.f1.b1.menu add command -label "Choose..." -command {::s2a::SelFont}



		#pack [label $w.f3.f1.l0 -text "Size:"] -side left
		pack [spinbox $w.f3.f1.s1 -textvariable ::s2a::fontsize -from 20 -to 80 -state readonly -width 2 -justify right] -side left
		pack [scale $w.f3.f1.s2 -sliderlength 18 -orient h -showvalue 0 -variable ::s2a::fontsize -from 20 -to 80] -side left -fill x -expand 1
		pack [label $w.f3.f1.l1 -text "Colour:"] -side left
		#pack [button $w.f3.f1.b2 -text [RGB2Txt $::s2a::color] -command ::s2a::SelColor -bg $::s2a::color -fg black -width 10] -side left
		pack [menubutton $w.f3.f1.b2 -menu $w.f3.f1.b2.menu -fg black -width 10 -bd 2 -relief raised] -side left
		SetColor  $::s2a::color
		menu $w.f3.f1.b2.menu -tearoff false
		$w.f3.f1.b2.menu add command -label "White" -command {::s2a::SetColor #FFFFFF} -background #FFFFFF
		$w.f3.f1.b2.menu add command -label "Lighter grey" -command {::s2a::SetColor #E0E0E0} -background #E0E0E0
		$w.f3.f1.b2.menu add command -label "Light grey" -command {::s2a::SetColor #C0C0C0} -background #C0C0C0
		$w.f3.f1.b2.menu add command -label "Darker grey" -command {::s2a::SetColor #A0A0A0} -background #A0A0A0
		$w.f3.f1.b2.menu add command -label "Yellow" -command {::s2a::SetColor #FFFF00} -background #FFFF00
		$w.f3.f1.b2.menu add command -label "Light yellow" -command {::s2a::SetColor #F0F080} -background #F0F080
		$w.f3.f1.b2.menu add separator
		$w.f3.f1.b2.menu add command -label "Choose..." -command {::s2a::SelColor}
		pack [frame $w.f3.f1.pad -width 4] -side left

		pack [frame $w.f3.f2] -fill x -expand 1 -padx 1 -pady 1
		grid [label $w.f3.f2.l2 -text "Outline:"] -row 1 -column 1 -sticky ew
		grid [spinbox $w.f3.f2.s3 -textvariable ::s2a::outline -from 0 -to 10 -state readonly -width 2 -justify right] -row 1 -column 2 -sticky ew
		grid [scale $w.f3.f2.s4 -sliderlength 18 -length 50 -orient h -showvalue 0 -variable ::s2a::outline -from 0 -to 10] -row 1 -column 3 -sticky ew
		grid [label $w.f3.f2.l5 -text "Shadow:"] -row 1 -column 4 -sticky ew
		grid [spinbox $w.f3.f2.s6 -textvariable ::s2a::shadow -from 0 -to 10 -state readonly -width 2 -justify right] -row 1 -column 5 -sticky ew
		grid [scale $w.f3.f2.s7 -sliderlength 18 -length 50 -orient h -showvalue 0 -variable ::s2a::shadow -from 0 -to 10] -row 1 -column 6 -sticky ew

		grid [label $w.f3.f2.110 -text "Shadow\ntransparency:" -padx 1 -pady 0 -bg grey -bd 1 -relief sunken] -row 1 -column 7 -sticky ew -padx 2
		grid [spinbox $w.f3.f2.s8 -textvariable ::s2a::shadowtr -from 0 -to 255 -state readonly -width 3 -justify right -command ::s2a::SetShadowTransparency] -row 1 -column 8 -sticky ew
		grid [scale $w.f3.f2.s9 -sliderlength 18 -length 80 -orient h -showvalue 0 -variable ::s2a::shadowtr -from 0 -to 255 -command ::s2a::SetShadowTransparency] -row 1 -column 9 -sticky ew


# 		grid [frame $w.f3.f2.pad -width 2] -row 1 -column 11 -sticky ew -padx 2
		grid columnconfigure $w.f3.f2 3 -weight 2
		grid columnconfigure $w.f3.f2 6 -weight 2
		grid columnconfigure $w.f3.f2 9 -weight 4
		SetShadowTransparency


		pack [::ttk::labelframe $w.f4 -text "Subtitles Positions"] -padx 4 -pady 4 -fill x -expand 1

		# TODO: Implement alignment
#  		pack [frame $w.f4.f5] -padx 2 -fill x -expand 1
#  		pack [label $w.f4.f5.l -text "Alignment of the 2-lines subtitles:"] -side left
#  		pack [ttk::radiobutton $w.f4.f5.r0 -text "Top (for black borders)" -variable ::s2a::topaligned -value 1] -side left
#  		pack [ttk::radiobutton $w.f4.f5.r1 -text "Bottom (recommended)" -variable ::s2a::topaligned -value 0] -side left

		pack [frame $w.f4.f1] -padx 2 -fill x -expand 1
		pack [label $w.f4.f1.t1 -text "Bottom margin:"] -side left
		pack [::ttk::menubutton $w.f4.f1.ps -menu $w.f4.f1.ps.menu -text "presets" -width 7] -padx 2 -side left
		menu $w.f4.f1.ps.menu -tearoff false
		$w.f4.f1.ps.menu add command -label "1.78:1 (Full 16:9)" -command {set ::s2a::margin 40}
		$w.f4.f1.ps.menu add command -label "1.85:1 (Thin black borders)" -command {set ::s2a::margin 56}
		$w.f4.f1.ps.menu add command -label "2.40:1 (Cinemascope), subtitles in picture" -command {set ::s2a::margin 150}
		$w.f4.f1.ps.menu add command -label "2.40:1 (Cinemascope), subtitles in black borders" -command {set ::s2a::margin 20}

		pack [spinbox $w.f4.f1.s1 -textvariable ::s2a::margin -from 10 -to 200 -state readonly -width 4 -justify right] -side left
		pack [scale $w.f4.f1.s2 -sliderlength 18 -orient h -showvalue 0 -variable ::s2a::margin -from 10 -to 200] -side left -fill x -expand 1
		pack [::ttk::button $w.f4.f1.bh -text "?" -width 3 -command ::s2a::MarginHelp] -side right -padx 2

		pack [frame $w.f4.f2] -padx 2 -fill x -expand 1
		pack [label $w.f4.f2.l1 -text "Grab the individual position of each subtitle from this 2D Guide file:"] -side left
		pack [::ttk::button $w.f4.f2.b -text "?" -width 3 -command ::s2a::GuideHelp] -side right -padx 2
		pack [frame $w.f4.f3] -padx 2 -fill x -expand 1
		pack [::ttk::entry $w.f4.f3.e -textvariable ::s2a::guidefile -width 40] -side left -padx 2 -fill x -expand 1
		pack [::ttk::button $w.f4.f3.b -text "..." -width 3 -command ::s2a::OpenGuide] -side left -padx 2

		pack [frame $w.f4.fg1] -padx 2 -fill x -expand 1 -padx 2
		pack [::ttk::checkbutton $w.f4.fg1.cb1 -text "Ignore the guide for Y position" -variable ::s2a::ignoreguidey -command ::s2a::GuideIgnoreValidate] -side left -padx 1
		pack [::ttk::checkbutton $w.f4.fg1.cb2 -text "except for subtitles in the top of the screen" -variable ::s2a::excepttop -state disabled] -side left
		pack [::ttk::button $w.f4.fg1.b -text "?" -width 3 -command ::s2a::GuideIgnoreHelp] -side right -padx 2

		pack [frame $w.f4.fg] -padx 2 -fill x -expand 1 -padx 2 -pady 2
		pack [frame $w.f4.fg.f] -fill x -expand 1 -side left
		pack [frame $w.f4.fg.f.f]
		pack [ttk::button $w.f4.fg.f.f.bs -text " Show me the subtitle Guide " -command ::s2a::ShowXMLGuide] -padx 4 -side left
		pack [ttk::button $w.f4.fg.f.f.ba -text "  Analyse the subtitle Guide  " -command ::s2a::AnalyseXMLGuide] -padx 4 -side left
		pack [ttk::button $w.f4.fg.f.f.bc -text "  Clear  " -command {set ::s2a::guidefile ""}] -padx 4 -side left
		pack [::ttk::button $w.f4.fg.h -text "?" -width 3 -command ::s2a::AnalyseHelp] -side right -padx 2


		pack [::ttk::labelframe $w.f5 -text "Output ASS (Advanced SubStation Alpha) file"] -padx 4 -pady 4 -fill x -expand 1

# 		pack [label $w.f5.l1 -text "Output ASS (Advanced SubStation Alpha v4+) file:"] -padx 2 -anchor w
		pack [frame $w.f5.f3] -padx 2 -fill x -expand 1
		pack [::ttk::entry $w.f5.f3.e -textvariable ::s2a::outass -width 40] -side left -padx 2 -fill x -expand 1
		pack [::ttk::button $w.f5.f3.b -text "..." -width 3 -command ::s2a::SetOutAss] -side left -padx 2

		pack [frame $w.f5.f1] -padx 2 -fill x -expand 1
		pack [label $w.f5.f1.l1 -text "Method to position the subtitles:"] -side left
		pack [::ttk::radiobutton $w.f5.f1.r2 -text "Margins" -variable ::s2a::usepostags -value 0] -side left
		pack [::ttk::radiobutton $w.f5.f1.r1 -text "{\\pos(x,y)} commands" -variable ::s2a::usepostags -value 1] -side left
		pack [::ttk::button $w.f5.f1.bh -text "?" -width 3 -command ::s2a::PositionsHelp] -side right -padx 2
# 		pack [::ttk::checkbutton $w.f5.ce -text "Save the ASS file encoded in UTF-8, regardless of the input character encoding" -variable ::s2a::saveutf8] -anchor w -padx 2


		pack [::ttk::button $w.go -text " Convert SRT to ASS 3D... " -command ::s2a::GuiGo] -padx 4 -pady 4 -fill x

# 		pack [ttk::progressbar $w.pr -orient horiz -maximum 100 -variable ::progress] -fill x -padx 4 -pady 2
		pack [frame $w.stf -bd 1 -height 2 -relief sunken] -fill x
		pack [entry $w.st -textvariable ::status -state readonly -exportselection false -bd 0 -relief flat -takefocus 0] -fill x -padx 4

		update
	 	wm minsize $w [winfo reqwidth $w] [winfo reqheight $w]
	  	wm resizable $w 1 0
	  	wm protocol $w WM_DELETE_WINDOW "grab release $w; wm withdraw $w"
	  	wm geometry $w +[expr [winfo rootx .] + 12]+[expr [winfo rooty .] -34]

		if {! [catch {package require tkdnd}]} {
			dnd bindtarget $w text/uri-list <Drop> {::s2a::Srt2Ass3D_GUI_drop %D}
		}

	}

	if {[file exists [file join [file dirname $::TOOLSETPATH] "Default.srt2ass.cfg"]]} {
		LoadS2ASettings "Default.srt2ass.cfg"
	}

  	wm deiconify $w
 	Pause
  	focus -force $w
  	focus -force $w.f1.f1.e
  	grab set $w
}
proc Srt2Ass3D_GUI_drop {files} {
	set ::status ""
	set ext ""
	foreach f $files {
		set ext [string tolower [file extension $f]]
		if {$ext == ".srt"} {
			set ::s2a::insrtfile [file nativename $f]
			.srt2ass3d.f1.f1.e icursor end
			.srt2ass3d.f1.f1.e xview 1000
			focus .srt2ass3d.f1.f1.e
		} elseif {$ext == ".ofs"} {
			set ::s2a::ofsfile [file nativename $f]
			.srt2ass3d.f2.f2.e icursor end
			.srt2ass3d.f2.f2.e xview 1000
			focus .srt2ass3d.f2.f2.e
		} elseif {$ext == ".xml"} {
			set ::s2a::guidefile [file nativename $f]
			.srt2ass3d.f4.f3.e icursor end
			.srt2ass3d.f4.f3.e xview 1000
			focus .srt2ass3d.f4.f3.e
		} else {
			set ::status "Drop only SRT or XML subtitles, or OFS 3D-plane files."
			bell
		}
	}
}
proc SetPreset {margin topaligned outline shadow color {maxfontsize 100}} {
	set ::s2a::margin $margin
	set ::s2a::topaligned $topaligned
	set ::s2a::outline $outline
	set ::s2a::shadow $shadow
	SetColor $color
	if {$maxfontsize > 20 && $::s2a::fontsize > $maxfontsize} {
		set ::s2a::fontsize $maxfontsize
	}
}
proc OpenSrt {} {
	set ::status ""
	set initialdir [GetProjectFolder]
	set initialfile ""
	if {$::s2a::insrtfile != ""} {
		if {[file isdirectory [file dirname $::s2a::insrtfile]]} {
			set initialdir [file dirname $::s2a::insrtfile]
			if {[file exists $::s2a::insrtfile]} {
				set initialfile [file tail $::s2a::insrtfile]
			}
		}
	}
	set r [tk_getOpenFile -initialdir $initialdir -initialfile $initialfile \
			-filetypes {{{SRT (SubRip) subtitles} {.srt}}} -parent .srt2ass3d \
			-title "Open the SRT file to convert to ASS 3D..."]
	if {$r != ""} {
		set ::s2a::insrtfile [file nativename $r]
		set fh [open $r r]
		if {$fh != ""} {
			unset -nocomplain ::s2a::utf16bom
			fconfigure $fh -encoding binary
			set c3 [read $fh 3]
			set c2 [string range $c3 0 1]
			if {$c3 == "\xEF\xBB\xBF"} {
				# UTF-8 BOM present: force utf-8 encoding
				set ::s2a::inencoding "utf-8"
				set ::status "Character encoding of input SRT file is UTF-8."
			} elseif {$c2 == "\xFF\xFE" || $c2 == "\xFE\xFF"} {
				# UTF-16 BOM present: force unicode encoding
				set ::s2a::inencoding "unicode"
				set ::s2a::utf16bom $c2
				set ::status "Character encoding of input SRT file is unicode (UTF-16)."
			} else {
				set ::status "Cannot determine the character encoding of input SRT file.  Please check it!"
			}
			close $fh
		}
		set ::s2a::outass "[file nativename [file rootname $::s2a::insrtfile]] 3D.ass"
	}
	return $r
}
proc OpenOfs {} {
	set ::status ""
	set initialdir ""
	set initialfile ""
	if {$::s2a::ofsfile != ""} {
		if {[file isdirectory [file dirname $::s2a::ofsfile]]} {
			set initialdir [file dirname $::s2a::ofsfile]
			if {[file exists $::s2a::ofsfile]} {
				set initialfile [file tail $::s2a::ofsfile]
			}
		}
	}
	if {$initialdir == "" && $::s2a::insrtfile != ""} {
		if {[file isdirectory [file dirname $::s2a::insrtfile]]} {
			set initialdir [file dirname $::s2a::insrtfile]
		}
	}
	if {$initialdir == ""} {
		set initialdir [GetProjectFolder]
	}
	set r [tk_getOpenFile -initialdir $initialdir -initialfile $initialfile \
			-filetypes {{{3D-planes} {.ofs}}} -parent .srt2ass3d \
			-title "Open the 3D-Plane file with the right 3D depth values..."]
	if {$r != ""} {
		set ::s2a::ofsfile [file nativename $r]
	}
	return $r
}
proc OpenGuide {} {
	set ::status ""
	set initialdir ""
	set initialfile ""
	if {$::s2a::guidefile != ""} {
		if {[file isdirectory [file dirname $::s2a::guidefile]]} {
			set initialdir [file dirname $::s2a::guidefile]
			if {[file exists $::s2a::guidefile]} {
				set initialfile [file tail $::s2a::guidefile]
			}
		}
	}
	if {$initialdir == "" && $::s2a::ofsfile != ""} {
		if {[file isdirectory [file dirname $::s2a::ofsfile]]} {
			set initialdir [file dirname $::s2a::ofsfile]
		}
	}
	if {$initialdir == "" && $::s2a::insrtfile != ""} {
		if {[file isdirectory [file dirname $::s2a::insrtfile]]} {
			set initialdir [file dirname $::s2a::insrtfile]
		}
	}
	if {$initialdir == ""} {
		set initialdir [GetProjectFolder]
	}
	set r [tk_getOpenFile -initialdir $initialdir -initialfile $initialfile \
			-filetypes {{{XML/PNG subtitle} {.xml}}} -parent .srt2ass3d \
			-title "Open guide XML/PNG file with the right subtitle positions..."]
	if {$r != ""} {
		set ::s2a::guidefile [file nativename $r]
	}
	return $r
}
proc SetOutAss {} {
	set ::status ""
	set initialdir ""
	set initialfile ""

	if {$::s2a::outass != ""} {
		if {[file isdirectory [file dirname $::s2a::outass]]} {
			set initialdir [file dirname $::s2a::outass]
		}
		set initialfile [file tail $::s2a::outass]
	}
	if {$initialdir == "" && $::s2a::insrtfile != ""} {
		if {[file isdirectory [file dirname $::s2a::insrtfile]]} {
			set initialdir [file dirname $::s2a::insrtfile]
			set initialfile "[file rootname [file tail $::s2a::insrtfile]].ass"
		}
	}
	if {$initialdir == ""} {
		set initialdir [GetProjectFolder]
	}
	set r [tk_getSaveFile -initialdir $initialdir -initialfile $initialfile \
			-filetypes {{{Advanced SubStation Alpha} {.ass}}} -defaultextension .ass \
			-parent .srt2ass3d -title "Save the ASS subtitle file as..."]
	if {$r != ""} {
		set ::s2a::outass [file nativename $r]
	}
	return $r
}
proc GuideIgnoreValidate {} {
	if {$::s2a::ignoreguidey} {
		.srt2ass3d.f4.fg1.cb2 configure -state normal
	} else {
		.srt2ass3d.f4.fg1.cb2 configure -state disabled
	}
}

proc SelFont {{font ""}} {
	set ::status ""
	if {$font == ""} {
		set font [::fontreq::FontReq $::s2a::fontname .srt2ass3d]
		if {$font == ""} {
			return ""
		}
	}
	set ::s2a::fontname $font
	.srt2ass3d.f3.f1.b1 configure -text $::s2a::fontname
	return $font
}
proc SelColor {} {
	set ::status ""
	set c [tk_chooseColor -initialcolor $::s2a::color -parent .srt2ass3d -title "Choose font colour..."]
	if {$c != ""} {
		SetColor $c
	}
	return $c
}
proc SetColor {color} {
	set ::s2a::color $color
	.srt2ass3d.f3.f1.b2 configure -text [RGB2Txt $::s2a::color] \
			-bg $::s2a::color -activebackground $::s2a::color
}
proc RGB2Txt {color} {
	set r [expr 0x[string range [string toupper $color] 1 2]]
	set g [expr 0x[string range [string toupper $color] 3 4]]
	set b [expr 0x[string range [string toupper $color] 5 6]]
	return $r,$g,$b
}
proc SetShadowTransparency {args} {
	set t [expr round($::s2a::shadowtr / 1.0625)]
	.srt2ass3d.f3.f2.110 configure -bg [format "#%02X%02X%02X" $t $t $t]
}
proc CheckEncoding {} {
	set ::status ""
	if {$::s2a::insrtfile == "" || ! [file exists $::s2a::insrtfile]} {
		set ::status "Select a SRT file first!"
		focus .srt2ass3d.f1.f1.e
		bell
		return
	}
	if {[catch {set fh [open $::s2a::insrtfile r]} err]} {
		set ::status $err
		focus .srt2ass3d.f1.f1.e
		bell
		return
	}
	fconfigure $fh -encoding $::s2a::inencoding
	set test ""
	set numlines 0
	while { ! [eof $fh]} {
		set line [string trim [gets $fh]]
		if {$line == ""} {
			append test \n
			incr numlines
			if {$numlines >= 30} break
			continue
		}
		if {[string is integer $line] || [string first " --> " $line] > 0 || [string length $line] < 3} {
			continue
		}
		append test "[string map {"<i>" "" "</i>" "" "<b>" "" "</b>" "" "<u>" "" "</u>" "" "</font>" ""} $line] "
	}
	close $fh
	set msg "You should see the text of the first 30 subtitles below.  If the accented or foreign characters are not correct, select another encoding or convert the encoding of the original SRT file to UTF-8 with a good text editor and retry.  If you see a few bizarre characters at the beginning of the text, try utf-8 or unicode.  Otherwise, try [encoding system].\n\n"
	append msg [string trim $test \n]
	tk_messageBox -message $msg -title "Test \"$::s2a::inencoding\" encoding" -parent .srt2ass3d
}
proc AnalyseXMLGuide {} {
	set minheightofdoublesub 100

	set ::status ""
	if {$::s2a::guidefile == "" || ! [file exists $::s2a::guidefile]} {
		set ::status "Select a guide file first!"
		focus .srt2ass3d.f4.f3.e
		bell
		return
	}
	# TODO: Retrieve video resolution from XML guide

	# subtitles data is a list the following values for each subtitle:
	# subnum intc outtc width height x y depth image.png (where depth may be empty)
	set r [GetSubtitleDataFromXML $::s2a::guidefile]
	set rc [lindex $r 0]
	set data [lindex $r 1]
	if {$rc != 0} {
		set ::status $data
		focus .srt2ass3d.f4.f3.e
		bell
		return
	}

	set minposx 10000
	set maxposx 0
	set avgposx 0

	set numsubs 0
	set numsingles 0
	set numdoubles 0

	set singleminheight 10000
	set singlemaxheight 0
	set singleavgheight 0
	set singleminbottom 10000
	set singlemaxbottom 0
	set singleavgbottom 0

	set doubleminheight 10000
	set doublemaxheight 0
	set doubleavgheight 0
	set doubleminbottom 10000
	set doublemaxbottom 0
	set doubleavgbottom 0

	set largestsinglesub {}
	set singlemaxwidth 0
	set largestdoublesub {}
	set doublemaxwidth 0

	# results
	set topaligned 0
	set baseline -1
	set bottommargin -1
	set lightercolor ""
	set lightercolorrgb ""
	set sfontsize -1

	foreach sub $data {
		foreach {subnum intc outtc width height x y depth img} $sub {}
		incr numsubs

		set posx [expr $x + ( $width / 2.0)]
		if {$posx < $minposx} {set minposx $posx}
		if {$posx > $maxposx} {set maxposx $posx}
		set avgposx [expr $avgposx + $posx]

		set bottom [expr $y + $height]
		if {$height < $minheightofdoublesub} {
			incr numsingles
			if {$singleminheight > $height} {
				set singleminheight $height
			}
			if {$singlemaxheight < $height} {
				set singlemaxheight $height
			}
			incr singleavgheight $height

			if {$singleminbottom > $bottom} {
				set singleminbottom $bottom
			}
			if {$singlemaxbottom < $bottom} {
				set singlemaxbottom $bottom
			}
			incr singleavgbottom $bottom
			if {$width > $singlemaxwidth} {
				set singlemaxwidth $width
				set largestsinglesub [list $subnum $width $img]
			}
		} else {
			incr numdoubles
			if {$doubleminheight > $height} {
				set doubleminheight $height
			}
			if {$doublemaxheight < $height} {
				set doublemaxheight $height
			}
			incr doubleavgheight $height

			if {$doubleminbottom > $bottom} {
				set doubleminbottom $bottom
			}
			if {$doublemaxbottom < $bottom} {
				set doublemaxbottom $bottom
			}
			incr doubleavgbottom $bottom
			if {$width > $doublemaxwidth} {
				set doublemaxwidth $width
				set largestdoublesub [list $subnum $width $img]
			}
		}
	}
	set avgposx [expr 1.0 * $avgposx / $numsubs]
	set singleavgheight [expr $singleavgheight * 1.0 / $numsingles]
	set singleavgbottom [expr $singleavgbottom * 1.0 / $numsingles]
	set doubleavgheight [expr $doubleavgheight * 1.0 / $numdoubles]
	set doubleavgbottom [expr $doubleavgbottom * 1.0 / $numdoubles]

	if {$numsubs == 0} {
		set ::status "There are no subtitles in the guide file!  Wrong XML?"
		focus .srt2ass3d.f4.f3.e
		bell
		return
	}

	set msg "Analysed $numsubs subtitles.\n\n"
	if {$numsingles == 0} {
		append msg "There are no single subtitles.\n\n"
	}
	if {$numdoubles == 0} {
		append msg "There are no double subtitles.\n\n"
	}

	append msg "X positions of the center of the subtitles:\n"
	append msg "Min: [expr round($minposx)], Max: [expr round($maxposx)], Average: $avgposx\n"
	if {$minposx >= 950 && $maxposx < 970} {
		append msg "All subtitles are centered in the middle of the screen (around X pos 960).\n\n"
		set xcentered 1
	} else {
		append msg "The subtitles are NOT centered in the middle of the screen (around X pos 960).\n\n"
		set xcentered 0
	}

	if {$numsingles > 0} {
		append msg "Y positions of the $numsingles single subtitles:\n"
		append msg "Height: Min: $singleminheight, Max: $singlemaxheight, Average: $singleavgheight\n"
		append msg "Bottom: Min: $singleminbottom, Max: $singlemaxbottom, Average: $singleavgbottom\n"
	}
	if {$numdoubles > 0} {
		append msg "Y positions of the $numdoubles double subtitles:\n"
		append msg "Height: Min: $doubleminheight, Max: $doublemaxheight, Average: $doubleavgheight\n"
		append msg "Bottom: Min: $doubleminbottom, Max: $doublemaxbottom, Average: $doubleavgbottom\n"
	}

	if {$numsingles > 0 && $numdoubles > 0} {
		if {$singleminbottom > [expr $singleavgbottom - 10] && $singlemaxbottom < [expr $singleavgbottom + 10] && \
			$doubleminbottom > [expr $doubleavgbottom - 10] && $doublemaxbottom < [expr $doubleavgbottom + 10]} {
			append msg "All subtitles are at (approximately) the same Y position.\n"
			set ycentered 1
			if {$doubleavgbottom > [expr $singleavgbottom - 10] && $doubleavgbottom < [expr $singleavgbottom + 10]} {
				append msg "In double subtitles, the first line is above the single subtitles (bottom-aligned).\n"
# 				if {$singleminbottom < $doubleminbottom} {
# 					set baseline $singleminbottom
# 				} else {
# 					set baseline $doubleminbottom
# 				}
				if {$singlemaxbottom > $doublemaxbottom} {
					set baseline $singlemaxbottom
				} else {
					set baseline $doublemaxbottom
				}
			} else {
				append msg "In double subtitles, the first line is below the single subtitles (top-aligned).\n"
# 				set baseline $doubleminbottom
				set baseline $doublemaxbottom
				set topaligned 1
			}
		} else {
			append msg "The subtitles are NOT at the same Y position.\n"
			set ycentered 0
# 			if {$singleminbottom < $doubleminbottom} {
# 				set baseline [expr $singlemaxbottom - ($singleminheight / 6)]
# 			} else {
# 				set baseline [expr $doublemaxbottom - ($singleminheight / 6)]
# 			}
			if {$singlemaxbottom > $doublemaxbottom} {
				set baseline $singlemaxbottom
			} else {
				set baseline $doublemaxbottom
			}
		}
	} elseif {$numsingles > 0} {
		if {$singleminbottom > [expr $singleavgbottom - 10] && $singlemaxbottom < [expr $singleavgbottom + 10]} {
			append msg "All subtitles are at (approximately) the same Y position.\n"
# 			set baseline $singleminbottom
			set baseline $singlemaxbottom
			set ycentered 1
		} else {
			append msg "The subtitles are NOT at the same Y position.\n"
# 			set baseline [expr $singlemaxbottom - ($singleminheight / 6)]
			set baseline $singlemaxbottom
			set ycentered 0
		}
	} else {
		if {$doubleminbottom > [expr $doubleavgbottom - 10] && $doublemaxbottom < [expr $doubleavgbottom + 10]} {
			append msg "All subtitles are at (approximately) the same Y position.\n"
# 			set baseline $doubleminbottom
			set baseline $doubleminbottom
			set ycentered 1
		} else {
			append msg "The subtitles are NOT at the same Y position.\n"
# 			set baseline [expr $doublemaxbottom - 8]
			set baseline $doublemaxbottom
			set ycentered 0
		}
	}
	if {$baseline != -1} {
		incr baseline -4 ;# outline and shadow should not be counted in.  Assumes 4 pixels for both
		set bottommargin [expr 1080 - $baseline]
		append msg "The bottom margin is approximately $bottommargin pixels ([expr round(($bottommargin/1080.0)*10000)/100.0]%).\n"
	}

	# Analyse the largest single subtitle...
	
	if {$largestsinglesub != {}} {
		set pngimage [file join [file dirname $::s2a::guidefile] [lindex $largestsinglesub 2]]
	} else {
		set pngimage [file join [file dirname $::s2a::guidefile] [lindex $largestdoublesub 2]]
	}
	if {[file exists $pngimage]} {
		if {$largestsinglesub != {}} {
			set imgw [expr [lindex $largestsinglesub 1] - ($::s2a::outline * 2)]
		} else {
			set imgw [expr [lindex $largestdoublesub 1] - ($::s2a::outline * 2)]
		}

		if {$::s2a::fontname == "Arial" || $::s2a::fontname == "Verdana" || $::s2a::fontname == "Times New Roman"} {
			set analysesize 0
			if {$largestsinglesub != {}} {
				set txt [GetTextFromPNG $pngimage]
			} else {
				set txt [GetTextFromPNG $pngimage true]
			}
		} else {
			set analysesize 0
			set txt ""
			append msg "\nSince you have selected a non-universal font, it is not possible to help you determine the correct font size to use.  Sorry.\n"
		}

		# ... to determine the best font size
		if {$txt != ""} {
			set ss -30
			while {[font measure [list $::s2a::fontname $ss] $txt] <= $imgw} {
				incr ss -5
			}
			incr ss
			while {[font measure [list $::s2a::fontname $ss] $txt] > $imgw} {
				incr ss
			}
			# TODO: Find correct formula
			switch $::s2a::fontname {
				"Arial" {
					set mult 1.126
				}
				"Verdana" {
					set mult 1.225
				}
				"Times New Roman" {
					set mult 1.1
				}
				default {
					set mult 1.1
				}
			}
			set sfontsize [expr round(floor($ss * -1 * $mult))]
			append msg "\nThe analysis of the subtitle image \"[file tail $pngimage]\" gives the following results:\n"
			append msg "The suggested font size (for \"$::s2a::fontname\" only!) is $sfontsize.\n"
			#puts "Font size calculated with [file tail $pngimage] (width $imgw): $ss (width = [font measure [list $::s2a::fontname $ss] $txt]) Metrics: [font metrics [list $::s2a::fontname $ss]]) - Converted to $sfontsize"
			if {$sfontsize >= 20 && $sfontsize <= 80} {
				append msg "Note that it's only an approximation.  The value can be wrong if the subtitle is special (for example in bold or using an unusual font).\n"
			} else {
				append msg "Something went wrong with the font size calculation, because the result is obviously out of range (<20 or >80).\n"
				set sfontsize -1
			}
		}


		# ... and to determine the best font color
		set imexe [GetAppPath convert.exe true]
		if {! [catch {set histogram [exec -- $imexe $pngimage -background black \
				-alpha remove -dither None -colors 16 -format %c histogram:info:-]} err]} {
			#puts "Histogram: $histogram"
			set histogram [split $histogram \n]
			set lightercolor {0 0 0 255}
			set lightercolorlum 0
			foreach l $histogram {
				set line [string trim $l]
				set idx1 [expr [string first "(" $line]+1]
				set idx2 [expr [string first ")" $line]-1]
				set tmp [string map {"  " "" " " ""} [string range $line $idx1 $idx2]]
				set rgba [split $tmp ,]
				set colorlum [expr ([lindex $rgba 0]*[lindex $rgba 0])+([lindex $rgba 1]*[lindex $rgba 1])+([lindex $rgba 2]*[lindex $rgba 2])]
				if {$colorlum > $lightercolorlum} {
					set lightercolor $rgba
				}
			}
			set lightercolorrgb [format %02X%02X%02X [lindex $lightercolor 0] [lindex $lightercolor 1] [lindex $lightercolor 2]]
 			append msg "The histogram of the image suggests that the best font colour (in RGB) is [lindex $lightercolor 0],[lindex $lightercolor 1],[lindex $lightercolor 2] (#$lightercolorrgb).\n"
		}
	} else {
		append msg "\nThe analysis of the subtitle image \"[file tail $pngimage]\" has been skipped because the file does not exist.\n"
	}

	if {$xcentered && $ycentered} {
		append msg "\nSince the subtitles are not placed according to the content of the scenes, it is not necessary to use the guide file, as long as you use the correct bottom margin.  You can therefore delete the file name of the 2D guide from the GUI.\n"
	} else {
		append msg "\nSince the subtitles are placed in various X and/or Y positions according to the content of the scenes, it is highly recommended to use the guide file to retrieve the individual positions of the subtitles.  Leave its file name in the GUI.  However, be sure that the guide file corresponds as close as possible to the subtitles you want to convert to ASS 3D.\n"
	}

	set items {}
	if {$sfontsize != -1 && $sfontsize != $::s2a::fontsize} {
		lappend items "the font size to $sfontsize"
	}
	if {$lightercolorrgb != "" && "#$lightercolorrgb" != $::s2a::color} {
		lappend items "the font colour to [lindex $lightercolor 0],[lindex $lightercolor 1],[lindex $lightercolor 2] (#$lightercolorrgb)"
	}
# 	if {$topaligned != $::s2a::topaligned} {
# 		if {$topaligned} {
# 			lappend items "the font alignment to Top"
# 		} else {
# 			lappend items "the font alignment to Bottom"
# 		}
# 	}
	if {$bottommargin != -1 && $bottommargin != $::s2a::margin} {
		lappend items "the bottom margin to $bottommargin"
	}
	if {$items == {}} {
		append msg "\nThere is nothing to change in the GUI."
		tk_messageBox -message $msg -parent .srt2ass3d \
				-title "Convert subtitles from SRT 2D to ASS 3D: Analysis result"
	} else {
		append msg "\nShould I change [join $items {, }] ?"
		set r [tk_messageBox -message $msg -parent .srt2ass3d -icon question -type yesno -default yes \
						-title "Convert subtitles from SRT 2D to ASS 3D: Analysis result"]
		if {$r == "yes"} {
			if {$sfontsize != -1 && $sfontsize != $::s2a::fontsize} {
				set ::s2a::fontsize $sfontsize
			}
			if {$lightercolorrgb != "" && $lightercolorrgb != $::s2a::color} {
				SetColor #$lightercolorrgb
			}
			if {$topaligned != $::s2a::topaligned} {
				set ::s2a::topaligned $topaligned
			}
			if {$bottommargin != -1 && $bottommargin != $::s2a::margin} {
				set ::s2a::margin $bottommargin
			}

		}
		set ::status "GUI updated with the result of the analysis of the guide."
	}
	return [list $sfontsize $lightercolorrgb $topaligned $bottommargin]
}

proc GetTextFromPNG {imagefile {doublesub false}} {
	if {[catch {image create photo tmp_img1 -file $imagefile} err]} {
		return ""
	}
	set img tmp_img1
	if {[image width tmp_img1] > 800} {
		image create photo tmp_img2 -width [expr [image width tmp_img1] / 2] -height [expr [image height tmp_img1] / 2]
		tmp_img2 copy tmp_img1 -subsample 2 2
		image delete tmp_img1
		set img tmp_img2
	}

	if {! [info exists ::s2a::previmgfile] || $imagefile != $::s2a::previmgfile} {
		set ::s2a::tmptxt ""
	}
	set ::s2a::previmgfile $imagefile

	set w .imgtxt
	catch {destroy $w}
	toplevel $w
	wm withdraw $w
	wm transient $w .srt2ass3d
	wm title $w "Convert subtitles from SRT 2D to ASS 3D"

	pack [label $w.l1 -text "Please type in EXACTLY what you see below. (Case sensitive !)\nThis will help evaluate the correct font size for the current font."] -padx 4 -pady 2
	if {$doublesub} {
		pack [label $w.l2 -text "If the subtitle below is a double-line subtitle,\ntype ONLY the WIDEST line (in pixels, not in number of characters)!" -fg red -justify left] -padx 4 -pady 2
	}
	pack [label $w.img -image $img] -padx 2 -pady 2
	pack [ttk::entry $w.e -textvariable ::s2a::tmptxt] -padx 4 -pady 4 -fill x
	pack [frame $w.f] -padx 4 -pady 4
	pack [ttk::button $w.f.ok -width 8 -command {set ::s2a::imgtxt_done 1} -text "OK"] -side left -padx 2
	pack [ttk::button $w.f.ca -width 8 -command {set ::s2a::imgtxt_done 0} -text "Cancel"] -side left -padx 2

	update
  	wm resizable $w 0 0
  	wm protocol $w WM_DELETE_WINDOW {set ::s2a::imgtxt_done 0}
  	bind $w <Return> {set ::s2a::imgtxt_done 1}
  	wm geometry $w +[winfo rootx .srt2ass3d]+[expr [winfo rooty .srt2ass3d] + 12]
  	wm deiconify $w
 	Pause
  	focus -force $w
  	focus -force $w.e
  	grab set $w

	tkwait variable ::s2a::imgtxt_done
	set done $::s2a::imgtxt_done
	set txt $::s2a::tmptxt
	unset ::s2a::imgtxt_done
	destroy $w
	image delete $img
	if {$done} {
		return [string trim $txt]
	} else {
		return ""
	}
}
proc ShowXMLGuide {} {
	set ::status ""
	if {$::s2a::guidefile == "" || ! [file exists $::s2a::guidefile]} {
		set ::status "Select a guide file first!"
		focus .srt2ass3d.f4.f3.e
		bell
		return
	}
	OpenSubtitle $::s2a::guidefile
}

proc MainHelp {} {
	set ::status ""
	set txt "Normally, all 3D subtitles are graphics subtitles (in BD SUP or DVD VobSub format).  Unfortunately, not all players can display the graphics subtitles.  This tool allows you to create 3D text subtitles (in ASS or \"Advanced SubStation Alpha\" format) that your player may recognise more easily.\n\n"
	append txt "Since it is necessary to download the original SRT file yourself, or convert the original BD SUP to SRT with a SRT converter (usually using OCR), it is not possible to automatically convert the original graphics subtitles to ASS and mux them to the final 3D MKV.  But you can do it yourself easily.  Here is how.\n\n"
	append txt "When you prepare the project with BD3D2MK3D, you should select at least one subtitle stream.  That stream and its associated 3D-Plane will be used as a \"guide\" to position the subtitles at the correct depth and position on screen.  If a subtitle stream in your own language exists, select it.  Otherwise, select the closest stream to the language you want to incorporate in the MKV.  Ideally, the original subtitle should have the same number of subtitles (including the forced subtitles) at the same timings, and the sentences should have approximately the same number of characters than the translations in your language, or possibly a little bit more but not less.  For example, if you want to add a French stream in 3D ASS format, you could select the Spanich subtitle stream of the original BD.  You can also select all subtitle streams and do the selection of the best guide later.\n\n"
	append txt "If you have demuxed the subtitle stream in your own language, it is better to convert it to SRT format yourself with SubtitleEdit.  Otherwise, download the subtitles in your language.  You should download only subtitles extracted from a BD in NTSC-Film frame rate (23.976 fps), and preferably coming from the same BD3D.  Anyway, verify the timings of the subtitles carefully.  It is very important that the sentences are EXACTLY synchronised with the movie (and, better, with the subtitles of the guide stream).  You can verify if they are synchronised with a good software player.  Launch the preview from tab 1 of BD3D2MK3D, and add the SRT subtitle file.  Verify if the subtitles are correctly synchronised near the beginning and end of the movie.  If it's not the case, use the synchronisation options of SubtitleEdit to fix the timings.\n\n"
	append txt "Now, you can convert the SRT subtitles to ASS 3D with this tool.  Use the 3D-Plane that is normally used with the \"guide\", and for the guide, select the \"temp2D.xml\" file in the folder with the XML/PNG subtitles created by BD3D2MK3D during the conversion of the original guide stream to 3D.\n\n"
	append txt "You should also select a good font (Arial is usually recommended) and especially the right font size in the GUI.  The subtitles generated by the ASS rendering engine should ideally occupy a little bit LESS space than the original subtitles of the guide, to minimise the risk of collisions with objects or characters in the foreground of the scene.  It is also very important to select the right value for the bottom margin.  It should be equal to the bottom margin of the original subtitles of the guide (or, if the subtitles are placed at various positions, like in Avatar, the margin should be the margin of the bottom-most original subtitle).  The button \"Analyse the subtitle Guide\" can help you find the right values.  Note that it is better to NOT specify the guide file if all subtitles are centered in the bottom part of the screen (like in many movies) and you have specified the correct bottom margin.\n\n"
	append txt "Note that this tool assumes that the original movie is in its unaltered 16:9 format, and its resolution is 1080p.  You should NEVER crop the black borders of a 3D movie.  If you have resized the movie to 720p, don't worry.  All values must be given and computed for the full 1080p resolution, but the player will resize the subtitles if necessary at playback time.\n\n"
	append txt "Finally, do the conversion.  When the conversion is finished, you will have to edit the \"__MUX_3D_OPTIONS.json\" file to include the new 3D ASS subtitles in the final MKV.  To help you, BD3D2MK3D includes an example of the subtitle definition that you should use at the end of the log file it generates during the conversion.  Just copy it and add it in the 3D Subtitles section of the MUX options file, or replace the original 3D stream used as a guide if you wish.  You will have to edit it a bit, but it's easy.  Since the SRT format is recognised by almost all players, it might be a good idea to include also the original 2D SRT file the same way, in the 2D Subtitles section of the \"__MUX_3D_OPTIONS.json\" file.\n\n"
	append txt "Launch \"__ENCODE_3D_LAUNCHER.cmd\" to encode the project and mux the final MKV with your 3D ASS file (or just launch \"__MUX_3D.cmd\" if the h264 video stream has already been computed and you want only to remux the final MKV with the new 3D ASS subtitles).\n\n"
	append txt "Enjoy your movie with 3D text subtitles in your language and at the correct depth and position on screen !"
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc CharEncHelp {} {
	set ::status ""
	set txt "All text files are encoded in a specific character encoding.  The encoding determines how certain foreign characters (like accented characters) are displayed.\n\n"
	append txt "Since the SRT file is a text file, it needs to have the right character encoding, or the foreign characters will be wrong.  Unfortunately, it is rarely possible to determine the right character encoding automatically, and you may have to specify it, especially if your SRT file is not in English.\n\n"
	append txt "Since the MKV format requires the UTF-8 encoding, it is highly recommended to convert the non-English SRT files to UTF-8 first, with a good text editor like PSPad (free).  If you can see the accented and foreign characters correctly in the text editor, then convert the encoding to UTF-8.  The text should not change.  Save it, and of course use utf-8 in this tool.\n\n"
	append txt "You can click the \"Check Character Encoding\" button to display the beginning of the subtitles, and verify if the foreign characters are displayed correctly with the currently selected encoding.\n\n"
	append txt "Note that BD3D2MK3D saves always the final ASS 3D file in UTF-8 format (with BOM), because MkvMerge stores it internally in UTF-8 anyway, and will not have to convert it."
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc MarginHelp {} {
	set ::status ""
	set txt "This is the position in the image where the program should place the subtitles, when no Guide file is used.\n\n"
	append txt "Note that the bottom margin indicates where the bottom parts of the text must be placed (so, for example, the bottom of the letter \"p\", that is below the baseline of the font).  The outline and shadow are not taken into account when the subtitles are positionad.\n\n"
	append txt "If you specify a \"Guide\" subtitle file, BD3D2MK3D will try to copy the positions of the subtitles of the guide and the bottom margin will usually be ignored.  However, it is not always possible to find a subtitle at the same timings in the guide.  In that case, the bottom margin will be used.  It is therefore important to give a correct margin anyway.\n\n" 
	append txt "If all subtitles are at the same height in the image and are horizontally centered in the middle of the screen, there is no need to clone the positions from the guide, and using only a good bottom margin gives better results.  In that case, you can leave the Guide option empty, but you should give the correct bottom margin so that the subtitles will be at the right height.\n\n" 
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc GuideHelp {} {
	set ::status ""
	set txt "For best results, the 3D subtitles should be placed at the same position than in the original subtitle stream of the BD, so that there is no risk to cover another part of the image, and possibly enter in an object in the foreground of the scene.\n\n"
	append txt "If you specify a \"Guide\" subtitle file, BD3D2MK3D will try to copy the positions of the subtitles of the guide to the subtitles of the stream you want to convert to 3D." 
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc GuideIgnoreHelp {} {
	set ::status ""
	set txt "If you select a guide file but you want to use the specified bottom margin anyway, you can tick the Ignore the Y position option.  The vertical position from the guide will be replaced with the value specified for the bottom margin, and only the horizontal position from the guide will be taken into account.  This option allows you to move the subtitles near the bottom of the image, largely out of the view, or even in the black border of a movie shot in Cinemascope format.  But take care!  When this option is enabled, some subtitles may enter in the ground or in objects in the foreground, so use it with caution.\n\n"
	append txt "When this option is enabled, you can also restrict its action to the subtitles located in the lower half of the screen, so that the (rare) subtitles located at the top will still be displayed correctly.\n\n"
	append txt "Of course, these two options are ignored if you do not specify a guide file.  In that case, the bottom margin is used for all subtitles anyway (and all subtitles are centered horizontally).\n\n"
	 
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc AnalyseHelp {} {
	set ::status ""
	set txt "The \"Analyse the subtitle Guide\" function can be used to grab some of the characteristics of the subtitle guide and inject them automatically in the GUI.  This function shows also some statistics about the placement of the subtitles on screen, so that you can decide to use the Guide to position each subtitle individually, or let the program position all subtitles in the bottom center of the screen.\n\n"
	append txt "The values that can be retrieved from the guide and copied to the GUI are the approximative font size (only if Arial, Verdana or Times New Roman is selected when the analysis is launched), the bottom margin and the colour of the font.\n\n" 
	append txt "If you prefer, you can also visually inspect the subtitles in BDSup2Sub and try to determine yourself the best font size and bottom margin with the \"Show me the subtitle Guide\" option." 
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc PositionsHelp {} {
	set ::status ""
	set txt "The ASS format permits to position the subtitles with two different methods.\n\n"
	append txt "When the Margins method is used, different margins are used to shift an individual subtitle to the left or right, and position it at the right height on screen.  The advantage of the margin method is that there is no risk to position the subtitle partially off screen (or, worse, partially over the other view of a 3D-SBS movie).  When a subtitle is too large to fit within the margins, the player should split the long line in several parts, and still display it approximately at the right position.  It's therefore the recommended method.\n\n" 
	append txt "The other method uses Positions commands (in the form {\pos(x,y)}) to place each subtitle at the right location.  It is less safe to use that method, because some players may not position very large subtitles correctly on screen, and the depth of the resulting 3D subtitle may be wrong.  However, the Position method has the advantage that it is much easier to edit manually the position or depth of an individual subtitle, if some subtitles are not positioned correctly.  It's therefore the method to use by expert users who may want to fine-tune the subtitle stream manually."
	tk_messageBox -message $txt -title "Convert SRT to ASS 3D" -parent .srt2ass3d
}
proc GuiGo {} {
	set ::status ""

	# verify GUI values
	set ::s2a::insrtfile [string trim $::s2a::insrtfile]
	set ::s2a::ofsfile   [string trim $::s2a::ofsfile]
	set ::s2a::guidefile [string trim $::s2a::guidefile]
	if {$::s2a::insrtfile == "" || ! [file exists $::s2a::insrtfile]} {
		set ::status "Select a SRT file first!"
		focus .srt2ass3d.f1.f1.e
		bell
		return 1
	}
	if {$::s2a::ofsfile != "" && ! [file exists $::s2a::ofsfile]} {
		set ::status "The OFS 3D-plane file does not exist!"
		focus .srt2ass3d.f2.f2.e
		bell
		return 1
	}
	if {$::s2a::guidefile != "" && ! [file exists $::s2a::guidefile]} {
		set ::status "The XML Guide file does not exist!"
		focus .srt2ass3d.f4.f3.e
		bell
		return 1
	}
	if {$::s2a::outass == ""} {
		set ::status "Select the output ASS file first!"
		focus .srt2ass3d.f5.f3.e
		bell
		return 1
	}
	if {[file exists $::s2a::outass]} {
		set ::status "The output ASS file already exists!"
		if {[tk_messageBox -type okcancel -default cancel -icon question -message \
				"The output ASS file already exists :\n\"[file tail $::s2a::outass]\"\n\nOverwrite ?" \
				-title "Convert SRT to ASS 3D" -parent .srt2ass3d] == "cancel"} {
			focus .srt2ass3d.f5.f3.e
			return 1
		}
	}
	
	if {[catch {set ::logfh [open $::s2a::outass.log w]} err]} {
		puts stderr $err
		puts "Continuing anyway..."
		unset -nocomplain ::logfh
	}
	

	set r [ConvertSrtToAss3D $::s2a::insrtfile $::s2a::inencoding $::s2a::keepformatting \
		$::s2a::half $::s2a::sbs $::s2a::leftfirst $::s2a::ofsfile $::s2a::searchalt3dp \
		$::s2a::adddepth $::s2a::fontname $::s2a::fontsize $::s2a::color $::s2a::outline \
		$::s2a::shadow $::s2a::shadowtr $::s2a::margin $::s2a::guidefile $::s2a::usepostags \
		$::s2a::ignoreguidey $::s2a::excepttop]
		# Not yet implemented: $::s2a::topaligned $::s2a::framerate
	set rc  [lindex $r 0]
	set out [lindex $r 1]
	if {$rc} {
		set ::status $out
		bell
		return 1
	}

	# Save the subtitles
	ToLog "Saving \"[file nativename $::s2a::outass]\"..."
	if {[catch {set fh [open $::s2a::outass w]} err]} {
		set ::status $err
		ToLog $err 1
		focus .srt2ass3d.f5.f3.e
		bell
		close $::logfh
		return 1
	}
	# Since MkvMerge converts the text subtitles to UTF-8 anyway, save the ASS file in UTF-8, with the BOM
	fconfigure $fh -encoding binary
	puts -nonewline $fh "\xEF\xBB\xBF"
	close $fh
	set fh [open $::s2a::outass a]
	fconfigure $fh -encoding "utf-8"
	puts -nonewline $fh $out
	if {[catch {close $fh} err]} {
		set ::status $err
		ToLog $err 1
		bell
		set rc 1
	} else {
		set rc 0
		ToLog "\nDone.  ASS 3D file saved OK." 0
		set ::status "Done.  \"[file tail $::s2a::outass]\" saved OK."

		ToLog "\nTo include the ASS 3D file in the final 3D MKV created by BD3D2MK3D, you should copy and paste the following stream definition in the \"### 3D Subtitle stream(s)\" section of the \"__MUX_3D_OPTIONS.json\" file." 0
		ToLog "Be sure to edit the \"0:und\" line below --language to set the right language code (like for example \"0:fre\" for French)." 0
		ToLog "You may also need to change the --sync value if you have used the option to include N seconds of black at the beginning of the video in the last tab.  Use 0:1001 for 1 second, 0:2002 for 2 seconds, and so on..." 0
		ToLog "You may also want to change the --track-name option to any better label or the --default-track and --forced-track options to suit your needs.  (Note that there can be only ONE Default subtitle track in the whole MKV.)\n" 0
		set example ""
		append example "\t\"--track-name\",\n"
		append example "\t\"0:SSA 3D subs\",\n"
		append example "\t\"--language\",\n"
		append example "\t\"0:und\",\n"
		append example "\t\"--default-track\",\n"
		append example "\t\"0:no\",\n"
		append example "\t\"--forced-track\",\n"
		append example "\t\"0:no\",\n"
		append example "\t\"--sync\",\n"
		append example "\t\"0:0\",\n"
		append example "\t\"--compression\",\n"
		append example "\t\"0:none\",\n"
		append example "\t\"--sub-charset\",\n"
		append example "\t\"0:UTF-8\",\n"
		append example "\t\"[file normalize $::s2a::outass]\",\n"
		ToLog $example
	
		close $::logfh
	
		set txt "Done.\n\"[file nativename $::s2a::outass]\" saved OK.\n\n"
		append txt "To mux it automatically with the final MKV, you should edit the __MUX_3D_OPTIONS.json file generated by BD3D2MK3D and add the correct stream definition in the 3D subtitle stream(s) section (or if you prefer, replace the original definition of the guide file with the ASS 3D one).\n"
		append txt "For your convenience, BD3D2MK3D can copy the definition in the clipboard.  You will have to edit it anyway (to change the label, the language code, and if necessary the Sync delay, as well as the Default and Forced flags.)\n"
		append txt "The template of the definition is included at the end of the log file too (\"[file tail $::s2a::outass].log\") and you can see it right now in the BD3D2MK3D Console.\n"
		append txt "\nShould I copy the template of the stream definition to the clipboard ?\n"
		if {[tk_messageBox -message $txt -icon info -type yesno -default yes] == "yes"} {
			clipboard clear
			clipboard append $example
			set ::status "ASS 3D definition template for __MUX_3D_OPTIONS.json copied to the clipboard."
		}
	}
	return $rc
}

proc ConvertSrtToAss3D {insrtfile inencoding keepformatting half sbs leftfirst ofsfile \
			searchalt3dp adddepth fontname fontsize color outline shadow shadowtr margin \
			guidefile usepostags ignoreguidey excepttop} {
			# Not yet implemented: topaligned framerate

	if {[catch {set fh [open $insrtfile r]} err]} {
		return [list 1 $err]
	}
	fconfigure $fh -encoding $inencoding
	set data [read $fh]
	set srtlines [split $data \n]
	unset data
	close $fh

	if {$guidefile != ""} {
		if {[catch {set fh [open $guidefile r]} err]} {
			return [list 1 $err]
		}
# 		set guidexml [read $fh]
		close $fh
	}

	if {$ofsfile != ""} {
		if {[catch {set fh [open $ofsfile r]} err]} {
			return [list 1 $err]
		}
		fconfigure $fh -encoding binary -translation binary
		set plane [read $fh]
		close $fh
		if {[string range $plane 0 7] == "\x89\x4f\x46\x53\x0d\x0a\x1a\x0a"} {
			set plane [string range $plane 41 end]
		}
	}

	puts \n[string repeat * 79]

	set stereostring "3D " 
	if {$half} {append stereostring "Half-"} else {append stereostring "Full-"}
	if {$sbs}  {append stereostring "SBS"} else {append stereostring "T&B"}
	if {$leftfirst}  {append stereostring ", left"} else {append stereostring ", right"}
	append stereostring " view first"

	ToLog "Converting \"[file nativename $insrtfile]\" to ASS $stereostring..." 0
	set ::status "Converting SRT to ASS $stereostring..."
	Pause

	if {$keepformatting} {
		set substitutions [list \
				"<b>" "{\\b1}" "</b>" "{\\b0}" "<B>" "{\\b1}" "</B>" "{\\b0}" \
				"{b}" "{\\b1}" "{/b}" "{\\b0}" "{B}" "{\\b1}" "{/B}" "{\\b0}" \
				"<i>" "{\\i1}" "</i>" "{\\i0}" "<I>" "{\\i1}" "</I>" "{\\i0}" \
				"{i}" "{\\i1}" "{/i}" "{\\i0}" "{I}" "{\\i1}" "{/I}" "{\\i0}" \
				"<u>" "{\\u1}" "</u>" "{\\u0}" "<U>" "{\\u1}" "</U>" "{\\u0}" \
				"{u}" "{\\u1}" "{/u}" "{\\u0}" "{U}" "{\\u1}" "{/U}" "{\\u0}" \
				"</font>" "{\\c}" "</FONT>" "{\\c}"]
	} else {
		set substitutions [list \
				"<b>" "" "</b>" "" "<B>" "" "</B>" "" \
				"{b}" "" "{/b}" "" "{B}" "" "{/B}" "" \
				"<i>" "" "</i>" "" "<I>" "" "</I>" "" \
				"{i}" "" "{/i}" "" "{I}" "" "{/I}" "" \
				"<u>" "" "</u>" "" "<U>" "" "</U>" "" \
				"{u}" "" "{/u}" "" "{U}" "" "{/U}" "" \
				"</font>" "" "</FONT>" ""]
	}

	set subtitles {}
	set insub 1
	set numsubs 0
	if {$inencoding == "unicode"} {
# 		set insub 1
# 		set srtlines [lreplace $srtlines 0 0]
		set srtlines [lreplace $srtlines 0 0 "1"]
	}
	foreach line $srtlines {
		set line [string trim $line]
		if {$insub == 2 && $line == ""} {
			set insub 0
			set text [string map {"\n" "\\N"} [string trim $text \n]]
			lappend subtitles [list $intc $outtc $text]
			set intc  ""
			set outtc ""
			set text ""
			continue
		}
		if {$insub == 0 && ([string is integer $line] || $line == "1")} {
			set insub 1
			set intc  ""
			set outtc ""
			set text ""
			incr numsubs
			continue
		}
		set idx [string first " --> " $line]
		if {$insub == 1 && $idx == 12} {
			set intc  [string trim [string range $line 0 [expr $idx-1]]]
			set outtc [string trim [string range $line [expr $idx+5] end]]
			set insub 2
			set text ""
			incr numsubs
			continue
		}

		# modified in v0.5 to skip illegal <font face="XXX"> tags
		if {$insub == 2} {
			set line [string map $substitutions $line]

			set idxa [string first "<font " [string tolower $line]]
			while {$idxa >= 0} {
				set idxb [string first ">" $line $idxa]
				if {$idxb > 0} {
					if {$keepformatting} {
						set thiscolor ""
						set idxc [string first " color=" $line $idxa]
						if {$idxc > 0 && $idxc < $idxb} {
							set idx1 [string first \" $line $idxc]
							if {$idx1 > 0 && $idx1 < $idxb} {
								incr idx1
								set idx2 [string first \" $line $idx1]
								if {$idx2 > 0 && $idx2 < $idxb} {
									incr idx2 -1
									set thiscolor [SrtColorToAssCode [string range $line $idx1 $idx2]]
								}
							}
						}
					} else {
						set thiscolor ""
					}
					if {$thiscolor != ""} {
						set line [string map [list [string range $line $idxa $idxb] "{\\c&H$thiscolor&}"] $line]
					} else {
						set line [string map [list [string range $line $idxa $idxb] ""] $line]
#						# Remove </font> completely if it follows a font face change only
#						# Bug: Doesn't work when the color change is on the first line, and </font> on the second line
# 						set idx1 [string first "</font>" $line]
# 						set idx2 [string last  "</font>" $line]
# 						if {$idx1 == $idx2} {
# 							set line [string map [list "</font>" ""] $line]
# 						}
					}
# 					set line [string map [list "</font>" "{\\c}" "</FONT>" "{\\c}"] $line]

					set idxa [string first "<font " [string tolower $line] [expr $idxa+1]]
				}
			}

			append text "$line\n"
		}
	}
	ToLog "Found $numsubs subtitles in SRT file." 0
# 	if {$::config(debug)} {
# 		puts "DEBUG: Subtitles\n[join $subtitles \n]"
# 	}

	Pause
	set depths ""
	if {$ofsfile != ""} {
		ToLog "Retrieving the depth values from 3D-Plane \"[file nativename $ofsfile]\"..." 0
		set r [GetDepths $subtitles $ofsfile 24.0/1.001 $searchalt3dp]
		set rc     [lindex $r 0]
		if {$rc == 0} {
			set depths [lindex $r 1]
# 			if {$::config(debug)} {
# 				puts "DEBUG: Depths\n$depths"
# 			}
		}
	}

	Pause
	set positions ""
	if {$guidefile != ""} {
		ToLog "Retrieving the subtitle positions from guide \"[file nativename $guidefile]\"..." 0
		set positions [GetPositions $subtitles $guidefile 24.0/1.001 24.0 25]
# 		if {$::config(debug)} {
# 			puts "DEBUG: Positions\n[join $positions \n]"
# 		}
	}

	# Now, we have the necessary information.
	# Write the ASS file

	Pause
	ToLog "Generating the ASS 3D file with $numsubs subtitles..."

	set out ""
	append out "\[Script Info\]\n"
	append out "; Script generated by $::APPNAME v$::VERSION\n"
	append out "; http://forum.doom9.org/showthread.php?t=170828\n"
	append out "Title: [file rootname [file tail $insrtfile]] ($stereostring)\n"
	append out "Original Script: [file tail $insrtfile]\n"
	append out "Original Timing: 23.976fps\n"
	append out "Original Editing: Conversion to ASS $stereostring\n"
	append out "; Character encoding: $inencoding\n"
	if {$ofsfile != ""} {
		append out "; 3D-Plane used: [file tail $ofsfile]\n"
		append out "; Additional depth: $adddepth\n"
	} else {
		append out "; Fixed depth: $adddepth\n"
	}
	if {$positions != ""} {
		append out "; Individual subtitles positions taken from: $guidefile\n"
	}
	append out "ScriptType: v4.00+\n"
	append out "Collisions: Normal\n"
	append out "PlayDepth: 0\n"
	append out "WrapStyle: 0\n"
	if { ! $half && $sbs} {
		append out "PlayResX: 3840\n"
	} else {
		append out "PlayResX: 1920\n"
	}
	if { ! $half && ! $sbs} {
		append out "PlayResY: 2160\n"
	} else {
		append out "PlayResY: 1080\n"
	}
# 	append out "Last Style Storage: Default\n"
# 	append out "Scroll Position: 0\n"
# 	append out "Active Line: 0\n"
# 	append out "Video Zoom Percent: 1\n"
	append out "ScaledBorderAndShadow: yes\n"
	append out "\n"
	append out "\[V4+ Styles\]\n"
	append out "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n"
	set scalex 100; set scaley 100
	if {$half} {if {$sbs} {set scalex 50} else {set scaley 50}} 
	# TODO: Verify encoding
	append out "Style: 3D,$fontname,$fontsize,&H00[SrtColorToAssCode $color],&H00000000,&H00000000,&H[format %02X $shadowtr]000000,0,0,0,0,$scalex,$scaley,0,0,1,$outline,$shadow,2,20,20,$margin,0\n"
	append out "\n"
	append out "\[Events\]\n"
	append out "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"

	set subnum1 0
	foreach subtitle $subtitles {
		foreach {intc outtc subtext} $subtitle {}
		set inssatc  [SrtTcToAssTc $intc]
		set outssatc [SrtTcToAssTc $outtc]
		if {$depths != ""} {
			set depth [expr [lindex $depths $subnum1] + $adddepth]
		} else {
			set depth $adddepth
		}
		set depth1 [expr $depth / 2]
		set depth2 [expr ($depth+1) / 2]
		set posx -1; set posy -1
		if {$positions != ""} {
			foreach {gwidth gheight gx gy} [lindex $positions $subnum1] {}
			if {$gx != -1} {
				set posx [expr $gx + ($gwidth/2)]
				set posy [expr $gy + $gheight]	;# TODO: Should take 1/2 lines height into account
			}			
		}
		if {$posx == -1} {
			set posx 960
			set posy [expr 1080 - $margin]
		}
		if {$ignoreguidey && ( ! $excepttop || $posy > 500 )} {
			set posy [expr 1080 - $margin]
		}

		set minoffset [expr $outline + $shadow + 2]
		if {$leftfirst} {
			set posx1 [expr $posx+$depth1]
			set posx2 [expr $posx-$depth2]
		} else {
			set posx1 [expr $posx-$depth1]
			set posx2 [expr $posx+$depth2]
		}
		set bigmargin1 [expr abs( 1920 - ($posx1 * 2) )]
		set bigmargin2 [expr abs( 1920 - ($posx2 * 2) )]
		if {$posx1 < 960} {
			set lmargin1 $minoffset
			set rmargin1 [expr $bigmargin1 + $minoffset]
		} else {
			set lmargin1 [expr $bigmargin1 + $minoffset]
			set rmargin1 [expr $minoffset]
		}
		if {$posx2 < 960} {
			set lmargin2 $minoffset
			set rmargin2 [expr $bigmargin2 + $minoffset]
		} else {
			set lmargin2 [expr $bigmargin2 + $minoffset]
			set rmargin2 [expr $minoffset]
		}
# 		puts "\nPOSX : Guide: $posx; 3D: $posx1, $posx2"
# 		puts "LEFT : bigmargin: $bigmargin1; left, right margins: $lmargin1, $rmargin1"
# 		puts "RIGHT: bigmargin: $bigmargin2; left, right margins: $lmargin2, $rmargin2"

		if {$sbs} {
			if {$half} {
				set posx1 [expr $posx1 / 2]
				set posx2 [expr $posx2 / 2 + 960]
 				set hmargin 960

				set lmargin1 [expr $lmargin1 / 2]
				set rmargin1 [expr $rmargin1 / 2 + 960]
				set lmargin2 [expr ($lmargin2+1) / 2 + 960]
				set rmargin2 [expr ($rmargin2+1) / 2]

			} else {
				incr posx2 1920
				set hmargin 1920

				incr rmargin1 1920
				incr lmargin2 1920
			}
			set posy1 $posy
			set posy2 $posy
			set bmargin1 [expr 1080 - $posy]
			set bmargin2 [expr 1080 - $posy]
		} else {
			set hmargin 0

			if {$half} {
				set posy1 [expr $posy/2]
				set posy2 [expr $posy/2 + 540]
				set vmargin [expr (1080 - $posy) / 2]
				set bmargin1 [expr $vmargin + 540]
				set bmargin2 [expr $vmargin]
			} else {
				set posy1 $posy
				set posy2 [expr $posy + 1080]
				set vmargin [expr 1080 - $posy]
				set bmargin1 [expr $vmargin + 1080]
				set bmargin2 [expr $vmargin]
			}
		}
		if {$usepostags} {
			append out "Dialogue: 0,$inssatc,$outssatc,3D,,$minoffset,[expr $hmargin+$minoffset],$minoffset,,{\\pos($posx1,$posy1)}$subtext\n"
			append out "Dialogue: 0,$inssatc,$outssatc,3D,,[expr $hmargin+$minoffset],$minoffset,$minoffset,,{\\pos($posx2,$posy2)}$subtext\n"
		} else {
			append out "Dialogue: 0,$inssatc,$outssatc,3D,,$lmargin1,$rmargin1,$bmargin1,,$subtext\n"
			append out "Dialogue: 0,$inssatc,$outssatc,3D,,$lmargin2,$rmargin2,$bmargin2,,$subtext\n"
		}
		
		incr subnum1
	}

	#if {$::config(debug)} {puts $out}

	Pause
	return [list 0 $out]
}

proc GetDepths {subtitles in3dp {srtframerate 24.0/1.001} {searchalt3dp false}} {
	if {[catch {set fh [open $in3dp r]} err]} {
		ToLog $err 1
		return [list 1 $err\n]
	}
	fconfigure $fh -encoding binary -translation binary
	set plane [read $fh]
	close $fh
	if {[string range $plane 0 7] == "\x89\x4f\x46\x53\x0d\x0a\x1a\x0a"} {
		set plane [string range $plane 41 end]
	}
	set numframes [string length $plane]

	ToLog "Found the depth values of $numframes frames in the 3D-Plane." 0

	set otherplanes {}
	if {$searchalt3dp} {
		set ext [file extension $in3dp]
		set dir [file dirname $in3dp]
		if {$dir == ""} {set dir [pwd]}
		set otherplanefiles [lsort -dictionary [glob -nocomplain -directory $dir -tails -- *$ext]]
		set otherplanenames {}
		foreach planefile $otherplanefiles {
			if {[string tolower $planefile] == [string tolower [file tail $in3dp]]} continue
			set fh [open [file join [file dirname $in3dp] $planefile] r]
			if {$fh != ""} {
				fconfigure $fh -encoding binary -translation binary
				set p [read $fh]
				close $fh
				if {[string range $p 0 7] == "\x89\x4f\x46\x53\x0d\x0a\x1a\x0a"} {
					set p [string range $p 41 end]
				}
				lappend otherplanes $p
				lappend otherplanenames [file tail $planefile]
			}
		}
	}

	set depths {}
	set numsubs 0
	set numwarnings 0
	set mindepth 300
	set maxdepth -300
	set alldepths 0

	foreach subtitle $subtitles {
		incr numsubs
		set inframe  [SrtTc2frame [lindex $subtitle 0] $srtframerate]
		set outframe [SrtTc2frame [lindex $subtitle 1] $srtframerate]
		set subtitletext [lindex $subtitle 2]
		set lenframes [expr $outframe - $inframe]
		set margin [expr $outframe - $inframe / 6]
		if {$margin > $::config(marginFor3DSubs)} {set margin $::config(marginFor3DSubs)}
		binary scan [string range $plane [expr $inframe+$margin] [expr $outframe-$margin]] H* p
		set depth -300
		set n [string length $p]
		set cuts 0
		set warn 0
		set val [string range $p 0 1]
		for {set i 0} {$i < $n} {incr i 2} {
			set h [string range $p $i [expr $i+1]]
			if {$h != $val} {
				incr cuts
				set val $h
			}
			if {$h == "80"} {
				incr warn
			} else {
				set v [expr 0x$h&127]
				if {[expr (0x$h&128)/128]} {
					set v -$v
				}
				set v [expr $v * 2]
				if {$v>$depth} {
					set depth $v
				}
			}
		}
		if {$warn > 0} {
			ToLog "subtitle #$numsubs: Number of frames with undefined depth: $warn" 0
		}
		if {$depth == -300} {
			# Search for a valid depth within the other 3D-Plane files
			set takenfrom ""
			for {set i 0} {$i < [llength $otherplanes]} {incr i} {
				set otherplane [lindex $otherplanes $i]
				binary scan [string range $otherplane [expr $inframe+$margin] [expr $outframe-$margin]] H* p
				for {set j 0} {$j < $n} {incr j 2} {
					set h [string range $p $j [expr $j+1]]
					if {$h != "80"} {
						set v [expr 0x$h&127]
						if {[expr (0x$h&128)/128]} {
							set v -$v
						}
						set v [expr $v * 2]
						if {$v>$depth} {
							set depth $v
							set takenfrom [lindex $otherplanefiles $i]
						}
					}
				}
				if {$depth != -300} {
					ToLog "subtitle #$numsubs: Depth taken from \"$takenfrom\"." 0
					break
				}
			}
			if {$depth == -300} {
				ToLog "subtitle #$numsubs: WARNING: Undefined depth.  Assuming depth 0." 1
				set depth 0
			}
		} else {
			incr alldepths $depth
			if {$depth < $mindepth} {
				set mindepth $depth
			}
			if {$depth > $maxdepth} {
				set maxdepth $depth
			}
		}
		lappend depths $depth

# 		if {$::config(debug)} {
# 			puts -nonewline "subtitle #$numsubs: Depth=$depth, frames=$inframe -> $outframe, window=[expr $inframe+$margin] -> [expr $outframe-$margin], $cuts cuts,"
# 			if {$cuts > 0} {
# 				puts -nonewline " values=0x$p\""
# 			} else {
# 				puts -nonewline " values=[expr $n / 2] x 0x$val\""
# 			}
# 			puts "  $subtitletext"
# 		}
	}
	set avgdepth [expr round($alldepths.0 / $numsubs.0 * 100.0) / 100.0]
# 	set ::status "$numsubs subtitles, $numwarnings subtitles with undefined depth values, average depth: $avgdepth, minimum depth: $mindepth, maximum depth: $maxdepth"
	ToLog "Extracted the depth values of $numsubs subtitles."
	ToLog "Source 3D-plane:  \"[file tail $in3dp]\""
	ToLog "Min depth:  $mindepth"
	ToLog "Max depth:  $maxdepth"
	ToLog "Average depth:  $avgdepth"
	if {$numwarnings > 0} {
		ToLog "Number of warnings for undefined frame's depth:  $numwarnings" 1
	} else {
		ToLog "No warnings for undefined frame's depth.  :-)" 0
	}

	return [list 0 $depths]
}

proc GetPositions {subtitles guidefile {srtframerate 24.0/1.001} {xmlframerate 24.0} {margin 25}} {
	# TODO: margin hould be modifiable by user

	# subtitles data is a list the following values for each subtitle:
	# subnum intc outtc width height x y depth image.png (where depth may be empty)
	ToLog "Parsing XML file..." 0
	set r [GetSubtitleDataFromXML $guidefile]
	set rc     [lindex $r 0]
	set guides [lindex $r 1]
	if {$rc != 0} {
		set ::status $guides
		ToLog $guides 1
		bell
		return
	}
	set numguides [llength $guides]
	if {$numguides == 0} {
		ToLog "\"[file tail $guidefile]\" is not a XML subtitle file or it contains no subtitles!" 1
		bell
		return ""
	}

	set numfullscreen 0
	foreach guide $guides {
		foreach {gnum gintc gouttc gwidth gheight gx gy gdepth gimg} $guide {}
		if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
			incr numfullscreen
		}
	}
	if {$numfullscreen == $numguides} {
		ToLog "\"[file tail $guidefile]\" contains only full-screen subtitles.  Sorry." 1
		bell
		return ""
	} elseif {$numfullscreen > 0} {
		ToLog "WARNING: \"[file tail $guidefile]\" contains $numfullscreen full-screen subtitles." 1
		ToLog "A full-screen guides cannot be used to determine the right position of the subtitle." 1
	}

	set guideidx 0
	set subnum 0
	set numperfect  0
	set numgood     0
	set numpartial  0
	set numnotfound 0
	set outputpos {}
	set numfullscreen 0
	foreach sub $subtitles {
		foreach {intc outtc subtitletext} $sub {}
		incr subnum
		set found false
		for {set curmargin -1} {$curmargin <= $margin} {incr curmargin [expr $margin+1]} {
			set inframe  [expr [SrtTc2frame $intc  $srtframerate] - $curmargin]
			set outframe [expr [SrtTc2frame $outtc $srtframerate] + $curmargin]
			if {$inframe > $outframe} {
				set inframe [expr $outframe + (($inframe-$outframe)/2) - 3]
				set outframe [expr $inframe +3]
			}
			for {set ii $guideidx} {$ii < $numguides} {incr ii} {
				foreach {dummy gintc gouttc gwidth gheight gx gy dummy dummy} [lindex $guides $ii] {}
				set gin  [SrtTc2frame $gintc  $xmlframerate]
				set gout [SrtTc2frame $gouttc $xmlframerate]
				if {$inframe >= $gin && $outframe <= $gout} {
					set guideidx $ii
					if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
						incr numfullscreen
						lappend outputpos [list -1 -1 -1 -1]
						ToLog "subtitle #$subnum: WARNING: Can't get the subtitle position from a full-screen subtitle in guide!" 1
					} else {
						incr numperfect
						lappend outputpos [list $gwidth $gheight $gx $gy]
					}
					set found true
					break
				} elseif {$inframe <= $gin && $outframe >= $gout} {
					set guideidx $ii
					if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
						incr numfullscreen
						lappend outputpos [list -1 -1 -1 -1]
						ToLog "subtitle #$subnum: WARNING: Can't get the subtitle position from a full-screen subtitle in guide!" 1
					} else {
						incr numgood
						lappend outputpos [list $gwidth $gheight $gx $gy]
					}
					set found true
					break
				} elseif {$inframe >= $gin && $inframe < $gout && $outframe >= $gout} {
					set duration1 [expr $gout - $inframe]
					if {[expr $ii+1] < $numguides} {
						foreach {dummy gintc2 gouttc2 gwidth2 gheight2 gx2 gy2 dummy dummy} [lindex $guides [expr $ii+1]] {}
						set gin2  [SrtTc2frame $gintc2  $xmlframerate]
						set gout2 [SrtTc2frame $gouttc2 $xmlframerate]
						if {$gout2 < $outframe} {
							set end $gout2
						} else {
							set end $outframe
						}
						set duration2 [expr $end - $gin2]
					} else {
						set duration2 0
					}
					set guideidx $ii
					if {$duration2 > $duration1} {
						if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
							incr numfullscreen
							lappend outputpos [list -1 -1 -1 -1]
							ToLog "subtitle #$subnum: WARNING: Can't get the subtitle position from a full-screen subtitle in guide!" 1
						} else {
							incr numpartial
							lappend outputpos [list $gwidth2 $gheight2 $gx2 $gy2]
						}
					} else {
						if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
							incr numfullscreen
							lappend outputpos [list -1 -1 -1 -1]
							ToLog "subtitle #$subnum: WARNING: Can't get the subtitle position from a full-screen subtitle in guide!" 1
						} else {
							incr numpartial
							lappend outputpos [list $gwidth $gheight $gx $gy]
						}
					}
					set found true
					break
				} elseif {$inframe <= $gin && $outframe >= $gin && $outframe <= $gout} {
					set guideidx $ii
					if {$gwidth == 1920 || $gheight == 1080 || $gx == 0 || $gy == 0} {
						incr numfullscreen
						lappend outputpos [list -1 -1 -1 -1]
						ToLog "subtitle #$subnum: WARNING: Can't get the subtitle position from a full-screen subtitle in guide!" 1
					} else {
						incr numpartial
						lappend outputpos [list $gwidth $gheight $gx $gy]
					}
					set found true
					break
				} elseif {$gin > $outframe} {
					break
				}
			}
			if {$found} break
		}
		if { ! $found} {
			lappend outputpos [list -1 -1 -1 -1]
			ToLog "subtitle #$subnum: WARNING: Can't find a subtitle at similar timings ($intc -> $outtc) in guide file!" 1
			Pause
			incr numnotfound
		}
	}

	ToLog "Searched the positions of $subnum subtitles." 0
	ToLog "There are $numguides subtitles in the guide file \"[file tail $guidefile]\"." 0
	ToLog "Details: $numperfect perfect matches, $numgood good matches, $numpartial partial matches." 0
	if {$numnotfound > 0} {
		ToLog "WARNING: Cannot determine the position of $numnotfound subtitles because there is no subtitle at similar timings in the guide file." 1
	}
	if {$numfullscreen > 0} {
		ToLog "WARNING: Cannot determine the position of $numnotfound subtitles because the subtitles at similar timings in the guide file is full-screen." 1
	}
	return $outputpos
}

proc SrtTc2frame {timecode {framerate 24/1.001}} {
	set tc [string range $timecode 0 7]
	set dc 0.[string range $timecode 9 end]
	set secs [expr [clock scan $tc] - [clock scan 00:00:00] + $dc]
	return [expr round($secs * ($framerate))]
}

proc SrtTcToAssTc {srttc} {
	set ssatc $srttc
	if {[string range $ssatc 0 0] == "0" && [string range $ssatc 2 2] == ":"} {
		set ssatc [string range $ssatc 1 end]
	}
	set idx [string first "," $ssatc]
	if {$idx < 0} {
		set idx [string first "." $ssatc]
	}
	if {$idx > 0} {
		set tc [string range $ssatc 0 [expr $idx-1]]
		set frac [string map {, .} [string range $ssatc $idx end]]
		if {[string length $frac] > 3} {
			set frac [string range $frac 0 2]
		}
		set ssatc $tc$frac
	}
	return $ssatc
}

set colornames [list \
	AliceBlue #F0F8FF \
	AntiqueWhite #FAEBD7 \
	Aqua #00FFFF \
	Aquamarine #7FFFD4 \
	Azure #F0FFFF \
	Beige #F5F5DC \
	Bisque #FFE4C4 \
	Black #000000 \
	BlanchedAlmond #FFEBCD \
	Blue #0000FF \
	BlueViolet #8A2BE2 \
	Brown #A52A2A \
	BurlyWood #DEB887 \
	CadetBlue #5F9EA0 \
	Chartreuse #7FFF00 \
	Chocolate #D2691E \
	Coral #FF7F50 \
	CornflowerBlue #6495ED \
	Cornsilk #FFF8DC \
	Crimson #DC143C \
	Cyan #00FFFF \
	DarkBlue #00008B \
	DarkCyan #008B8B \
	DarkGoldenRod #B8860B \
	DarkGray #A9A9A9 \
	DarkGrey #A9A9A9 \
	DarkGreen #006400 \
	DarkKhaki #BDB76B \
	DarkMagenta #8B008B \
	DarkOliveGreen #556B2F \
	DarkOrange #FF8C00 \
	DarkOrchid #9932CC \
	DarkRed #8B0000 \
	DarkSalmon #E9967A \
	DarkSeaGreen #8FBC8F \
	DarkSlateBlue #483D8B \
	DarkSlateGray #2F4F4F \
	DarkSlateGrey #2F4F4F \
	DarkTurquoise #00CED1 \
	DarkViolet #9400D3 \
	DeepPink #FF1493 \
	DeepSkyBlue #00BFFF \
	DimGray #696969 \
	DimGrey #696969 \
	DodgerBlue #1E90FF \
	FireBrick #B22222 \
	FloralWhite #FFFAF0 \
	ForestGreen #228B22 \
	Fuchsia #FF00FF \
	Gainsboro #DCDCDC \
	GhostWhite #F8F8FF \
	Gold #FFD700 \
	GoldenRod #DAA520 \
	Gray #808080 \
	Grey #808080 \
	Green #008000 \
	GreenYellow #ADFF2F \
	HoneyDew #F0FFF0 \
	HotPink #FF69B4 \
	IndianRed  #CD5C5C \
	Indigo  #4B0082 \
	Ivory #FFFFF0 \
	Khaki #F0E68C \
	Lavender #E6E6FA \
	LavenderBlush #FFF0F5 \
	LawnGreen #7CFC00 \
	LemonChiffon #FFFACD \
	LightBlue #ADD8E6 \
	LightCoral #F08080 \
	LightCyan #E0FFFF \
	LightGoldenRodYellow #FAFAD2 \
	LightGray #D3D3D3 \
	LightGrey #D3D3D3 \
	LightGreen #90EE90 \
	LightPink #FFB6C1 \
	LightSalmon #FFA07A \
	LightSeaGreen #20B2AA \
	LightSkyBlue #87CEFA \
	LightSlateGray #778899 \
	LightSlateGrey #778899 \
	LightSteelBlue #B0C4DE \
	LightYellow #FFFFE0 \
	Lime #00FF00 \
	LimeGreen #32CD32 \
	Linen #FAF0E6 \
	Magenta #FF00FF \
	Maroon #800000 \
	MediumAquaMarine #66CDAA \
	MediumBlue #0000CD \
	MediumOrchid #BA55D3 \
	MediumPurple #9370DB \
	MediumSeaGreen #3CB371 \
	MediumSlateBlue #7B68EE \
	MediumSpringGreen #00FA9A \
	MediumTurquoise #48D1CC \
	MediumVioletRed #C71585 \
	MidnightBlue #191970 \
	MintCream #F5FFFA \
	MistyRose #FFE4E1 \
	Moccasin #FFE4B5 \
	NavajoWhite #FFDEAD \
	Navy #000080 \
	OldLace #FDF5E6 \
	Olive #808000 \
	OliveDrab #6B8E23 \
	Orange #FFA500 \
	OrangeRed #FF4500 \
	Orchid #DA70D6 \
	PaleGoldenRod #EEE8AA \
	PaleGreen #98FB98 \
	PaleTurquoise #AFEEEE \
	PaleVioletRed #DB7093 \
	PapayaWhip #FFEFD5 \
	PeachPuff #FFDAB9 \
	Peru #CD853F \
	Pink #FFC0CB \
	Plum #DDA0DD \
	PowderBlue #B0E0E6 \
	Purple #800080 \
	RebeccaPurple #663399 \
	Red #FF0000 \
	RosyBrown #BC8F8F \
	RoyalBlue #4169E1 \
	SaddleBrown #8B4513 \
	Salmon #FA8072 \
	SandyBrown #F4A460 \
	SeaGreen #2E8B57 \
	SeaShell #FFF5EE \
	Sienna #A0522D \
	Silver #C0C0C0 \
	SkyBlue #87CEEB \
	SlateBlue #6A5ACD \
	SlateGray #708090 \
	SlateGrey #708090 \
	Snow #FFFAFA \
	SpringGreen #00FF7F \
	SteelBlue #4682B4 \
	Tan #D2B48C \
	Teal #008080 \
	Thistle #D8BFD8 \
	Tomato #FF6347 \
	Turquoise #40E0D0 \
	Violet #EE82EE \
	Wheat #F5DEB3 \
	White #FFFFFF \
	WhiteSmoke #F5F5F5 \
	Yellow #FFFF00 \
	YellowGreen #9ACD32 \
]
proc SrtColorToAssCode {srtcolor} {
	if {[string range $srtcolor 0 0] != "#"} {
		set idx [lsearch $::s2a::colornames $srtcolor]
		if {$idx >= 0} {
			incr idx
			set srtcolor [lindex $::s2a::colornames $idx]
		} else {
			return ""
		}
	}
	if {[string length $srtcolor] != 7} {
		return ""
	}
	return "[string range $srtcolor 5 6][string range $srtcolor 3 4][string range $srtcolor 1 2]"
}

proc SaveS2ASettings {{filename ""}} {
	set ::status ""
	set txt "# Config file for BD3D2MK3D's tool Convert SRT to ASS 3D\n"
	append txt "# DO NOT EDIT MANUALLY!\n\n"
	append txt "set ::s2a::inencoding     [list $::s2a::inencoding]\n"
	append txt "set ::s2a::keepformatting $::s2a::keepformatting\n"
	append txt "set ::s2a::half           $::s2a::half\n"
	append txt "set ::s2a::sbs            $::s2a::sbs\n"
	append txt "set ::s2a::leftfirst      $::s2a::leftfirst\n"
	append txt "set ::s2a::searchalt3dp   $::s2a::searchalt3dp\n"
	append txt "set ::s2a::adddepth       $::s2a::adddepth\n"
	append txt "set ::s2a::fontname       [list $::s2a::fontname]\n"
	append txt "set ::s2a::fontsize       $::s2a::fontsize\n"
	append txt "set ::s2a::color          [list $::s2a::color]\n"
	append txt "set ::s2a::outline        $::s2a::outline\n"
	append txt "set ::s2a::shadow         $::s2a::shadow\n"
	append txt "set ::s2a::shadowtr       $::s2a::shadowtr\n"
	append txt "set ::s2a::margin         $::s2a::margin\n"
	append txt "set ::s2a::topaligned     $::s2a::topaligned\n"
	append txt "set ::s2a::usepostags     $::s2a::usepostags\n"
# 	append txt "set ::s2a::saveutf8       $::s2a::saveutf8\n"
	if {$filename == ""} {
		set filename [tk_getSaveFile -initialdir [file dirname $::TOOLSETPATH] \
				-filetypes {{{SRT to ASS 3D settings files} {.srt2ass.cfg}}} -parent .srt2ass3d \
				-title "Save the SRT to ASS 3D settings as..." -defaultextension ".srt2ass.cfg"]
		if {$filename == ""} {
			return 1
		}
	} elseif {[file dirname $filename] == "."} {
		set filename [file join [file dirname $::TOOLSETPATH] $filename]
		if {[file exists $filename]} {
			if {[tk_messageBox -message "Overwrite default settings ?" \
					-parent .srt2ass3d -type yesno -icon question \
					-title "Convert SRT to ASS 3D"] == "no"} {
				return 1
			}
		}
	}
	if {[catch {set fh [open $filename w]} err]} {
		set ::status $err
		bell
		return 1
	}
	puts -nonewline $fh $txt
	if {[catch {close $fh} err]} {
		set ::status $err
		bell
		return 1
	}
	set ::status "SRT to ASS 3D Settings saved."
	return 0
}
proc LoadS2ASettings {{filename ""}} {
	set ::status ""
	set interactive 0
	if {$filename == ""} {
		set interactive 1
		set filename [tk_getOpenFile -initialdir [file dirname $::TOOLSETPATH] \
				-filetypes {{{SRT to ASS 3D settings files} {.srt2ass.cfg}}} -parent .srt2ass3d \
				-title "Load SRT to ASS 3D settings..."]
		if {$filename == ""} {
			return 1
		}
	} elseif {[file dirname $filename] == "."} {
		set filename [file join [file dirname $::TOOLSETPATH] $filename]
	}
	if {[catch {source $filename} err]} {
		set ::status $err
		bell
		return 1
	}

	.srt2ass3d.f3.f1.b1 configure -text $::s2a::fontname
	.srt2ass3d.f3.f1.b2 configure -text [RGB2Txt $::s2a::color] \
			-bg $::s2a::color -activebackground $::s2a::color
	SetShadowTransparency

	if {$interactive} {
		set ::status "SRT to ASS 3D Settings loaded."
	}
	return 0
}

} ;# end of namespace eval ::s2a



namespace eval ::fontreq {
namespace export FontReq

proc FontReq {current_font {parent ""}} {
	set ::fontreq::family $current_font
	set w .fontreq

	if {! [info exists ::fontreq::fontlist]} {
		set fontlist {}
		foreach f [font families] {
			if { ! [font metrics \"$f\" -fixed]} {
				lappend fontlist $f
			}
		}
		set ::fontreq::fontlist [lsort -dictionary $fontlist]
	
		toplevel $w ;#-class Dialog
		wm withdraw $w
		wm protocol $w WM_DELETE_WINDOW {set ::fontreq::done 0}
		bind $w <Escape> "set ::fontreq::done 0"
		bind $w <Return> "set ::fontreq::done 1"
		if {$parent != ""} {
			wm transient $w $parent
		}
		#if {$::tcl_platform(platform) == "windows"} {catch {wm attributes $w -toolwindow 1}}
		wm title $w "Select font"
		set txt "WARNING !\nIt is highly recommended to use only one of the 3 \"universal\" fonts (Arial,\n"
		append txt "Verdana or Times New Roman) because they exist on (almost) all platforms.\n"
		append txt "Furthermore, with that fonts, BD3D2MK3D can help you find the best font\n"
		append txt "size to clone as close as possible the subtitles of the Guide file.  It's not\n"
		append txt "possible with the other fonts.\n"
		append txt "If you select another font, do it at your own risk !"
		
		pack [label $w.warn -text $txt -justify left -bd 2 -relief groove -background Pink -padx 4 -pady 2] -side top -fill x -padx 2 -pady 2

		pack [frame $w.fpicker] -fill both -expand 1 -padx 2 -pady 2
		pack [listbox $w.fpicker.lb -listvariable ::fontreq::fontlist \
				-height 12 -width 30 -yscrollcommand "$w.fpicker.yscr set" \
				-selectmode single] -side left -fill y
		pack [scrollbar $w.fpicker.yscr -command "$w.fpicker.lb yview"] -side left -fill y
		bind  $w.fpicker.lb <ButtonRelease-1> ::fontreq::SetFontFamily
		pack [frame $w.fpicker.f] -padx 4 -side left -fill both -expand 1
		pack [frame $w.fpicker.f.fr] -fill y -expand 1
		pack [::ttk::labelframe $w.fpicker.f.fr.lf -text "Recommended fonts:"] -side left -padx 4 -pady 4
		pack [::ttk::button $w.fpicker.f.fr.lf.b1 -width 16 -text "Arial" -command {::fontreq::UpdateFontFamily "Arial"}] -fill x -padx 4 -pady 2
		pack [::ttk::button $w.fpicker.f.fr.lf.b2 -width 16 -text "Verdana" -command {::fontreq::UpdateFontFamily "Verdana"}] -fill x -padx 4 -pady 2
		pack [::ttk::button $w.fpicker.f.fr.lf.b3 -width 16 -text "Times New Roman" -command {::fontreq::UpdateFontFamily "Times New Roman"}] -fill x -padx 4 -pady 2

		pack [frame $w.fpicker.f.fa] -side bottom -fill x -pady 2 -padx 4
		pack [::ttk::button $w.fpicker.f.fa.ok -text "OK"     -width 8 -command {set ::fontreq::done 1}] -side left -padx 2 -fill x -expand 1
		pack [::ttk::button $w.fpicker.f.fa.ca -text "Cancel" -width 8 -command {set ::fontreq::done 0}] -side left -padx 2 -fill x -expand 1

		pack [label $w.fexample -borderwidth 2 \
				-relief groove -height 4 -text [join [list \
			"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
			"abcdefghijklmnopqrstuvwxyz" \
			"0123456789~`!@#$%^&*()_-+=" \
			"{}[]:;\"'<>,.?/"] "\n"]] -fill x -padx 2 -pady 2

		update
		if {$parent != ""} {
			set wx [expr [winfo rootx $parent]+10]
			set wy [expr [winfo rooty $parent]+10]
			wm geometry $w +$wx+$wy
		}
		#wm resizable $w 1 1
	}

	wm title $w "Current font: \"[lindex $current_font 0]\" [lindex $current_font 1].  Select subtitle font..."
	UpdateFontFamily $current_font

	wm deiconify $w
	grab set $w
	update
	wm minsize $w [winfo reqwidth $w] [winfo reqheight $w]

	set ::fontreq::done -1
	tkwait variable ::fontreq::done
	grab release $w
	wm withdraw $w
	if {$::fontreq::done} {
		return $::fontreq::family
	} else {
		return ""
	}
}
proc SetFontFamily {} {
	set idx [lindex [.fontreq.fpicker.lb curselection] 0]
	set ::fontreq::family [lindex $::fontreq::fontlist $idx]
	ConfigureFontExample
	return $::fontreq::family
}
proc UpdateFontFamily {font} {
	set fontindex [lsearch $::fontreq::fontlist $font]
	if {$fontindex >= 0} {
		.fontreq.fpicker.lb activate $fontindex
		.fontreq.fpicker.lb selection clear 0 end
		.fontreq.fpicker.lb selection set $fontindex
		.fontreq.fpicker.lb see $fontindex
	}
	set ::fontreq::family $font
	ConfigureFontExample
	return $fontindex
}
proc ConfigureFontExample {} {
	catch {.fontreq.fexample configure -font [list $::fontreq::family 16]}
}


}	;# End fo namespace eval ::fontreq




# Add menu item
if {[catch {.mainmenu.subs index "Convert SRT to ASS 3D (with 3D-Plane/OFS)"}]} {
	.mainmenu.subs add separator
	.mainmenu.subs add command -label "Convert SRT to ASS 3D (with 3D-Plane/OFS)" -command ::s2a::Srt2Ass3D_GUI

	# Debug helper
	if {$::config(debug) && [winfo exists .mainmenu.debug]} {
		.mainmenu.debug add separator
		.mainmenu.debug add command -label "Reload SRTtoASS3D.tcl" -command {
			destroy .srt2ass3d .srt2ass3d_menu .srt2ass3d.f3.f1.b2.menu .fontreq
			catch {namespace delete ::s2a}
			catch {namespace delete ::fontreq}
			after 10 {
				source [file join $::TOOLSETPATH SRTtoASS3D.tcl]
				if {[info proc ::s2a::Srt2Ass3D_GUI] != ""} {::s2a::Srt2Ass3D_GUI}
			}
		}
	}
}
