package mode

import (
	
	

	
	
	
	
)

// Histwalk is a mode for walking through history.
type Histwalk interface {
	tk.Widget
	// Walk to the previous entry in history.
	Prev() error
	// Walk to the next entry in history.
	Next() error
}

// HistwalkSpec specifies the configuration for the histwalk mode.
type HistwalkSpec struct {
	// Key bindings.
	Bindings tk.Bindings
	// History store to walk.
	Store histutil.Store
	// Only walk through items with this prefix.
	Prefix string
}

type histwalk struct {
	app    cli.App
	cursor histutil.Cursor
	HistwalkSpec
}

func ( *histwalk) (,  int) *term.Buffer {
	,  := .cursor.Get()
	 := modeLine(fmt.Sprintf(" HISTORY #%d ", .Seq), false)
	 := term.NewBufferBuilder().WriteStyled().Buffer()
	.TrimToLines(0, )
	return 
}

func ( *histwalk) ( term.Event) bool {
	 := .Bindings.Handle(, )
	if  {
		return true
	}
	.app.SetAddon(nil, true)
	return .app.CodeArea().Handle()
}

func ( *histwalk) () bool { return false }

var errNoHistoryStore = errors.New("no history store")

// NewHistwalk creates a new Histwalk mode.
func ( cli.App,  HistwalkSpec) (Histwalk, error) {
	if .Store == nil {
		return nil, errNoHistoryStore
	}
	if .Bindings == nil {
		.Bindings = tk.DummyBindings{}
	}
	 := .Store.Cursor(.Prefix)
	.Prev()
	,  := .Get()
	if  != nil {
		return nil, 
	}
	 := histwalk{app: , HistwalkSpec: , cursor: }
	.updatePending()
	return &, nil
}

func ( *histwalk) () error {
	return .walk(histutil.Cursor.Prev, histutil.Cursor.Next)
}

func ( *histwalk) () error {
	return .walk(histutil.Cursor.Next, histutil.Cursor.Prev)
}

func ( *histwalk) ( func(histutil.Cursor),  func(histutil.Cursor)) error {
	(.cursor)
	,  := .cursor.Get()
	if  == nil {
		.updatePending()
	} else if  == histutil.ErrEndOfHistory {
		(.cursor)
	}
	return 
}

func ( *histwalk) ( bool) {
	.app.CodeArea().MutateState(func( *tk.CodeAreaState) {
		if  {
			.ApplyPending()
		} else {
			.Pending = tk.PendingCode{}
		}
	})
}

func ( *histwalk) () {
	,  := .cursor.Get()
	.app.CodeArea().MutateState(func( *tk.CodeAreaState) {
		.Pending = tk.PendingCode{
			From: len(.Prefix), To: len(.Buffer.Content),
			Content: .Text[len(.Prefix):],
		}
	})
}