#!/usr/bin/ruby
# encoding: utf-8

require 'gtk2'
require "rexml/document"

# License? GPL v2.0

#LANGUAGE = ENV['LANGUAGE'][0..1]

#@xbranding = File.new( "/etc/lesslinux/branding/branding.xml" )
#@branding = REXML::Document.new  @xbranding

assi = Gtk::Assistant.new
# assi.deletable = false

$dummy = false
alldisks = nil
partarray = []
diskarray = []
niceparts = []
nicedrives = []
partsizes = []
drivesizes = []
target_dir = "/tmp"
targetsuff = Time.now.strftime("photorec_%Y%m%d-%H%M%S")
xml_read_count = 0

def read_suffixes
	suffixes = []
	begin
		File.open("/etc/lesslinux/emergencytools/photorec_suffixes.txt").each { |line|
			# puts line
			suffixes.push(line.strip) if line.strip.length > 0
		}
	rescue
		File.open("photorec_suffixes.txt").each { |line|
			# puts line
			suffixes.push(line.strip) if line.strip.length > 0
		}
	end
	return suffixes
end

def read_devs
	xml_obj = nil
	if ARGV.size > 0 
		file = File.new( ARGV[0] )
		doc = REXML::Document.new(file)
		$dummy = true
	else	
		system("sudo /sbin/mdev -s")
		sleep 2
		xmlstr = ""
		IO.popen("sudo /usr/sbin/lshw-static -xml") { |x|
			while x.gets
				xmlstr = xmlstr +$_
			end
		}
		doc = REXML::Document.new(xmlstr)
	end
	return doc
end

