// Copyright 2015 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.

//go:generate stringer -type=Kind
//go:generate go run gen.go gen_common.go gen_trieval.go

// Package width provides functionality for handling different widths in text.
//
// Wide characters behave like ideographs; they tend to allow line breaks after
// each character and remain upright in vertical text layout. Narrow characters
// are kept together in words or runs that are rotated sideways in vertical text
// layout.
//
// For more information, see http://unicode.org/reports/tr11/.
package width // import "golang.org/x/text/width"

import (
	"unicode/utf8"

	"golang.org/x/text/transform"
)

// TODO
// 1) Reduce table size by compressing blocks.
// 2) API proposition for computing display length
//    (approximation, fixed pitch only).
// 3) Implement display length.

// Kind indicates the type of width property as defined in http://unicode.org/reports/tr11/.
type Kind int

const (
	// Neutral characters do not occur in legacy East Asian character sets.
	Neutral Kind = iota

	// EastAsianAmbiguous characters that can be sometimes wide and sometimes
	// narrow and require additional information not contained in the character
	// code to further resolve their width.
	EastAsianAmbiguous

	// EastAsianWide characters are wide in its usual form. They occur only in
	// the context of East Asian typography. These runes may have explicit
	// halfwidth counterparts.
	EastAsianWide

	// EastAsianNarrow characters are narrow in its usual form. They often have
	// fullwidth counterparts.
	EastAsianNarrow

	// Note: there exist Narrow runes that do not have fullwidth or wide
	// counterparts, despite what the definition says (e.g. U+27E6).

	// EastAsianFullwidth characters have a compatibility decompositions of type
	// wide that map to a narrow counterpart.
	EastAsianFullwidth

	// EastAsianHalfwidth characters have a compatibility decomposition of type
	// narrow that map to a wide or ambiguous counterpart, plus U+20A9 ₩ WON
	// SIGN.
	EastAsianHalfwidth

	// Note: there exist runes that have a halfwidth counterparts but that are
	// classified as Ambiguous, rather than wide (e.g. U+2190).
)

// TODO: the generated tries need to return size 1 for invalid runes for the
// width to be computed correctly (each byte should render width 1)

var trie = newWidthTrie(0)

// Lookup reports the Properties of the first rune in b and the number of bytes
// of its UTF-8 encoding.
func Lookup(b []byte) (p Properties, size int) {
	v, sz := trie.lookup(b)
	return Properties{elem(v), b[sz-1]}, sz
}

// LookupString reports the Properties of the first rune in s and the number of
// bytes of its UTF-8 encoding.
func LookupString(s string) (p Properties, size int) {
	v, sz := trie.lookupString(s)
	return Properties{elem(v), s[sz-1]}, sz
}

// LookupRune reports the Properties of rune r.
func LookupRune(r rune) Properties {
	var buf [4]byte
	n := utf8.EncodeRune(buf[:], r)
	v, _ := trie.lookup(buf[:n])
	last := byte(r)
	if r >= utf8.RuneSelf {
		last = 0x80 + byte(r&0x3f)
	}
	return Properties{elem(v), last}
}

// Properties provides access to width properties of a rune.
type Properties struct {
	elem elem
	last byte
}

func (e elem) kind() Kind {
	return Kind(e >> typeShift)
}

// Kind returns the Kind of a rune as defined in Unicode TR #11.
// See http://unicode.org/reports/tr11/ for more details.
func (p Properties) Kind() Kind {
	return p.elem.kind()
}

// Folded returns the folded variant of a rune or 0 if the rune is canonical.
func (p Properties) Folded() rune {
	if p.elem&tagNeedsFold != 0 {
		buf := inverseData[byte(p.elem)]
		buf[buf[0]] ^= p.last
		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
		return r
	}
	return 0
}

// Narrow returns the narrow variant of a rune or 0 if the rune is already
// narrow or doesn't have a narrow variant.
func (p Properties) Narrow() rune {
	if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianFullwidth || k == EastAsianWide || k == EastAsianAmbiguous) {
		buf := inverseData[byte(p.elem)]
		buf[buf[0]] ^= p.last
		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
		return r
	}
	return 0
}

// Wide returns the wide variant of a rune or 0 if the rune is already
// wide or doesn't have a wide variant.
func (p Properties) Wide() rune {
	if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianHalfwidth || k == EastAsianNarrow) {
		buf := inverseData[byte(p.elem)]
		buf[buf[0]] ^= p.last
		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
		return r
	}
	return 0
}

// TODO for Properties:
// - Add Fullwidth/Halfwidth or Inverted methods for computing variants
// mapping.
// - Add width information (including information on non-spacing runes).

// Transformer implements the transform.Transformer interface.
type Transformer struct {
	t transform.SpanningTransformer
}

// Reset implements the transform.Transformer interface.
func (t Transformer) Reset() { t.t.Reset() }

// Transform implements the transform.Transformer interface.
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	return t.t.Transform(dst, src, atEOF)
}

// Span implements the transform.SpanningTransformer interface.
func (t Transformer) Span(src []byte, atEOF bool) (n int, err error) {
	return t.t.Span(src, atEOF)
}

// Bytes returns a new byte slice with the result of applying t to b.
func (t Transformer) Bytes(b []byte) []byte {
	b, _, _ = transform.Bytes(t, b)
	return b
}

// String returns a string with the result of applying t to s.
func (t Transformer) String(s string) string {
	s, _, _ = transform.String(t, s)
	return s
}

var (
	// Fold is a transform that maps all runes to their canonical width.
	//
	// Note that the NFKC and NFKD transforms in golang.org/x/text/unicode/norm
	// provide a more generic folding mechanism.
	Fold Transformer = Transformer{foldTransform{}}

	// Widen is a transform that maps runes to their wide variant, if
	// available.
	Widen Transformer = Transformer{wideTransform{}}

	// Narrow is a transform that maps runes to their narrow variant, if
	// available.
	Narrow Transformer = Transformer{narrowTransform{}}
)

// TODO: Consider the following options:
// - Treat Ambiguous runes that have a halfwidth counterpart as wide, or some
//   generalized variant of this.
// - Consider a wide Won character to be the default width (or some generalized
//   variant of this).
// - Filter the set of characters that gets converted (the preferred approach is
//   to allow applying filters to transforms).
