#!/usr/local/bin/wish8.2
#############################################################################
# Visual Tcl v1.07 Project
#

#################################
# GLOBAL VARIABLES
#
global Cover; set Cover {0}
global Frame; set Frame {}
global HTML_Synchro; set HTML_Synchro {0}
global RANDOM_MAX; set RANDOM_MAX {0x7FFFFFFF}
global Recursif_intelligent; set Recursif_intelligent {0}
global artiste; set artiste {}
global player_mode; set player_mode {disc}
global random.a1; set random.a1 { 1941 1860 1812 1776 1492 1215 1066 12013 }
global random.a2; set random.a2 { 1111 2222 3333 4444 5555 6666 7777   827 }
global random.a3; set random.a3 { 1111 2222 3333 4444 5555 6666 7777   251 }
global random.m1; set random.m1 {8729 43215 8810 53075 59930 23253 16377 62489 11794}
global random.m2; set random.m2 {18086 23696 42786 37815 59442 39280 18624 35510 38884}
global termine; set termine {2}
global xmpeg3_version; set xmpeg3_version {1.0}
global widget; 
#################################
# USER DEFINED PROCEDURES
#
proc init {argc argv} {

}

init $argc $argv


proc browse {file} {
global TAT index_exists termine player_mode
#puts $file

set realname ""

if { $player_mode == "directory" } {
#    On fait un catch, car il peut d'agir d'une liste de fichiers...
    catch { set realname [.top17.cpd37.01 get $file] }
}

#puts $realname

if { $player_mode == "disc" } {
# C'est une piste d'un disque, on la joue...
            playfile $file
} else {

# On est en mode "fichier"
    if [file isdirectory $realname] {
	.top17.cpd37.01 delete 0 end
	.top17.cpd37.01 insert end ".."
        set index_exists 0
        cd $realname
	foreach i [exec ls ] {
            if {[file isdir $i] || [expr [string first ".mp3" $i ] != -1] } {
	        .top17.cpd37.01 insert end $i
            }
            if {[string compare $i "tracks.idx"] == 0} {
                 set index_exists 1
            }
	}    
        .top17.fra45.cpd46.02 delete 0 end
        .top17.fra45.cpd47.02 delete 0 end

        if {$index_exists == 1} {
#              .top17.cpd37.01 insert 0 "tracks.idx"
#                puts "parsing tracks.idx"
                .top17.cpd37.01 delete 0 end
                parse "tracks.idx"
                set player_mode "disc"
         }
    } else {
# On joue une liste de fichiers
        playfile $file
    }
}
}

proc parse {file} {
global TAT Cover HTML_Synchro

# On efface entierement le hash-table...
foreach i  [array names TAT] {
array set TAT [list $i ""]
}


# On parse tous les champs, sans distinction...
set index [open $file]
       while {[eof $index] ==0} {
#         .top17.cpd37.01 insert end [gets $index]
        set arg [gets $index]
        array set TAT [split $arg :]

        }
#parray TAT
close $index

# On absolutise les champs "File", comme ca on peut
# fusionner des playlists sans difficulte...
#puts $TAT(Tracks)

for {set i 1} {$i < [string trim $TAT(Tracks) " "]} {incr i} {
    set dummy "Track_"
    append dummy $i
    append dummy "_File"
    set dummy2 [pwd]
    append dummy2 "/"
    append dummy2 [string trimleft $TAT($dummy) " "]   
#    puts $dummy2
    set TAT($dummy) $dummy2 
}

#parray TAT

#Remplissage des champs:
.top17.fra45.cpd46.02 delete 0 end
.top17.fra45.cpd46.02 insert 0 [lindex [array get TAT Artiste] 1]
.top17.fra45.cpd47.02 delete 0 end
.top17.fra45.cpd47.02 insert 0 [lindex [array get TAT Album] 1]


# Liste des titres:

for {set i 1} {$i <= [string trim [lindex [array get TAT Tracks] 1] " "]} {incr i} {
        set dummy "Track_"
        append dummy $i
        append dummy "_Title"
        set tname [lindex [array get TAT $dummy] 1]
        if {$i < 10} { set dummy " $i: $tname" } else {
            set dummy "$i: $tname" }
        .top17.cpd37.01 insert end $dummy
}

# Affichage de l'image s'il y en a une:
if { $Cover == 1 } {
set dummy [string trim [lindex [array get TAT "Cover"] 1] " "]
if {[string length $dummy] != 0} {
 exec xv $dummy &
}
}

# Attention, on fait du... multimedia synchronise !
# i.e. on lance l'ouverture d'un URL par Net$cape
# avant de jouer la piste...
    if { $HTML_Synchro == 1 } {
        set dummy [string trim [lindex [array get TAT URL] 1] " "]
        if {[string length $dummy] != 0} {
            set dummy2 "file:[pwd]/$dummy"
#            puts "URL found; $dummy2"
            exec netscape -remote openURL($dummy2)
        }
    }
}

