package mode

import (
	

	
	
	
)

// Listing is a customizable mode for browsing through a list of items. It is
// based on the ComboBox widget.
type Listing interface {
	tk.ComboBox
}

// ListingSpec specifies the configuration for the listing mode.
type ListingSpec struct {
	// Key bindings.
	Bindings tk.Bindings
	// Caption of the listing. If empty, defaults to " LISTING ".
	Caption string
	// A function that takes the query string and returns a list of Item's and
	// the index of the Item to select. Required.
	GetItems func(query string) (items []ListingItem, selected int)
	// A function to call when the user has accepted the selected item. If the
	// return value is true, the listing will not be closed after accpeting.
	// If unspecified, the Accept function default to a function that does
	// nothing other than returning false.
	Accept func(string) bool
	// Whether to automatically accept when there is only one item.
	AutoAccept bool
}

// ListingItem is an item to show in the listing.
type ListingItem struct {
	// Passed to the Accept callback in Config.
	ToAccept string
	// How the item is shown.
	ToShow ui.Text
}

var errGetItemsMustBeSpecified = errors.New("GetItems must be specified")

// NewListing creates a new listing mode.
func ( cli.App,  ListingSpec) (Listing, error) {
	if .GetItems == nil {
		return nil, errGetItemsMustBeSpecified
	}
	if .Accept == nil {
		.Accept = func(string) bool { return false }
	}
	if .Caption == "" {
		.Caption = " LISTING "
	}
	 := func( string) {
		 := .Accept()
		if ! {
			.SetAddon(nil, false)
		}
	}
	 := tk.NewComboBox(tk.ComboBoxSpec{
		CodeArea: tk.CodeAreaSpec{
			Prompt: modePrompt(.Caption, true),
		},
		ListBox: tk.ListBoxSpec{
			Bindings: .Bindings,
			OnAccept: func( tk.Items,  int) {
				(.(listingItems)[].ToAccept)
			},
			ExtendStyle: true,
		},
		OnFilter: func( tk.ComboBox,  string) {
			,  := .GetItems()
			.ListBox().Reset(listingItems(), )
			if .AutoAccept && len() == 1 {
				([0].ToAccept)
			}
		},
	})
	return , nil
}

type listingItems []ListingItem

func ( listingItems) () int           { return len() }
func ( listingItems) ( int) ui.Text { return [].ToShow }