class AppExtras(CanvasVBox):
    __gsignals__ = {
        "more-info" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))
    }
    def __init__(self, filterfunc, **args):
        super(AppExtras, self).__init__(background_color=0xFFF9DDFF,
                                        color=0x3F3F3FFF,
                                        **args)

        self.__search = False
        self.__search_filter = filterfunc
        self.__catname = None
        self.__apps = None

        self.__have_search_hits = False        
        self.__found_app_count = 0

        self.__headerbox = CanvasHBox(padding=6)
        self.append(self.__headerbox)

        thing = self.__get_section_name()
        self.__left_title = hippo.CanvasText(text="New Popular %s" % (thing,),
                                             font="12px Bold",
                                             xalign=hippo.ALIGNMENT_START)
        self.__headerbox.append(self.__left_title)
        # TODO this won't underline properly until ActionLink->set_underline listens for text changes
        # underline=pango.UNDERLINE_LOW
        self.__right_title = ActionLink(font="12px",
                                        xalign=hippo.ALIGNMENT_END)
        self.__right_title.connect("activated", self.__on_more_popular)
        self.__headerbox.append(self.__right_title, hippo.PACK_EXPAND)

        self.__app_pair = CanvasHBox(box_height=120)
        self.__app_pair2 = CanvasHBox(box_height=120)
        self.append(self.__app_pair)
        self.append(self.__app_pair2)

        self.__repo = apps.get_apps_repo()

    def __get_section_name(self):
        return self.__catname or 'Apps'

    def have_apps(self):
        return not not self.__found_app_count

    def __on_search_results(self, applications, category, search_terms):
        _logger.debug("Got %d search results for category '%s' terms '%s'" % (len(applications), str(category), str(search_terms)))

        if search_terms != self.__search or category != self.__catname:
            _logger.debug("Search terms have changed since starting search, ignoring results")
            return

        if search_terms is not None:
            self.__have_search_hits = len(applications) > 0
        else:
            self.__have_search_hits = False

        self.__apps = applications
        
        self.__sync()

    def set_search_parameters(self, catname, search):
        if self.__catname != catname or self.__search != search:
            self.__catname = catname
            self.__search = search
            self.__repo.search(self.__catname, self.__search, self.__on_search_results)

    def __on_more_popular(self, w):
        subquery = (self.__search and ("?q=" + urllib.quote(self.__search))) \
                    or self.__catname and ("?category=" + urllib.quote(self.__catname)) \
                    or ''
        libbig.show_url(urlparse.urljoin(globals.get_baseurl(),
                                         "applications%s" % (subquery,)))
        # more-info with None just means hide window
        self.emit("more-info", None)

    def __sync(self):
        thing = self.__get_section_name()
        if self.__apps:
            if self.__search:
                if self.__have_search_hits:
                    self.__left_title.set_property('markup', "Searching for <b>%s</b>" % (gobject.markup_escape_text(self.__search),))

                else:
                    self.__left_title.set_property('markup', "No results for <b>%s</b>" % (gobject.markup_escape_text(self.__search),))
            else:
                self.__left_title.set_property('text', "New Popular %s" % (thing,))
            self.__right_title.set_property('text', u"More Popular %s" % (thing,))

        elif self.__apps is None:
            self.__left_title.set_property('text', '')
            self.__right_title.set_property("text", "Loading popular %s..." % (thing,))
        else:
            self.__left_title.set_property('text', '')
            self.__right_title.set_property("text", "No popular %s found" % (thing,))

        self.__app_pair.clear()
        self.__app_pair2.clear()
        self.set_child_visible(self.__app_pair, not not self.__apps)
        found = 0
        for i,app in enumerate(self.__apps or []):
            if app.is_installed():
                continue
            if self.__search_filter and (not self.__search_filter(app)):
                continue
            app_view = apps_widgets.AppDisplay(apps_widgets.AppLocation.APP_BROWSER, app, color=0x3F3F3FFF)
            app_view.connect("title-clicked", self.__on_app_clicked)
            app_view.set_description_mode(True)
            if found > 1:
                self.__app_pair2.append(app_view, hippo.PACK_EXPAND)
            else:
                self.__app_pair.append(app_view, hippo.PACK_EXPAND)
            found += 1
            if found > 3:
                break
        self.set_child_visible(self.__app_pair, found > 0)
        self.set_child_visible(self.__app_pair2, found > 2 and (not not self.__search))
        self.__found_app_count = found

    def __on_app_clicked(self, app_view):
        self.emit("more-info", app_view.get_app())