#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class App(Gtk.Window):
    def __init__(self):
        super().__init__(title='Base Converter')
        self.set_default_size(360, 240)
        grid = Gtk.Grid(column_spacing=8, row_spacing=8)
        grid.set_margin_top(16); grid.set_margin_bottom(16)
        grid.set_margin_start(16); grid.set_margin_end(16)
        self.add(grid)
        grid.attach(Gtk.Label(label='Number:', xalign=0), 0, 0, 1, 1)
        self.inp = Gtk.Entry()
        self.inp.connect('changed', self.update)
        grid.attach(self.inp, 1, 0, 2, 1)
        grid.attach(Gtk.Label(label='Input Base:', xalign=0), 0, 1, 1, 1)
        self.base_sel = Gtk.ComboBoxText()
        for b in ['2 (Binary)', '8 (Octal)', '10 (Decimal)', '16 (Hex)']:
            self.base_sel.append_text(b)
        self.base_sel.set_active(2)
        self.base_sel.connect('changed', self.update)
        grid.attach(self.base_sel, 1, 1, 2, 1)
        self.labels = {}
        for i, (name, base) in enumerate([('Binary (2)', 2), ('Octal (8)', 8),
                                           ('Decimal (10)', 10), ('Hex (16)', 16)]):
            grid.attach(Gtk.Label(label=name+':', xalign=0), 0, i+2, 1, 1)
            lbl = Gtk.Label(label='—', xalign=0, selectable=True)
            lbl.set_markup('<span font_family="monospace">—</span>')
            grid.attach(lbl, 1, i+2, 2, 1)
            self.labels[base] = lbl
    def update(self, *_):
        bases = [2, 8, 10, 16]
        ib = bases[self.base_sel.get_active()]
        txt = self.inp.get_text().strip()
        if not txt:
            for b in bases: self.labels[b].set_markup('<span font_family="monospace">—</span>')
            return
        try:
            val = int(txt, ib)
            self.labels[2].set_markup(f'<span font_family="monospace">{bin(val)[2:]}</span>')
            self.labels[8].set_markup(f'<span font_family="monospace">{oct(val)[2:]}</span>')
            self.labels[10].set_markup(f'<span font_family="monospace">{val}</span>')
            self.labels[16].set_markup(f'<span font_family="monospace">{hex(val)[2:].upper()}</span>')
        except ValueError:
            for b in bases: self.labels[b].set_markup('<span foreground="red">Invalid input</span>')

win = App()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
