// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package text

// TODO: do we care about "\n" vs "\r" vs "\r\n"? We only recognize "\n" for
// now.

import (
	"bytes"
	"errors"
	"io"
	"strings"
	"unicode/utf8"

	"golang.org/x/image/math/fixed"
)

// Caret is a location in a Frame's text, and is the mechanism for adding and
// removing bytes of text. Conceptually, a Caret and a Frame's text is like an
// int c and a []byte t such that the text before and after that Caret is t[:c]
// and t[c:]. That byte-count location remains unchanged even when a Frame is
// re-sized and laid out into a new tree of Paragraphs, Lines and Boxes.
//
// A Frame can have multiple open Carets. For example, the beginning and end of
// a text selection can be represented by two Carets. Multiple Carets for the
// one Frame are not safe to use concurrently, but it is valid to interleave
// such operations sequentially. For example, if two Carets c0 and c1 for the
// one Frame are positioned at the 10th and 20th byte, and 4 bytes are written
// to c0, inserting what becomes the equivalent of text[10:14], then c0's
// position is updated to be 14 but c1's position is also updated to be 24.
type Caret struct {
	f *Frame

	// caretsIndex is the index of this Caret in the f.carets slice.
	caretsIndex int

	// seqNum is the Frame f's sequence number for which this Caret's cached p,
	// l, b and k fields are valid. If f has been modified since then, those
	// fields will have to be re-calculated based on the pos field (which is
	// always valid).
	//
	// TODO: when re-calculating p, l, b and k, be more efficient than a linear
	// scan from the start or end?
	seqNum uint64

	// p, l and b cache the index of the Caret's Paragraph, Line and Box. None
	// of these values can be zero.
	p, l, b int32

	// k caches the Caret's position in the text, in Frame.text order. It is
	// valid to index the Frame.text slice with k, analogous to the Box.i and
	// Box.j fields. For a Caret c, letting bb := c.f.boxes[c.b], an invariant
	// is that bb.i <= c.k && c.k <= bb.j if the cache is valid (i.e. the
	// Caret's seqNum equals the Frame's seqNum).
	k int32

	// pos is the Caret's position in the text, in layout order. It is the "c"
	// as in "t[:c]" in the doc comment for type Caret above. It is not valid
	// to index the Frame.text slice with pos, since the Frame.text slice does
	// not necessarily hold the textual content in layout order.
	pos int32

	tmp [utf8.UTFMax]byte
}

// Close closes the Caret.
func (c *Caret) Close() error {
	i, j := c.caretsIndex, len(c.f.carets)-1

	// Swap c with the last element of c.f.carets.
	if i != j {
		other := c.f.carets[j]
		other.caretsIndex = i
		c.f.carets[i] = other
	}

	c.f.carets[j] = nil
	c.f.carets = c.f.carets[:j]
	*c = Caret{}
	return nil
}

type leanResult int

const (
	// leanOK means that the lean changed the Caret's Box.
	leanOK leanResult = iota
	// leanFailedEOF means that the lean did not change the Caret's Box,
	// because the Caret was already at the end / beginning of the Frame (when
	// leaning forwards / backwards).
	leanFailedEOF
	// leanFailedNotEOB means that the lean did not change the Caret's Box,
	// because the Caret was not placed at the end / beginning of the Box (when
	// leaning forwards / backwards).
	leanFailedNotEOB
)

// leanForwards moves the Caret from the right end of one Box to the left end
// of the next Box, crossing Lines and Paragraphs to find that next Box. It
// returns whether the Caret moved to a different Box.
//
// Diagramatically, suppose we have two adjacent boxes (shown by square
// brackets below), with the Caret (an integer location called Caret.pos in the
// Frame's text) in the middle of the "foo2bar3" word:
//	[foo0 foo1 foo2]^[bar3 bar4 bar5]
// leanForwards moves Caret.k from fooBox.j to barBox.i, also updating the
// Caret's p, l and b. Caret.pos remains unchanged.
func (c *Caret) leanForwards() leanResult {
	if c.k != c.f.boxes[c.b].j {
		return leanFailedNotEOB
	}
	if nextB := c.f.boxes[c.b].next; nextB != 0 {
		c.b = nextB
		c.k = c.f.boxes[c.b].i
		return leanOK
	}
	if nextL := c.f.lines[c.l].next; nextL != 0 {
		c.l = nextL
		c.b = c.f.lines[c.l].firstB
		c.k = c.f.boxes[c.b].i
		return leanOK
	}
	if nextP := c.f.paragraphs[c.p].next; nextP != 0 {
		c.p = nextP
		c.l = c.f.paragraphs[c.p].firstL
		c.b = c.f.lines[c.l].firstB
		c.k = c.f.boxes[c.b].i
		return leanOK
	}
	return leanFailedEOF
}

