

namespace eval RetrievePT {
    variable w
    variable list
    variable progressbar
    variable progresslabel
    variable ftpid ""
    variable FileSize
    variable LastTimeMiliSec 0
    variable modulesinfo
    variable images

    variable server gid.cimne.com
    variable relativedir [file join pub gidmodules]
    variable localdir [file join $::GIDDEFAULT problemtypes]
    variable blocksize 4096 ;#default value 4096
    variable contcallbacks 0
}

proc RetrievePT::Close {} {
    variable w
    variable ftpid
    variable progresslabel

    if { [info exists ftpid] && $ftpid != "" } {
	set progresslabel "Closing..."
	update
	ftp::Close $ftpid
	set ftpid ""
    }
    destroy $w
}


proc RetrievePT::Callback { bytes } {
    variable FileSize
    variable progressbar
    variable progresslabel
    variable LastTimeMiliSec
    variable blocksize
    variable contcallbacks
    if { $contcallbacks == [expr int($FileSize/$blocksize/15)] } {            
	set contcallbacks 0
	set percent [expr 10+90*$bytes/double($FileSize)]
	set progressbar $percent
	
	set TimeMiliSec [clock clicks -milliseconds]
	set speed [expr $bytes/1024.0/($TimeMiliSec-$LastTimeMiliSec)*1000.0]
	
	set progresslabel [format "$bytes/$FileSize (%.3g Kb/s)" $speed]      
	update idletasks
    } else {
	incr contcallbacks
    }    
}

proc RetrievePT::Connect {} {
    variable w
    variable ftpid
    variable server
    variable progressbar
    variable progresslabel
    variable relativedir
    variable InitialPercentage
    variable blocksize

    set progressbar 0
    $w conf -cursor watch
    update

    if { ![info exists ftpid] } {
	set ftpid ""
    }

    if { $ftpid != "" && [catch {
	ftp::Pwd $ftpid
    }] } {
	set ftpid ""
    }
    
    if { $ftpid == "" } {
	set ftpid [ftp::Open $server ftp gidretriever@  -mode passive \
		        -progress ::RetrievePT::Callback -timeout 30 -blocksize $blocksize]

	if { $ftpid == -1 } {
	    WarnWin [_ "Could not connect to server"]
	    set progressbar 0
	    set progresslabel ""
	    $w conf -cursor ""
	    return -1
	}
	ftp::Cd $ftpid $relativedir
    }
    set progresslabel "Connected"
    update
    return 0
}