def scan_parts (doc)
	alldisks = []
	doc.elements.each("//node[@class='storage']") { |x|
		businfo = x.elements["businfo"].text.to_s
		storageproduct = ""
		begin
			storageproduct = x.elements["vendor"].text.to_s + " " + x.elements["product"].text.to_s
		rescue
		end
		x.elements.each("node[@class='disk']") { |element|
			parts = []
			product = ""
			size = 0
			unit = ""
			cdrom = false
			diskname = element.elements["logicalname"].text.to_s
			begin
				product = element.elements["product"].text.to_s
			rescue
				product = element.elements["description"].text.to_s 
				product = storageproduct unless storageproduct == ""
			end
			begin
				size = element.elements["size"].text.to_i
				unit = element.elements["size"].attributes["units"]
			rescue
			end
			# puts element.attributes["handle"]  + " " + product + " " + businfo + " " + size.to_s + " " + unit
			if element.attributes["id"] =~ /^cdrom/ 
				#	puts "  " + element.elements["logicalname"].text
				cdrom = true
				mount_point = nil
				log_name = []
				element.elements.each("logicalname") { |l| log_name.push(l.text) }
				state = "clear"
				if log_name.size > 1
					mount_point = log_name[1] 
					state = "mounted"
				end
				parts.push( [ element.elements["logicalname"].text, "iso9660", state, mount_point, false, 0 ] )
			end
			element.elements.each("node[@class='volume']") { |n|
				state = ""
				mount_options = []
				rw = false
				begin
					puts "Checking: " + n.elements["logicalname"].text
					state = n.elements["configuration/setting[@id='state']"].attributes["value"].to_s
					mount_options = n.elements["configuration/setting[@id='mount.options']"].
						attributes["value"].to_s.split(",")
					mount_options.each { |m| rw = true if m == "rw" }
				rescue
				end
				fstype = nil
				begin
					fstype = n.elements["configuration/setting[@id='filesystem']"].attributes["value"].strip
				rescue
					fstype = n.elements["logicalname"].text
				end
				is_extended = false
				begin
					is_extended = true if n.elements["capabilities/capability[@id='partitioned:extended']"].text.strip == "Extended partition"
				rescue
				end
				unless  is_extended == true # || fstype == "swap"
					# puts "  " + n.attributes["id"] + " " + n.elements["logicalname"].text + " " + 
					#	n.elements["configuration/setting[@id='filesystem']"].attributes["value"] + " " + state
					mount_point = nil
					log_name = []
					capacity = 0
					begin
						capacity = n.elements["capacity"].text.to_i
					rescue
					end
					n.elements.each("logicalname") { |l| log_name.push(l.text) }
					mount_point = log_name[1] if log_name.size > 1
					parts.push( [ n.elements["logicalname"].text,
					fstype.to_s,
					state, mount_point, rw, capacity ] )
				end
				if is_extended == true
					n.elements.each("node[@class='volume']") { |m|
						begin
							istate = ""
							imount_options = []
							irw = false
							begin
								istate = m.elements["configuration/setting[@id='state']"].attributes["value"].to_s
								imount_options = m.elements["configuration/setting[@id='mount.options']"].
									attributes["value"].to_s.split(",")
								imount_options.each { |o| irw = true if o == "rw" }
							rescue
							end
							ifstype = nil
							begin
								ifstype = m.elements["configuration/setting[@id='filesystem']"].attributes["value"].strip
							rescue
								ifstype = "unbekanntes Dateisystem"
								m.elements.each("description") { |d|
									puts "Checking: " + d.text
									ifstype = "fat" if d.text =~ /FAT/
									ifstype = "ntfs" if d.text =~ /NTFS/
 									ifstype = "ext3" if d.text =~ /Linux/
									if d.text =~ /swap/
										ifstype = "swap"
										fstype = "swap"
									end
								}
							end
							unless fstype == "swap"
								mount_point = nil
								log_name = []
								capacity = 0
								begin
									capacity = m.elements["capacity"].text.to_i
								rescue
								end
								m.elements.each("logicalname") { |l| log_name.push(l.text) }
								mount_point = log_name[1] if log_name.size > 1
								parts.push( [ m.elements["logicalname"].text,
								ifstype.to_s,
								istate, mount_point, rw, capacity ] )
							end
						rescue
						end
					}
				end
				
			}
			alldisks.push( [  businfo, product, size, unit, cdrom, parts, diskname ] )
		}
		# FIXME: This is weird copy&paste
		x.elements.each("node[@class='disk']/node[@class='disk']") { |element|
			parts = []
			product = ""
			size = 0
			unit = ""
			cdrom = false
			diskname = element.elements["logicalname"].text.to_s
			begin
				product = element.elements["product"].text.to_s
			rescue
				# product = element.elements["description"].text.to_s
				product = "unbekannt"
			end
			begin
				size = element.elements["size"].text.to_i
				unit = element.elements["size"].attributes["units"]
			rescue
			end
			# puts element.attributes["handle"]  + " " + product + " " + businfo + " " + size.to_s + " " + unit
			if element.attributes["id"] =~ /^cdrom/ 
				#	puts "  " + element.elements["logicalname"].text
				cdrom = true
				mount_point = nil
				log_name = []
				element.elements.each("logicalname") { |l| log_name.push(l.text) }
				state = "clear"
				if log_name.size > 1
					mount_point = log_name[1] 
					state = "mounted"
				end
				parts.push( [ element.elements["logicalname"].text, "iso9660", state, mount_point, false, 0 ] )
			end
			element.elements.each("node[@class='volume']") { |n|
				state = ""
				mount_options = []
				rw = false
				begin
					puts "Checking: " + n.elements["logicalname"].text
					state = n.elements["configuration/setting[@id='state']"].attributes["value"].to_s
					mount_options = n.elements["configuration/setting[@id='mount.options']"].
						attributes["value"].to_s.split(",")
					mount_options.each { |m| rw = true if m == "rw" }
				rescue
				end
				fstype = nil
				begin
					fstype = n.elements["configuration/setting[@id='filesystem']"].attributes["value"].strip
				rescue
					fstype = "unbekanntes Dateisystem"
				end
				is_extended = false
				begin
					is_extended = true if n.elements["capabilities/capability[@id='partitioned:extended']"].text.strip == "Extended partition"
				rescue
				end
				unless is_extended == true # || fstype == "swap" 
					# puts "  " + n.attributes["id"] + " " + n.elements["logicalname"].text + " " + 
					#	n.elements["configuration/setting[@id='filesystem']"].attributes["value"] + " " + state
					mount_point = nil
					log_name = []
					capacity = 0
					begin
						capacity = n.elements["capacity"].text.to_i
					rescue
					end
					n.elements.each("logicalname") { |l| log_name.push(l.text) }
					mount_point = log_name[1] if log_name.size > 1
					parts.push( [ n.elements["logicalname"].text,
					fstype.to_s,
					state, mount_point, rw, capacity ] )
				end
				if is_extended == true
					n.elements.each("node[@class='volume']") { |m|
						begin
							istate = ""
							imount_options = []
							irw = false
							begin
								istate = m.elements["configuration/setting[@id='state']"].attributes["value"].to_s
								imount_options = m.elements["configuration/setting[@id='mount.options']"].
									attributes["value"].to_s.split(",")
								imount_options.each { |o| irw = true if o == "rw" }
							rescue
							end
							ifstype = nil
							begin
								ifstype = m.elements["configuration/setting[@id='filesystem']"].attributes["value"].strip
							rescue
								ifstype = "unbekanntes Dateisystem"
							end
							# unless fstype == "swap"
							mount_point = nil
							log_name = []
							capacity = 0
							begin
								capacity = m.elements["capacity"].text.to_i
							rescue
							end
							m.elements.each("logicalname") { |l| log_name.push(l.text) }
							mount_point = log_name[1] if log_name.size > 1
							parts.push( [ m.elements["logicalname"].text,
							ifstype.to_s,
							istate, mount_point, rw, capacity ] )
							# end
						rescue
						end
					}
				end
				
			}
			alldisks.push( [  businfo, product, size, unit, cdrom, parts, diskname ] )
		}
		x.elements.each("node[@class='volume']") { |element|
			if element.elements["logicalname"].text =~ /^\/dev\/sd/ && businfo =~ /^usb/
				diskname = element.elements["logicalname"].text.to_s
				parts = []
				product = ""
				size = 0
				unit = ""
				cdrom = false
				istate = ""
				imount_options = []
				irw = false
				begin
					istate = element.elements["configuration/setting[@id='state']"].attributes["value"].to_s
					imount_options = element.elements["configuration/setting[@id='mount.options']"].
					attributes["value"].to_s.split(",")
					imount_options.each { |o| irw = true if o == "rw" }
				rescue
				end
				ifstype = nil
				begin
					ifstype = element.elements["configuration/setting[@id='filesystem']"].attributes["value"].strip
				rescue
					ifstype = "unbekanntes Dateisystem"
				end
				# udrive = UsbDrive.new(element.elements["logicalname"].text)
				begin
					product = x.elements["vendor"].text + " " + x.elements["product"].text
				#	udrive.product = x.elements["product"].text
				rescue
				end
				mount_point = nil
				log_name = []
				size = element.elements["size"].text.to_i
				capacity = 0
				begin
					capacity = m.elements["capacity"].text.to_i
				rescue
				end
				element.elements.each("logicalname") { |l| log_name.push(l.text) }
				mount_point = log_name[1] if log_name.size > 1
				parts.push( [ element.elements["logicalname"].text, ifstype.to_s, istate, mount_point, irw, capacity ] )
				alldisks.push( [  businfo, product, size, unit, cdrom, parts, diskname ] )
			end
			#all_drives[element.elements["logicalname"].text] = udrive unless 
			#all_drives.has_key?( element.elements["logicalname"].text )
		}
	}
	return alldisks