proc playfile {file2} {
global TAT outval termine pipe index_exists termine HTML_Synchro player_mode

# Notes:
# En mode "disc" -> l'argument $file2 est une liste de chiffres
# En mode "directory" -> egalement !!!


# Joue les pistes...
if {[string length $file2] != 0} {

foreach file $file2 {

        .top17.fra49.currplaying delete 0 end
        if {$player_mode == "disc"} {
            .top17.fra49.currplaying insert 0 "Track [expr $file+1]"
        } else {
            .top17.fra49.currplaying insert 0 "Playing"
        }
        # Puis on selectionne la piste en cours:
        .top17.cpd37.01 selection clear 0 end
        .top17.cpd37.01 see $file
        .top17.cpd37.01 selection set $file


# Attention, on fait du... multimedia synchronise !
# i.e. on lance l'ouverture d'un URL par Net$cape
# avant de jouer la piste...
    if { $HTML_Synchro == 1 && $player_mode == "disc" } {
        set dummy2 "Track_"
        append dummy2 [expr $file+1]
        append dummy2 "_URL"
        set dummy [string trim [lindex [array get TAT $dummy2] 1] " "]
        if {[string length $dummy] != 0} {
            set dummy2 "file:[pwd]/$dummy"
#            puts "URL found; $dummy2"
            exec netscape -remote openURL($dummy2)
        }
    }
# On lance la lecture de la piste
if {$player_mode == "disc"} {
        set dummy "Track_"
        append dummy [expr $file+1]
        append dummy "_File"
        set ff2 [string trim [lindex [array get TAT $dummy] 1] " "]
        append ff2 " "
#puts $ff2
        set playcommand  "amp -p $ff2"
        } else {
        set dummy  [.top17.cpd37.01 get $file ]
        set playcommand "amp -p $dummy"
        }

set termine 0
set outval "The Five percent nation"
set pipe [open "|$playcommand" r+]
fileevent $pipe readable {
           global pipe termine outval
#           puts "."
           set outval [gets $pipe]
           if { $outval == "Audio streamer closing"} {
               puts "Audio streamer closing"
               set termine 1
               catch {close $pipe}
           }
           if { $termine != 0} {
#                puts "stopping"
               catch {close $pipe}
#               puts "Pipe closed"
           }
           .top17.fra49.txt delete 0 end
           .top17.fra49.txt insert 0 $outval
#            puts "."
           update
       }
       tkwait variable termine
#       puts "Termine"
       catch {close $pipe}
        after 800
       .top17.fra49.txt delete 0 end
       .top17.fra49.txt insert 0 "Stopped"
       # Si on appuie sur "Stop":
       if {$termine == 2} { break }
       }
}
}

proc random {} {
global random.m1 random.m2 random.a1 random.a2;
    set random.m1 [random.rand16 [set random.a1] [set random.m1]];
    set random.m2 [random.rand16 [set random.a2] [set random.m2]];
    return [expr (([lindex [set random.m1] 1] << 16) + [lindex [set random.m2] 1]) & 0x7FFFFFFF];
}

proc random.rand16 {a m} {
set n [expr  [lindex $m 0] +  [lindex $a 0] * [lindex $m 1] +  [lindex $a 1] * [lindex $m 2] +  [lindex $a 2] * [lindex $m 3] +  [lindex $a 3] * [lindex $m 4] +  [lindex $a 4] * [lindex $m 5] +  [lindex $a 5] * [lindex $m 6] +  [lindex $a 6] * [lindex $m 7] +  [lindex $a 7] * [lindex $m 8]];

    return [concat [expr $n >> 16] [expr $n & 0xFFFF] [lrange $m 1 7]];
}

proc random.srand16 {seed} {
set n1 [expr $seed & 0xFFFF];
    set n2 [expr $seed & 0x7FFFFFFF];
    set n2 [expr 30903 * $n1 + ($n2 >> 16)];
    set n1 [expr $n2 & 0xFFFF];
    set m  [expr $n1 & 0x7FFF];
    foreach i {1 2 3 4 5 6 7 8} {
	set n2 [expr 30903 * $n1 + ($n2 >> 16)];
	set n1 [expr $n2 & 0xFFFF];
	lappend m $n1;
    }
    return $m;
}