// leanBackwards is like leanForwards but in the other direction.
func (c *Caret) leanBackwards() leanResult {
	if c.k != c.f.boxes[c.b].i {
		return leanFailedNotEOB
	}
	if prevB := c.f.boxes[c.b].prev; prevB != 0 {
		c.b = prevB
		c.k = c.f.boxes[c.b].j
		return leanOK
	}
	if prevL := c.f.lines[c.l].prev; prevL != 0 {
		c.l = prevL
		c.b = c.f.lines[c.l].lastBox(c.f)
		c.k = c.f.boxes[c.b].j
		return leanOK
	}
	if prevP := c.f.paragraphs[c.p].prev; prevP != 0 {
		c.p = prevP
		c.l = c.f.paragraphs[c.p].lastLine(c.f)
		c.b = c.f.lines[c.l].lastBox(c.f)
		c.k = c.f.boxes[c.b].j
		return leanOK
	}
	return leanFailedEOF
}

func (c *Caret) seekStart() {
	c.p = c.f.firstP
	c.l = c.f.paragraphs[c.p].firstL
	c.b = c.f.lines[c.l].firstB
	c.k = c.f.boxes[c.b].i
	c.pos = 0
}

func (c *Caret) seekEnd() {
	c.p = c.f.lastParagraph()
	c.l = c.f.paragraphs[c.p].lastLine(c.f)
	c.b = c.f.lines[c.l].lastBox(c.f)
	c.k = c.f.boxes[c.b].j
	c.pos = int32(c.f.len)
}

// calculatePLBK ensures that the Caret's cached p, l, b and k fields are
// valid.
func (c *Caret) calculatePLBK() {
	if c.seqNum != c.f.seqNum {
		c.seek(c.pos)
	}
}

// Seek satisfies the io.Seeker interface.
func (c *Caret) Seek(offset int64, whence int) (int64, error) {
	switch whence {
	case SeekSet:
		// No-op.
	case SeekCur:
		offset += int64(c.pos)
	case SeekEnd:
		offset += int64(c.f.len)
	default:
		return 0, errors.New("text: invalid seek whence")
	}
	if offset < 0 {
		return 0, errors.New("text: negative seek position")
	}
	if offset > int64(c.f.len) {
		offset = int64(c.f.len)
	}
	c.seek(int32(offset))
	return offset, nil
}

func (c *Caret) seek(off int32) {
	delta := off - c.pos
	// If the new offset is closer to the start or the end than to the current
	// c.pos, or if c's cached {p,l,b,k} values are invalid, move to the start
	// or end first. In case of a tie, we prefer to seek forwards (i.e. set
	// delta > 0).
	if (delta < 0 && -delta >= off) || (c.seqNum != c.f.seqNum) {
		c.seekStart()
		delta = off - c.pos
	}
	if delta > 0 && delta > int32(c.f.len)-off {
		c.seekEnd()
		delta = off - c.pos
	}

	if delta != 0 {
		// Seek forwards.
		for delta > 0 {
			if n := c.f.boxes[c.b].j - c.k; n > 0 {
				if n > delta {
					n = delta
				}
				c.pos += n
				c.k += n
				delta -= n
			} else if c.leanForwards() != leanOK {
				panic("text: invalid state")
			}
		}

		// Seek backwards.
		for delta < 0 {
			if n := c.f.boxes[c.b].i - c.k; n < 0 {
				if n < delta {
					n = delta
				}
				c.pos += n
				c.k += n
				delta -= n
			} else if c.leanBackwards() != leanOK {
				panic("text: invalid state")
			}
		}

		// A Caret can't be placed at the end of a Paragraph, unless it is the
		// final Paragraph. A simple way to enforce this is to lean forwards.
		c.leanForwards()
	}

	c.seqNum = c.f.seqNum
}