end

def update_partcombo(disks, partcombo, partrows, drivecombo, driverows)
	(partrows - 1).downto(0) { |i| 
		puts "removing " + i.to_s
		partcombo.remove_text(i)
	}
	(driverows - 1).downto(0) { |i| 
		puts "removing " + i.to_s
		drivecombo.remove_text(i)
	}
	part_array = []
	new_rows = 0
	disk_array = []
	disk_rows = 0
	niceparts = []
	nicedrives = []
	partsizes = []
	drivesizes = []
	disks.each { |d|
		sizestr = ""
		if d[2] > 7_900_000_000
			sizestr = ((d[2].to_f / 1073741824 ) + 0.5).to_i.to_s + "GB"
		else
			sizestr = (d[2].to_f / 1048576 ).to_i.to_s + "MB"
		end
		businfo = "IDE/SATA"
		businfo = "USB" if d[0] =~ /^usb/
		mounted = false
		d[5].each { |p|
			psize = ""
			if p[5] > 7_900_000_000
				psize = ((p[5].to_f / 1073741824 ) + 0.5).to_i.to_s + "GB"
			else
				psize = (p[5].to_f / 1048576 ).to_i.to_s + "MB"
			end
			unless p[2] == "mounted" || d[4] == true
				nicepart = d[1] + " (" + businfo + ", " + sizestr + ") Partition " + p[0] + " (" + p[1] + ", " + psize + ")"
				partcombo.append_text(nicepart)
				new_rows += 1
				part_array.push(p[0])
				niceparts.push(nicepart)
				partsizes.push(p[5])
			else
				mounted = true
			end
		}
		unless mounted == true || d[6].strip =~ /^\/dev\/sr/
			begin
				device = d[6]
				nicedrive = d[1] + " " + device + " (" + businfo + ", " + sizestr + ")"
				drivecombo.append_text(nicedrive)
				disk_rows += 1
				disk_array.push(device)
				nicedrives.push(nicedrive)
				drivesizes.push(d[2])
			rescue
				puts "trouble processing " + d[5].join(" // ")
			end
		end
	}
	if new_rows < 1
		partcombo.append_text("Keine geeignete Partition für die Suche gefunden - ggf. Laufwerkseinbindungen lösen")
		partcombo.active = 0
		partcombo.sensitive = false
	end
	if disk_rows < 1
		drivecombo.append_text("Keine geeignete Festplatte für die Suche gefunden - ggf. Laufwerkseinbindungen lösen")
		drivecombo.active = 0
		drivecombo.sensitive = false
	end
	partcombo.active = 0
	drivecombo.active = 0
	return new_rows, part_array, disk_rows, disk_array, niceparts, nicedrives, partsizes, drivesizes
