diff --git a/btn4ws.py b/btn4ws.py
index f728430..624d107 100644
--- a/btn4ws.py
+++ b/btn4ws.py
@@ -30,7 +30,7 @@ port of the older gimp-perl version to python.
 (c) 2007 Jan Dittberner <jan@dittberner.info>
 """
 import os, urllib, logging, sys
-import gimp, gimpplugin
+import gimp, gimpplugin, gimpui, gimpcolor
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -44,6 +44,13 @@ logging.basicConfig(level=logging.DEBUG,
                     format='%(asctime)s %(levelname)s %(message)s',
                     stream=sys.stderr)
 
+def parsefont(font):
+    """
+    Parses a font into its fontname and size parts.
+    """
+    parts = font.split(" ")
+    return (" ".join(parts[:-1]), parts[-1])
+
 class text_to_name_mapper:
     """
     Text string to name mapper class. This class provides mappings for several target
@@ -149,40 +156,426 @@ class text_to_name_mapper:
             return os.path.join(dirname, fname)
         return fname
 
-class Btn4wsDialog:
+class IntEntry(gtk.Entry):
+    """Input field for integer numbers."""
+
+    def __init__(self, max = 0):
+        gtk.Entry.__init__(self, max)
+        self.set_property("truncate-multiline", True)
+        self.connect("insert-text", self._cb_int_field_insert)
+
+    def _cb_int_field_insert(self, w, new_text, new_text_length, position):
+        """Allow integer input only."""
+        if not new_text.isdigit():
+            w.stop_emission("insert-text")
+
+class Btn4wsDialog(gtk.Assistant):
     """This class is the input dialog field for btn4ws"""
-    def delete_event(self, widget, event, data = None):
+    def _cb_delete_event(self, widget, event, data = None):
+        logging.debug("delete_event")
         return False
 
-    def destroy(self, widget, data = None):
-        gtk.main_quit()
+    def __init__(self, **kwargs):
+        self.data = kwargs
+        self.pages = {}
+        logging.debug("kwargs: " + str(kwargs))
+        gtk.Assistant.__init__(self)
 
-    def __init__(self, filename, outdir, font,
-                 strcolor, transparency, bgcolor,
-                 glow, glowcolor,
-                 usepattern, pattern,
-                 buttoncolor, roundradius,
-                 padding, glowsize, bevelwidth,
-                 nova, novasparkles, novaradius,
-                 novacolor, writexcf, makeinactive,
-                 makeactive, makepressed, makejscript):
-        self.window = gtk.Assistant()
-        self.window.connect("delete_event", self.delete_event)
-        self.window.connect("destroy", self.destroy)
-        self.window.show()
+        self._addIntroPage()
+        #self._addPathSelectionPage()
+        #self._addBasicSettingsPage()
+        self._addLayoutPage()
+        self._addEffectsPage()
+        self._addLastPage()
+        self.show()
+        self.connect("delete_event", self._cb_delete_event)
 