// Read satisfies the io.Reader interface by copying those bytes after the
// Caret and incrementing the Caret.
func (c *Caret) Read(buf []byte) (n int, err error) {
	c.calculatePLBK()
	for len(buf) > 0 {
		if j := c.f.boxes[c.b].j; c.k < j {
			nn := copy(buf, c.f.text[c.k:j])
			buf = buf[nn:]
			n += nn
			c.pos += int32(nn)
			c.k += int32(nn)
		}
		// A Caret can't be placed at the end of a Paragraph, unless it is the
		// final Paragraph. A simple way to enforce this is to lean forwards.
		if c.leanForwards() == leanFailedEOF {
			break
		}
	}
	if int(c.pos) == c.f.len {
		err = io.EOF
	}
	return n, err
}

// ReadByte returns the next byte after the Caret and increments the Caret.
func (c *Caret) ReadByte() (x byte, err error) {
	c.calculatePLBK()
	for {
		if j := c.f.boxes[c.b].j; c.k < j {
			x = c.f.text[c.k]
			c.pos++
			c.k++
			// A Caret can't be placed at the end of a Paragraph, unless it is
			// the final Paragraph. A simple way to enforce this is to lean
			// forwards.
			c.leanForwards()
			return x, nil
		}
		if c.leanForwards() == leanFailedEOF {
			return 0, io.EOF
		}
	}
}

// ReadRune returns the next rune after the Caret and increments the Caret.
func (c *Caret) ReadRune() (r rune, size int, err error) {
	c.calculatePLBK()
	for {
		if c.k < c.f.boxes[c.b].j {
			r, size, c.b, c.k = c.f.readRune(c.b, c.k)
			c.pos += int32(size)
			// A Caret can't be placed at the end of a Paragraph, unless it is
			// the final Paragraph. A simple way to enforce this is to lean
			// forwards.
			c.leanForwards()
			return r, size, nil
		}
		if c.leanForwards() == leanFailedEOF {
			return 0, 0, io.EOF
		}
	}
}

// WriteByte inserts x into the Frame's text at the Caret and increments the
// Caret.
func (c *Caret) WriteByte(x byte) error {
	c.tmp[0] = x
	return c.write(c.tmp[:1], "")
}

// WriteRune inserts r into the Frame's text at the Caret and increments the
// Caret.
func (c *Caret) WriteRune(r rune) (size int, err error) {
	size = utf8.EncodeRune(c.tmp[:], r)
	if err = c.write(c.tmp[:size], ""); err != nil {
		return 0, err
	}
	return size, nil
}

// WriteString inserts s into the Frame's text at the Caret and increments the
// Caret.
func (c *Caret) WriteString(s string) (n int, err error) {
	for len(s) > 0 {
		i := 1 + strings.IndexByte(s, '\n')
		if i == 0 {
			i = len(s)
		}
		if err = c.write(nil, s[:i]); err != nil {
			break
		}
		n += i
		s = s[i:]
	}
	return n, err
}

// Write inserts s into the Frame's text at the Caret and increments the Caret.
func (c *Caret) Write(s []byte) (n int, err error) {
	for len(s) > 0 {
		i := 1 + bytes.IndexByte(s, '\n')
		if i == 0 {
			i = len(s)
		}
		if err = c.write(s[:i], ""); err != nil {
			break
		}
		n += i
		s = s[i:]
	}
	return n, err
}