end

def apply_settings(assi, device, filetypes, target, partition, target_dir, opentarget )
	puts target
	puts target_dir
	partstring = "partition_i386"
	partstring = "partition_none" if partition == true
	fileopt = "enable,"
	if filetypes.size > 0 
		fileopt = "disable,"
		filetypes.each { |f|
			fileopt = fileopt + f + ",enable,"
		}
	end
	phrecstring = "photorec /d \"" + target + "\" /cmd " + device + " " + partstring + ",fileopt,everything," + fileopt + "search"
	if $dummy == true
		puts phrecstring
	else
		system("Terminal --hide-toolbars --hide-menubar --disable-server -T \"Bitte nicht schließen\" -x " + phrecstring )
	end
	freespace = 0
	IO.popen("df \"" + target_dir + "\"") { |i|
		while i.gets
			puts $_
			cols = $_.split
			freespace = cols[3].strip.to_i
			puts cols.join("+")
		end
	}
	if freespace > 0
		dialog = Gtk::Dialog.new("Datenrettung abgeschlossen",assi,Gtk::Dialog::MODAL,
			[ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ]
		)
		dialog.has_separator = false
		label = Gtk::Label.new("Die Datenrettung ist abgeschlossen!")
		label.wrap = true
		image = Gtk::Image.new(Gtk::Stock::DIALOG_INFO, Gtk::IconSize::DIALOG)
	else
		dialog = Gtk::Dialog.new("Datenrettung abgeschlossen",assi,Gtk::Dialog::MODAL,
			[ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ]
		)
		dialog.has_separator = false
		label = Gtk::Label.new("Der Zielordner ist voll. Möglicherweise konnten nicht alle Dateien gesichert werden!")
		label.wrap = true
		image = Gtk::Image.new(Gtk::Stock::DIALOG_WARNING, Gtk::IconSize::DIALOG)
	end
	hbox = Gtk::HBox.new(false, 5)
	hbox.border_width = 10
	hbox.pack_start_defaults(image);
	hbox.pack_start_defaults(label);

	dialog.vbox.add(hbox)
	dialog.show_all
	dialog.run
	dialog.destroy
	system("chown -R surfer \"" + target + ".1\"")
	# assi.destroy
	system("su surfer -c 'exo-open \"" + target + ".1\"'") if opentarget == true
	puts "Alles hat ein Ende!"
	assi.destroy
