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

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

glyph-module

glyph-block Letter-Latin-Lower-E : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Letter-Shared : CreateSelectorVariants DefineSelectorGlyph CreateTurnedLetter
	glyph-block-import Letter-Shared-Shapes : FlatHookDepth RetroflexHook RhoticHookShape
	glyph-block-import Letter-Shared-Shapes : SerifedArcEnd InwardSlabArcEnd ArcEndSerif
	glyph-block-import Mark-Shared-Metrics : markExtend markStroke markStress markFine
	glyph-block-import Mark-Above : aboveMarkTop aboveMarkBot aboveMarkMid aboveMarkStack
	glyph-block-import Mark-Adjustment : ExtendBelowBaseAnchors
	glyph-block-import Letter-Latin-C : CConfig

	define [HookHeightFull top stroke noSwash] : Math.min Hook : AHook * (top / XH)

	define [HookHeight top stroke noSwash] : Math.min [HookHeightFull top stroke noSwash]
		if (para.isItalic && !noSwash) top : stroke + 0.277 * (top - stroke * 3)

	define SLAB-NONE       0
	define SLAB-CLASSICAL  1
	define SLAB-INWARD     2

	define [SmallESerifedTerminalShape df top stroke tailSlab noSwash] : match tailSlab
		[Just SLAB-CLASSICAL] : begin
			SerifedArcEnd.LtrLhs df.rightSB 0 stroke [HookHeightFull top stroke noSwash]
		[Just SLAB-INWARD] : begin
			InwardSlabArcEnd.LtrLhs df.rightSB 0 stroke [HookHeightFull top stroke noSwash]
		__ : list
			hookend 0 (sw -- stroke) (noSwash -- noSwash)
			g4 (df.rightSB - [if (para.isItalic && !noSwash) 0 0.5] * OX) [HookHeight top stroke noSwash]

	define [SmallETerminalSerif df top stroke tailSlab noSwash] : match tailSlab
		[Just SLAB-CLASSICAL] : ArcEndSerif.R       df.rightSB 0 stroke [HookHeightFull top stroke noSwash]
		[Just SLAB-INWARD]    : ArcEndSerif.InwardR df.rightSB 0 stroke [HookHeightFull top stroke noSwash]
		__ : no-shape

	glyph-block-export SmallEShape
	define [SmallEShape] : with-params [
		df top [stroke : AdviceStroke2 2 3 top] [barpos DesignParameters.eBarPos] [bbd 0]
		[ada SmallArchDepthA] [adb SmallArchDepthB] [tailSlab nothing] [noSwash false]
		] : glyph-proc
		local barBottom : top * barpos - (stroke / 2)

		include : HBar.b (df.leftSB + (stroke / 2) + OX + bbd) (df.rightSB - (stroke / 2) - OX) barBottom stroke
		local path : include : dispiro
			widths.lhs stroke
			flat (df.rightSB - OX) barBottom [heading Upward]
			curl (df.rightSB - OX) (top - adb)
			arch.lhs top (sw -- stroke)
			flatside.ld df.leftSB 0 top ada adb
			SmallESerifedTerminalShape df top stroke tailSlab noSwash

		include : SmallETerminalSerif df top stroke tailSlab noSwash

		return path.rhsKnots.[path.rhsKnots.length - 1]

	glyph-block-export RevSmallEShape
	define [RevSmallEShape] : with-params [
		df top [stroke : AdviceStroke2 2 3 top] [barpos DesignParameters.eBarPos]
		[ada SmallArchDepthA] [adb SmallArchDepthB]
		] : glyph-proc
		local barBottom : top * barpos - (stroke / 2)

		include : HBar.b (df.leftSB + (stroke / 2) + OX) (df.rightSB - (stroke / 2) - OX) barBottom stroke
		include : dispiro
			widths.rhs stroke
			flat (df.leftSB + OX) barBottom [heading Upward]
			curl (df.leftSB + OX) (top - ada)
			arch.rhs top (sw -- stroke)
			flatside.rd df.rightSB 0 top ada adb
			hookend 0 (sw -- stroke)
			g4 (df.leftSB + 0.5 * OX) [HookHeight top stroke true]

	glyph-block-export SmallERoundedShape
	define [SmallERoundedShape] : with-params [
		df top [stroke : AdviceStroke2 2 3 top] [barpos : if para.isItalic 0.500 0.475]
		[ada SmallArchDepthA] [adb SmallArchDepthB] [tailSlab nothing] [noSwash false]
		] : glyph-proc
		local barBottom : top * barpos - (stroke / 2)
		local xStart : df.leftSB + [HSwToV : 0.125 * stroke]
		local extraCurliness : if para.isItalic (0.1 * (top - barBottom)) 0
		local path : include : dispiro
			widths.lhs stroke
			[if para.isItalic g2 flat] xStart (barBottom + (2/3) * extraCurliness)
			[if para.isItalic g2.right.mid curl] [mix xStart df.rightSB (0.475 + 0.1 * TanSlope)] (barBottom - (1/3) * extraCurliness)
			if (para.isItalic && !noSwash) {} [archv]
			g4 (df.rightSB - OX) [YSmoothMidR top barBottom (0.5 * SmallArchDepthA) (0.5 * SmallArchDepthB)]
			arch.lhs top (sw -- stroke)
			flatside.ld df.leftSB 0 top ada adb
			SmallESerifedTerminalShape df top stroke tailSlab noSwash

		include : SmallETerminalSerif df top stroke tailSlab noSwash

		return path.rhsKnots.[path.rhsKnots.length - 1]

	glyph-block-export RevSmallERoundedShape
	define [RevSmallERoundedShape] : with-params [
		df top [stroke : AdviceStroke2 2 3 top] [barpos : if para.isItalic 0.500 0.475]
		[ada SmallArchDepthA] [adb SmallArchDepthB]
		] : glyph-proc
		local barBottom : top * barpos - (stroke / 2)
		local xStart : df.rightSB - [HSwToV : 0.125 * stroke]
		local pfIt : if para.isItalic 1 0
		local extraCurliness : if para.isItalic (0.1 * (top - barBottom)) 0
		include : dispiro
			widths.rhs stroke
			[if para.isItalic g2 flat] xStart (barBottom + (2/3) * extraCurliness)
			[if para.isItalic g2.left.mid curl] [mix xStart df.leftSB (0.475 + 0.1 * TanSlope)] (barBottom - (1/3) * extraCurliness)
			archv
			g4 (df.leftSB + OX) [YSmoothMidL top barBottom (0.5 * SmallArchDepthA) (0.5 * SmallArchDepthB)]
			arch.rhs top (sw -- stroke)
			flatside.rd df.rightSB 0 top ada adb
			hookend 0 (sw -- stroke)
			g4 (df.leftSB + 0.5 * OX) [HookHeight top stroke true]

	define [AbkCheShape] : with-params [
		fDesc Body df top [stroke : Math.min df.mvs : AdviceStroke2 2 3 top] [barpos nothing]
		[ada SmallArchDepthA] [adb SmallArchDepthB] [tailSlab nothing]
		] : glyph-proc
		local gap : 0.375 * (df.width - 2 * df.leftSB - 2.5 * stroke) - [HSwToV : 0.25 * stroke]
		define divSub : (df.width - gap - stroke) / Width
		define subDf : DivFrame divSub 2
		include : Body subDf top
			stroke -- stroke
			barpos -- barpos
			ada -- (ada * 0.7 * df.adws)
			adb -- (adb * 0.7 * df.adws)
			tailSlab -- tailSlab
		define shift : Width * (df.adws - divSub)
		if fDesc : begin
			local desc : (-LongVJut) + QuarterStroke
			include : ExtendBelowBaseAnchors desc
			include : difference
				VBar.m subDf.middle desc (stroke + O) (VJutStroke * subDf.mvs / Stroke)
				OShapeOutline.NoOvershoot top 0 subDf.leftSB subDf.rightSB stroke
		include : Translate shift 0

		local hd : FlatHookDepth df
		local yBar : top * DesignParameters.eBarPos - 0.5 * stroke
		include : intersection [MaskLeft : subDf.leftSB + shift] : dispiro
			flat (df.leftSB - [HSwToV : 0.25 * stroke]) (yBar + Hook) [widths.lhs.heading stroke Downward]
			curl (df.leftSB - [HSwToV : 0.25 * stroke]) (yBar + [Math.min Hook hd.y] - 0.25 * stroke) [heading Downward]
			arcvh
			flat [Math.min (df.leftSB + hd.x - [HSwToV : 0.5 * stroke]) (subDf.leftSB + shift)] yBar
			curl (subDf.middle + shift) yBar

	define SmallEConfig : object
		flatCrossbar { SmallEShape        RevSmallEShape        }
		rounded      { SmallERoundedShape RevSmallERoundedShape }

	foreach { suffix { Body RevBody } } [Object.entries SmallEConfig] : do
		create-glyph "e.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : Body [DivFrame 1] XH
				ada -- SmallArchDepthA
				adb -- SmallArchDepthB

		create-glyph "eOgonek.\(suffix)" : glyph-proc
			include : MarkSet.e
			local lastKnot : include : Body [DivFrame 1] XH
				ada -- SmallArchDepthA
				adb -- SmallArchDepthB
			include : refer-glyph 'ogonekTR/spacer'

			# Connected Ogonek shape
			local fine : AdviceStroke 8
			local depth : (-Descender) - markStroke
			local extL : (7 / 16) * depth + 0.25 * markStress
			local extR : Math.max (0.0625 * markExtend) (1.5 * TanSlope * markStroke)
			local beginCoSlope : if para.isItalic 0.2 0

			set-base-anchor 'trailing' (RightSB + extR) ((-depth) + 0.5 * O - markStroke)
			set-base-anchor 'belowBraceL' (RightSB - extL - [HSwToV : 0.25 * markStroke]) ((-0.75) * depth)
			set-base-anchor 'belowBraceR' (RightSB - 0.75 * extL) ((-0.75) * depth)

			local turnSlope : 0.5 * ((markStroke - fine) / markStroke - (ArchDepthB - ArchDepth) / ArchDepth)

			include : intersection
				MaskBelow lastKnot.y
				dispiro
					g4 lastKnot.x lastKnot.y [widths.rhs fine]
					g4 (lastKnot.x - beginCoSlope * TINY) (lastKnot.y - TINY)
					alsoThruThem.computed { (1/3) (2/3) } : object
						rx       : function [rt] rt
						deltaX   : function [rt] 0
						ry       : function [rt] : (1/24) + rt + ((1/2) - rt) * (3/8)
						deltaY   : function [rt] : (-0.25) * [mix fine markStroke rt]
						modifier : function [rt] : widths.rhs [mix fine markStroke : rt ** 2]
					g4.down.mid (RightSB - extL) ((-0.75) * depth) [widths.rhs.heading markStroke {.x HVContrast .y turnSlope}]
					arcvh [widths.rhs markStroke]
					g4 (RightSB + [mix (-extL) extR (11/16)]) ((-depth) + O) [heading Rightward]
					g4 (RightSB + extR) ((-depth) + 0.5 * O) [heading Rightward]

		create-glyph "eWithNotch.\(suffix)" : glyph-proc
			include : MarkSet.e
			local lastKnot : include : Body [DivFrame 1] XH
				ada -- SmallArchDepthA
				adb -- SmallArchDepthB
			local sw : AdviceStroke 4
			local ry : Math.min (lastKnot.y - sw) (XH * 0.08)
			local rx : Math.min ry
			include : dispiro
				g4.down.start lastKnot.x lastKnot.y [widths.rhs sw]
				arcvh
				g4 (lastKnot.x + rx) (lastKnot.y - ry + O)
				archv
				g4.up.end (lastKnot.x + rx * 2) lastKnot.y

		create-glyph "eRetroflexHook.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : Body [DivFrame 1] XH
				ada -- SmallArchDepthA
				adb -- SmallArchDepthB
				tailSlab -- SLAB-CLASSICAL
			include : RetroflexHook.r
				x -- RightSB
				y -- 0
				yAttach -- DToothlessRise

		create-glyph "Schwa.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : Body [DivFrame 1] CAP
				ada -- ArchDepthA
				adb -- ArchDepthB
			include : FlipAround Middle (CAP / 2)

		create-glyph "schwa.\(suffix)" : glyph-proc
			include [refer-glyph "e.\(suffix)"] AS_BASE ALSO_METRICS
			include : FlipAround Middle (XH / 2)

		create-glyph "schwaRhoticHook.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleM 1
			include : df.markSet.e
			local divSub : Math.min 1 : 0.85 * para.advanceScaleM
			local dfSub : DivFrame divSub 2
			local stroke : AdviceStroke2 2 3 XH divSub
			include : Body dfSub XH
				stroke -- stroke
				ada -- [dfSub.archDepthAOf SmallArchDepth stroke]
				adb -- [dfSub.archDepthBOf SmallArchDepth stroke]
			include : FlipAround dfSub.middle (XH / 2)
			include : RhoticHookShape (dfSub.rightSB - [HSwToV : 1.25 * markFine]) df.width (XH * 0.5) (XH * 0.2)

		create-glyph "schwaRetroflexHook.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleM 1
			include : df.markSet.e
			local divSub : Math.min 1 : 0.85 * para.advanceScaleM
			local dfSub : DivFrame divSub 2
			local stroke : AdviceStroke2 2 3 XH divSub
			include : Body dfSub XH
				stroke -- stroke
				ada -- [dfSub.archDepthAOf SmallArchDepth stroke]
				adb -- [dfSub.archDepthBOf SmallArchDepth stroke]
			include : FlipAround dfSub.middle (XH / 2)
			include : RetroflexHook.r
				x -- [mix RightSB df.width 0.5]
				y -- 0
				yAttach -- (XH / 2 - HalfStroke)
				xLink -- (dfSub.rightSB - [HSwToV : 0.5 * stroke])
				refSw -- [AdviceStroke 4]

		create-glyph "eRev.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : RevBody [DivFrame 1] XH
				ada -- SmallArchDepthA
				adb -- SmallArchDepthB

		create-glyph "eBar.\(suffix)" : glyph-proc
			include [refer-glyph "e.\(suffix)"] AS_BASE ALSO_METRICS
			include : HBar.m [mix SB 0 0.7] [mix RightSB Width 0.7] (XH * 0.25 + QuarterStroke)
				Math.min (0.25 * (XH - 3 * Stroke)) : AdviceStroke 5

		DefineSelectorGlyph "cyrl/Schwa" suffix [DivFrame 1] 'capital'
		DefineSelectorGlyph "cyrl/schwa" suffix [DivFrame 1] 'e'

		define abkCheDf : DivFrame para.advanceScaleM 3

		DefineSelectorGlyph "cyrl/abk/Che"          suffix abkCheDf 'capital'
		DefineSelectorGlyph "cyrl/abk/che"          suffix abkCheDf 'e'
		DefineSelectorGlyph "cyrl/abk/CheDescender" suffix abkCheDf 'capDesc'
		DefineSelectorGlyph "cyrl/abk/cheDescender" suffix abkCheDf 'p'

		foreach { suffixSerif { styTop styBot } } [Object.entries CConfig] : do
			create-glyph "cyrl/Schwa.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : Body [DivFrame 1] CAP
					ada -- ArchDepthA
					adb -- ArchDepthB
					tailSlab -- styTop
					noSwash -- true
				include : FlipAround Middle (CAP / 2)
			create-glyph "cyrl/schwa.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : Body [DivFrame 1] XH
					ada -- SmallArchDepthA
					adb -- SmallArchDepthB
					tailSlab -- styTop
					noSwash -- true
				include : FlipAround Middle (XH / 2)

			create-glyph "cyrl/abk/Che.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : AbkCheShape false Body abkCheDf CAP
					ada -- ArchDepthA
					adb -- ArchDepthB
					tailSlab -- styBot
			create-glyph "cyrl/abk/che.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : AbkCheShape false Body abkCheDf XH
					ada -- SmallArchDepthA
					adb -- SmallArchDepthB
					tailSlab -- styBot
			create-glyph "cyrl/abk/CheDescender.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : AbkCheShape true Body abkCheDf CAP
					ada -- ArchDepthA
					adb -- ArchDepthB
					tailSlab -- styBot
			create-glyph "cyrl/abk/cheDescender.\(suffix).\(suffixSerif)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : AbkCheShape true Body abkCheDf XH
					ada -- SmallArchDepthA
					adb -- SmallArchDepthB
					tailSlab -- styBot

		select-variant "cyrl/Schwa.\(suffix)" (follow -- 'cyrl/ETopSerifOnly')
		select-variant "cyrl/schwa.\(suffix)" (follow -- 'cyrl/eTopSerifOnly')
		select-variant "cyrl/abk/Che.\(suffix)" (follow -- 'CBottomSerifOnly')
		select-variant "cyrl/abk/che.\(suffix)" (follow -- 'cBottomSerifOnly')
		select-variant "cyrl/abk/CheDescender.\(suffix)" (follow -- 'CBottomSerifOnly')
		select-variant "cyrl/abk/cheDescender.\(suffix)" (follow -- 'cBottomSerifOnly')

	select-variant 'e' 'e'
	alias 'cyrl/ie' 0x435 'e'
	CreateTurnedLetter 'turne' 0x1DD 'e' HalfAdvance (XH / 2)

	select-variant 'eOgonek' 0x119 (follow -- 'e')
	select-variant 'eRetroflexHook' 0x1D92 (follow -- 'e')
	select-variant 'eWithNotch' 0x2C78 (follow -- 'e')

	select-variant 'Schwa' 0x18F
	select-variant 'schwa' 0x259
	select-variant 'schwaRhoticHook' 0x25A (follow -- 'schwa')
	select-variant 'schwaRetroflexHook' 0x1D95 (follow -- 'schwa')

	select-variant 'eRev' 0x258 (follow -- 'e')

	select-variant 'eBar' 0xAB33 (follow -- 'e')

	CreateSelectorVariants 'cyrl/Schwa' 0x4D8 [Object.keys SmallEConfig] (follow -- 'Schwa')
	alias 'Schwa.TRK' null 'cyrl/Schwa'

	CreateSelectorVariants 'cyrl/schwa' 0x4D9 [Object.keys SmallEConfig] (follow -- 'schwa')
	alias 'schwa.TRK' null 'cyrl/schwa'

	CreateSelectorVariants 'cyrl/abk/Che' 0x4BC [Object.keys SmallEConfig]
	CreateSelectorVariants 'cyrl/abk/che' 0x4BD [Object.keys SmallEConfig]
	CreateSelectorVariants 'cyrl/abk/CheDescender' 0x4BE [Object.keys SmallEConfig] (follow -- 'cyrl/abk/Che')
	CreateSelectorVariants 'cyrl/abk/cheDescender' 0x4BF [Object.keys SmallEConfig] (follow -- 'cyrl/abk/che')

	glyph-block-import Letter-Blackboard : BBS BBD
	create-glyph 'mathbb/e' 0x1D556 : glyph-proc
		include : MarkSet.e
		include : SmallEShape [DivFrame 1] XH
			stroke -- BBS
			bbd -- BBD
			ada -- SmallArchDepthA
			adb -- SmallArchDepthB
		include : intersection
			OShapeOutline.NoOvershoot XH 0 SB RightSB BBS
			union
				VBar.l (SB + BBD + OX) 0 XH BBS
				VBar.r (RightSB - BBD - OX) (XH * DesignParameters.eBarPos) XH BBS