// write inserts a []byte or string into the Frame's text at the Caret.
//
// Exactly one of s0 and s1 must be non-empty. That non-empty argument must
// contain at most one '\n' and if it does contain one, it must be the final
// byte.
func (c *Caret) write(s0 []byte, s1 string) error {
	if m := maxLen - len(c.f.text); len(s0) > m || len(s1) > m {
		return errors.New("text: insufficient space for writing")
	}

	// Ensure that the Caret is at the end of its Box, and that Box's text is
	// at the end of the Frame's buffer.
	c.calculatePLBK()
	for {
		bb, n := &c.f.boxes[c.b], int32(len(c.f.text))
		if c.k == bb.j && c.k == n {
			break
		}

		// If the Box's text is empty, move its empty i:j range to the
		// equivalent empty range at the end of c.f.text.
		if bb.i == bb.j {
			bb.i = n
			bb.j = n
			for _, cc := range c.f.carets {
				if cc.b == c.b {
					cc.k = n
				}
			}
			continue
		}

		// Make the Caret be at the end of its Box.
		if c.k != bb.j {
			c.splitBox(true)
			continue
		}

		// Make a new empty Box and move the Caret to it.
		c.splitBox(true)
		c.leanForwards()
	}

	length, nl := len(s0), false
	if length > 0 {
		nl = s0[length-1] == '\n'
		c.f.text = append(c.f.text, s0...)
	} else {
		length = len(s1)
		nl = s1[length-1] == '\n'
		c.f.text = append(c.f.text, s1...)
	}
	c.f.len += length
	c.f.boxes[c.b].j += int32(length)
	c.k += int32(length)
	for _, cc := range c.f.carets {
		if cc.pos > c.pos {
			cc.pos += int32(length)
		}
	}
	c.pos += int32(length)
	oldL := c.l

	if nl {
		breakParagraph(c.f, c.p, c.l, c.b)
		c.p = c.f.paragraphs[c.p].next
		c.l = c.f.paragraphs[c.p].firstL
		c.b = c.f.lines[c.l].firstB
		c.k = c.f.boxes[c.b].i
	}

	// TODO: re-layout the new c.p paragraph, if we saw '\n'.
	layout(c.f, oldL)

	c.f.seqNum++
	return nil
}

// breakParagraph breaks the Paragraph p into two Paragraphs, just after Box b
// in Line l in Paragraph p. b's text must end with a '\n'. The new Paragraph
// is inserted after p.
func breakParagraph(f *Frame, p, l, b int32) {
	// Assert that the Box b's text ends with a '\n'.
	if j := f.boxes[b].j; j == 0 || f.text[j-1] != '\n' {
		panic("text: invalid state")
	}

	// Make a new, empty Paragraph after this Paragraph p.
	newP, _ := f.newParagraph()
	nextP := f.paragraphs[p].next
	if nextP != 0 {
		f.paragraphs[nextP].prev = newP
	}
	f.paragraphs[newP].next = nextP
	f.paragraphs[newP].prev = p
	f.paragraphs[p].next = newP

	// Any Lines in this Paragraph after the break point's Line l move to the
	// newP Paragraph.
	if nextL := f.lines[l].next; nextL != 0 {
		f.lines[l].next = 0
		f.lines[nextL].prev = 0
		f.paragraphs[newP].firstL = nextL
	}

	// Any Boxes in this Line after the break point's Box b move to a new Line
	// at the start of the newP Paragraph.
	if nextB := f.boxes[b].next; nextB != 0 {
		f.boxes[b].next = 0
		f.boxes[nextB].prev = 0
		newL, _ := f.newLine()
		f.lines[newL].firstB = nextB
		if newPFirstL := f.paragraphs[newP].firstL; newPFirstL != 0 {
			f.lines[newL].next = newPFirstL
			f.lines[newPFirstL].prev = newL
		}
		f.paragraphs[newP].firstL = newL
	}

	// Make the newP Paragraph's first Line and first Box explicit, since
	// Carets require an explicit p, l and b.
	{
		pp := &f.paragraphs[newP]
		if pp.firstL == 0 {
			pp.firstL, _ = f.newLine()
		}
		ll := &f.lines[pp.firstL]
		if ll.firstB == 0 {
			ll.firstB, _ = f.newBox()
		}
	}

	// TODO: re-layout the newP paragraph.
}