-    def main(self):
-        gtk.main()
+        for pagename in self.pages.iterkeys():
+            self.checkcompletion(pagename)
+
+    def _addIntroPage(self):
+        label = gtk.Label("""Buttons for website allows you to produce a series of buttons for use on a website. On the next pages you may choose several options to change the content and the look of the buttons.""")
+        label.set_line_wrap(True)
+        label.show()
+        self.append_page(label)
+        self.set_page_title(label, "Introduction")
+        self.set_page_complete(label, True)
+
+    def _addPathSelectionPage(self):
+        page = gtk.VBox(False, 5)
+        self.pages["pathselection"] = page
+        page.set_border_width(5)
+        page.show()
+        self.append_page(page)
+        self.set_page_title(page,
+                            "Select the input file and output directory")
+        self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
+        
+        label = gtk.Label("Please choose the file containing your button labels and the directory where the generated files should be put.")
+        label.set_line_wrap(True)
+        label.show()
+        page.pack_start(label, True, True, 0)
+
+        table = gtk.Table(rows=2, columns=2, homogeneous=False)
+        table.show()
+        label = gtk.Label("Button label file")
+        label.show()
+        table.attach(label, 0, 1, 0, 1)
+        button = gtk.FileChooserButton("Choose file")
+        button.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+        button.connect("selection-changed", self._cb_file_selected)
+        button.show()
+        table.attach(button, 1, 2, 0, 1)
+
+        label = gtk.Label("Output directory")
+        label.show()    
+        table.attach(label, 0, 1, 1, 2)
+        button = gtk.FileChooserButton("Choose directory")
+        button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+        button.connect("selection-changed", self._cb_dir_selected)
+        button.show()
+        table.attach(button, 1, 2, 1, 2)
+        
+        page.pack_end(table)
+
+    def _addBasicSettingsPage(self):
+        page = gtk.VBox(False, 5)
+        self.pages["basicsettings"] = page
+        page.set_border_width(5)
+        page.show()
+        self.append_page(page)
+        self.set_page_title(page,
+                           "Select the basic button settings")
+        self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
+
+        label = gtk.Label("Please choose the basic layout settings of your buttons.")
+        label.set_line_wrap(True)
+        label.show()
+        page.pack_start(label, True, True, 0)
+
+        table = gtk.Table(rows=4, columns=2, homogeneous=False)
+        table.show()
+
+        # font
+        label = gtk.Label("Button text font")
+        label.show()
+        table.attach(label, 0, 1, 0, 1)
+        fontsel = gtk.FontButton()
+        fontsel.set_show_size(True)
+        if self.data["font"]:
+            fontsel.set_font_name(self.data["font"])
+        fontsel.show()
+        fontsel.connect("font-set", self._cb_set_font)
+        table.attach(fontsel, 1, 2, 0, 1)
+
+        # strcolor
+        label = gtk.Label("Button text color")
+        label.show()
+        table.attach(label, 0, 1, 1, 2)
+        colorsel = gimpui.ColorSelector()
+        if self.data["strcolor"]:
+            colorsel.set_color(self.data["strcolor"])
+        colorsel.show()
+        colorsel.connect("color-changed", self._cb_set_color, "strcolor",
+                         "basicsettings")
+        table.attach(colorsel, 1, 2, 1, 2)
+
+        # background toggle
+        bgtoggle = gtk.CheckButton("Use a pattern for button")
+        bgtoggle.set_active(self.data["usepattern"])
+        bgtoggle.show()
+        table.attach(bgtoggle, 1, 2, 2, 3)
+
+        # background color / pattern
+        if self.data["usepattern"]:
+            label = gtk.Label("Button pattern")
+        else:
+            label = gtk.Label("Button color")
+        label.show()
+        patternsel = gimpui.PatternSelectButton()
+        if self.data["pattern"]:
+            patternsel.set_pattern(self.data["pattern"])
+        patternsel.connect("pattern-set", self._cb_set_pattern)
+        colorsel = gimpui.ColorSelector()
+        if self.data["buttoncolor"]:
+            colorsel.set_pattern(self.data["buttoncolor"])
+        colorsel.connect("color-changed", self._cb_set_color, "buttoncolor",
+                         "basicsettings")
+        bgtoggle.connect("toggled", self._cb_bgtoggle_toggle, label,
+                         "Button pattern", patternsel,
+                         "Button color", colorsel)
+        if self.data["usepattern"]:
+            patternsel.show()
+        else:
+            colorsel.show()
+
+        table.attach(label, 0, 1, 3, 4)
+        table.attach(patternsel, 1, 2, 3, 4)
+        table.attach(colorsel, 1, 2, 3, 4)
+
+        page.pack_end(table)
+
+    def _addLayoutPage(self):
+        page = gtk.VBox(False, 5)
+        self.pages["layout"] = page
+        page.set_border_width(5)
+        page.show()
+        self.append_page(page)
+        self.set_page_title(page,
+                           "Select the layout settings")
+        self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
+
+        label = gtk.Label("Select the layout options for your buttons")
+        label.set_line_wrap(True)
+        label.show()
+        page.pack_start(label, True, True, 0)
+
+        table = gtk.Table(rows=4, columns=2, homogeneous=False)
+        table.show()
+
+        #roundradius
+        label = gtk.Label("Round radius")
+        label.show()
+        entry = IntEntry(max = 2)
+        if self.data["roundradius"]:
+            entry.set_text(str(self.data["roundradius"]))
+        entry.connect("changed", self._cb_set_intvalue, "roundradius",
+                      "layout")
+        entry.show()
+        table.attach(label, 0, 1, 0, 1)
+        table.attach(entry, 1, 2, 0, 1)
+
+        #bevelwidth
+        label = gtk.Label("Bevel width")
+        label.show()
+        entry = IntEntry(max = 2)
+        entry.connect("changed", self._cb_set_intvalue, "bevelwidth",
+                      "layout")
+        entry.show()
+        table.attach(label, 0, 1, 1, 2)
+        table.attach(entry, 1, 2, 1, 2)
+
+        #transparency
+        transp = gtk.CheckButton("Transparent button background")
+        transp.set_active(self.data["transparency"])
+        transp.show()
+        transp.connect("toggled", self._cb_toggle_simple, "transparency",
+                       "layout")
+        table.attach(transp, 1, 2, 2, 3)
+
+        #bgcolor
+        label = gtk.Label("Background color")
+        label.show()
+        colorsel = gimpui.ColorSelector()
+        if self.data["buttoncolor"]:
+            colorsel.set_pattern(self.data["bgcolor"])
+        colorsel.connect("color-changed", self._cb_set_color, "bgcolor",
+                         "layout")
+        colorsel.show()
+        table.attach(label, 0, 1, 3, 4)
+        table.attach(colorsel, 1, 2, 3, 4)
+
+        page.pack_end(table)
+
+    def _addEffectsPage(self):
+        page = gtk.VBox(False, 5)
+        self.pages["effects"] = page
+        page.set_border_width(5)
+        page.show()
+        self.append_page(page)
+        self.set_page_title(page,
+                           "Select the effect settings")
+        self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
+
+        table = gtk.Table(rows=6, columns=2, homogeneous=False)
+        table.show()
+
+        #nova
+        novatoggle = gtk.CheckButton("Enable nova effect")
+        novatoggle.set_active(self.data["nova"])
+        novatoggle.show()
+        table.attach(novatoggle, 1, 2, 0, 1)
+
+        #novacolor
+        label = gtk.Label("Nova color")
+        label.show()
+        novacolor = gimpui.ColorSelector()
+        if self.data["novacolor"]:
+            novacolor.set_pattern(self.data["novacolor"])
+        novacolor.connect("color-changed", self._cb_set_color, "novacolor",
+                          "effects")
+        novacolor.set_sensitive(self.data["nova"])
+        novacolor.show()
+        table.attach(label, 0, 1, 1, 2)
+        table.attach(novacolor, 1, 2, 1, 2)
+        
+        #novaradius
+        novaradius = IntEntry(max = 2)
+        if self.data["novaradius"] is not None:
+            novaradius.set_text(str(self.data["novaradius"]))
+        novaradius.connect("changed", self._cb_set_intvalue, "novaradius",
+                           "effects")
+        novaradius.set_sensitive(self.data["nova"])
+        novaradius.show()
+        table.attach(novaradius, 1, 2, 2, 3)
+
+        #novasparkles
+        novasparkles = IntEntry(max = 2)
+        if self.data["novasparkles"] is not None:
+            novasparkles.set_text(str(self.data["novasparkles"]))
+        novasparkles.connect("changed", self._cb_set_intvalue, "novasparkles",
+                             "effects")
+        novasparkles.set_sensitive(self.data["nova"])
+        novasparkles.show()
+        table.attach(novasparkles, 1, 2, 3, 4)
+        novatoggle.connect("toggled", self._cb_nova_toggle, novacolor,
+                           novaradius, novasparkles)
+        
+        #glow
+        #glowcolor        
+
+        page.pack_end(table)
+
+    def _addLastPage(self):
+        page = gtk.VBox(False, 5)
+        self.pages["output"] = page
+        page.set_border_width(5)
+        page.show()
+        self.append_page(page)
+        self.set_page_title(page,
+                           "Output formats")
+        self.set_page_type(page, gtk.ASSISTANT_PAGE_CONFIRM)
+
+        label = gtk.Label("Choose the output data.")
+        label.show()
+        page.pack_start(label)
+
+        #makejscript
+        toggle = gtk.CheckButton("Make HTML, CSS and JavaScript")
+        toggle.set_active(self.data["makejscript"])
+        toggle.connect("toggled", self._cb_toggle_simple, "makejscript",
+                       "output")
+        toggle.show()
+        page.pack_start(toggle)
+
+        #makeinactive
+        toggle = gtk.CheckButton("Make inactive buttons")
+        toggle.set_active(self.data["makeinactive"])
+        toggle.connect("toggled", self._cb_toggle_simple, "makeinactive",
+                       "output")
+        toggle.show()
+        page.pack_start(toggle)
+
+        #makeactive
+        toggle = gtk.CheckButton("Make active buttons")
+        toggle.set_active(self.data["makeactive"])
+        toggle.connect("toggled", self._cb_toggle_simple, "makeactive",
+                       "output")
+        toggle.show()
+        page.pack_start(toggle)
+
+        #makepressed
+        toggle = gtk.CheckButton("Make pressed buttons")
+        toggle.set_active(self.data["makepressed"])
+        toggle.connect("toggled", self._cb_toggle_simple, "makepressed",
+                       "output")
+        toggle.show()
+        page.pack_start(toggle)
+
+        #writexcf
+        toggle = gtk.CheckButton("Write the XCF file")
+        toggle.set_active(self.data["writexcf"])
+        toggle.connect("toggled", self._cb_toggle_simple, "writexcf",
+                       "output")
+        toggle.show()
+        page.pack_start(toggle)
+
+    def checkcompletion(self, pagename):
+        logging.debug(str(self.data))
+        criteriamatched = False
+        if pagename == "pathselection":
+            criteriamatched = self.data["filename"] and self.data["outdir"]
+        elif pagename == "basicsettings":
+            criteriamatched = self.data["font"] and self.data["strcolor"] \
+                and ((self.data["usepattern"] and self.data["pattern"]) or \
+                         (not self.data["usepattern"] and \
+                              self.data["buttoncolor"]))
+        elif pagename == "layout":
+            criteriamatched = self.data["roundradius"] is not None and \
+                self.data["bevelwidth"] is not None and \
+                (self.data["transparency"] or self.data["bgcolor"] is not None)
+        elif pagename == "output":
+            criteriamatched = self.data["makejscript"] is not None and \
+                self.data["makeinactive"] is not None and \
+                self.data["makeactive"] is not None and \
+                self.data["makepressed"] is not None
+        if criteriamatched:
+            self.set_page_complete(self.pages[pagename], True)
+        else:
+            self.set_page_complete(self.pages[pagename], False)
+
+    def _cb_set_intvalue(self, w, fieldname, pagename):
+        try:
+            self.data[fieldname] = int (w.get_text())
+        except ValueError:
+            pass
+        self.checkcompletion(pagename)
+
+    def _cb_toggle_simple(self, w, datafield, pagename):
+        self.data[datafield] = w.get_active()
+        self.checkcompletion(pagename)
+
+    def _cb_file_selected(self, w, filesel):
+        self.data["filename"] = w.get_filename()
+        self.checkcompletion("pathselection")
+
+    def _cb_dir_selected(self, w, dirsel):
+        self.data["outdir"] = w.get_filename()
+        self.checkcompletion("pathselection")
+
+    def _cb_set_font(self, w):
+        self.data["font"] = w.get_font_name()
+        self.checkcompletion("basicsettings")
+
+    def _cb_set_color(self, w, fieldname, pagename):
+        self.data[fieldname] = w.get_color()
+        self.checkcompletion(pagename)
+
+    def _cb_set_pattern(self, w, patternname, width, height, bpp, mask_data,
+                        finished):
+        if finished:
+            self.data["pattern"] = patternname
+        self.checkcompletion("basicsettings")
+
+    def _cb_bgtoggle_toggle(self, w, label, patterntext, patternsel,
+                            colortext, colorsel):
+        if w.get_active():
+            self.data["usepattern"] = True
+            colorsel.hide()
+            patternsel.show()
+            label.set_text(patterntext)
+        else:
+            self.data["usepattern"] = False
+            patternsel.hide()
+            colorsel.show()
+            label.set_text(colortext)
+        self.checkcompletion("basicsettings")
+
+    def _cb_nova_toggle(self, w, colorfield, radiusfield, sparksfield):
+        if w.get_active():
+            self.data["nova"] = True
+            colorfield.set_sensitive(True)
+            radiusfield.set_sensitive(True)
+            sparksfield.set_sensitive(True)
+        else:
+            self.data["nova"] = False
+            colorfield.set_sensitive(False)
+            radiusfield.set_sensitive(False)
+            sparksfield.set_sensitive(False)
+        self.checkcompletion("effects")
 
 class btn4wsplugin(gimpplugin.plugin):
     """This is the btn4ws gimp plugin."""
