package strutil

import (
	

	
)

// PosFlag type
type PosFlag = comdef.Position

// Position for padding/resize string
const (
	PosLeft PosFlag = iota
	PosMiddle
	PosRight
	PosAuto
)

/*************************************************************
 * String padding operation
 *************************************************************/

// Padding Fill the string to the specified length.
//
// params:
//   - s: 原始字符串
//   - pad: 用于填充的字符或字符串
//   - length: 目标长度
//   - padPos: 填充位置标志(左填充或右填充)
func (,  string,  int,  PosFlag) string {
	return padding(, , len(), , )
}

// Utf8Padding Fill the string to the specified length. use utf8 width.
func (,  string,  int,  PosFlag) string {
	return padding(, , Utf8Width(), , )
}

func padding(,  string, ,  int,  PosFlag) string {
	 :=  - 
	if  >= 0 { // do not need padding.
		return 
	}

	// pad space.
	if len() ==  && ( == "" ||  == " ") {
		// Sprintf: 是按字数来填充的,不管中英文都是一个字符 - 有问题
		if  == PosRight { // to right
			return  + strings.Repeat(" ", -)
		}
		return strings.Repeat(" ", -) + 
	}

	// other character.
	if  == PosRight { // to right
		return  + Repeat(, -)
	}
	return Repeat(, -) + 
}

// PadLeft a string.
func (,  string,  int) string {
	return Padding(, , , PosLeft)
}

// PadRight a string.
func (,  string,  int) string {
	return Padding(, , , PosRight)
}

// PadChars padding a rune/byte to want length and with position flag
func [ byte | rune]( [],  ,  int,  PosFlag) [] {
	 := len()
	if  >=  {
		 := make([], )
		copy(, [:])
		return 
	}

	 :=  - 
	 := make([], )
	if  == PosRight {
		copy(, )
		for  := ;  < ; ++ {
			[] = 
		}
		return 
	}

	// to left
	for  := 0;  < ; ++ {
		[] = 
	}
	copy([:], )
	return 
}

// PadBytes padding a byte to want length and with position flag
func ( []byte,  byte,  int,  PosFlag) []byte {
	return PadChars(, , , )
}

// PadBytesLeft a byte to want length
func ( []byte,  byte,  int) []byte {
	return PadChars(, , , PosLeft)
}

// PadBytesRight a byte to want length
func ( []byte,  byte,  int) []byte {
	return PadChars(, , , PosRight)
}

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

// PadRunesLeft a rune to want length
func ( []rune,  rune,  int) []rune {
	return PadChars(, , , PosLeft)
}

// PadRunesRight a rune to want length
func ( []rune,  rune,  int) []rune {
	return PadChars(, , , PosRight)
}

// Align a string by given length and align settings. alias of Resize
func ( string,  int,  comdef.Align) string {
	return resize(, len(), , , false)
}

// Utf8Align a string by given length and align settings. alias of Utf8Resize
func ( string,  int,  comdef.Align) string {
	return resize(, Utf8Width(), , , false)
}

// Resize a string by given length and align settings. use padding space.
// If len(s) > wantLen, will truncate it.
func ( string,  int,  comdef.Align) string {
	return resize(, len(), , , true)
}

// Utf8Resize a string by given length and align settings. use padding space.
// If width(s) > wantLen, will truncate it.
func ( string,  int,  comdef.Align) string {
	return resize(, Utf8Width(), , , true)
}

// resize a string by given length and align settings. use padding space.
func resize( string, ,  int,  comdef.Align,  bool) string {
	 :=  - 
	if  >= 0 { // do not need padding.
		// cutOverflow: truncate on sLen > wantLen
		if  &&  >  {
			if len() ==  {
				return [:]
			}
			return utf8Truncate(, , , "")
		}
		return 
	}

	if  == comdef.Center {
		 := ( - ) / 2
		if  =  - *2;  > 0 {
			 += " "
		}
		 := string(RepeatBytes(' ', ))
		return  +  + 
	}

	 := string(RepeatBytes(' ', -))
	// tip: 左对齐 - 使用空白填充右边
	if  == comdef.Left ||  == comdef.PosAuto {
		return  + 
	}
	return  + 
}

/*************************************************************
 * String repeat operation
 *************************************************************/

// Repeat a string by given times.
func ( string,  int) string {
	if  < 1 {
		return ""
	}
	if  == 1 {
		return 
	}

	var  strings.Builder
	.Grow(len() * )

	for  := 0;  < ; ++ {
		.WriteString()
	}
	return .String()
}

// RepeatRune repeat a rune char.
func ( rune,  int) []rune { return RepeatChars(, ) }

// RepeatBytes repeat a byte char.
func ( byte,  int) []byte { return RepeatChars(, ) }

// RepeatChars repeat a byte char.
func [ byte | rune]( ,  int) [] {
	if  <= 0 {
		return make([], 0)
	}

	 := make([], )
	for  := 0;  < ; ++ {
		[] = 
	}
	return 
}