// breakLine breaks the Line l at text index k in Box b. The b-and-k index must
// not be at the start or end of the Line. Text to the right of b-and-k in the
// Line l will be moved to the start of the next Line in the Paragraph, with
// that next Line being created if it didn't already exist.
func breakLine(f *Frame, l, b, k int32) {
	// Split this Box into two if necessary, so that k equals a Box's j end.
	bb := &f.boxes[b]
	if k != bb.j {
		if k == bb.i {
			panic("TODO: degenerate split left, possibly adjusting the Line's firstB??")
		}
		newB, realloc := f.newBox()
		if realloc {
			bb = &f.boxes[b]
		}
		nextB := bb.next
		if nextB != 0 {
			f.boxes[nextB].prev = newB
		}
		f.boxes[newB].next = nextB
		f.boxes[newB].prev = b
		f.boxes[newB].i = k
		f.boxes[newB].j = bb.j
		bb.next = newB
		bb.j = k
	}

	// Assert that the break point isn't already at the start or end of the Line.
	if bb.next == 0 || (bb.prev == 0 && k == bb.i) {
		panic("text: invalid state")
	}

	// Insert a line after this one, if one doesn't already exist.
	ll := &f.lines[l]
	if ll.next == 0 {
		newL, realloc := f.newLine()
		if realloc {
			ll = &f.lines[l]
		}
		f.lines[newL].prev = l
		ll.next = newL
	}

	// Move the remaining boxes to the next line.
	nextB, nextL := bb.next, ll.next
	bb.next = 0
	f.boxes[nextB].prev = 0
	fb := f.lines[nextL].firstB
	f.lines[nextL].firstB = nextB

	// If the next Line already contained Boxes, append them to the end of the
	// nextB chain, and join the two newly linked Boxes if possible.
	if fb != 0 {
		lb := f.lines[nextL].lastBox(f)
		lbb := &f.boxes[lb]
		fbb := &f.boxes[fb]
		lbb.next = fb
		fbb.prev = lb
		f.joinBoxes(lb, fb, lbb, fbb)
	}
}

// layout inserts a soft return in the Line l if its text measures longer than
// f.maxWidth and a suitable line break point is found. This may spill text
// onto the next line, which will also be laid out, and so on recursively.
func layout(f *Frame, l int32) {
	if f.maxWidth <= 0 || f.face == nil {
		return
	}
	f.seqNum++

	for ; l != 0; l = f.lines[l].next {
		var (
			firstB     = f.lines[l].firstB
			reader     = f.lineReader(firstB, f.boxes[firstB].i)
			breakPoint bAndK
			prevR      rune
			prevRValid bool
			advance    fixed.Int26_6
		)
		for {
			r, _, err := reader.ReadRune()
			if err != nil || r == '\n' {
				return
			}
			if prevRValid {
				advance += f.face.Kern(prevR, r)
			}
			// TODO: match all whitespace, not just ' '?
			if r == ' ' {
				breakPoint = reader.bAndK()
			}
			a, ok := f.face.GlyphAdvance(r)
			if !ok {
				panic("TODO: is falling back on the U+FFFD glyph the responsibility of the caller or the Face?")
			}
			advance += a
			if r != ' ' && advance > f.maxWidth && breakPoint.b != 0 {
				breakLine(f, l, breakPoint.b, breakPoint.k)
				break
			}
			prevR, prevRValid = r, true
		}
	}
}

