package strutil

import (
	
	
	

	
)

// RuneIsWord char: a-zA-Z
func ( rune) bool {
	return RuneIsLower() || RuneIsUpper()
}

// RuneIsLower char
func ( rune) bool {
	return 'a' <=  &&  <= 'z'
}

// RuneIsUpper char
func ( rune) bool {
	return 'A' <=  &&  <= 'Z'
}

// RunePos alias of the strings.IndexRune
func ( string,  rune) int { return strings.IndexRune(, ) }

// IsSpaceRune returns true if the given rune is a space, otherwise false.
func ( rune) bool {
	return  <= 256 && IsSpace(byte()) || unicode.IsSpace()
}

// Utf8Len count rune of the string.
//
// Examples:
//
//	str := "hi,你好"
//
//	len(str) // 9
//	strutil.RunesWidth(str) // 7 一个中文字占两个字符
//	RuneCount(str) = Utf8Len(s) // 5 按字算
func ( string) int { return utf8.RuneCountInString() }

// Utf8len count rune of the string.
func ( string) int { return utf8.RuneCountInString() }

// RuneCount of the string.
//
// Examples:
//
//	str := "hi,你好"
//
//	len(str) // 9
//	strutil.RunesWidth(str) // 7 一个中文字占两个字符
//	RuneCount(str) = utf8.RuneCountInString(s) // 5 按字算
func ( string) int { return len([]rune()) }

// RuneWidth of the rune.
//
// Example:
//
//	RuneWidth('你') // 2
//	RuneWidth('a') // 1
//	RuneWidth('\n') // 0
func ( rune) int {
	 := width.LookupRune()
	 := .Kind()

	// eg: "\n"
	if  == width.Neutral {
		return 0
	}

	if  == width.EastAsianFullwidth ||  == width.EastAsianWide ||  == width.EastAsianAmbiguous {
		return 2
	}
	return 1
}

// TextWidth utf8 string width. alias of RunesWidth()
func ( string) int { return Utf8Width() }

// Utf8Width utf8 string width. alias of RunesWidth
func ( string) int { return RunesWidth([]rune()) }

// RunesWidth utf8 runes string width.
//
// Examples:
//
//	str := "hi,你好"
//
//	len(str) // 9
//	strutil.RunesWidth(str) // 7 一个中文字占两个字符
//	len([]rune(str)) = utf8.RuneCountInString(s) // 5 按字算
func ( []rune) ( int) {
	if len() == 0 {
		return
	}

	for ,  := range  {
		 += RuneWidth()
	}
	return 
}

// Truncate alias of the Utf8Truncate()
func ( string,  int,  string) string { return Utf8Truncate(, , ) }

// TextTruncate alias of the Utf8Truncate()
func ( string,  int,  string) string { return Utf8Truncate(, , ) }

// Utf8Truncate a string with given width.
func ( string,  int,  string) string { return utf8Truncate(, Utf8Width(), , ) }

// utf8Truncate a string with given width.
func utf8Truncate( string, ,  int,  string) string {
	if  <=  {
		return 
	}

	 := 0
	 := []rune()
	 -= TextWidth()

	 := 0
	for ;  < len(); ++ {
		 := RuneWidth([])
		if + >  {
			break
		}
		 += 
	}
	return string([0:]) + 
}

// Chunk split string to chunks by size.
// func Chunk[T ~string](s T, size int) []T {
// }

// TextSplit alias of the Utf8Split()
func ( string,  int) []string { return Utf8Split(, ) }

// Utf8Split split a string by width.
func ( string,  int) []string {
	 := Utf8Width()
	if  <=  {
		return []string{}
	}

	 := 0
	 := ""

	 := make([]string, 0, /+1)
	for ,  := range  {
		 := RuneWidth()
		if + ==  {
			 += string()
			 = append(, )

			,  = 0, "" // reset
			continue
		}

		if + >  {
			 = append(, )

			// append to next line.
			,  = , string()
			continue
		}

		 += 
		 += string()
	}

	if  > 0 {
		 = append(, )
	}
	return 
}

// TextWrap a string by "\n". alias of the WidthWrap()
func ( string,  int) string { return WidthWrap(, ) }

// WidthWrap a string by "\n"
//
// Example:
//	s := "hello 你好, world 世界"
//  s1 := strutil.TextWrap(s, 6) // "hello \n你好, \nworld \n世界"
func ( string,  int) string {
	 := 0
	 := ""

	for ,  := range  {
		 := RuneWidth()
		if  == '\n' {
			 += string()
			 = 0
			continue
		}

		if + >  {
			 += "\n"
			 = 0
			 += string()
			 += 
			continue
		}

		 += string()
		 += 
	}
	return 
}

// WordWrap text string and limit width.
func ( string,  int) string {
	 := 0
	 := ""

	for ,  := range strings.Split(, " ") {
		 := TextWidth()
		if + >  {
			if  != 0 {
				 += "\n"
			}

			 = 0
			 += 
			 += 
			continue
		}

		 += 
		 += 
	}
	return 
}

// Runes data slice
type Runes []rune

// Padding a rune to want length and with position
func ( Runes) ( rune,  int,  PosFlag) []rune {
	return PadChars(, , , )
}

// PadLeft a rune to want length
func ( Runes) ( rune,  int) []rune {
	return .Padding(, , PosLeft)
}

// PadRight a rune to want length
func ( Runes) ( rune,  int) []rune {
	return .Padding(, , PosRight)
}