package harfbuzz

import (
	

	ot 
	
)

// ported from harfbuzz/src/hb-ot-shape-complex-myanmar.cc, .hh Copyright © 2011,2012,2013  Google, Inc.  Behdad Esfahbod

// Myanmar shaper.
type complexShaperMyanmar struct {
	complexShaperNil
}

var _ otComplexShaper = complexShaperMyanmar{}

func setMyanmarProperties( *GlyphInfo) {
	 := .codepoint
	 := indicGetCategories()
	 := uint8( & 0xFF)
	// pos := uint8(type_ >> 8)

	.complexCategory = 
	// info.complexAux = pos
}

/* Note:
 *
 * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
 * cannot happen in a consonant syllable.  The plus side however is, we can call the
 * consonant syllable logic from the vowel syllable function and get it all right!
 *
 * Keep in sync with consonant_categories in the generator. */
const consonantFlagsMyanmar = (1 << myaSM_ex_C) | 1<<myaSM_ex_CS | 1<<myaSM_ex_Ra |
	1<<myaSM_ex_IV | 1<<myaSM_ex_GB | 1<<myaSM_ex_DOTTEDCIRCLE

func isConsonantMyanmar( *GlyphInfo) bool {
	return isOneOf(, consonantFlagsMyanmar)
}

/*
 * Basic features.
 * These features are applied in order, one at a time, after reordering.
 */
var myanmarBasicFeatures = [...]tables.Tag{
	ot.NewTag('r', 'p', 'h', 'f'),
	ot.NewTag('p', 'r', 'e', 'f'),
	ot.NewTag('b', 'l', 'w', 'f'),
	ot.NewTag('p', 's', 't', 'f'),
}

/*
* Other features.
* These features are applied all at once, after clearing syllables.
 */
var myanmarOtherFeatures = [...]tables.Tag{
	ot.NewTag('p', 'r', 'e', 's'),
	ot.NewTag('a', 'b', 'v', 's'),
	ot.NewTag('b', 'l', 'w', 's'),
	ot.NewTag('p', 's', 't', 's'),
}

func (complexShaperMyanmar) ( *otShapePlanner) {
	 := &.otMap

	/* Do this before any lookups have been applied. */
	.addGSUBPause(setupSyllablesMyanmar)

	.enableFeature(ot.NewTag('l', 'o', 'c', 'l'))
	/* The Indic specs do not require ccmp, but we apply it here since if
	* there is a use of it, it's typically at the beginning. */
	.enableFeature(ot.NewTag('c', 'c', 'm', 'p'))

	.addGSUBPause(reorderMyanmar)

	for ,  := range myanmarBasicFeatures {
		.enableFeatureExt(, ffManualZWJ|ffPerSyllable, 1)
		.addGSUBPause(nil)
	}

	.addGSUBPause(nil)

	for ,  := range myanmarOtherFeatures {
		.enableFeatureExt(, ffManualZWJ, 1)
	}
}

func (complexShaperMyanmar) ( *otShapePlan,  *Buffer,  *Font) {
	// No masks, we just save information about characters.

	 := .Info
	for  := range  {
		setMyanmarProperties(&[])
	}
}

func foundSyllableMyanmar( uint8, ,  int,  []GlyphInfo,  *uint8) {
	for  := ;  < ; ++ {
		[].syllable = (* << 4) | 
	}
	*++
	if * == 16 {
		* = 1
	}
}

func setupSyllablesMyanmar( *otShapePlan,  *Font,  *Buffer) bool {
	findSyllablesMyanmar()
	,  := .syllableIterator()
	for ,  := .next();  < ; ,  = .next() {
		.unsafeToBreak(, )
	}
	return false
}

/* Rules from:
 * https://docs.microsoft.com/en-us/typography/script-development/myanmar */
func initialReorderingConsonantSyllableMyanmar( *Buffer, ,  int) {
	 := .Info

	 := 
	 := false

	 := 
	if +3 <=  &&
		[].complexCategory == myaSM_ex_Ra &&
		[+1].complexCategory == myaSM_ex_As &&
		[+2].complexCategory == myaSM_ex_H {
		 += 3
		 = 
		 = true
	}

	if ! {
		 = 
	}

	for  := ;  < ; ++ {
		if isConsonantMyanmar(&[]) {
			 = 
			break
		}
	}

	/* Reorder! */
	 := 
	 := 
	if  {
		 =  + 3
	}
	for ;  < ; ++ {
		[].complexAux = posAfterMain
	}
	for ;  < ; ++ {
		[].complexAux = posPreC
	}
	if  <  {
		[].complexAux = posBaseC
		++
	}
	var  uint8 = posAfterMain
	/* The following loop may be ugly, but it implements all of
	 * Myanmar reordering! */
	for ;  < ; ++ {
		if [].complexCategory == myaSM_ex_MR /* Pre-base reordering */ {
			[].complexAux = posPreC
			continue
		}
		if [].complexCategory == myaSM_ex_VPre /* Left matra */ {
			[].complexAux = posPreM
			continue
		}
		if [].complexCategory == myaSM_ex_VS {
			[].complexAux = [-1].complexAux
			continue
		}

		if  == posAfterMain && [].complexCategory == myaSM_ex_VBlw {
			 = posBelowC
			[].complexAux = 
			continue
		}

		if  == posBelowC && [].complexCategory == myaSM_ex_A {
			[].complexAux = posBeforeSub
			continue
		}
		if  == posBelowC && [].complexCategory == myaSM_ex_VBlw {
			[].complexAux = 
			continue
		}
		if  == posBelowC && [].complexCategory != myaSM_ex_A {
			 = posAfterSub
			[].complexAux = 
			continue
		}
		[].complexAux = 
	}

	/* Sit tight, rock 'n roll! */
	.sort(, , func(,  *GlyphInfo) int { return int(.complexAux) - int(.complexAux) })

	/* Flip left-matra sequence. */
	 := 
	 := 
	for  := ;  < ; ++ {
		if [].complexAux == posPreM {
			if  ==  {
				 = 
			}
			 = 
		}
	}
	/* https://github.com/harfbuzz/harfbuzz/issues/3863 */
	if  <  {
		// No need to merge clusters, done already?
		.reverseRange(, +1)
		// Reverse back VS, etc.
		 := 
		for  := ;  <= ; ++ {
			if [].complexCategory == myaSM_ex_VPre {
				.reverseRange(, +1)
				 =  + 1
			}
		}
	}
}

func reorderSyllableMyanmar( *Buffer, ,  int) {
	 := .Info[].syllable & 0x0F
	switch  {
	/* We already inserted dotted-circles, so just call the consonant_syllable. */
	case myanmarBrokenCluster, myanmarConsonantSyllable:
		initialReorderingConsonantSyllableMyanmar(, , )
	}
}

func reorderMyanmar( *otShapePlan,  *Font,  *Buffer) bool {
	if debugMode {
		fmt.Println("MYANMAR - start reordering myanmar", .Info)
	}

	 := syllabicInsertDottedCircles(, , myanmarBrokenCluster, myaSM_ex_DOTTEDCIRCLE, -1, -1)

	,  := .syllableIterator()
	for ,  := .next();  < ; ,  = .next() {
		reorderSyllableMyanmar(, , )
	}

	if debugMode {
		fmt.Println("MYANMAR - end reordering myanmar", .Info)
	}

	return 
}

func (complexShaperMyanmar) () (zeroWidthMarks, bool) {
	return zeroWidthMarksByGdefEarly, false
}

func (complexShaperMyanmar) () normalizationMode {
	return nmComposedDiacriticsNoShortCircuit
}