# Initial state of the entry
def init():
    entry.place = entry.previousPlace = None

    # This is a hint that says something like "Press ENTER to search",
    # "Press ENTER to search for %s" or "Press ENTER to see more results"
    entry.popup.hidePressEnterHint()
    entry.popup.mustShowPressEnterHint = False

# User starts the search
when entry.searchStarted():
    entry.previousPlace = entry.place

    # Initially, when there is no search and we focus on the entry, we
    # show the popup with some "Special places" like favourites, history,
    # friend's locations, current location, etc. Sorted and filtered by
    # relevance like a combination of MRU and MFU. We could also add some
    # special entries to show the whole favourites list or history
    entry.popup.show()

# Search cancelled, this includes focusing out the entry and the popup.
# This is not emitted when we call entry.finishSearch.
when entry.searchCancelled():
    entry.place = entry.previousPlace
    entry.contentModified = False

    # This hides the popup
    entry.finishSearch()

# User changes the content
when entry.changed():
    entry.contentModified = True
    entry.place = None

    # Filter favourites and history as we write, this should be instantaneous,
    # there is no need to use "search-changed" signal.
    entry.popup.filterSpecialPlaces()
    entry.popup.hideSearchResults()

    if entry.isEmpty:
        entry.popup.hidePressEnterHint()
        entry.popup.mustShowPressEnterHint = False
    else:
        entry.popup.showPressEnterHint()
        entry.popup.mustShowPressEnterHint = True

# User press ENTER when focusing the search entry
when entry.activated():
    if entry.isEmpty():
        return

    if entry.contentModified:
        if entry.popup.isSearchInProgress():
            return
        # The idea here is to have a feedback that we are searching but
        # I think there is no need to remove all the popup content for
        # that like we are doing now with the popup spinner, since we
        # can have history or favourites to show for the entry content.
        # We could use some a spinner in the entry or another animated
        # component in the popup.
        entry.popup.performSearch(entry.text)
        entry.popup.hidePressEnterHint()
        entry.popup.mustShowPressEnterHint = False
    else:
        # If user has not modified the content before she press ENTER
        # we just notify the place property so Maps can react to this
        # as we select the same place as before.
        entry.notify('place')

# When search query has finished
when entry.popup.searchFinished():
    # The search results will be shown together with the filtered
    # special places (if any), separated by some GUI component like a line.
    entry.popup.populateSearchResults()

# User gains keyboard focus on the popup (by pressing down arrow or TAB)
when entry.popup.focused():
    if entry.popup.isPressEnterHintVisible():
        entry.popup.hidePressEnterHint()

# User gains keyboard focus on the entry again
when entry.popup.focusedOut() and entry.focus():
    if entry.popup.mustShowPressEnterHint:
        entry.popup.showPressEnterHint()

# User activated a popup row
when entry.popup.activated():
    entry.place = entry.previousPlace = entry.popup.selectedPlace
    entry.contentModified = False

    # Cancel the current search query if any
    if entry.popup.isSearchInProgress():
        entry.popup.cancelSearch()

    entry.finishSearch()

# Handler for user key press
when entry.keyPress():
    if event.key == ESC:
        if entry.contentModified:
            entry.place = entry.previousPlace
            entry.contentModified = False
            entry.selectAll()
        else:
            entry.finishSearch()
    else:
        if not entry.popup.isVisible():
            entry.popup.show()

        if event.key == ARROW_DOWN:
            entry.popup.grabFocus()
