#!/usr/bin/python3
import gi, os, re, jwmkit_utils
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf
import xml.etree.ElementTree as ET

# JWM Kit - A set of Graphical Apps to simplify use of JWM (Joe's Window Manager) <https://codeberg.org/JWMKit/JWM_Kit>
# Copyright ©  2020-2022 Calvin Kent McNabb <apps.jwmkit@gmail.com>
#
# This file is part of JWM Kit.
#
# JWM Kit is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2,
# as published by the Free Software Foundation.
#
# JWM Kit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with JWM Kit.  If not, see <https://www.gnu.org/licenses/>.


def screen_size():
    try:
        screen_data = os.popen('xrandr').read()
        screen_data = re.findall('current (\d\d+) x (\d\d+)', screen_data)[0]
    except IndexError:
        screen_data = ('1920', '1080')
    return screen_data


class GroupWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="JWM Kit Groups Editor")
        self.set_border_width(15)
        try:
            self.set_icon_from_file('/usr/share/pixmaps/jwmkit/groups.svg')
        except gi.repository.GLib.Error:
            self.set_icon_name('edit-paste')
        self.home = os.path.expanduser('~')
        self.status_message = Gtk.Label()
        self.group_path = ''
        self.group_data = self.get_xml()
        if self.group_data == 'warning_settings':
            jwmkit_utils.warning_settings(self)
            return
        screen_data = screen_size()
        self.jwm_icon_paths = self.get_icon_paths()
        self.entry_values = [[''], [], '']
        self.option_list = ['aerosnap', 'border', 'centered', 'constrain', 'drag', 'fixed', 'hmax', 'iignore',
                            'maximized', 'minimized', 'noborder', 'noclose', 'nodrag', 'nofocus', 'nofullscreen',
                            'nolist', 'nomax', 'nomin', 'nomove', 'nopager', 'noresize', 'noshade', 'notitle',
                            'noturgent', 'pignore', 'shaded', 'sticky', 'tiled', 'title', 'vmax']
        # basic layout
        main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        if int(screen_data[1]) <= 800:
            left_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
        else:
            left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
        header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        left_1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        left_2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        right_1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_5 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_7 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_8 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_9 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_9.pack_start(Gtk.Label(label=""), True, True, 0)
        right_10 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        right_11 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)

        self.add(main_box)
        main_box.add(header_box)
        main_box.add(left_box)
        main_box.add(right_box)
        left_box.add(left_1)
        left_box.add(left_2)
        right_box.add(right_1)
        right_box.add(right_2)
        right_box.add(right_5)
        right_box.add(right_7)
        right_box.add(right_8)
        right_box.add(right_9)
        right_box.pack_end(right_11, False, True, 0)
        right_box.pack_end(right_10, False, True, 0)

        # left frame
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        scrolled_window.set_min_content_height(250)
        left_1.add(Gtk.Label(label='Groups'))
        left_1.add(scrolled_window)

        self.listbox = Gtk.ListBox()
        self.listbox.set_selection_mode(Gtk.SelectionMode.SINGLE)
        self.listbox.connect("row-selected", self.populate_listbox2)
        scrolled_window.add(self.listbox)

        scrolled_window2 = Gtk.ScrolledWindow()
        scrolled_window2.set_min_content_width(200)
        scrolled_window2.set_min_content_height(250)
        left_2.add(Gtk.Label(label='Options'))
        left_2.add(scrolled_window2)
        self.listbox2 = Gtk.ListBox()
        self.listbox2.set_selection_mode(Gtk.SelectionMode.SINGLE)
        scrolled_window2.add(self.listbox2)

        # right frame
        self.type_combo = Gtk.ComboBoxText()
        self.type_combo.set_property("width-request", 100)
        self.type_combo.set_tooltip_text('Select the option type to add to the group')
        self.type_combo.append_text('Name')
        self.type_combo.append_text('Class')
        self.type_combo.append_text('Icon')
        self.type_combo.append_text('Option')
        self.type_combo.append_text('Layer')
        self.type_combo.set_active(0)
        self.name_entry = Gtk.Entry()
        self.name_entry.set_no_show_all(True)
        self.name_entry.set_visible(True)
        self.type_combo.connect("changed", self.type_combo_changed)
        self.name_entry.connect("changed", self.on_icon_changed)

        self.option_combo = Gtk.ComboBoxText()
        count = 0
        for option in self.option_list:
            count += 1
            self.option_combo.append_text(option)
        self.option_combo.set_tooltip_text("Select Option")
        self.option_combo.set_active(0)
        self.option_combo.set_no_show_all(True)
        self.option_combo.set_visible(False)

        self.layer_combo = Gtk.ComboBoxText()
        self.layer_combo.append_text('below')
        self.layer_combo.append_text('normal')
        self.layer_combo.append_text('above')
        self.layer_combo.set_tooltip_text("Select Layer")
        self.layer_combo.set_no_show_all(True)
        self.layer_combo.set_visible(False)

        name_add_button = Gtk.Button(label='Add', image=Gtk.Image(stock=Gtk.STOCK_ADD))
        name_add_button.set_property("width-request", 100)
        name_add_button.set_tooltip_text('Add a this name or class entry to the group')
        name_add_button.connect("clicked", self.add_name_command)
        name_add_button.set_always_show_image(True)

        about_button = Gtk.Button(image=Gtk.Image(stock=Gtk.STOCK_ABOUT))
        about_button.set_property("width-request", 35)
        about_button.set_always_show_image(True)
        about_button.connect('clicked', jwmkit_utils.get_about, self)

        self.width_check = Gtk.CheckButton(label="Width:")
        self.width_spin = Gtk.SpinButton()
        self.width_spin.set_tooltip_text("Width in pixel")
        self.width_spin.set_adjustment(Gtk.Adjustment(value=0, lower=0, upper=int(screen_data[0]), step_increment=1))
        self.width_spin.connect("value-changed", self.spin_change, 'width')
        self.width_check.connect("toggled", self.on_check, self.width_spin, 'width')

        self.height_check = Gtk.CheckButton(label="Height:")
        self.height_spin = Gtk.SpinButton()
        self.height_spin.set_tooltip_text("Height in pixel")
        self.height_spin.set_adjustment(Gtk.Adjustment(value=0, lower=0, upper=int(screen_data[1]), step_increment=1))
        self.height_spin.connect("value-changed", self.spin_change, 'height')
        self.height_check.connect("toggled", self.on_check, self.height_spin, 'height')

        self.x_check = Gtk.CheckButton(label="X:")
        self.x_spin = Gtk.SpinButton()
        self.x_spin.set_tooltip_text("X position")
        self.x_spin.set_adjustment(Gtk.Adjustment(value=0, lower=-int(screen_data[0]), upper=int(screen_data[0]), step_increment=1))
        self.x_spin.connect("value-changed", self.spin_change, 'x')
        self.x_check.connect("toggled", self.on_check, self.x_spin, 'x')

        self.y_check = Gtk.CheckButton(label="Y:")
        self.y_spin = Gtk.SpinButton()
        self.y_spin.set_tooltip_text("Y position")
        self.y_spin.set_adjustment(Gtk.Adjustment(value=0, lower=-int(screen_data[1]), upper=int(screen_data[1]), step_increment=1))
        self.y_spin.connect("value-changed", self.spin_change, 'y')
        self.y_check.connect("toggled", self.on_check, self.y_spin, 'y')

        self.desktop_check = Gtk.CheckButton(label="Desktop:")
        self.desktop_spin = Gtk.SpinButton()
        self.desktop_spin.set_tooltip_text("Desktop")
        self.desktop_spin.set_adjustment(Gtk.Adjustment(value=1, lower=1, upper=24, step_increment=1))
        self.desktop_spin.connect("value-changed", self.spin_change, 'desktop')
        self.desktop_check.connect("toggled", self.on_check, self.desktop_spin, 'desktop')

        self.opacity_check = Gtk.CheckButton(label="Opacity:")
        self.opacity_spin = Gtk.SpinButton()
        self.opacity_spin.set_digits(1)
        self.opacity_spin.set_tooltip_text("Opacity")
        self.opacity_spin.set_adjustment(Gtk.Adjustment(value=1.0, lower=0.0, upper=1.0, step_increment=0.100))
        self.opacity_spin.connect("value-changed", self.spin_change, 'opacity')
        self.opacity_check.connect("toggled", self.on_check, self.opacity_spin, 'opacity')

        add_button = Gtk.Button(label="Create", image=Gtk.Image(stock=Gtk.STOCK_ADD))
        add_button.set_tooltip_text('Add a new group')
        add_button.connect("clicked", self.add_command)
        add_button.set_property("width-request", 110)
        add_button.set_always_show_image(True)

        remove_button = Gtk.Button(label="Remove", image=Gtk.Image(stock=Gtk.STOCK_DELETE))
        remove_button.set_tooltip_text('Remove a group or option')
        remove_button.connect("clicked", self.remove_command)
        remove_button.set_property("width-request", 110)
        remove_button.set_always_show_image(True)

        self.remove_popover = Gtk.Popover()
        pop_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        pop_group_button = Gtk.ModelButton(label="Group")
        pop_group_button.set_tooltip_text('Delete the selected Group')
        pop_option_button = Gtk.ModelButton(label="Option")
        pop_option_button.set_tooltip_text('Delete the selected Option')
        pop_group_button.connect("clicked", self.remove_pop_command, 'Group')
        pop_option_button.connect("clicked", self.remove_pop_command, 'Option')
        self.remove_popover.add(pop_box)
        self.remove_popover.set_position(Gtk.PositionType.BOTTOM)
        pop_box.pack_start(pop_group_button, False, True, 5)
        pop_box.pack_start(pop_option_button, False, True, 5)

        save_button = Gtk.Button(label="Save", image=Gtk.Image(stock=Gtk.STOCK_SAVE))
        save_button.set_tooltip_text('Saving will overwrite the existing file')
        save_button.connect("clicked", self.save_command)
        save_button.set_property("width-request", 110)
        save_button.set_always_show_image(True)

        close_button = Gtk.Button(label="Close", image=Gtk.Image(stock=Gtk.STOCK_CANCEL))
        close_button.connect("clicked", Gtk.main_quit)
        close_button.set_property("width-request", 110)
        close_button.set_always_show_image(True)

        right_1.pack_start(Gtk.Label(), True, True, 0)
        right_2.pack_start(self.type_combo, False, False, 10)
        right_2.pack_start(self.name_entry, True, True, 0)
        right_2.pack_start(self.option_combo, True, True, 0)
        right_2.pack_start(self.layer_combo, True, True, 0)
        right_2.pack_end(about_button, False, False, 0)
        right_2.pack_end(name_add_button, False, False, 0)
        right_5.pack_start(Gtk.Separator(), True, True, 30)
        right_7.pack_start(self.width_check, False, False, 3)
        right_7.pack_start(self.width_spin, False, False, 5)
        right_7.pack_start(self.x_check, False, False, 0)
        right_7.pack_start(self.x_spin, False, False, 4)
        right_7.pack_start(self.desktop_check, False, False, 0)
        right_7.pack_start(self.desktop_spin, False, False, 0)
        right_8.pack_start(self.height_check, False, False, 3)
        right_8.pack_start(self.height_spin, False, False, 0)
        right_8.pack_start(self.y_check, False, False, 4)
        right_8.pack_start(self.y_spin, False, False, 0)
        right_8.pack_start(self.opacity_check, False, False, 3)
        right_8.pack_start(self.opacity_spin, False, False, 5)
        right_10.pack_start(add_button, False, False, 5)
        right_10.pack_end(save_button, False, False, 0)
        right_11.pack_start(remove_button, False, False, 5)
        right_11.pack_start(self.status_message, True, False, 0)
        right_11.pack_end(close_button, False, False, 0)

        self.populate_listbox()

    def type_combo_changed(self, entry):
        self.status_message.set_markup('')
        # hide or show widgets based on combo selection
        self.name_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition(1), None)
        if self.type_combo.get_active_text() == 'Icon':
            self.on_icon_changed(self.name_entry)
        if self.type_combo.get_active_text() == 'Option':
            self.name_entry.set_visible(False)
            self.layer_combo.set_visible(False)
            self.option_combo.set_visible(True)
        elif self.type_combo.get_active_text() == 'Layer':
            self.name_entry.set_visible(False)
            self.option_combo.set_visible(False)
            self.layer_combo.set_visible(True)
        else:
            self.option_combo.set_visible(False)
            self.layer_combo.set_visible(False)
            self.name_entry.set_visible(True)

    def on_check(self, check, spin, spin_type):
        index = self.listbox.get_selected_rows()[0].get_index()
        if check.get_active():
            spin.set_sensitive(True)
            if spin_type + ':' not in self.group_data[index]:
                self.spin_change(spin, spin_type)
        else:
            spin_type = spin_type + ':'
            spin.set_sensitive(False)
            for item in self.group_data[index]:
                if item.startswith(spin_type):
                    index2 = self.group_data[index].index(item) - 1
                    del self.group_data[index][index2]
                    del self.group_data[index][index2]
                    del self.group_data[index][index2]
                    del self.group_data[index][index2]
                    i = self.listbox.get_selected_rows()[0]
                    self.populate_listbox2(self.listbox, i)

    def spin_change(self, spin, spin_type):
        spin_type = spin_type + ':'
        value = format(spin.get_value(), '.1f')
        index = self.listbox.get_selected_rows()[0].get_index()
        for item in self.group_data[index]:
            if item == spin_type:
                index2 = self.group_data[index].index(item) - 1
                del self.group_data[index][index2]
                del self.group_data[index][index2]
                del self.group_data[index][index2]
                del self.group_data[index][index2]
                self.populate_listbox2(self.listbox, self.listbox.get_selected_rows()[0])
        self.group_data[index].append('Option')
        self.group_data[index].append(spin_type)
        if spin_type == 'opacity:':
            self.group_data[index].append(str(value))
        else:
            self.group_data[index].append(str(int(float(value))))
        self.group_data[index].append('endOption')
        self.populate_listbox2(self.listbox, self.listbox.get_selected_rows()[0])
        self.listbox2.select_row(self.listbox2.get_row_at_index(int(len(self.group_data[index])/4)-1))

    def add_name_command(self, button):
        def cleanup_dups():
            # function to remove existing layer or Icon option before adding a new
            # also remove an item if it conflicts with the newly added item
            index2 = -1
            conflicts_dic = {'border': ['noborder'], 'noborder': ['border'], 'shade': ['noshade'], 'noshade': ['shade'],
                             'title': ['notitle'], 'notitle': ['title'], 'minimized': ['maximized', 'nomin'],
                             'maximized': ['minimized', 'nomax'], 'nomin': ['minimized'],
                             'nomax': ['maximized', 'aerosnap'], 'aerosnap': ['nomax']}
            if pre_name in ['layer:', 'icon:']:
                if pre_name in self.group_data[index][1::4]:
                    index2 = self.group_data[index][1::4].index(pre_name) * 4
            else:
                if name in conflicts_dic.keys():
                    for conflict in conflicts_dic[name]:
                        if conflict in self.group_data[index]:
                            index2 = (self.group_data[index][2::4].index(conflict) * 4)
                            break
            if index2 != -1:
                del self.group_data[index][index2]
                del self.group_data[index][index2]
                del self.group_data[index][index2]
                del self.group_data[index][index2]

        def option_add():
            # function to append options to the list
            self.group_data[index].append(entry_type)
            self.group_data[index].append(pre_name)
            self.group_data[index].append(name)
            self.group_data[index].append('end' + entry_type)

        index = self.listbox.get_selected_rows()[0].get_index()
        entry_type = self.type_combo.get_active_text()
        # add items to the group
        pre_name = ''
        if entry_type in ['Name', 'Class']:
            name = self.name_entry.get_text()
            if name not in [None, '']:
                if "'" + entry_type + "', '" + pre_name + "', '" + name + "'" not in str(self.group_data[index]):
                    self.group_data[index].insert(0, 'end' + entry_type)
                    self.group_data[index].insert(0, name)
                    self.group_data[index].insert(0, pre_name)
                    self.group_data[index].insert(0, entry_type)
        elif entry_type == 'Layer':
            name = self.layer_combo.get_active_text()
            entry_type = 'Option'
            pre_name = 'layer:'
            if name not in [None, '']:
                cleanup_dups()
                option_add()
        elif entry_type == 'Icon':
            name = self.name_entry.get_text()
            entry_type = 'Option'
            pre_name = 'icon:'
            if name not in [None, '']:
                cleanup_dups()
                option_add()
        elif entry_type == 'Option':
            name = self.option_combo.get_active_text()
            add_test = True
            if name in self.group_data[index]:
                indexes = [i for i in range(len(self.group_data[index])) if self.group_data[index][i] == name]
                for i in indexes:
                    if self.group_data[index][i - 1] == '':
                        if self.group_data[index][i - 2] == 'Option':
                            add_test = False
            if add_test:
                cleanup_dups()
                option_add()
        self.populate_listbox2(self.listbox, self.listbox.get_selected_rows()[0])
        # add items with the Option Tag to the bottom (Name & Class items added to top)
        if entry_type == 'Option':
            self.listbox2.select_row(self.listbox2.get_row_at_index(int(len(self.group_data[index])/4)-1))

    def add_command(self, button):
        self.group_data.append([])
        self.clear_list(-5)
        self.populate_listbox()
        self.listbox.select_row(self.listbox.get_row_at_index(len(self.group_data)-1))

    def remove_command(self, button):
        self.remove_popover.set_relative_to(button)
        self.remove_popover.show_all()
        self.remove_popover.popup()

    def remove_pop_command(self, button, choice):
        index = self.listbox.get_selected_rows()[0].get_index()
        if choice == 'Group':
            del self.group_data[index]
            self.clear_list(-5)
            self.populate_listbox()
            i = index-1
            if i == -1:
                i = 0
            self.listbox.select_row(self.listbox.get_row_at_index(i))
        else:
            index2 = (self.listbox2.get_selected_rows()[0].get_index() * 4)
            del self.group_data[index][index2]
            del self.group_data[index][index2]
            del self.group_data[index][index2]
            del self.group_data[index][index2]
            self.clear_list(index)
            self.populate_listbox2(self.listbox, self.listbox.get_selected_rows()[0])
            i = int(index2/4) -1
            if i == -1:
                i = 0
            self.listbox2.select_row(self.listbox2.get_row_at_index(i))

    def save_command(self, button):
        output = '<?xml version="1.0"?>\n<JWM>\n'
        for data_list in self.group_data:
            if len(data_list) > 3:
                output += '   <Group>\n'
                for data in data_list:
                    if data in ['Name', 'Class', 'Option']:
                        output += '      <%s>' % data
                    elif data[:3] == 'end':
                        output += '</%s>\n' % data[3:]
                    else:
                        output += data
                output += '   </Group>\n'
        output += '</JWM>\n'
        with open(self.group_path, "w") as f:
            f.write(output)
        os.system('jwm -restart')
        self.status_message.set_markup('<big>Saved</big>')

    def populate_listbox(self):
        # list of the groups placed in the top of window
        count = 1
        for item in self.group_data:
            row = Gtk.ListBoxRow()
            box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
            row.add(box)
            box.pack_start(Gtk.Label(label='Group {}'.format(count)), False, False, 5)
            self.listbox.add(row)
            count += 1
        self.listbox.show_all()

    def populate_listbox2(self, listbox, row):
        self.name_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition(1), None)
        self.name_entry.set_text('')
        # list of group options placed in lower window

        if row is not None:
            index = row.get_index()
            self.clear_list(index)
            for option in self.group_data[index]:
                if option in ['Name', 'Option', 'Class']:
                    name = option + ': '
                elif option[:3] == 'end':
                    row = Gtk.ListBoxRow()
                    box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
                    row.add(box)
                    box.pack_start(Gtk.Label(label=name), False, False, 0)
                    self.listbox2.add(row)
                else:
                    name += option
            # enable/disable and set value of spin buttons
            if 'height:' in self.group_data[index]:
                index2 = self.group_data[index].index('height:') + 1
                self.height_spin.set_value(int(self.group_data[index][index2]))
                self.height_spin.set_sensitive(True)
                self.height_check.set_active(True)
            else:
                self.height_spin.set_sensitive(False)
                self.height_check.set_active(False)
            if 'width:' in self.group_data[index]:
                index2 = self.group_data[index].index('width:') + 1
                self.width_spin.set_value(int(self.group_data[index][index2]))
                self.width_spin.set_sensitive(True)
                self.width_check.set_active(True)
            else:
                self.width_spin.set_sensitive(False)
                self.width_check.set_active(False)
            if 'x:' in self.group_data[index]:
                index2 = self.group_data[index].index('x:') + 1
                self.x_spin.set_value(int(self.group_data[index][index2]))
                self.x_spin.set_sensitive(True)
                self.x_check.set_active(True)
            else:
                self.x_spin.set_sensitive(False)
                self.x_check.set_active(False)
            if 'y:' in self.group_data[index]:
                index2 = self.group_data[index].index('y:') + 1
                self.y_spin.set_value(int(self.group_data[index][index2]))
                self.y_spin.set_sensitive(True)
                self.y_check.set_active(True)
            else:
                self.y_spin.set_sensitive(False)
                self.y_check.set_active(False)
            if 'desktop:' in self.group_data[index]:
                index2 = self.group_data[index].index('desktop:') + 1
                self.desktop_spin.set_value(int(self.group_data[index][index2]))
                self.desktop_spin.set_sensitive(True)
                self.desktop_check.set_active(True)
            else:
                self.desktop_spin.set_sensitive(False)
                self.desktop_check.set_active(False)
            if 'opacity:' in self.group_data[index]:
                index2 = self.group_data[index].index('opacity:') + 1
                self.opacity_spin.set_value(float(self.group_data[index][index2]))
                self.opacity_spin.set_sensitive(True)
                self.opacity_check.set_active(True)
            else:
                self.opacity_spin.set_sensitive(False)
                self.opacity_check.set_active(False)

            self.listbox2.show_all()
            self.listbox2.select_row(self.listbox2.get_row_at_index(0))

    def clear_list(self, index):
        self.status_message.set_markup('')
        ok = True
        while ok:
            try:
                if index == -5:
                    self.listbox.select_row(self.listbox.get_row_at_index(0))
                    self.listbox.remove(self.listbox.get_selected_rows()[0])
                else:
                    self.listbox2.select_row(self.listbox2.get_row_at_index(0))
                    self.listbox2.remove(self.listbox2.get_selected_rows()[0])

            except IndexError:
                ok = False

    def get_xml(self):
        # search JWM Kit setting file for path to groups xml then
        # make a list of the groups found in the JWM groups xml
        settings = self.home + '/.config/jwmkit/settings'
        path_ok = False
        if os.path.isfile(settings):
            with open(settings) as f:
                f = f.read()
            f = '\n{}'.format(f)
            try:
                group_path = re.findall('\ngroup.*=(.*)', f)[0]
                if group_path.startswith('$HOME'):
                    group_path = self.home + group_path[5:]
                path_ok = True
            except IndexError:
                pass
        if not path_ok:
            return 'warning_settings'

        self.group_path = group_path
        try:
            tree = ET.parse(group_path)
            root = tree.getroot()
            group_data = []
            for node in root:
                data = []
                for children in node:
                    second_items = children.text
                    second_items = second_items.split(':')
                    if len(second_items) == 1:
                        second_items.insert(0, '')
                    else:
                        second_items[0] += ':'
                    data += [children.tag, second_items[0], second_items[1], 'end' + children.tag]
                group_data += [data]
        except (ET.ParseError, FileNotFoundError):
            # file is missing or corrupt
            # icon paths list will be empty
            if os.path.isfile(group_path):
                self.status_message.set_markup('<b>Warning!</b> Group config is corrupt'
                                               '\nSave will overwrite with a new file')
            else:
                try:
                    with open(self.group_path, 'w+') as new:
                        new.write('<JWM></JWM>')
                except FileNotFoundError:
                    self.status_message.set_markup('<b>Warning!</b> Group config is missing'
                                                   '\nUse JWM Kit Repair to repair the settings file')
            group_data = []

        return group_data

    def on_icon_changed(self, entry):
        if self.type_combo.get_active_text() == 'Icon':
            image_data = self.name_entry.get_text()
            if image_data not in [None, '']:
                if not os.path.isfile(image_data):
                    try:
                        if '/' not in list(image_data):
                            image_data = self.get_icon_dir(image_data)[0]
                        else:
                            self.name_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition(1), None)
                    except IndexError:
                        self.name_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition(1), None)
                if os.path.isfile(image_data):
                    pb = GdkPixbuf.Pixbuf.new_from_file_at_size(image_data, 22, 22)
                    self.name_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition(1), pb)

    def get_icon_dir(self, icon_name):
        icons = []
        icon_name = icon_name.replace(' ', '\ ')
        for dir in self.jwm_icon_paths:
            icons.extend(os.popen('find -L ' + dir + ' -type f -name ' + icon_name + '.png -o -name ' + icon_name +
                                  '.svg -o -name ' + icon_name + '.xpm').read().split('\n'))
        while '' in icons: icons.remove('')
        return icons

    def get_icon_paths(self):
        # read settings file to find user defined icons file
        settings = self.home + '/.config/jwmkit/settings'
        if os.path.isfile(settings):
            with open(settings) as f:
                f = f.read()
            try:
                icon_path = re.findall('icons.*=(.+)', f)[0]
                if icon_path.startswith('$HOME'):
                    icon_path = self.home + icon_path[5:]
            except IndexError:
                # use default icons file if it is not specified in settings file
                print('Icon path not found in settings')
                print('Use JWM Kit Repair & Restore to repair the settings file ')
                print('or manually edit the file\nIcon preview is disabled')
                icon_path = ''
                return icon_path
        # make a list of icons paths defined in the JWM xml icon file
        try:
            tree = ET.parse(icon_path)
            root = tree.getroot()
            icon_path = []
            for node in root:
                node = node.text
                if node.startswith('$HOME'):
                    node = self.home + node[5:]
                # if the file exist add it to the list
                if os.path.isdir(node):
                    icon_path.append(node)
        except (ET.ParseError, FileNotFoundError):
            # file is missing or corrupt.
            print(icon_path + ' is missing or corrupt\nIcon preview is disabled')
            icon_path = ''
        return icon_path

    def get_about(self, button):
        about_window = jwmkit_utils.AboutWindow()
        about_window.connect("delete-event", Gtk.main_quit)
        about_window.set_transient_for(self)
        about_window.show_all()
        self.set_sensitive(False)
        Gtk.main()
        self.set_sensitive(True)


window = GroupWindow()
window.connect("delete-event", Gtk.main_quit)
window.set_position(Gtk.WindowPosition.CENTER)
window.set_resizable(False)
window.show_all()
Gtk.main()