end

#========================================
# First window - tell the user what we do
#========================================

desclabel = Gtk::Label.new("Dieser Assistent hilft Ihnen beim Aufspüren verlorener oder versehentlich gelöschter Dateien. Damit können sogar Dateien wiederhergestellt werden, nachdem ein Datenträger formatiert wurde. Auch die Suche auf beschädigten Festplatten ist möglich.")
desclabel.wrap = true
desclabel.width_request = 550
desclabel.xalign = 0.1

descpage = assi.append_page(desclabel)
assi.set_page_title(desclabel, "Datenwiederherstellung" )
assi.set_page_type(desclabel, Gtk::Assistant::PAGE_CONTENT)
assi.set_page_complete(desclabel, true) # false)

#========================================
# Second window - choose the partition
#========================================

partlabel = Gtk::Label.new("Wählen Sie das Laufwerk, auf dem Sie die Daten suchen wollen. Falls Sie eine Festplatte umpartitioniert haben oder die Partitionstabelle nicht (mehr) lesbar ist, können Sie die Suche über eine gesamte Platte durchführen. Ansonsten empfehlen wir die Suche auf einer Partition. Achtung: Es werden nur Partitionen und Festplatten angezeigt, die momentan nicht eingebunden sind!")
partlabel.wrap = true
partlabel.width_request = 550
partlabel.xalign = 0.1

partbox = Gtk::VBox.new(false, 5)
partbox.pack_start(partlabel, false, true, 5)

partradio = Gtk::RadioButton.new("Auf Partition suchen")
partcombo = Gtk::ComboBox.new
# partcombo.append_text("/dev/sda1 Hulla")
# partcombo.append_text("/dev/sdb9 Bulla")
# partcombo.active = 0
partrows = 0
partbox.pack_start(partradio, false, true, 5)
partbox.pack_start(partcombo, false, true, 5)
diskradio = Gtk::RadioButton.new(partradio, "Auf ganzer Platte suchen")
diskcombo = Gtk::ComboBox.new
# diskcombo.append_text("/dev/sda Hulla")
# diskcombo.append_text("/dev/sdb Bulla")
# diskcombo.active = 0
diskrows = 0
diskcombo.sensitive = false
partbox.pack_start(diskradio, false, true, 5)
partbox.pack_start(diskcombo, false, true, 5)

partradio.signal_connect("clicked") { |b|
	diskcombo.sensitive = false
	partcombo.sensitive = true
}

diskradio.signal_connect("clicked") { |b|
	partcombo.sensitive = false
	diskcombo.sensitive = true
}

partpage = assi.append_page(partbox)
assi.set_page_title(partbox, "Auswahl des Suchortes" )
assi.set_page_type(partbox, Gtk::Assistant::PAGE_CONTENT)
assi.set_page_complete(partbox, false)

#========================================
# Third window - choose filetypes to save
#========================================

typelabel = Gtk::Label.new("Wählen Sie die Dateitypen, nach denen gesucht werden soll. Die Suche nach allen Dateitypen bringt oft nicht benötigte Archive und EXE-Dateien zum Vorschein. In den meisten Fällen ist es daher besser, die Suche auf bestimmte Medien- oder Office-Formate einzuschränken.")
typelabel.wrap = true
typelabel.width_request = 550
typelabel.xalign = 0.1

typeradio = Gtk::RadioButton.new("Alle bekannten Dateitypen suchen")
typeselec = Gtk::RadioButton.new(typeradio, "Zu suchende Dateitypen auswählen")
typebox = Gtk::VBox.new(false, 5)
typebox.pack_start(typelabel, false, true, 5)
typebox.pack_start(typeradio, false, true, 5)
typebox.pack_start(typeselec, false, true, 5)

scroll_pane = Gtk::ScrolledWindow.new
scroll_pane.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)