proc RetrievePT::Retrievelist {} {
    variable w
    variable ftpid
    variable progressbar
    variable progresslabel
    variable list
    variable FileSize
    variable modulesinfo
    variable modulesarray
    variable modules

    if { [Connect] } { return }
    set FileSize [ftp::FileSize $ftpid modulesinfo]
    
    set progresslabel 0/$FileSize
    update
    ftp::Type $ftpid ascii
    ftp::Get $ftpid modulesinfo -variable RetrievePT::modulesinfo
    if { ![info exists modulesinfo] } {
	set progresslabel "Error retrieving list"
	$w conf -cursor ""
	update
	after 1000 {set ::RetrievePT::progresslabel ""}
	return
    }
    regsub -lineanchor -all {^#[^\n]*} $modulesinfo {} modulesinfo
    catch { unset modulesarray }
    set modules ""
    set Name ""
    catch {
	foreach "name value" $modulesinfo {
	    if { $name == "Name" } {
		set Name $value
		lappend modules $value
	    } else {
		set modulesarray($Name,$name) $value
	    }
	}
    }
    if { ![winfo exists $list] } { return }
    $list delete 0 end
    foreach i $modules {
	if { [info exists modulesarray($i,Version)] } {
	    set version $modulesarray($i,Version)
	} else { set version "" }
	if { [info exists modulesarray($i,ShortDescription)] } {
	    set shortdesc [string trim $modulesarray($i,ShortDescription)]
	} else { set shortdesc "" }
	$list insert end [list $i $version "" $shortdesc]
    }
    CheckExistance

    set progressbar 100
    set progresslabel ""
    $w conf -cursor ""
    update
    after 1000 set RetrievePT::progressbar 0
}

proc RetrievePT::IsVersionOK { module } { 
    variable modulesarray
    if { [info exists modulesarray($module,MinimumGiDVersion)] } {
	set moduleversion $modulesarray($module,MinimumGiDVersion)
    } else { return 1 }

    set comp -1
    catch { 
	#see proc GiDVersionCmp use in ConfigureProgram.tcl 
	set comp [GiDVersionCmp $moduleversion]
    }
    if { $comp < 0 } {
	#GiD is Old
	return 0
    } else {
	#GiD is OK
	return 1
    } 
#    set GidVersion [.central.s info GiDVersion]
#    for { set i 0 } { $i <= 2 } { incr i } {
#        set gid($i) 0
#        set mod($i) 0
#    }
#    set gid(3) ""
#    set mod(3) ""
#    regexp {([0-9]+)([.]([0-9]+))?([.]([0-9]+))?([a-zA-Z])?} $GidVersion {} gid(0) {} \
#        gid(1) {} gid(2) gid(3)
#    regexp {([0-9]+)([.]([0-9]+))?([.]([0-9]+))?([a-zA-Z])?} $moduleversion {} mod(0) {} \
#        mod(1) {} mod(2) mod(3)
#    for { set i 0 } { $i <= 3 } { incr i } {
#        if { $mod($i) != "" && $mod($i) > $gid($i) } { return 0 }
#        if { $mod($i) != "" && $gid($i) > $mod($i) } { return 1 }
#    }
#    return 1
}

proc RetrievePT::CheckExistance {} {
    variable list
    variable modulesarray
    variable localdir
    variable images
    
    if { ![winfo exists $list] } { return }

    for { set i 0 } { $i < [$list index end] } { incr i } {
	set module [lindex [$list get $i] 0]
	set InstalledFile [file join $localdir $modulesarray($module,InstalledFile)]
	if { [file exists $InstalledFile] } {
	    $list cellconfigure $i,2 -image $images(checked-on)
	} elseif { ![IsVersionOK $module] } {
	    $list cellconfigure $i,2 -image $images(cross)
	} else {
	    $list cellconfigure $i,2 -image $images(checked-off)
	}
    }
}

proc RetrievePT::RetrieveModule {} {
    variable w
    variable list
    variable modulesarray
    variable localdir
    variable ftpid
    variable progressbar
    variable progresslabel
    variable FileSize
    variable LastTimeMiliSec

    if { [llength [$list curselection]] == 0 } {
	WarnWin [_ "Select first one module"] $list
	return
    }
    
    if { [Connect] } { return }

    set GidVersion [.central.s info GiDVersion]

    foreach i [$list curselection] {
	set module [lindex [$list get $i] 0]

	if { ![IsVersionOK $module] } {
	    set moduleversion $modulesarray($module,MinimumGiDVersion)
	    set text "WARNING: module '$module' requires GiD version $moduleversion "
	    append text "and GiD version is $GidVersion. There can be incompatibilities. "
	    append text "Proceed?"
	    set retval [tk_messageBox -default ok -icon question -message $text -type okcancel]
	    if { $retval == "cancel" } {
		set progressbar 0
		set progresslabel ""
		$w conf -cursor ""
		return
	    }
	}
	set InstalledFile [file join $localdir $modulesarray($module,InstalledFile)]
	if { [file exists $InstalledFile] } {
	    set text "WARNING: module '$module' is already installed in the local system. "
	    append text "Are you sure to proceed?"
	    set retval [tk_messageBox -default ok -icon question -message $text -type okcancel]
	    if { $retval == "cancel" } {
		set progressbar 0
		set progresslabel ""
		$w conf -cursor ""
		return
	    }
	}
	set DownloadFile $modulesarray($module,DownloadFile)
	set FileSize [ftp::FileSize $ftpid $DownloadFile]
	set LastTimeMiliSec [clock clicks -milliseconds]

	ftp::Type $ftpid binary
	ftp::Get $ftpid $DownloadFile [file join $localdir $DownloadFile]
	if { ![file exists [file join $localdir $DownloadFile]] } {
	    WarnWin [_ "Problems retrieving the module"]
	    set progressbar 0
	    set progresslabel ""
	    catch { $w conf -cursor "" }
	    return
	}
	set progresslabel "$FileSize/$FileSize"
	$w conf -cursor watch
	update
	if { [file size [file join $localdir $DownloadFile]] == $FileSize } {
	    set pwd [pwd]
	    cd $localdir

	    #anulado, en su lugar arranco un proceso sin bloqueo con callback
	    if { 0 } {        
		set unzip [auto_execok unzip]
		if { $unzip == "" } {
		    set unzip [file join $::GIDDEFAULT unzip]
		    set unzip [auto_execok $unzip]
		}
		if { $unzip != "" } {
		    if { $::tcl_platform(platform) == "windows"} {
		        #eval exec $unzip -o [list $DownloadFile]
		    } else {
		        # flags para ficheros ASCII (CR LF => LF)
		        eval exec $unzip -a -o [list $DownloadFile]
		    }
		} else {
		    WarnWin [_ "Error: to execute this function it is necessary to have unzip"]
		}
	    }
		
	    if { $::tcl_platform(platform) == "windows"} {
		set exe "\"[file join $::GIDDEFAULT unzip.exe]\" -x -o \"$DownloadFile\""
		runExe run $exe -blocking false -callback [list AfterUnzip %m $w $DownloadFile] -timeout 3600
	    } else {
		# flags para ficheros ASCII (CR LF => LF)
		set exe "unzip -a -o $DownloadFile"
		runExe run $exe -blocking false -callback [list AfterUnzip %m $w $DownloadFile] -timeout 3600
	    }  
 
	    cd $pwd
	} elseif { [winfo exists $w] } {
	    WarnWin [_ "Error retrieving the module"] $w
	}
	#anulado, se llama al acabar unzip con un  callback
	if { 0 } {
	    file delete [file join $localdir $DownloadFile]
	    CheckExistance
	    ClearCacheFormProblemtypeMenuDir
	    FastCacheFromProblemtypeMenu
	}
    }
    
    if { 0 } {
	set progresslabel ""
	catch { $w conf -cursor "" }
	update
	after 1000 set RetrievePT::progressbar 0
    }
}

proc AfterUnzip { mode args } {
  switch -exact -- $mode {
    prepare  {
	set ::RetrievePT::progresslabel [_ "Unzipping"]...
	update
    }
    output {
	#set ::RetrievePT::progresslabel [lindex $args 0]
    }
     finished {
	 set w [lindex $args 0]
	 set DownloadFile [lindex $args 1]
	 file delete [file join $::RetrievePT::localdir $DownloadFile]
	 ::RetrievePT::CheckExistance
	 ClearCacheFormProblemtypeMenuDir
	 #if the problemtypes menu must be deleted to use FastCacheFromProblemtypeMenu
	 #FastCacheFromProblemtypeMenu
	 catch { $w conf -cursor "" }
	 set ::RetrievePT::progresslabel [_ "Module downloaded"]
	 set ::RetrievePT::progressbar 0
	 update
	 after 2000 { set ::RetrievePT::progresslabel "" }
     }
  }
}

proc RetrievePT::DisplayText { parent textinfo } {

    set w $parent.retrievepttext

#     catch { destroy $parent.retrievepttext }
#     toplevel $w
#     wm title $w "Display info"

    InitWindow $w [_ "Display info"] PreRetrievePTDisplayHelpWindowGeom

    set sw   [ScrolledWindow $w.lf \
	    -auto both -relief sunken -borderwidth 2]
    set text [text $sw.text -width 60 -height 20]
    bind $text <1> "focus $text"
    $sw setwidget $text

    button $w.close -text [_ "Close"] -width 10 -command "destroy $w"
    grid $sw -sticky nsew
    grid $w.close
    
    grid columnconf $w 0 -weight 1
    grid rowconf $w 0 -weight 1

    $text ins end $textinfo
    $text conf -state disabled
}

proc RetrievePT::ModuleInfo {} {
    variable list
    variable modulesarray
    variable localdir

    if { [llength [$list curselection]] == 0 } {
	WarnWin [_ "Select first one module"] $list
	return
    }
    if { [llength [$list curselection]] > 1 } {
	WarnWin [_ "Select ONLY one module"] $list
	return
    }
    set module [lindex [$list get [$list curselection]] 0]

    set desc ""
    if { ![IsVersionOK $module] } {
	set moduleversion $modulesarray($module,MinimumGiDVersion)
	set GidVersion [.central.s info GiDVersion]
	set desc "WARNING: This module requires GiD version $moduleversion\n"
	append desc "and GiD version is $GidVersion. There can be incompatibilities.\n\n"
    }
    set InstalledFile [file join $localdir $modulesarray($module,InstalledFile)]
    if { [file exists $InstalledFile] } {
	append desc "This module is already installed\n"
    }
    if { [info exists modulesarray($module,Description)] } {
	append desc $modulesarray($module,Description)
    } elseif { [info exists modulesarray($module,ShortDescription)] } {
	append desc $modulesarray($module,ShortDescription)
    } else {
	WarnWin [_ "This module has no description"] $list
	return
    }
    RetrievePT::DisplayText $list $desc
}

proc RetrievePT::ModuleNews {} {
    variable list
    variable modulesarray
    variable localdir

    if { [llength [$list curselection]] == 0 } {
	WarnWin [_ "Select first one module"] $list
	return
    }
    if { [llength [$list curselection]] > 1 } {
	WarnWin [_ "Select ONLY one module"] $list
	return
    }
    set module [lindex [$list get [$list curselection]] 0]

    set desc ""
    if { ![IsVersionOK $module] } {
	set GidVersion [.central.s info GiDVersion]
	set moduleversion $modulesarray($module,MinimumGiDVersion)
	set desc "WARNING: This module requires GiD version $moduleversion\n"
	append desc "and GiD version is $GidVersion. There can be incompatibilities.\n\n"
    }
    set InstalledFile [file join $localdir $modulesarray($module,InstalledFile)]
    if { [file exists $InstalledFile] } {
	append desc "This module is already installed\n"
    }
    if { [info exists modulesarray($module,NewsInVersion)] } {
	append desc $modulesarray($module,NewsInVersion)
    } else {
	WarnWin [_ "This module has no news information"] $list
	return
    }
    RetrievePT::DisplayText $list $desc
}

proc RetrievePT::ConfigureLabel { l } {
    set width [winfo width $l]
    if { $width > 1 } {
	$l conf -wraplength $width
    }
}

proc RetrievePT::OpenGUI { { parent .gid } } {
    variable w
    variable list
    variable progressbar
    variable progresslabel
    variable images

    set images(checked-on) [image create photo -data {
	R0lGODlhEAAQAIQAAIKCgrxdXe4AANnZ2fePj+0BAdVOWdl6fugGBuSgpeimpu0AANvW1up8
	fOwAANympv///+ttbe0fH+0UFNyrq+TAwOa1tf//////////////////////////////////
	/yH+Dk1hZGUgd2l0aCBHSU1QACH5BAEKAB8ALAAAAAAQABAAAAVL4CeOZGmeJqCuLFC2bSCQ
	6mDfA1EYNIDbB0Ti5VMsGIOG4wEhDhbHiEMBafYGAoFkQhlUndlFxfa9WhaWW3mkqrrfr7fc
	iqrb7/cQADs=
    }]
    set images(checked-off) [image create photo -data {
	R0lGODlhEAAQAKEAAP///4KCgv///////yH+Dk1hZGUgd2l0aCBHSU1QACH5BAEKAAIALAAA
	AAAQABAAAAImlI+py50AowRvylBXwAhqfnjKlo2gISZkR5mlegrQRtdPjcfO3hQAOw==
    }]
    set images(cross) [image create photo -data {
	R0lGODlhEAAQAIQAAIKCgrxdXe4AANnZ2fePj+0BAdVOWdl6fugGBuSgpeimpu0AANvW1up8
	fOwAANympv///+ttbe0fH+0UFNyrq+TAwOa1tf//////////////////////////////////
	/yH+Dk1hZGUgd2l0aCBHSU1QACH5BAEKAB8ALAAAAAAQABAAAAVJ4CeOZGmeJqCuLFC2bSCQ
	qiAMOG4bNDDYOVvi5VMIGD/BA0IcLBY2gQLC7CWjA2ozWrFprTaLTlAd1chUqu0FQafVqLh8
    }]

    #package require ftp
    #package require Tablelist 2.2

    set w $parent.retrievept

    catch { destroy $parent.retrievept }

    InitWindow $w [_ "Retrieve analysis modules"] PreRetrievePTWindowGeom RetrievePT::OpenGUI

    wm protocol $w WM_DELETE_WINDOW RetrievePT::Close

    frame $w.f1

    label $w.f1.l1 -text \
	[_ "Note: In order to use this function, it is necessary to be connected to internet"] \
	    -height 3 -font BoldFont -wraplength 300 -justify left -anchor w
    #bind $w.f1.l1 <Configure> "after idle RetrievePT::ConfigureLabel $w.f1.l1"

    set sw   [ScrolledWindow $w.f1.lf \
	    -auto both -relief sunken -borderwidth 2]
    set list [tablelist::tablelist $sw.lb \
	    -exportselection 0 \
	    -columns [list \
	    18 "Module"        left \
	    7 "Version"        left \
	    4 "Inst." center \
	    20 "Characteristics"        left \
	    ] \
	    -labelcommand tablelist::sortByColumn \
	    -background white \
	    -selectbackground navy -selectforeground white \
	    -stretch end -selectmode extended \
	    -highlightthickness 0]
    
    $sw setwidget $list

    set wp [::progressbar::progressbar $w.f1.f -variable ::RetrievePT::progressbar -width 200 \
	    -background [ $w.f1 cget -background]]
    label $w.f1.l2 -textvariable RetrievePT::progresslabel
    set progressbar 0
    set progresslabel ""
    
    grid $w.f1.l1    -     -sticky ew
    grid $sw         -     -sticky nsew
    grid $wp      $w.f1.l2 -sticky w
    grid columnconf $w.f1 1 -weight 1
    grid rowconf $w.f1 1 -weight 1

    set def_back [$w cget -background]
    frame $w.buts -bg [CCColorActivo $def_back]

    button $w.buts.b1 -text [_ "Retrieve list"] -width 13 -command RetrievePT::Retrievelist
    button $w.buts.b2 -text [_ "Module info"] -width 13 -command RetrievePT::ModuleInfo
    button $w.buts.b3 -text [_ "Module news"] -width 13 -command RetrievePT::ModuleNews
    button $w.buts.b4 -text [_ "Retrieve module"] -width 13 -command RetrievePT::RetrieveModule
    button $w.buts.b5 -text [_ "Close"] -width 10 -command "RetrievePT::Close"

    grid $w.buts.b1 $w.buts.b2 $w.buts.b3 $w.buts.b4 $w.buts.b5 -padx 2 -pady 3

    grid $w.f1 -sticky nsew
    grid $w.buts -sticky ew
    grid columnconf $w 0 -weight 1
    grid rowconf $w 0 -weight 1

    update idletasks
    $w.f1.l1 conf -wraplength [winfo reqwidth $w]
   
    set progresslabel [_ "Retrieving module list"]...
    update
    RetrievePT::Retrievelist
    set progresslabel ""
    update
}

# if { $::tcl_platform(platform) == "windows"} {
#     #font create BoldFont -family "MS Sans Serif" -size 8 -weight bold
#     font create BoldFont -family "Verdana" -size 8 -weight bold
# } else {
#     font create NormalFont -family {new century schoolbook} -size 12
#     option add *font NormalFont
#     font create BoldFont -family {new century schoolbook} -size 12 -weight bold
# }



# proc WarnWin { text { par .}} {

#     if { $par == "."} {
#         set w .__WarnWin
#     } else {
#         set w $par.__WarnWin
#     }
#     tk_messageBox -icon warning -message $text -parent $par -type ok

#     #tk_dialog  $w Warning $text warning 0 OK
# }

# wm withdraw .
# source /c/GiD\ project/scripts/progressbar.tcl
# lappend auto_path /c/compasser/addons
# package require BWidget
# RetrievePT::OpenGUI ""
