$$include '../../meta/macros.ptl'

import [mix linreg clamp fallback] from "@iosevka/util"

glyph-module

glyph-block Letter-Cyrillic-Yeri : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Letter-Shared-Metrics : BowlXDepth
	glyph-block-import Letter-Shared-Shapes : RightwardTailedBar
	glyph-block-import Letter-Shared-Shapes : LetterBarOverlay UpwardHookShape VerticalHook SerifFrame

	glyph-block-export YeriBarPos
	define YeriBarPos 0.55

	define Yeri : namespace
		define flex-params [CornerCommon] : glyph-proc
			local-parameter : top
			local-parameter : left   -- SB
			local-parameter : right  -- RightSB
			local-parameter : stroke -- Stroke
			local-parameter : jut    -- Jut
			local-parameter : pBar   -- YeriBarPos
			local-parameter : yStart -- top

			local bowl : top * pBar + stroke / 2
			local turnRadius : BowlXDepth bowl 0 left right stroke
			local ada : ArchDepthAOf ArchDepth (right - left + SB * 2)
			local adb : ArchDepthBOf ArchDepth (right - left + SB * 2)
			local fine : stroke * CThinB

			local yTurnBottomL : YSmoothMidL bowl 0 ada adb
			local yTurnBottomR : YSmoothMidR bowl 0 ada adb

			include : union
				dispiro
					widths.lhs stroke
					flat (left + Stroke * 0.2) 0 [heading Rightward]
					curl [arch.adjust-x.bot [Math.max (left + stroke * TanSlope) (right - turnRadius)] (sw -- stroke)] 0
					archv 8
					g4   (right - OX) yTurnBottomR
					arcvh 8
					flat [arch.adjust-x.top [Math.max (left + stroke * TanSlope) (right - turnRadius)] (sw -- stroke)] bowl
					curl (left + Stroke * 0.2) bowl [heading Leftward]
				VBar.l left 0 yStart stroke

		export : define flex-params [UprightShape] : glyph-proc
			local-parameter : top
			local-parameter : left   -- SB
			local-parameter : right  -- RightSB
			local-parameter : stroke -- Stroke
			local-parameter : jut    -- Jut
			local-parameter : pBar   -- YeriBarPos
			local-parameter : yStart -- top

			include : CornerCommon.apply null $-flex-arguments
			if SLAB : begin
				include : tagged 'serifYeriLB' : HSerif.lb left 0 (jut - [HSwToV : 0.5 * stroke]) stroke
				include : tagged 'serifYeriLT' : HSerif.mt (left + [HSwToV : 0.5 * stroke]) top jut stroke

		export : define flex-params [ItalicShape] : glyph-proc
			local-parameter : top
			local-parameter : left   -- SB
			local-parameter : right  -- RightSB
			local-parameter : stroke -- Stroke
			local-parameter : jut    -- Jut
			local-parameter : pBar   -- YeriBarPos
			local-parameter : yStart -- top

			include : CornerCommon.apply null $-flex-arguments
			if SLAB : begin
				include : tagged 'serifYeriLT' : HSerif.lt left top (jut - [HSwToV : 0.5 * stroke]) stroke

		export : define flex-params [AutoItalicShape] : begin
			if para.isItalic
			: then : ItalicShape.apply null $-flex-arguments
			: else : UprightShape.apply null $-flex-arguments

		export : define flex-params [RoundShape] : glyph-proc
			local-parameter : top
			local-parameter : left   -- SB
			local-parameter : right  -- RightSB
			local-parameter : stroke -- Stroke
			local-parameter : jut    -- Jut
			local-parameter : pBar   -- YeriBarPos
			local-parameter : yStart -- top

			local bowl : top * pBar + stroke / 2
			local turnRadius : BowlXDepth bowl 0 left right stroke
			local ada : ArchDepthAOf ArchDepth (right - left + SB * 2)
			local adb : ArchDepthBOf ArchDepth (right - left + SB * 2)
			local fine : stroke * CThinB

			local yTurnBottomL : YSmoothMidL bowl 0 ada adb
			local yTurnBottomR : YSmoothMidR bowl 0 ada adb

			include : dispiro
				flat left [Math.max yStart (yTurnBottomL + TINY)] [widths.lhs.heading stroke Downward]
				curl left yTurnBottomL
				arch.lhs 0 (sw -- stroke)
				g4 (right - OX) yTurnBottomR
				arcvh
				flat [arch.adjust-x.top [mix left right 0.5] (sw -- stroke)] bowl
				curl (left + Stroke * 0.2) bowl [heading Leftward]

			if SLAB : begin
				include : tagged 'serifYeriLT' : HSerif.lt left top (jut - [HSwToV : 0.5 * stroke]) stroke

		export : define flex-params [CursiveShape] : glyph-proc
			local-parameter : top
			local-parameter : left   -- SB
			local-parameter : right  -- RightSB
			local-parameter : stroke -- Stroke
			local-parameter : jut    -- Jut
			local-parameter : pBar   -- YeriBarPos
			local-parameter : yStart -- top

			local bowl : top * pBar + stroke / 2
			local turnRadius : BowlXDepth bowl 0 left right stroke
			local ada : ArchDepthAOf ArchDepth (right - left + SB * 2)
			local adb : ArchDepthBOf ArchDepth (right - left + SB * 2)
			local fine ShoulderFine

			local yTurnBottomL : YSmoothMidL bowl 0 ada adb
			local yTurnBottomR : YSmoothMidR bowl 0 ada adb

			include : dispiro
				flat left [Math.max yStart (yTurnBottomL + TINY)] [widths.lhs.heading stroke Downward]
				curl left yTurnBottomL
				arch.lhs 0 (sw -- stroke)
				g4 (right - OX) yTurnBottomR
				arch.lhs bowl (sw -- stroke) (swAfter -- fine)
				g4.down.end (left + [HSwToV (stroke - fine)]) yTurnBottomL [widths.lhs.heading fine Downward]

			if SLAB : begin
				include : tagged 'serifYeriLT' : HSerif.lt left top (jut - [HSwToV : 0.5 * stroke]) stroke

	define RevYeri : namespace
		export : define flex-params [Shape top [left SB] [right RightSB] [stroke Stroke] [jut Jut] [pBar YeriBarPos]] : glyph-proc
			local bowl : top * pBar + stroke / 2
			local turnRadius : bowl * 0.45
			local turnbottom : mix 0 bowl (ArchDepthB / (ArchDepthA + ArchDepthB))
			local trShrink : Math.sqrt : (right - left) / (RightSB - SB)
			include : dispiro
				widths.rhs stroke
				flat (right - Stroke * 0.2) 0 [heading Leftward]
				curl [arch.adjust-x.bot (left + turnRadius * trShrink) stroke] 0
				archv
				g4   (left + O) turnbottom
				arcvh
				flat [arch.adjust-x.top (left + turnRadius * trShrink) stroke] bowl
				curl (right - Stroke * 0.2) bowl [heading Rightward]
			include : VBar.r right 0 top stroke
			if SLAB : begin
				include : tagged 'serifYeriRB'
					HSerif.rb right 0 (jut - [HSwToV : 0.5 * stroke]) stroke
				include : tagged 'serifYeriRT'
					HSerif.mt (right - [HSwToV : 0.5 * stroke]) top jut stroke

		export : define flex-params [RoundShape top [left SB] [right RightSB] [stroke Stroke] [jut Jut] [pBar YeriBarPos] [yStart top]] : glyph-proc
			local bowl : top * pBar + stroke / 2
			local turnRadius : BowlXDepth bowl 0 left right stroke
			local ada : ArchDepthAOf ArchDepth (right - left + SB * 2)
			local adb : ArchDepthBOf ArchDepth (right - left + SB * 2)
			local fine : stroke * CThinB

			local yTurnBottomL : YSmoothMidL bowl 0 ada adb
			local yTurnBottomR : YSmoothMidR bowl 0 ada adb

			include : dispiro
				flat right [Math.max yStart (yTurnBottomR + TINY)] [widths.rhs.heading stroke Downward]
				curl right yTurnBottomR
				arch.rhs 0 (sw -- stroke)
				g4 (left + OX) yTurnBottomL
				arcvh
				flat [arch.adjust-x.top [mix left right 0.5] stroke] bowl
				curl (right - Stroke * 0.2) bowl [heading Rightward]

	define flex-params [CyrBackYerShape Base top left right [stroke Stroke] [jut Jut] [pBar YeriBarPos]] : glyph-proc
		local xLeftBarLeftEdge : Math.max (right - (RightSB - SB)) : if SLAB
			[mix left right 0.35] - [HSwToV : 0.50 * stroke]
			[mix left right 0.20] - [HSwToV : 0.25 * stroke]
		local xTopBarLeftEnd : mix 0 left : if SLAB 0.25 0.375

		include : HBar.t xTopBarLeftEnd (Stroke * 0.1 + xLeftBarLeftEdge) top stroke
		include : Base top
			left   -- xLeftBarLeftEdge
			right  -- right
			stroke -- stroke
			jut    -- jut
			pBar   -- pBar

		if SLAB : begin
			include : VSerif.dl xTopBarLeftEnd top VJut
				Math.min (VJutStroke * stroke / Stroke) (0.625 * (xLeftBarLeftEdge - xTopBarLeftEnd))

	define flex-params [CyrNeutralYerShape Base top left right [stroke Stroke] [jut Jut]] : glyph-proc
		local xLeftBarLeftEdge : Math.max (right - (RightSB - SB)) : if SLAB
			[mix left right 0.35] - [HSwToV : 0.50 * stroke]
			[mix left right 0.20] - [HSwToV : 0.25 * stroke]
		local xTopBarLeftEnd : mix 0 left : if SLAB 0.25 0.375

		include : Base top
			left   -- xLeftBarLeftEdge
			right  -- right
			stroke -- stroke
			jut    -- jut
			yStart -- (top - TailY - 0.5 * stroke)
		eject-contour 'serifYeriLT'
		include : VerticalHook.l xLeftBarLeftEdge (top - TailY - 0.5 * stroke) (xTopBarLeftEnd - xLeftBarLeftEdge - 0.5 * stroke) (-TailY) stroke

	define [CyrYeryShape LeftHalf df top fBackYer fTail] : glyph-proc
		local sw : if fBackYer [AdviceStroke 3.25 df.adws] df.mvs

		local jut : [Math.min 1 : Math.sqrt : sw / Stroke] * Jut
		local xm : mix (df.rightSB - [HSwToV sw]) (df.middle + [HSwToV : 0.5 * sw]) : if (fBackYer && df.adws > 1) 0.625 0.75

		include : if fBackYer
			CyrBackYerShape LeftHalf
				top    -- top
				left   -- df.leftSB
				right  -- xm
				stroke -- sw
				jut    -- jut
			LeftHalf
				top    -- top
				left   -- df.leftSB
				right  -- xm
				stroke -- sw
				jut    -- jut

		include : if fTail
			RightwardTailedBar df.rightSB 0 top sw
			VBar.r df.rightSB 0 top sw

		local useFullSerifs : LeftHalf === Yeri.UprightShape || LeftHalf === Yeri.AutoItalicShape && !para.isItalic

		if SLAB : begin
			include : tagged 'serifRT' : if useFullSerifs
				then : HSerif.mt (df.rightSB - [HSwToV : 0.5 * sw]) top jut sw
				else : glyph-proc
			if (!fTail) : include : tagged 'serifRB' : if useFullSerifs
				then : HSerif.mb (df.rightSB - [HSwToV : 0.5 * sw]) 0 jut sw
				else : HSerif.rb df.rightSB 0 (jut - [HSwToV : 0.5 * sw]) sw

	define [ZhuangToneSixShape Base top] : glyph-proc
		local xLeft : [mix SB RightSB 0.20] - [HSwToV : 0.125 * Stroke]
		include : Base top (left -- xLeft) (right -- RightSB)
		eject-contour 'serifYeriLT'
		include : dispiro
			corner xLeft top [widths.lhs : AdviceStroke 5.5]
			corner (0.25 * xLeft) (top - xLeft)

	glyph-block-export YeriConfig
	define YeriConfig : object
		corner        { Yeri.UprightShape Yeri.AutoItalicShape }
		round         { Yeri.RoundShape   Yeri.RoundShape      }
		cursive       { Yeri.CursiveShape Yeri.CursiveShape    }

	define YeryConfig : object
		corner        { Yeri.UprightShape Yeri.AutoItalicShape false }
		round         { Yeri.RoundShape   Yeri.RoundShape      false }
		cursive       { Yeri.CursiveShape Yeri.CursiveShape    false }
		cornerTailed  { Yeri.UprightShape Yeri.AutoItalicShape true  }
		roundTailed   { Yeri.RoundShape   Yeri.RoundShape      true  }
		cursiveTailed { Yeri.CursiveShape Yeri.CursiveShape    true  }

	define [YeriOverlayBar df top] : begin
		local stroke : AdviceStroke2 2 3 top
		return : LetterBarOverlay.l.in
			x   -- df.leftSB
			bot -- (top * YeriBarPos + stroke / 2)
			top -- (top - [if SLAB Stroke 0])

	foreach { suffix { Uc Lc } } [Object.entries YeriConfig] : do
		create-glyph "cyrl/Yeri.\(suffix)" : glyph-proc
			local df : include : DivFrame 1
			include : df.markSet.capital
			include : Uc CAP
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "cyrl/yeri.\(suffix)" : glyph-proc
			local df : include : DivFrame 1
			include : df.markSet.e
			include : Lc XH
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "cyrl/YeriBar.\(suffix)" : glyph-proc
			local df : include : DivFrame 1
			include : df.markSet.capital
			include : Uc CAP
				left  -- df.leftSB
				right -- df.rightSB
			include : YeriOverlayBar df CAP
		create-glyph "cyrl/yeriBar.\(suffix)" : glyph-proc
			local df : include : DivFrame 1
			include : df.markSet.e
			include : Lc XH
				left  -- df.leftSB
				right -- df.rightSB
			include : YeriOverlayBar df XH
		create-glyph "cyrl/Yer.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.capital
			include : CyrBackYerShape Uc CAP
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "cyrl/yer.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.e
			include : CyrBackYerShape Lc XH
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "cyrl/yerTall.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.b
			include : CyrBackYerShape Lc Ascender
				left  -- df.leftSB
				right -- df.rightSB
				pBar  -- (YeriBarPos * XH / Ascender)
		create-glyph "cyrl/YerNeutral.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.capital
			include : CyrNeutralYerShape Uc CAP
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "cyrl/yerNeutral.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.e
			include : CyrNeutralYerShape Lc XH
				left  -- df.leftSB
				right -- df.rightSB
		create-glyph "ZhuangToneSix.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : ZhuangToneSixShape Uc CAP
		create-glyph "zhuangToneSix.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : ZhuangToneSixShape Lc XH

	foreach { suffix { Uc Lc fTail } } [Object.entries YeryConfig] : do
		if [not fTail] : create-glyph "cyrl/Yery.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleM 3
			include : df.markSet.capital
			include : CyrYeryShape Uc df CAP false fTail
		create-glyph "cyrl/yery.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleM 3
			include : df.markSet.e
			include : CyrYeryShape Lc df XH false fTail
		if [not fTail] : create-glyph "cyrl/YeryBack.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleMM 3
			include : df.markSet.capital
			include : CyrYeryShape Uc df CAP true fTail
		create-glyph "cyrl/yeryBack.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleMM 3
			include : df.markSet.e
			include : CyrYeryShape Lc df XH true fTail

	select-variant 'cyrl/Yer'  0x42A
	select-variant 'cyrl/yer'  0x44A
	select-variant 'cyrl/yer.BGR' (shapeFrom -- 'cyrl/yer')
	select-variant 'cyrl/yerTall' 0x1C86 (follow -- 'cyrl/yer')

	select-variant 'cyrl/Yery' 0x42B
	select-variant 'cyrl/yery' 0x44B
	select-variant 'cyrl/Yeri' 0x42C
	select-variant 'cyrl/yeri' 0x44C
	select-variant 'cyrl/yeri.BGR' (shapeFrom -- 'cyrl/yeri')
	select-variant 'cyrl/YeriBar' 0x48C (follow -- 'cyrl/Yeri')
	select-variant 'cyrl/yeriBar' 0x48D (follow -- 'cyrl/yeri')
	select-variant 'cyrl/YerNeutral' 0xA64E (follow -- 'cyrl/Yer')
	select-variant 'cyrl/yerNeutral' 0xA64F (follow -- 'cyrl/yer')
	select-variant 'cyrl/YeryBack' 0xA650
	select-variant 'cyrl/yeryBack' 0xA651

	select-variant 'ZhuangToneSix' 0x184 (follow -- 'cyrl/Yer')
	select-variant 'zhuangToneSix' 0x185 (follow -- 'cyrl/yer')

	create-glyph 'cyrl/Be' 0x411 : glyph-proc
		include : MarkSet.capital
		include : Yeri.UprightShape CAP
		include : HBar.m SB [mix SB RightSB 0.9] (CAP - HalfStroke)
		if SLAB : begin
			include : VSerif.dr [mix SB RightSB 0.9] CAP VJut

	alias 'latn/Be' 0x182 'cyrl/Be'

	create-glyph 'latn/De' 0x18B : glyph-proc
		include : MarkSet.capital
		include : RevYeri.Shape CAP
		include : HBar.t [mix RightSB SB 0.9] (RightSB + O) CAP
		if SLAB : begin
			include : VSerif.dl [mix RightSB SB 0.9] CAP VJut

	create-glyph 'cyrl/DeKomi' 0x500 : glyph-proc
		include : MarkSet.capital
		include : RevYeri.Shape CAP

	create-glyph 'cyrl/DjeKomi' 0x502 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 3
		include : df.markSet.capital

		local xm : df.middle + [HSwToV : 0.5 * df.mvs]
		include : RevYeri.RoundShape CAP df.leftSB xm df.mvs
		include : UpwardHookShape
			left   -- (df.middle - [HSwToV : 0.5 * df.mvs])
			right  -- df.rightSB
			ybegin -- CAP
			yend   -- (CAP / 2 + HalfStroke)
			ada    -- (SmallArchDepthA * 0.6 * df.adws)
			adb    -- (SmallArchDepthB * 0.6 * df.adws)
			sw     -- df.mvs
		if SLAB : begin
			include : HSerif.mt df.middle CAP Jut df.mvs
			local sf2 : [SerifFrame.fromDf df (CAP / 2 + HalfStroke) 0].slice 1 2
			include sf2.rt.full
