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