package strutil

import (
	
	
	
	
)

/*************************************************************
 * change string case
 *************************************************************/

// methods aliases
var (
	UpWords = UpperWord
	LoFirst = LowerFirst
	UpFirst = UpperFirst

	Snake = SnakeCase
)

// Title alias of the strings.ToTitle()
func ( string) string { return strings.ToTitle() }

// Lower alias of the strings.ToLower()
func ( string) string { return strings.ToLower() }

// Lowercase alias of the strings.ToLower()
func ( string) string { return strings.ToLower() }

// Upper alias of the strings.ToUpper()
func ( string) string { return strings.ToUpper() }

// Uppercase alias of the strings.ToUpper()
func ( string) string { return strings.ToUpper() }

// UpperWord Change the first character of each word to uppercase
func ( string) string {
	if len() == 0 {
		return 
	}

	if len() == 1 {
		return strings.ToUpper()
	}

	 := true
	 := make([]byte, 0, len())

	 := 0
	 := []rune()
	if RuneIsLower([]) {
		 = append(, []byte(string(unicode.ToUpper([])))...)
	} else {
		 = append(, []byte(string([]))...)
	}

	for  :=  + 1;  < len(); ++ {
		if !RuneIsWord([]) && RuneIsWord([]) {
			 = false
		}

		if RuneIsLower([]) && ! {
			 = append(, []byte(string(unicode.ToUpper([])))...)
			 = true
		} else {
			 = append(, []byte(string([]))...)
		}

		if RuneIsWord([]) {
			 = true
		}

		++
	}

	return string()
}

// LowerFirst lower first char
func ( string) string {
	if len() == 0 {
		return 
	}

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

	if 'A' <=  &&  <= 'Z' {
		return string(unicode.ToLower()) + string([1:])
	}
	return 
}

// UpperFirst upper first char
func ( string) string {
	if len() == 0 {
		return 
	}

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

	if 'a' <=  &&  <= 'z' {
		return string(unicode.ToUpper()) + string([1:])
	}
	return 
}

// SnakeCase convert. eg "RangePrice" -> "range_price"
func ( string,  ...string) string {
	 := "_"
	if len() > 0 {
		 = [0]
	}

	 := toSnakeReg.ReplaceAllStringFunc(, func( string) string {
		return  + LowerFirst()
	})

	return strings.TrimLeft(, )
}

// Camel alias of the CamelCase
func ( string,  ...string) string { return CamelCase(, ...) }

// CamelCase convert string to camel case.
//
// Support:
//
//	"range_price" -> "rangePrice"
//	"range price" -> "rangePrice"
//	"range-price" -> "rangePrice"
func ( string,  ...string) string {
	 := "_"
	if len() > 0 {
		 = [0]
	}

	// Not contains sep char
	if !strings.Contains(, ) {
		return 
	}

	// Get regexp instance
	,  := toCamelRegs[]
	if ! {
		 = regexp.MustCompile(regexp.QuoteMeta() + "+[a-zA-Z]")
	}

	return .ReplaceAllStringFunc(, func( string) string {
		 = strings.TrimLeft(, )
		return UpperFirst()
	})
}

//
// Indent format multi line text
// from package: github.com/kr/text
//

// Indent inserts prefix at the beginning of each non-empty line of s. The
// end-of-line marker is NL.
func (,  string) string {
	return string(IndentBytes([]byte(), []byte()))
}

// IndentBytes inserts prefix at the beginning of each non-empty line of b.
// The end-of-line marker is NL.
func (,  []byte) []byte {
	if len() == 0 {
		return 
	}

	 := true
	 := make([]byte, 0, len()+len()*4)

	for ,  := range  {
		if  &&  != '\n' {
			 = append(, ...)
		}
		 = append(, )
		 =  == '\n'
	}
	return 
}

// Replaces replace multi strings
//
//	pairs: {old1: new1, old2: new2, ...}
//
// Can also use:
//
//	strings.NewReplacer("old1", "new1", "old2", "new2").Replace(str)
func ( string,  map[string]string) string {
	return NewReplacer().Replace()
}

// ReplaceVars replaces simple variables in a string. format: {varName}
//
// Usage:
//	strutil.ReplaceVars("{name}, age is {age}", map[string]string{
//		"name": "Joe",
//		"age": "18"
//	})
func ( string,  map[string]string) string {
	if !ContainsByte(, '{') {
		return 
	}

	// format var name to {name}
	 := make(map[string]string)
	for ,  := range  {
		 := "{" +  + "}"
		[] = 
	}
	return NewReplacer().Replace()
}

// NewReplacer instance
func ( map[string]string) *strings.Replacer {
	 := make([]string, len()*2)
	for ,  := range  {
		 = append(, , )
	}
	return strings.NewReplacer(...)
}

// WrapTag for given string.
func (,  string) string {
	if  == "" {
		return 
	}
	return fmt.Sprintf("<%s>%s</%s>", , , )
}