-    def parsefont(font):
-        """
-        Parses a font into its fontname and size parts.
-        """
-        parts = font.split(" ")
-        return (" ".join(parts[:-1]), parts[-1])
-
     def gimp2html_color(color):
         """
         Converts a color tuple to a hex encoded color for CSS.
@@ -300,8 +693,18 @@ class btn4wsplugin(gimpplugin.plugin):
                 False, False, False, False, True)
         gimp.delete(imgcopy)
 
+    def _cb_destroy(self, widget, data = None):
+        logging.debug("destroy")
+        gtk.main_quit()
+
+    def _cb_apply(self, widget):
+        self.data = widget.data
+
+    def __init__(self):
+        self.data = {}
+
     def btn4ws(self, runmode, filename = None, outdir = None, font = None,
-               strcolor = None, transparency = None, bgcolor = None,
+               strcolor = None, transparency = False, bgcolor = None,
                glow = False, glowcolor = None, usepattern = False,
                pattern = None, buttoncolor = None, roundradius = None,
                padding = None, glowsize = None, bevelwidth = None,
@@ -314,14 +717,28 @@ class btn4wsplugin(gimpplugin.plugin):
         """
         if runmode == RUN_INTERACTIVE:
             logging.debug("runmode interactive")
-            dialog = Btn4wsDialog(filename, outdir, font, strcolor,
-                                  transparency, bgcolor, glow, glowcolor,
-                                  usepattern, pattern, buttoncolor,
-                                  roundradius, padding, glowsize, bevelwidth,
-                                  nova, novasparkles, novaradius, novacolor,
-                                  writexcf, makeinactive, makeactive,
-                                  makepressed, makejscript)
-            dialog.main()
+            dialog = Btn4wsDialog(filename = filename, outdir = outdir,
+                                  font = font, strcolor = strcolor,
+                                  transparency = transparency,
+                                  bgcolor = bgcolor, glow = glow,
+                                  glowcolor = glowcolor,
+                                  usepattern = usepattern, pattern = pattern,
+                                  buttoncolor = buttoncolor,
+                                  roundradius = roundradius, padding = padding,
+                                  glowsize = glowsize, bevelwidth = bevelwidth,
+                                  nova = nova, novasparkles = novasparkles,
+                                  novaradius = novaradius,
+                                  novacolor = novacolor,
+                                  writexcf = writexcf,
+                                  makeinactive = makeinactive,
+                                  makeactive = makeactive,
+                                  makepressed = makepressed,
+                                  makejscript = makejscript)
+            dialog.connect("close", self._cb_destroy)
+            dialog.connect("cancel", self._cb_destroy)
+            dialog.connect("destroy", self._cb_destroy)
+            dialog.connect("apply", self._cb_apply)
+            gtk.main()
         elif runmode == RUN_NONINTERACTIVE:
             logging.debug("runmode noninteractive")
         elif runmode == RUN_WITH_LASTVALS:
diff --git a/gtktest.py b/gtktest.py
deleted file mode 100644
index 2cb31a1..0000000
--- a/gtktest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-class AssistantTest:
-    def delete_event(self, widget, event, data = None):
-        return False
-
-    def destroy(self, widget, data = None):
-        gtk.main_quit()
-
-    def __init__(self):
-        self.data = {
-            "filename" : None,
-            "outputdir" : None}
-        self.ass = gtk.Assistant()
-
-        self.ass.connect("delete_event", self.delete_event)
-        self.ass.connect("close", self.destroy)
-        self.ass.connect("cancel", self.destroy)
-
-        # Construct page 0
-        label = gtk.Label("""Buttons for website allows you to produce a series of buttons for use on a website. On the next pages you may choose several options to change the content and the look of the buttons.""")
-        label.set_line_wrap(True)
-        label.show()
-        self.ass.append_page(label)
-        self.ass.set_page_title(label, "Introduction to buttons for website")
-        self.ass.set_page_type(label, gtk.ASSISTANT_PAGE_INTRO)
-        self.ass.set_page_complete(label, True)
-
-        # Construct page 1
-        self.page1 = gtk.VBox(False, 5)
-        self.page1.set_border_width(5)
-        self.page1.show()
-        self.ass.append_page(self.page1)
-        self.ass.set_page_title(self.page1,
-                           "Select the input file and output directory")
-        self.ass.set_page_type(self.page1, gtk.ASSISTANT_PAGE_CONTENT)
-        
-        label = gtk.Label("Please choose the file containing your button labels and the directory where the generated files should be put.")
-        label.set_line_wrap(True)
-        label.show()
-        self.page1.pack_start(label, True, True, 0)
-
-        table = gtk.Table(rows=2, columns=2, homogeneous=False)
-        table.show()
-        label = gtk.Label("Button label file")
-        label.show()
-        table.attach(label, 0, 1, 0, 1)
-        button = gtk.FileChooserButton("Choose file")
-        button.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
-        button.connect("selection-changed", self.cb_file_selected, button)
-        button.show()
-        table.attach(button, 1, 2, 0, 1)
-
-        label = gtk.Label("Output directory")
-        label.show()    
-        table.attach(label, 0, 1, 1, 2)
-        button = gtk.FileChooserButton("Choose directory")
-        button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
-        button.connect("selection-changed", self.cb_dir_selected, button)
-        button.show()
-        table.attach(button, 1, 2, 1, 2)
-        
-        self.page1.pack_end(table)
-
-        # Construct page 2
-        label = gtk.Label('Thanks for using btn4ws')
-        label.set_line_wrap(True)
-        label.show()
-        self.ass.append_page(label)
-        self.ass.set_page_title(label, 'Page 1: The end')
-        self.ass.set_page_type(label, gtk.ASSISTANT_PAGE_SUMMARY)
-
-        self.ass.show()
-
-    def checkpage1completion(self):
-        print str(self.data)
-        if self.data["filename"] and self.data["outputdir"]:
-            self.ass.set_page_complete(self.page1, True)
-        else:
-            self.ass.set_page_complete(self.page1, False)
-
-    def cb_file_selected(self, w, filesel):
-        self.data["filename"] = filesel.get_filename()
-        self.checkpage1completion()
-
-    def cb_dir_selected(self, w, dirsel):
-        self.data["outputdir"] = dirsel.get_filename()
-        self.checkpage1completion()
-
-    def main(self):
-        gtk.main()
-
-if __name__ == "__main__":
-    assi = AssistantTest()
-    assi.main()