proc show_infos {iii} {
global TAT

    if [winfo exists $iii] {wm deiconify $iii; return}
    toplevel $iii
    wm geometry $iii 350x150
    wm resizable $iii 1 1
    wm title $iii "Infos"
    frame $iii.f  -borderwidth 2 -height 30 -relief groove -width 30 
    pack $iii.f  -in $iii -anchor center -expand 1 -fill both -ipadx 0 -ipady 0  -padx 3 -pady 3 -side top 
    text $iii.f.text  -height 2 -width 2 -wrap none  -yscrollcommand {$iii.f.scrollbar16 set} 
    pack $iii.f.text  -in $iii.f -anchor center -expand 1 -fill both -ipadx 0  -ipady 0 -padx 0 -pady 0 -side left 
    scrollbar $iii.f.scrollbar16  -borderwidth 1 -command "$iii.f.text yview" -width 10 
    pack $iii.f.scrollbar16  -in $iii.f -anchor center -expand 0 -fill y -ipadx 0 -ipady 0  -padx 0 -pady 0 -side left 
    frame $iii.f21  -borderwidth 1 -height 30 -relief sunken -width 30 
    pack $iii.f21  -in $iii -anchor center -expand 0 -fill x -ipadx 0 -ipady 0  -padx 3 -pady 3 -side top 
    button $iii.f21.button22  -command "destroy $iii" -padx 9  -pady 3 -text OK -width 5 
    pack $iii.f21.button22  -in $iii.f21 -anchor center -expand 1 -fill x -ipadx 0 -ipady 0  -padx 0 -pady 0 -side left 
    button $iii.f21.button23  -command "
            destroy $iii
        "  -padx 9  -pady 3 -text Cancel -width 5 
    pack $iii.f21.button23  -in $iii.f21 -anchor center -expand 1 -fill x -ipadx 0 -ipady 0  -padx 0 -pady 0 -side left 
    update idletasks
    bind $iii <Key-Escape> "
        destroy $iii
        break
    "
    $iii.f.text delete 0.0 end
    $iii.f.text insert end "Lyrics"
    focus $iii.f.text
    tkwait window $iii
    update idletasks
}

proc srandom {seed} {
global random.m1 random.m2;
    set random.m1 [random.srand16 $seed];
    set random.m2 [random.srand16 [expr 4321+$seed]];
    return {};
}

proc main {argc argv} {

}

proc Window {args} {
global vTcl
    set cmd [lindex $args 0]
    set name [lindex $args 1]
    set rest [lrange $args 2 end]
    if {$name == "" || $cmd == ""} {return}
    set exists [winfo exists $name]
    switch $cmd {
        show {
            if {[info procs vTclWindow(pre)$name] != ""} {
                vTclWindow(pre)$name $rest
            }
            if {[info procs vTclWindow$name] != ""} {
                vTclWindow$name
            }
            if {[info procs vTclWindow(post)$name] != ""} {
                vTclWindow(post)$name $rest
            }
        }
        hide    { if $exists {wm withdraw $name; return} }
        iconify { if $exists {wm iconify $name; return} }
        destroy { if $exists {destroy $name; return} }
    }
}

#################################
# VTCL GENERATED GUI PROCEDURES
#

proc vTclWindow. {args} {
    set base .
    ###################
    # CREATING WIDGETS
    ###################
    wm focusmodel . passive
    wm geometry . 1x1+0+0
    wm maxsize . 1137 834
    wm minsize . 1 1
    wm overrideredirect . 0
    wm resizable . 1 1
    wm withdraw .
    wm title . "vt.tcl"
    ###################
    # SETTING GEOMETRY
    ###################
}

