package tk

import (
	
	
	
)

// View model, calculated from State and used for rendering.
type view struct {
	prompt  ui.Text
	rprompt ui.Text
	code    ui.Text
	dot     int
	errors  []error
}

var stylingForPending = ui.Underlined

func ( *codeArea) *view {
	 := .CopyState()
	, ,  := patchPending(.Buffer, .Pending)
	,  := .Highlighter(.Content)
	if  <  {
		// Apply stylingForPending to [pFrom, pTo)
		 := .Partition(, )
		 := ui.StyleText([1], stylingForPending)
		 = ui.Concat([0], , [2])
	}

	var  ui.Text
	if !.HideRPrompt {
		 = .RPrompt()
	}

	return &view{.Prompt(), , , .Dot, }
}

func ( CodeBuffer,  PendingCode) (CodeBuffer, int, int) {
	if .From > .To || .From < 0 || .To > len(.Content) {
		// Invalid Pending.
		return , 0, 0
	}
	if .From == .To && .Content == "" {
		return , 0, 0
	}
	 := .Content[:.From] + .Content + .Content[.To:]
	 := 0
	switch {
	case .Dot < .From:
		// Dot is before the replaced region. Keep it.
		 = .Dot
	case .Dot >= .From && .Dot < .To:
		// Dot is within the replaced region. Place the dot at the end.
		 = .From + len(.Content)
	case .Dot >= .To:
		// Dot is after the replaced region. Maintain the relative position of
		// the dot.
		 = .Dot - (.To - .From) + len(.Content)
	}
	return CodeBuffer{Content: , Dot: }, .From, .From + len(.Content)
}

func ( *view,  *term.BufferBuilder) {
	.EagerWrap = true

	.WriteStyled(.prompt)
	if len(.Lines) == 1 && .Col*2 < .Width {
		.Indent = .Col
	}

	 := .code.Partition(.dot)
	.
		WriteStyled([0]).
		SetDotHere().
		WriteStyled([1])

	.EagerWrap = false
	.Indent = 0

	// Handle rprompts with newlines.
	if  := styledWcswidth(.rprompt);  > 0 {
		 := .Width - .Col - 
		if  >= 1 {
			.WriteSpaces()
			.WriteStyled(.rprompt)
		}
	}

	if len(.errors) > 0 {
		for ,  := range .errors {
			.Newline()
			.Write(.Error())
		}
	}
}

func ( *term.Buffer,  int) {
	switch {
	case len(.Lines) <= :
		// We can show all line; do nothing.
	case .Dot.Line < :
		// We can show all lines before the cursor, and as many lines after the
		// cursor as we can, adding up to maxHeight.
		.TrimToLines(0, )
	default:
		// We can show maxHeight lines before and including the cursor line.
		.TrimToLines(.Dot.Line-+1, .Dot.Line+1)
	}
}

func ( ui.Text) int {
	 := 0
	for ,  := range  {
		 += wcwidth.Of(.Text)
	}
	return 
}