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

// This package provides data and functions to test some properties of Unicode code points.
package unicode

const (
	MaxRune         = 0x10FFFF // Maximum valid Unicode code point.
	ReplacementChar = 0xFFFD   // Represents invalid code points.
)


// The representation of a range of Unicode code points.  The range runs from Lo to Hi
// inclusive and has the specified stride.
type Range struct {
	Lo     int
	Hi     int
	Stride int
}

// The representation of a range of Unicode code points for case conversion.
// The range runs from Lo to Hi inclusive, with a fixed stride of 1.  Deltas
// are the number to add to the code point to reach the code point for a
// different case for that character.  They may be negative.  If zero, it
// means the character is in the corresponding case. There is a special
// case representing sequences of alternating corresponding Upper and Lower
// pairs.  It appears with a fixed Delta of
//	{UpperLower, UpperLower, UpperLower}
// The constant UpperLower has an otherwise impossible delta value.
type CaseRange struct {
	Lo    int
	Hi    int
	Delta d
}

// Indices into the Delta arrays inside CaseRanges for case mapping.
const (
	UpperCase = iota
	LowerCase
	TitleCase
	MaxCase
)

type d [MaxCase]int32 // to make the CaseRanges text shorter

// If the Delta field of a CaseRange is UpperLower or LowerUpper, it means
// this CaseRange represents a sequence of the form (say)
// Upper Lower Upper Lower.
const (
	UpperLower = MaxRune + 1 // (Cannot be a valid delta.)
)

// Is tests whether rune is in the specified table of ranges.
func Is(ranges []Range, rune int) bool {
	// common case: rune is ASCII or Latin-1
	if rune < 0x100 {
		for _, r := range ranges {
			if rune > r.Hi {
				continue
			}
			if rune < r.Lo {
				return false
			}
			return (rune-r.Lo)%r.Stride == 0
		}
		return false
	}

	// binary search over ranges
	lo := 0
	hi := len(ranges)
	for lo < hi {
		m := lo + (hi-lo)/2
		r := ranges[m]
		if r.Lo <= rune && rune <= r.Hi {
			return (rune-r.Lo)%r.Stride == 0
		}
		if rune < r.Lo {
			hi = m
		} else {
			lo = m + 1
		}
	}
	return false
}

// IsUpper reports whether the rune is an upper case letter.
func IsUpper(rune int) bool {
	if rune < 0x80 { // quick ASCII check
		return 'A' <= rune && rune <= 'Z'
	}
	return Is(Upper, rune)
}

// IsLower reports whether the rune is a lower case letter.
func IsLower(rune int) bool {
	if rune < 0x80 { // quick ASCII check
		return 'a' <= rune && rune <= 'z'
	}
	return Is(Lower, rune)
}

// IsTitle reports whether the rune is a title case letter.
func IsTitle(rune int) bool {
	if rune < 0x80 { // quick ASCII check
		return false
	}
	return Is(Title, rune)
}

// IsLetter reports whether the rune is a letter.
func IsLetter(rune int) bool {
	if rune < 0x80 { // quick ASCII check
		rune &^= 'a' - 'A'
		return 'A' <= rune && rune <= 'Z'
	}
	return Is(Letter, rune)
}

// IsSpace reports whether the rune is a white space character.
func IsSpace(rune int) bool {
	if rune <= 0xFF { // quick Latin-1 check
		switch rune {
		case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
			return true
		}
		return false
	}
	return Is(White_Space, rune)
}

// To maps the rune to the specified case: UpperCase, LowerCase, or TitleCase
func To(_case int, rune int) int {
	if _case < 0 || MaxCase <= _case {
		return ReplacementChar // as reasonable an error as any
	}
	// binary search over ranges
	lo := 0
	hi := len(CaseRanges)
	for lo < hi {
		m := lo + (hi-lo)/2
		r := CaseRanges[m]
		if r.Lo <= rune && rune <= r.Hi {
			delta := int(r.Delta[_case])
			if delta > MaxRune {
				// In an Upper-Lower sequence, which always starts with
				// an UpperCase letter, the real deltas always look like:
				//	{0, 1, 0}    UpperCase (Lower is next)
				//	{-1, 0, -1}  LowerCase (Upper, Title are previous)
				// The characters at even offsets from the beginning of the
				// sequence are upper case; the ones at odd offsets are lower.
				// The correct mapping can be done by clearing or setting the low
				// bit in the sequence offset.
				// The constants UpperCase and TitleCase are even while LowerCase
				// is odd so we take the low bit from _case.
				return r.Lo + ((rune-r.Lo)&^1 | _case&1)
			}
			return rune + delta
		}
		if rune < r.Lo {
			hi = m
		} else {
			lo = m + 1
		}
	}
	return rune
}

// ToUpper maps the rune to upper case
func ToUpper(rune int) int {
	if rune < 0x80 { // quick ASCII check
		if 'a' <= rune && rune <= 'z' {
			rune -= 'a' - 'A'
		}
		return rune
	}
	return To(UpperCase, rune)
}

// ToLower maps the rune to lower case
func ToLower(rune int) int {
	if rune < 0x80 { // quick ASCII check
		if 'A' <= rune && rune <= 'Z' {
			rune += 'a' - 'A'
		}
		return rune
	}
	return To(LowerCase, rune)
}

// ToTitle maps the rune to title case
func ToTitle(rune int) int {
	if rune < 0x80 { // quick ASCII check
		if 'a' <= rune && rune <= 'z' { // title case is upper case for ASCII
			rune -= 'a' - 'A'
		}
		return rune
	}
	return To(TitleCase, rune)
}
