extends Control

var data
var gui_program
var tui_program
var other
var packages = []
var installed_packages = [] 
var packages_to_delete = [] 
var output = []
var root_tree

onready var Tree = $Panel/Tree
onready var ConsoleDisplay = $ConsolePanel/RichTextLabel

var color_delete =  Color(0.9,0.2,0.2,0.6)
var color_installed = Color(0.7, 0.7,0.2,0.5)
var color_toinstall = Color(0.5,1,0.5,1)

func get_installed_packages():
	var buffer = [] 
	installed_packages = [] 
# warning-ignore:return_value_discarded
	OS.execute("pkg_info", [], true, buffer, true)
	if buffer:
		for p in buffer[0].split("\n"):
			installed_packages.append(p.split(" ")[0])

func _ready():
	get_installed_packages()
	# the last parameter is a path to the packages database
	var db_path = OS.get_cmdline_args()[-1]
	var file = File.new()
	file.open(db_path, File.READ)
	var content_as_text = file.get_as_text()
	data = parse_json(content_as_text)
	$Panel/LineEdit.grab_focus()

# click on APPLY CHANGES
func _on_Button_pressed():
	ConsoleDisplay.text = ""
	if packages.size() > 0:
		ConsoleDisplay.text = "You are going to install these packages:\n"
		for l in packages:
			ConsoleDisplay.text += "- " + l + "\n"
	if packages_to_delete.size() > 0:
		ConsoleDisplay.text += "You are going to remove these packages:\n"
		for l in packages_to_delete:
			ConsoleDisplay.text += "- " + l + "\n"
	if packages_to_delete.size() > 0 or packages.size() > 0:
		ConsoleDisplay.text += "\n\nClick on Accept to apply changes"
		$ConsolePanel/Accept.visible = true
	else:
		ConsoleDisplay.text = "No change to make"
		$ConsolePanel/Accept.visible = false
	$ConsolePanel/Cancel.visible = true
	$ConsolePanel.visible = true

func _on_Tree_multi_selected():
	var item = Tree.get_selected()
	if item.get_parent() == root_tree:
		return(0)
	
	var status = item.get_metadata(0)
	if status == "for_install": # we don't want to install it
		item.set_metadata(0, null)
		item.clear_custom_bg_color(0)
		packages.erase(item.get_text(0))
	elif not status: # we install it
		packages.append(item.get_text(0))
		item.set_custom_bg_color(0, color_toinstall)
		item.set_metadata(0, "for_install")
	elif status == "installed": # we delete it 
		packages_to_delete.append(item.get_text(0))
		item.set_custom_bg_color(0, color_delete)
		item.set_metadata(0, "to_delete")
	elif status == "to_delete": # we keep it 
		packages_to_delete.erase(item.get_text(0))
		item.set_custom_bg_color(0, color_installed)
		item.set_metadata(0, "installed")

func _on_LineEdit_text_entered(text):
	Tree.clear()
	root_tree = Tree.create_item()
	Tree.set_hide_root(true)
	gui_program = Tree.create_item()
	gui_program.set_text(0, "Graphical programs")
	gui_program.collapsed = false
	tui_program = Tree.create_item(Tree)
	tui_program.set_text(0, "Terminal/console programs")
	tui_program.collapsed = false
	other = Tree.create_item(Tree)
	other.set_text(0, "Other programs")
	other.collapsed = false

	for d in data.size():
		var s = data[d]
		var root
		var found = false
		
		if text == "" or not text:
			found = true
		elif text.to_upper() in s["pkgname"].to_upper():
			found = true
		elif s["comment"] and text.to_upper() in s["comment"].to_upper():
			found = true
		elif $Panel/Search_Descr.pressed == true and s["descr"] and text.to_upper() in s["descr"].to_upper():
			found = true
		
		if found == false:
			continue
		
		if str(s["gui"]) == "True":
			root = Tree.create_item(gui_program)
		elif str(s["tui"]) == "True":
			root = Tree.create_item(tui_program)
		else:
			root = Tree.create_item(other)

		root.set_text(0, s["pkgname"])
		if s["comment"]:
			root.set_text(1, s["comment"])
			root.set_text(1, s["descr"])
		if s["pkgname"] in packages_to_delete:
			root.set_metadata(0, "to_delete")
			root.set_custom_bg_color(0, color_delete)
		elif s["pkgname"] in installed_packages:
			root.set_metadata(0, "installed")
			root.set_custom_bg_color(0, color_installed)
		elif s["pkgname"] in packages:
			root.set_metadata(0, "for_install")
			root.set_custom_bg_color(0, color_toinstall)

func reset_display():
	$ConsolePanel.hide()
	$ConsolePanel/Accept.hide()
	packages = []
	packages_to_delete = [] 
	get_installed_packages()
	_on_LineEdit_text_entered($Panel/LineEdit.text)

func _on_Accept_pressed():
	$ConsolePanel/Accept.visible = false
	$ConsolePanel/Cancel.visible = false
	ConsoleDisplay.text = ""
	if packages_to_delete.size() > 0:
		OS.execute("xterm", ["-e", "doas", "pkg_delete", "-Ivx"] + packages_to_delete, true, output, true)
	if packages.size() > 0:
		OS.execute("xterm", ["-e", "doas", "pkg_add", "-Ivx"] + packages, true, output, true)
	reset_display()

func _on_Cancel_pressed():
	$ConsolePanel.visible = false
	$ConsolePanel/Cancel.visible = false

func _on_Control_resized():
	if Tree:
		Tree.rect_size = self.rect_size


func _on_Search_Descr_pressed():
	if root_tree:
		_on_LineEdit_text_entered($Panel/LineEdit.text)