scrollbox = Gtk::VBox.new(false, 5)

checks = []
# formats = [ "doc", "xls", "jpg", "png", "abc", "cde", "ppt", "exif", "html", "h", "c", "c++", "d", "e" ]
formats = read_suffixes
format_checkboxes = []
formats.each { |f|
	checkme = Gtk::CheckButton.new(f)
	format_checkboxes.push(checkme)
	scrollbox.pack_start(checkme, false, true, 0)
}

scroll_pane.add_with_viewport(scrollbox)
scroll_pane.sensitive = false
typebox.pack_start(scroll_pane, true, true, 5)

typeselec.signal_connect("clicked") { |b| scroll_pane.sensitive = true }
typeradio.signal_connect("clicked") { |b| scroll_pane.sensitive = false }

typepage = assi.append_page(typebox)
assi.set_page_title(typebox, "Auswahl des Datenformate" )
assi.set_page_type(typebox, Gtk::Assistant::PAGE_CONTENT)
assi.set_page_complete(typebox, true) # false)

#========================================
# Fourth window - choose taget directory
#========================================

targlabel = Gtk::Label.new("Wählen Sie das Zielverzeichnis aus. In diesem entsteht ein neuer Ordner " + targetsuff + ".1, in dem die gefundenen Dateien abgelegt werden. Bedenken Sie bei der Auswahl des Zielverzeichnisses, dass das gefundene Datenvolumen der Partitionsgröße entsprechen kann!")
targlabel.wrap = true
targlabel.width_request = 550
targlabel.xalign = 0.1

chooser_dir  = Gtk::FileChooserButton.new("Zielverzeichnis wählen", Gtk::FileChooser::ACTION_SELECT_FOLDER)

opentarget = Gtk::CheckButton.new("Nach Datenrettung Zielverzeichnis öffnen")
opentarget.active = true

targbox = Gtk::VBox.new(false, 5)
targbox.pack_start(targlabel, false, true, 5)
targbox.pack_start(chooser_dir, false, true, 5)
targbox.pack_start(opentarget, false, true, 5)

targpage = assi.append_page(targbox)
assi.set_page_title(targbox, "Auswahl des Zielordners" )
assi.set_page_type(targbox, Gtk::Assistant::PAGE_CONTENT)
assi.set_page_complete(targbox, false)

chooser_dir.signal_connect('selection_changed') do |w|
  puts w.filename
  target_dir = w.filename
  assi.set_page_complete(targbox, true)
end

#========================================
# Last window - confirm the settings
#========================================

lastlabel = Gtk::Label.new("Wollen Sie die Wiederherstellung mit den vorgenommenen Einstellungen durchführen?")
lastlabel.wrap = true
lastlabel.width_request = 550
lastlabel.xalign = 0.1

ovlabel = Gtk::Label.new
ovlabel.wrap = true
ovlabel.width_request = 500
ovlabel.xalign = 0.3

lastdesc = Gtk::Label.new("Nach einem Klick auf \"Anwenden\" startet die Suche nach Dateien in einem neuen Fenster. Bitte schließen Sie dieses nicht. Am Ende wird eine Zusammenfassung der Wiederherstellung angezeigt.")
lastdesc.wrap = true
lastdesc.width_request = 550
lastdesc.xalign = 0.1

lastbox = Gtk::VBox.new(false, 5)
lastbox.pack_start(lastlabel, false, true, 5)
lastbox.pack_start(ovlabel, false, true, 5)
lastbox.pack_start(lastdesc, false, true, 5)

lastpage = assi.append_page(lastbox)
assi.set_page_title(lastbox, "Zusammenfassung" )
assi.set_page_type(lastbox, Gtk::Assistant::PAGE_CONFIRM)
assi.set_page_complete(lastbox, true)

#========================================
# Common settings and callbacks
#========================================

