// 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);
}