// Delete deletes nBytes bytes in the specified direction from the Caret's
// location. It returns the number of bytes deleted, which can be fewer than
// that requested if it hits the beginning or end of the Frame.
func (c *Caret) Delete(dir Direction, nBytes int) (dBytes int) {
	if nBytes <= 0 {
		return 0
	}

	// Convert a backwards delete of n bytes from position p to a forwards
	// delete of n bytes from position p-n.
	//
	// In general, it's easier to delete forwards than backwards. For example,
	// when crossing paragraph boundaries, it's easier to find the first line
	// of the next paragraph than the last line of the previous paragraph.
	if dir == Backwards {
		newPos := int(c.pos) - nBytes
		if newPos < 0 {
			newPos = 0
			nBytes = int(c.pos)
			if nBytes == 0 {
				return 0
			}
		}
		c.seek(int32(newPos))
	}

	if int(c.pos) == c.f.len {
		return 0
	}

	c.calculatePLBK()
	c.leanForwards()
	if c.f.boxes[c.b].i != c.k && c.splitBox(false) {
		c.leanForwards()
	}
	for nBytes > 0 && int(c.pos) != c.f.len {
		bb := &c.f.boxes[c.b]
		n := bb.j - bb.i
		newLine := n != 0 && c.f.text[bb.j-1] == '\n'
		if int(n) > nBytes {
			n = int32(nBytes)
		}
		bb.i += n
		c.k += n
		dBytes += int(n)
		nBytes -= int(n)
		c.f.len -= int(n)

		if bb.i != bb.j {
			break
		}

		if newLine {
			c.joinNextParagraph()
		}
		c.leanForwards()
	}

	// The mergeIntoOneLine will shake out any empty Boxes.
	l := c.f.mergeIntoOneLine(c.p)
	layout(c.f, l)

	// Compact c.f.text if it's large enough and the fraction of deleted text
	// is above some threshold. The actual threshold value (25%) is arbitrary.
	// A lower value means more frequent compactions, so less memory on average
	// but more CPU. A higher value means the opposite.
	if len(c.f.text) > 4096 && len(c.f.text)/4 < c.f.deletedLen() {
		c.f.compactText()
	}

	c.f.seqNum++
	for _, cc := range c.f.carets {
		if cc == c {
			continue
		}
		switch relPos := cc.pos - c.pos; {
		case relPos <= 0:
			// No-op.
		case relPos <= int32(dBytes):
			cc.pos = c.pos
		default:
			cc.pos -= int32(dBytes)
		}
	}
	return dBytes
}

// DeleteRunes deletes nRunes runes in the specified direction from the Caret's
// location. It returns the number of runes and bytes deleted, which can be
// fewer than that requested if it hits the beginning or end of the Frame.
func (c *Caret) DeleteRunes(dir Direction, nRunes int) (dRunes, dBytes int) {
	// Save the current Caret position, move the Caret by nRunes runes to
	// calculate how many bytes to delete, restore that saved Caret position,
	// then delete that many bytes.
	c.calculatePLBK()
	savedC := *c
	if dir == Forwards {
		for dRunes < nRunes {
			var size int
			_, size, c.b, c.k = c.f.readRune(c.b, c.k)
			if size != 0 {
				dRunes++
				dBytes += size
			} else if c.leanForwards() != leanOK {
				break
			}
		}
	} else {
		for dRunes < nRunes {
			var size int
			_, size, c.b, c.k = c.f.readLastRune(c.b, c.k)
			if size != 0 {
				dRunes++
				dBytes += size
			} else if c.leanBackwards() != leanOK {
				break
			}
		}
	}
	*c = savedC
	if dBytes != c.Delete(dir, dBytes) {
		panic("text: invalid state")
	}
	return dRunes, dBytes
}

// joinNextParagraph joins c's current and next Paragraph. That next Paragraph
// must exist, and c must be at the last Line of its current Paragraph.
func (c *Caret) joinNextParagraph() {
	pp0 := &c.f.paragraphs[c.p]
	ll0 := &c.f.lines[c.l]
	if pp0.next == 0 || ll0.next != 0 {
		panic("text: invalid state")
	}
	pp1 := &c.f.paragraphs[pp0.next]
	l1 := pp1.firstL

	ll0.next = l1
	c.f.lines[l1].prev = c.l

	toFree := pp0.next
	pp0.next = pp1.next
	if pp0.next != 0 {
		c.f.paragraphs[pp0.next].prev = c.p
	}

	c.f.freeParagraph(toFree)
}

// splitBox splits the Caret's Box into two, at the Caret's location. Unless
// force is set, it does nothing if the Caret is at either edge of its Box. It
// returns whether the Box was split. If so, the new Box is created after, not
// before, the Caret's current Box.
func (c *Caret) splitBox(force bool) bool {
	bb := &c.f.boxes[c.b]
	if !force && (c.k == bb.i || c.k == bb.j) {
		return false
	}
	newB, realloc := c.f.newBox()
	if realloc {
		bb = &c.f.boxes[c.b]
	}
	nextB := bb.next
	if nextB != 0 {
		c.f.boxes[nextB].prev = newB
	}
	c.f.boxes[newB] = Box{
		next: nextB,
		prev: c.b,
		i:    c.k,
		j:    bb.j,
	}
	bb.next = newB
	bb.j = c.k
	return true
}
