package mode

import (
	

	
	
	
	
)

// Completion is a mode specialized for viewing and inserting completion
// candidates. It is based on the ComboBox widget.
type Completion interface {
	tk.ComboBox
}

// CompletionSpec specifies the configuration for the completion mode.
type CompletionSpec struct {
	Bindings tk.Bindings
	Name     string
	Replace  diag.Ranging
	Items    []CompletionItem
	Filter   FilterSpec
}

// CompletionItem represents a completion item, also known as a candidate.
type CompletionItem struct {
	// Used in the UI and for filtering.
	ToShow string
	// Style to use in the UI.
	ShowStyle ui.Style
	// Used when inserting a candidate.
	ToInsert string
}

type completion struct {
	tk.ComboBox
	attached tk.CodeArea
}

var errNoCandidates = errors.New("no candidates")

// NewCompletion starts the completion UI.
func ( cli.App,  CompletionSpec) (Completion, error) {
	if len(.Items) == 0 {
		return nil, errNoCandidates
	}
	 := tk.NewComboBox(tk.ComboBoxSpec{
		CodeArea: tk.CodeAreaSpec{
			Prompt:      modePrompt(" COMPLETING "+.Name+" ", true),
			Highlighter: .Filter.Highlighter,
		},
		ListBox: tk.ListBoxSpec{
			Horizontal: true,
			Bindings:   .Bindings,
			OnSelect: func( tk.Items,  int) {
				 := .(completionItems)[].ToInsert
				.CodeArea().MutateState(func( *tk.CodeAreaState) {
					.Pending = tk.PendingCode{
						From: .Replace.From, To: .Replace.To, Content: }
				})
			},
			OnAccept: func( tk.Items,  int) {
				.SetAddon(nil, true)
			},
			ExtendStyle: true,
		},
		OnFilter: func( tk.ComboBox,  string) {
			.ListBox().Reset(filterCompletionItems(.Items, .Filter.makePredicate()), 0)
		},
	})
	return completion{, .CodeArea()}, nil
}

func ( completion) ( bool) {
	.attached.MutateState(func( *tk.CodeAreaState) {
		if  {
			.ApplyPending()
		} else {
			.Pending = tk.PendingCode{}
		}
	})
}

type completionItems []CompletionItem

func ( []CompletionItem,  func(string) bool) completionItems {
	var  []CompletionItem
	for ,  := range  {
		if (.ToShow) {
			 = append(, )
		}
	}
	return 
}

func ( completionItems) ( int) ui.Text {
	return ui.Text{&ui.Segment{Style: [].ShowStyle, Text: [].ToShow}}
}

func ( completionItems) () int { return len() }