proc vTclWindow.top17 {args} {
    set base .top17
    if {[winfo exists .top17]} {
        wm deiconify .top17; return
    }
    ###################
    # CREATING WIDGETS
    ###################
    toplevel .top17 -class Toplevel
    wm focusmodel .top17 passive
    wm geometry .top17 319x300+164+277
    wm maxsize .top17 1137 834
    wm minsize .top17 1 1
    wm overrideredirect .top17 0
    wm resizable .top17 1 1
    wm deiconify .top17
    wm title .top17 "Mpeg Layer3 Player"
    frame .top17.cpd37 \
        -borderwidth 1 -height 30 -relief raised \
         -width 30 
    listbox .top17.cpd37.01 \
        -selectmode multiple -xscrollcommand {.top17.cpd37.02 set} \
        -yscrollcommand {.top17.cpd37.03 set} 
    bind .top17.cpd37.01 <Double-Button-1> {
        browse [.top17.cpd37.01 curselection]
    }
    scrollbar .top17.cpd37.02 \
        -command {.top17.cpd37.01 xview} -orient horiz 
    scrollbar .top17.cpd37.03 \
        -command {.top17.cpd37.01 yview} -orient vert 
    frame .top17.fra45 \
        -borderwidth 1 -height 30 -relief sunken \
         -width 30 
    frame .top17.fra45.cpd46 \
        -borderwidth 1 -height 30 -relief raised \
         -width 30 
    label .top17.fra45.cpd46.01 \
        -anchor w -background gray \
        -relief groove -text Artist 
    entry .top17.fra45.cpd46.02 \
        -cursor {}  
    frame .top17.fra45.cpd47 \
        -borderwidth 1 -height 30 -relief raised \
         -width 30 
    label .top17.fra45.cpd47.01 \
        -anchor w -background gray \
        -relief groove -text Album 
    entry .top17.fra45.cpd47.02 \
        -cursor {}  
    button .top17.fra45.but48 \
        -command {show_infos .infos} \
         -padx 9 \
        -pady 3 -text Infos 
    button .top17.fra45.cover \
        -command {global TAT

# Affichage de l'image s'il y en a une:
set dummy [string trim [lindex [array get TAT "Cover"] 1] " "]
if {[string length $dummy] != 0} {
 exec xv $dummy &
}} \
         -padx 9 \
        -pady 3 -text Cover 
    frame .top17.fra49 \
        -borderwidth 1 -height 30 -relief sunken \
         -width 30 
    button .top17.fra49.but51 \
        -command {global termine pipe

set termine 2
catch {close $pipe}
#catch {exec fuser -k /dev/dsp}
.top17.cpd37.01 selection clear 0 end} \
         -padx 9 \
        -pady 3 -text Stop 
    button .top17.fra49.but52 \
        -command {global index_exists

if  {[.top17.cpd37.01 curselection] == ""} {
if {$index_exists == 1} {
       .top17.cpd37.01 selection set 0 end
} else {
        .top17.cpd37.01 selection set 1 end
}
}
browse [.top17.cpd37.01 curselection]} \
         -padx 9 \
        -pady 3 -text Play 
    entry .top17.fra49.txt
         
    entry .top17.fra49.currplaying
         
    button .top17.fra49.next \
        -command {global termine pipe
.top17.fra49.txt delete 0 end
.top17.fra49.txt insert 0 "Next..."

set termine 1
catch {close $pipe}} \
         -padx 9 \
        -pady 3 -text Next 
    button .top17.fra49.rplay \
        -command {global termine player_mode

set termine 0
set done " "

set num [expr [random ] % [.top17.cpd37.01 size] ]

#puts $num

if {[.top17.cpd37.01 size] > 0} {
while {$termine !=2} {

for {set rplay 1} {$rplay < [expr [.top17.cpd37.01 size] - 1]} {incr rplay} {
# On vite de jouer 2 fois de suite la meme chose...
if {$termine !=2} {

        while {[string first " $num " $done] != -1 } {
        set num [expr [random ] % [.top17.cpd37.01 size] ]
        after 100
        if {$termine == 2} {break}
        update
#        puts $num
        }
        append done "$num "
        if { [.top17.cpd37.01 get $num] != ".." } {
        browse $num
        }

        }
    }
}
}} \
         -padx 9 \
        -pady 3 -text Rplay 
    frame .top17.cpd17 \
        -borderwidth 1 -height 30 -relief sunken \
         -width 30 
    menubutton .top17.cpd17.01 \
        -anchor w  \
        -menu .top17.cpd17.01.02 -padx 4 -pady 3 -text File -width 6 
    menu .top17.cpd17.01.02 \
        -cursor {}  \
        -tearoff 0 
    .top17.cpd17.01.02 add command \
        -command {global player_mode

cd ".."
.top17.cpd37.01 insert 0 "./"
set player_mode "directory"
browse 0} \
        -label Up -state active 
    .top17.cpd17.01.02 add command \
        -command {global player_mode

set player_mode "directory"
.top17.cpd37.01 insert 0 "./"
browse 0} \
        -label Browse 
    .top17.cpd17.01.02 add command \
        -command {global Recursif_intelligent player_mode

if {$Recursif_intelligent == 0} {
    .top17.cpd37.01 delete 0 end
    foreach i [exec find -name *.mp3 ] {
            .top17.cpd37.01 insert end $i
        }    
    set player_mode "directory"
    }} \
        -label {Recursive Browse} 
    .top17.cpd17.01.02 add command \
        -command exit -label Quit 
    menubutton .top17.cpd17.03 \
        -anchor w  \
        -menu .top17.cpd17.03.04 -padx 4 -pady 3 -text Commands -width 9 
    menu .top17.cpd17.03.04 \
        -cursor {}  \
        -tearoff 0 
    .top17.cpd17.03.04 add command \
        -command {.top17.cpd37.01 selection set 0 end} -label {Select all} \
        -state active 
    menubutton .top17.cpd17.05 \
        -anchor w  \
        -menu .top17.cpd17.05.06 -padx 4 -pady 3 -text Options -width 6 
    menu .top17.cpd17.05.06 \
        -cursor {}  \
        -tearoff 0 
    .top17.cpd17.05.06 add checkbutton \
        -label HTML_Synchro -state active -variable HTML_Synchro 
    .top17.cpd17.05.06 add checkbutton \
        -label Cover -variable Cover 
    button .top17.updir \
        -command {global player_mode

cd ".."
.top17.cpd37.01 insert 0 "./"
set player_mode "directory"
browse 0} \
         -padx 9 \
        -pady 3 -relief groove -text Up 
    ###################
    # SETTING GEOMETRY
    ###################
    place .top17.cpd37 \
        -x 5 -y 110 -width 310 -height 145 -anchor nw -bordermode ignore 
    grid columnconf .top17.cpd37 0 -weight 1
    grid rowconf .top17.cpd37 0 -weight 1
    grid .top17.cpd37.01 \
        -column 0 -row 0 -columnspan 1 -rowspan 1 -sticky nesw 
    grid .top17.cpd37.02 \
        -column 0 -row 1 -columnspan 1 -rowspan 1 -sticky ew 
    grid .top17.cpd37.03 \
        -column 1 -row 0 -columnspan 1 -rowspan 1 -sticky ns 
    place .top17.fra45 \
        -x 5 -y 35 -width 310 -height 70 -anchor nw -bordermode ignore 
    place .top17.fra45.cpd46 \
        -x 5 -y 5 -width 245 -height 25 -anchor nw -bordermode ignore 
    pack .top17.fra45.cpd46.01 \
        -anchor center -expand 0 -fill none -padx 2 -pady 2 -side left 
    pack .top17.fra45.cpd46.02 \
        -anchor center -expand 1 -fill x -padx 2 -pady 2 -side right 
    place .top17.fra45.cpd47 \
        -x 5 -y 35 -width 245 -height 25 -anchor nw -bordermode ignore 
    pack .top17.fra45.cpd47.01 \
        -anchor center -expand 0 -fill none -padx 2 -pady 2 -side left 
    pack .top17.fra45.cpd47.02 \
        -anchor center -expand 1 -fill x -padx 2 -pady 2 -side right 
    place .top17.fra45.but48 \
        -x 255 -y 5 -width 48 -height 24 -anchor nw -bordermode ignore 
    place .top17.fra45.cover \
        -x 255 -y 35 -width 48 -height 24 -anchor nw -bordermode ignore 
    place .top17.fra49 \
        -x 5 -y 260 -width 310 -height 35 -anchor nw -bordermode ignore 
    place .top17.fra49.but51 \
        -x 5 -y 5 -width 32 -height 24 -anchor nw -bordermode ignore 
    place .top17.fra49.but52 \
        -x 41 -y 5 -width 32 -height 24 -anchor nw -bordermode ignore 
    place .top17.fra49.txt \
        -x 200 -y 7 -width 106 -height 20 -anchor nw -bordermode ignore 
    place .top17.fra49.currplaying \
        -x 150 -y 7 -width 51 -height 20 -anchor nw -bordermode ignore 
    place .top17.fra49.next \
        -x 75 -y 5 -width 32 -height 24 -anchor nw -bordermode ignore 
    place .top17.fra49.rplay \
        -x 110 -y 5 -width 37 -height 24 -anchor nw -bordermode ignore 
    place .top17.cpd17 \
        -x 5 -y 5 -width 212 -height 26 -anchor nw 
    pack .top17.cpd17.01 \
        -anchor center -expand 0 -fill none -side left 
    pack .top17.cpd17.03 \
        -anchor center -expand 0 -fill none -side left 
    pack .top17.cpd17.05 \
        -anchor center -expand 0 -fill none -side right 
    place .top17.updir \
        -x 290 -y 10 -width 26 -height 19 -anchor nw -bordermode ignore 
}

Window show .
Window show .top17

main $argc $argv
