package shaping

import (
	
)

// AddWordSpacing alters the run, adding [additionalSpacing] on each
// word separator.
// [text] is the input slice used to create the run.
// Note that space is always added, even on boundaries.
//
// See also the convenience function [AddSpacing] to handle a slice of runs.
//
// See also https://www.w3.org/TR/css-text-3/#word-separator
func ( *Output) ( []rune,  fixed.Int26_6) {
	 := .Direction.IsVertical()
	for ,  := range .Glyphs {
		// find the corresponding runes :
		// to simplify, we assume a simple one to one rune/glyph mapping
		// which should be common in practice for word separators
		if !(.RuneCount == 1 && .GlyphCount == 1) {
			continue
		}
		 := [.ClusterIndex]
		switch  {
		case '\u0020', // space
			'\u00A0',                   // no-break space
			'\u1361',                   // Ethiopic word space
			'\U00010100', '\U00010101', // Aegean word separators
			'\U0001039F', // Ugaritic word divider
			'\U0001091F': // Phoenician word separator
		default:
			continue
		}
		// we have a word separator: add space
		// we do it by enlarging the separator glyph advance
		// and distributing space around the glyph content
		.Glyphs[].Advance += 
		if  {
			.Glyphs[].YAdvance += 
			.Glyphs[].YOffset +=  / 2
		} else {
			.Glyphs[].XAdvance += 
			.Glyphs[].XOffset +=  / 2
		}
	}
	.RecomputeAdvance()
}

// AddLetterSpacing alters the run, adding [additionalSpacing] between
// each Harfbuzz clusters.
//
// Space is added at the boundaries if and only if there is an adjacent run, as specified by [isStartRun] and [isEndRun].
//
// See also the convenience function [AddSpacing] to handle a slice of runs.
//
// See also https://www.w3.org/TR/css-text-3/#letter-spacing-property
func ( *Output) ( fixed.Int26_6, ,  bool) {
	 := .Direction.IsVertical()

	 :=  / 2
	for  := 0;  < len(.Glyphs); {
		 := .Glyphs[]
		 :=  + .GlyphCount - 1

		// start : apply spacing at boundary only if the run is not the first
		if  > 0 || ! {
			.Glyphs[].Advance += 
			if  {
				.Glyphs[].YAdvance += 
				.Glyphs[].YOffset += 
			} else {
				.Glyphs[].XAdvance += 
				.Glyphs[].XOffset += 
			}
			.Glyphs[].startLetterSpacing += 
		}

		// end : apply spacing at boundary only if the run is not the last
		 := +.GlyphCount >= len(.Glyphs)
		if ! || ! {
			.Glyphs[].Advance += 
			if  {
				.Glyphs[].YAdvance += 
			} else {
				.Glyphs[].XAdvance += 
			}
			.Glyphs[].endLetterSpacing += 
		}

		// go to next cluster
		 += .GlyphCount
	}

	.RecomputeAdvance()
}

// does not run RecomputeAdvance
func ( *Output) () {
	if len(.Glyphs) == 0 {
		return
	}
	 := &.Glyphs[0]
	 := .startLetterSpacing
	.Advance -= 
	if .Direction.IsVertical() {
		.YAdvance -= 
		.YOffset -= 
	} else {
		.XAdvance -= 
		.XOffset -= 
	}
	.startLetterSpacing = 0
}

// AddSpacing adds additionnal spacing between words and letters, mutating the given [runs].
// [text] is the input slice the [runs] refer to.
//
// See the method [Output.AddWordSpacing] and [Output.AddLetterSpacing] for details
// about what spacing actually is.
func ( []Output,  []rune, ,  fixed.Int26_6) {
	for  := range  {
		,  :=  == 0,  == len()-1
		if  != 0 {
			[].AddWordSpacing(, )
		}
		if  != 0 {
			[].AddLetterSpacing(, , )
		}
	}
}