#!/data/data/com.termux/files/usr/bin/env python3

import sys
import time
import subprocess
import os
from math import ceil
import re

try:
	import termuxgui as tg
except ModuleNotFoundError:
	sys.exit("termuxgui module not found. Please install the Termux:GUI python bindings: https://github.com/tareksander/termux-gui-python-bindings")
 


c = tg.Connection()


PAGESIZE = 30



a = tg.Activity(c)

root = tg.LinearLayout(a)

bar = tg.LinearLayout(a, root, False)
bar.setlinearlayoutparams(0)
bar.setheight("WRAP_CONTENT")

upgrade = tg.Button(a, "upgrade", bar)
upgrade.setheight("WRAP_CONTENT")

apply = tg.Button(a, "apply", bar)
apply.setheight("WRAP_CONTENT")


filterlayout = tg.LinearLayout(a, root, False)
filterlayout.setheight("WRAP_CONTENT")
filterlayout.setlinearlayoutparams(0)

filtertext = tg.EditText(a, "", filterlayout, True)

filterbutton = tg.Button(a, "filter", filterlayout)
filterbutton.setwidth("WRAP_CONTENT")
filterbutton.setlinearlayoutparams(0)




bar2 = tg.LinearLayout(a, root, False)
bar2.setlinearlayoutparams(0)
bar2.setheight("WRAP_CONTENT")

installbox = tg.Checkbox(a, "install", bar2, True)
installbox.setheight("WRAP_CONTENT")
installbox.setlinearlayoutparams( 0)
installbox.setmargin(30, "right")


prevpage = tg.Button(a, "-", bar2)
prevpage.setwidth("WRAP_CONTENT")
prevpage.setlinearlayoutparams(0)

page = tg.TextView(a, "0/", bar2)
page.setwidth("WRAP_CONTENT")
page.setlinearlayoutparams( 0)
page.setmargin(5)

nextpage = tg.Button(a, "+", bar2)
nextpage.setwidth("WRAP_CONTENT")
nextpage.setlinearlayoutparams(0)





packages = tg.LinearLayout(a, root, False)
packages.setlinearlayoutparams(3)
packages.setheight( 0)
packages.setmargin(10, "top")

availablescroll = tg.NestedScrollView(a, packages)
availablescroll.setwidth(0)

available = tg.LinearLayout(a, availablescroll)


selectedscroll = tg.NestedScrollView(a, packages)
selectedscroll.setwidth(0)

selected = tg.LinearLayout(a, selectedscroll)


cpage = 1

infos = tg.NestedScrollView(a, root)
infos.setheight(0)
infos.setmargin(5, "top")
infostext = tg.TextView(a, "", infos)


lastpagesize = 0
pagebuttons = []
for i in range(0, PAGESIZE):
    b = tg.Button(a, "", available)
    b.setvisibility(0)
    pagebuttons.append(b)


pkglist=[]
selectedpkg=[]
selectedids=[]

install=True

def update():
    global pkglist
    ls = ""
    if install:
        ls = subprocess.check_output(["(apt-cache pkgnames; apt-mark showmanual; apt-mark showauto) | sort | uniq -u"], shell=True,stderr=subprocess.DEVNULL).decode("ascii")
    else:
        ls = subprocess.check_output(["apt-mark showmanual | sort"], shell=True,stderr=subprocess.DEVNULL).decode("ascii")
    pkglist=ls.splitlines()
update()


def displaypage(p):
    global cpage
    global lastpagesize
    cpage = p
    page.settext(f"{p}/{ceil(len(pkglist)/PAGESIZE)}")
    l = pkglist[p*PAGESIZE-PAGESIZE:p*PAGESIZE]
    for i, p in enumerate(l):
        pagebuttons[i].settext(p)
        if (i >= lastpagesize):
            pagebuttons[i].setvisibility(2)
    for i in range(len(l), PAGESIZE):
        if (i < lastpagesize):
            pagebuttons[i].setvisibility(0)
    lastpagesize = len(l)
displaypage(1)



def closeconnection():
    c.close()



def showinfo(pkg):
    infostext.settext(subprocess.check_output(["apt", "show", pkg],stderr=subprocess.DEVNULL).decode("ascii"))




for ev in c.events():
    if ev.type == "destroy" and ev.value["finishing"]:
        c.totermux()
        sys.exit()
    if ev.type == "click" and ev.value["id"] == installbox:
        install = ev.value["set"]
        update()
        selected.clearchildren()
        selectedpkg=[]
        selectedids=[]
        displaypage(1)
        continue
    if ev.type == "click" and ev.value["id"] == prevpage:
        if cpage > 1:
            displaypage(cpage-1)
        continue
    if ev.type == "click" and ev.value["id"] == nextpage:
        if cpage < ceil(len(pkglist)/PAGESIZE):
            displaypage(cpage+1)
        continue
    if ev.type == "click" and ev.value["id"] == upgrade:
        c.totermux()
        closeconnection()
        os.execlp("pkg", "pkg", "upgrade")
        continue
    if ev.type == "click" and ev.value["id"] == filterbutton:
        update()
        text = filtertext.gettext()
        r = re.compile("^"+text)
        pkglist = list(filter(lambda p: r.match(p) , pkglist))
        displaypage(1)
        continue
    if ev.type == "click" and ev.value["id"] == apply:
        if len(selectedpkg) != 0:
            c.totermux()
            closeconnection()
            if install:
                selectedpkg.insert(0,"install")
            else:
                selectedpkg.insert(0,"uninstall")
            selectedpkg.insert(0,"pkg")
            print(" ".join(selectedpkg))
            sys.stdout.flush()
            os.execvp("pkg", selectedpkg)
        continue
    if ev.type == "click":
        pkgview = tg.View(a, ev.value["id"])
        pkg = tg.TextView.gettext(pkgview)
        if ev.value["id"] in selectedids:
            selectedids.remove(ev.value["id"])
            selectedpkg.remove(pkg)
            tg.View.delete(pkgview)
            continue
        if pkg in pkglist:
            if pkg not in selectedpkg:
                selectedids.append(tg.Button(a, pkg, selected).id)
                selectedpkg.append(pkg)
                showinfo(pkg)
        
    
    
    
    
    
    
    
    
    
    
    