assi.set_title  "Datenwiederherstellung"
assi.border_width = 10
assi.set_size_request(600, 410)
assi.signal_connect('destroy') { Gtk.main_quit }
assi.signal_connect('cancel')  { assi.destroy }
assi.signal_connect('close')   { |w| 
	puts niceparts[partcombo.active]
	puts nicedrives[diskcombo.active]
	puts partsizes[partcombo.active]
	puts drivesizes[diskcombo.active]
	puts partarray[partcombo.active]
	puts diskarray[diskcombo.active]
	puts partradio.active?
	puts typeradio.active?
	searchformats = []
	formatcount = 0
	format_checkboxes.each { |c|
		searchformats.push(formats[formatcount]) if c.active?
		formatcount += 1
	}
	scandev = nil
	nicedev = nil
	scantypes = []
	scansize = 0
	if partradio.active? == true
		scandev = partarray[partcombo.active]
		nicedev = niceparts[partcombo.active]
		scansize = partsizes[partcombo.active]
	else
		scandev = diskarray[diskcombo.active]
		nicedev = nicedrives[diskcombo.active]
		scansize = drivesizes[diskcombo.active]
	end
	if typeradio.active? == true
		scantypes = []
	else
		scantypes = searchformats 
	end
	apply_settings(w, scandev, scantypes, target_dir + "/" + targetsuff, partradio.active?, target_dir, opentarget.active?)
}

assi.set_forward_page_func{|curr|
	searchformats = []
	formatcount = 0
	format_checkboxes.each { |c|
		searchformats.push(formats[formatcount]) if c.active?
		formatcount += 1
	}
	scandev = nil
	nicedev = nil
	scantypes = []
	scansize = 0
	if partradio.active? == true
		scandev = partarray[partcombo.active]
		nicedev = niceparts[partcombo.active]
		scansize = partsizes[partcombo.active]
	else
		scandev = diskarray[diskcombo.active]
		nicedev = nicedrives[diskcombo.active]
		scansize = drivesizes[diskcombo.active]
	end
	if typeradio.active? == true
		scantypes = []
		searchfor = "allen Dateitypen"
	else
		scantypes = searchformats
		searchfor = "ausgewählten Dateitypen"
	end
	maxtime = scansize.to_i / 400_000_000
	mintime = scansize.to_i / 2_000_000_000
	ovlabel.set_markup("<b>Suche auf:</b> " + nicedev.to_s + "\n\n<b>Suche nach:</b> " + searchfor + 
		"\n\n<b>Gefundene Dateien speichern in:</b> " + target_dir + "/" + targetsuff + ".1\n\n<b>Benötigte Zeit:</b> " + 
		mintime.to_i.to_s + " bis " + maxtime.to_i.to_s + " Minuten (geschätzt)" )
	puts curr
	if curr == 0
		# when switching from first to second screen, read drivelist
		puts "current screen 0, rereading drivelist"
		alldisks = scan_parts(read_devs) if xml_read_count < 1
		xml_read_count += 1
		alldisks.each { |d|
			# d[0] businfo
			# d[1] Name
			# d[2] Größe in Bytes
			# d[3] Einheit
			# d[4] Boolean CDROM
			# d[5] Partitionen / Array
			# d[5][0][0] Device 
			# d[5][0][1] Filesystem
			# d[5][0][2] Mounted (String)
			# d[5][0][4] Mounted (Boolean)
			# puts " -+- " + d[5][0][6].to_s + " -+-"
		}
		partrows, partarray, diskrows, diskarray, niceparts, nicedrives, partsizes, drivesizes = 
			update_partcombo(alldisks, partcombo, partrows, diskcombo, diskrows)
		if diskrows < 1 
			diskradio.sensitive = false
		else
			diskradio.sensitive = true
		end
		if partrows < 1 
			partradio.sensitive = false
			diskradio.active = true
		else
			partradio.sensitive = true
		end
		if diskrows + partrows > 0
			assi.set_page_complete(partbox, true)
		else
			assi.set_page_complete(partbox, false)
		end
		# usbdrives = get_usbdrives_lshw
		# puts usbdrives
		# usable_drives = create_drivelist(choicebox, usable_drives.size, usbdrives)
		# assi.set_page_complete(choice_vbox, usable_drives.size > 0)
		1
	else
		curr + 1
	end
}

assi.show_all
Gtk.main
