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

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

glyph-module

glyph-block Letter-Cyrillic-Che : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Mark-Adjustment : LeaningAnchor
	glyph-block-import Letter-Shared : CreateSelectorVariants DefineSelectorGlyph CreateTurnedLetter
	glyph-block-import Letter-Shared-Shapes : cheBowl SerifFrame RightwardTailedBar
	glyph-block-import Letter-Shared-Shapes : TopHook CyrDescender BottomExtension
	glyph-block-import Letter-Latin-Lower-M : EarlessCornerDoubleArchSmallMShape

	glyph-block-export BODY
	define BODY : object
		STRAIGHT 0
		TAILED   1

	glyph-block-export SERIFS
	define SERIFS : object
		NONE        0
		TL          1
		BR          2
		TL-BR       3
		ALL         4
		TOP         5
		ALL-BGR     6
		TOP-BGR     7
		ALL-SYM     8

	glyph-block-export CyrCheShape
	define [CyrCheShape] : with-params [df top pyBar bodyType slabType [sw df.mvs] [yBarOffset 0]] : glyph-proc
		local bar : top * [fallback pyBar 0.5] + yBarOffset

		include : tagged 'strokeR' : match bodyType
			[Just BODY.TAILED] : RightwardTailedBar df.rightSB 0 top (sw -- sw)
			__                 : VBar.r df.rightSB 0 top sw

		include : cheBowl.shape
			left   -- df.leftSB
			right  -- df.rightSB
			top    -- top
			bottom -- (bar - 0.5 * sw)
			sw     -- sw

		local sf : SerifFrame.fromDf df top 0
		include : tagged 'serifLT' : match slabType
			[Just SERIFS.ALL]        sf.lt.full
			[Just SERIFS.TOP]        sf.lt.full
			[Just SERIFS.ALL-SYM]    sf.lt.full
			[Just SERIFS.ALL-BGR]    sf.lt.outer
			[Just SERIFS.TOP-BGR]    sf.lt.outer
			[Just SERIFS.TL-BR]      sf.lt.outer
			[Just SERIFS.TL]         sf.lt.outer
			__                   : glyph-proc
		include : tagged 'SerifRT' : match slabType
			[Just SERIFS.ALL]        sf.rt.full
			[Just SERIFS.TOP]        sf.rt.full
			[Just SERIFS.ALL-SYM]    sf.rt.full
			[Just SERIFS.ALL-BGR]    sf.rt.inner
			[Just SERIFS.TOP-BGR]    sf.rt.inner
			__                   : glyph-proc
		include : tagged 'SerifRB' : match slabType
			[Just SERIFS.ALL]        sf.rb.fullSide
			[Just SERIFS.ALL-BGR]    sf.rb.fullSide
			[Just SERIFS.ALL-SYM]    sf.rb.full
			[Just SERIFS.TL-BR]      sf.rb.outer
			[Just SERIFS.BR]         sf.rb.outer
			__                   : glyph-proc

	define [CyrCcheShape] : with-params [df top pyBar bodyType slabType [sw df.mvs] [yBarOffset 0]] : glyph-proc
		local bar : top * [fallback pyBar 0.5] + yBarOffset

		include : EarlessCornerDoubleArchSmallMShape df (top - (bar - 0.5 * sw)) 0 0 0
		eject-contour 'barL'
		include : FlipAround df.middle (top / 2)

		include : tagged 'strokeR' : match bodyType
			[Just BODY.TAILED] : RightwardTailedBar df.rightSB 0 top (sw -- sw)
			__                 : VBar.r df.rightSB 0 top sw

		local sf : SerifFrame.fromDf df top 0
		include : tagged 'serifLT' : match slabType
			[Just SERIFS.ALL]        [if sf.enoughSpaceForFullSerifs sf.lt.full sf.lt.outer]
			[Just SERIFS.TOP]        [if sf.enoughSpaceForFullSerifs sf.lt.full sf.lt.outer]
			[Just SERIFS.TL-BR]      sf.lt.outer
			[Just SERIFS.TL]         sf.lt.outer
			__                   : glyph-proc
		include : tagged 'serifMT' : match slabType
			[Just SERIFS.ALL]        [if sf.enoughSpaceForFullSerifs sf.mt.full [glyph-proc]]
			[Just SERIFS.TOP]        [if sf.enoughSpaceForFullSerifs sf.mt.full [glyph-proc]]
			__                   : glyph-proc
		include : tagged 'SerifRT' : match slabType
			[Just SERIFS.ALL]        [if sf.enoughSpaceForFullSerifs sf.rt.full sf.rt.outer]
			[Just SERIFS.TOP]        [if sf.enoughSpaceForFullSerifs sf.rt.full sf.rt.outer]
			__                   : glyph-proc
		include : tagged 'SerifRB' : match slabType
			[Just SERIFS.ALL]        sf.rb.fullSide
			[Just SERIFS.TL-BR]      sf.rb.outer
			[Just SERIFS.BR]         sf.rb.outer
			__                   : glyph-proc

	define [CyrTcheShape] : with-params [df top pyBar bodyType slabType [teSerifs SLAB] [sw : AdviceStroke 2.75] [yBarOffset 0]] : glyph-proc
		local bar : top * [fallback pyBar 0.5] + yBarOffset

		local left : [mix df.leftSB df.rightSB : if (df.adws > 1) 0.25 0.2] - [HSwToV : 0.25 * sw] + OX
		local right : df.rightSB - OX

		include : tagged 'strokeR' : match bodyType
			[Just BODY.TAILED] : RightwardTailedBar right 0 top (sw -- sw)
			__                 : VBar.r right 0 top sw

		include : cheBowl.shape
			left   -- left
			right  -- right
			top    -- top
			bottom -- (bar - 0.5 * sw)
			sw     -- sw
			fine   -- (0.5 * sw)

		local xTopBarLeft : df.leftSB - SideJut
		local xTopBarRight : mix xTopBarLeft (left + [HSwToV : 0.5 * sw]) 2

		include : dispiro
			widths.rhs sw
			flat xTopBarLeft  top [if teSerifs [heading Rightward] null]
			curl xTopBarRight top [if teSerifs [heading Rightward] null]

		local sf : SerifFrame top 0 left right (swRef -- sw)
		include : tagged 'SerifRT' : match slabType
			[Just SERIFS.ALL]        sf.rt.outer
			[Just SERIFS.TOP]        sf.rt.outer
			__                   : glyph-proc
		include : tagged 'SerifRB' : match slabType
			[Just SERIFS.ALL]        sf.rb.fullSide
			[Just SERIFS.TL-BR]      sf.rb.outer
			[Just SERIFS.BR]         sf.rb.outer
			__                   : glyph-proc

		if teSerifs : begin
			local swVJut : Math.min (0.625 * (left - xTopBarLeft)) : AdviceStroke 4.5
			include : VSerif.dl xTopBarLeft  top VJut swVJut
			include : VSerif.dr xTopBarRight top VJut swVJut

	create-glyph 'cyrl/Che' 0x427 : glyph-proc
		include : MarkSet.capital
		include : LeaningAnchor.Below.VBar.r RightSB
		include : CyrCheShape [DivFrame 1] CAP [if SLAB 0.45 0.35] BODY.STRAIGHT
			if SLAB SERIFS.ALL SERIFS.NONE

	create-glyph 'cyrl/CheDescender' 0x4B6 : composite-proc
		refer-glyph 'cyrl/Che'
		CyrDescender.rSideJut RightSB 0
	create-glyph 'cyrl/kjh/Che' 0x4CB : composite-proc
		refer-glyph 'cyrl/Che'
		CyrDescender.lSideJut (RightSB - [HSwToV Stroke]) 0 (jut -- MidJutSide)

	create-glyph 'cyrl/Cche' 0xA686 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 3
		include : df.markSet.capital
		include : LeaningAnchor.Below.VBar.r df.rightSB
		include : CyrCcheShape df CAP [if SLAB 0.45 0.35] BODY.STRAIGHT
			if SLAB SERIFS.ALL SERIFS.NONE

	define TcheConfig : object
		serifless     { false false }
		motionSerifed { true  false }

	foreach { suffix { doST doSB } } [Object.entries TcheConfig] : do
		create-glyph "cyrl/Tche.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleT
			include : df.markSet.capital
			include : LeaningAnchor.Below.VBar.r df.rightSB
			include : CyrTcheShape df CAP [if SLAB 0.45 0.35] BODY.STRAIGHT
				if SLAB SERIFS.ALL SERIFS.NONE
				teSerifs -- doST

	select-variant 'cyrl/Tche' 0xA692 (follow -- 'T/rtailBase')

	glyph-block-export ItalicConfig
	define ItalicConfig : object
		standard { BODY.STRAIGHT SERIFS.ALL SERIFS.ALL-BGR SERIFS.TL-BR }
		tailed   { BODY.TAILED   SERIFS.TOP SERIFS.TOP-BGR SERIFS.TL    }

	foreach { suffix { body slabUpright slabUprightBGR slabItalic } } [pairs-of ItalicConfig] : do
		create-glyph "cyrl/che.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : LeaningAnchor.Below.VBar.r RightSB
			include : CyrCheShape [DivFrame 1] XH [if SLAB 0.45 0.4] body
				if SLAB [if para.isItalic slabItalic slabUpright] SERIFS.NONE

		create-glyph "cyrl/che.BGR.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : LeaningAnchor.Below.VBar.r RightSB
			include : CyrCheShape [DivFrame 1] XH [if SLAB 0.45 0.4] body
				if SLAB [if para.isItalic slabItalic slabUprightBGR] SERIFS.NONE

		create-glyph "cyrl/cche.\(suffix)" : glyph-proc
			local df : include : DivFrame para.advanceScaleMM 3
			include : df.markSet.e
			include : LeaningAnchor.Below.VBar.r df.rightSB
			include : CyrCcheShape df XH [if SLAB 0.45 0.4] body
				if SLAB [if para.isItalic slabItalic slabUpright] SERIFS.NONE

		define cyrTcheDf : DivFrame para.advanceScaleT

		DefineSelectorGlyph "cyrl/tche" suffix cyrTcheDf 'e'

		foreach { suffixTe { doST doSB } } [Object.entries TcheConfig] : do
			create-glyph "cyrl/tche.\(suffix).\(suffixTe)" : glyph-proc
				set-width 0
				set-mark-anchor 'cvDecompose' 0 0
				include : LeaningAnchor.Below.VBar.r cyrTcheDf.rightSB
				include : CyrTcheShape cyrTcheDf XH [if SLAB 0.45 0.4] body
					if SLAB [if para.isItalic slabItalic slabUpright] SERIFS.NONE
					teSerifs -- doST

		select-variant "cyrl/tche.\(suffix)" (follow -- 'T/rtailBase')

	select-variant 'cyrl/che' 0x447
	select-variant 'cyrl/che.BGR' (follow -- 'cyrl/che')

	create-glyph 'cyrl/cheDescender' 0x4B7 : composite-proc
		refer-glyph 'cyrl/che.standard'
		CyrDescender.rSideJut RightSB 0
	create-glyph 'cyrl/kjh/che' 0x4CC : composite-proc
		refer-glyph 'cyrl/che.standard'
		CyrDescender.lSideJut (RightSB - [HSwToV Stroke]) 0 (jut -- MidJutSide)

	select-variant 'cyrl/cche' 0xA687 (follow -- 'cyrl/che')

	CreateSelectorVariants 'cyrl/tche' 0xA693 [Object.keys ItalicConfig] (follow -- 'cyrl/che')

	define [CheVBarBarShape top pyBar] : begin
		local SwCheVBar : Math.min OverlayStroke : VSwToH : 0.625 * ((RightSB - SB) - [HSwToV : 2 * Stroke])
		local yc : top * [fallback pyBar 0.5] + Stroke * 0.1
		return : VBar.m Middle (yc + LongVJut * 0.8) (yc - LongVJut * 0.8) SwCheVBar

	derive-composites 'cyrl/CheVBar' 0x4B8 'cyrl/Che' [CheVBarBarShape CAP : if SLAB 0.45 0.35]
	derive-composites 'cyrl/cheVBar' 0x4B9 'cyrl/che' [CheVBarBarShape XH  : if SLAB 0.45 0.4]

	define ShhaConfig : object
		serifless                 SERIFS.NONE
		topLeftSerifed            SERIFS.BR
		topLeftBottomRightSerifed SERIFS.TL-BR
		serifed                   SERIFS.ALL-SYM

	foreach { suffix serifs } [pairs-of ShhaConfig] : do
		create-glyph "cyrl/Shha.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : LeaningAnchor.Above.VBar.l SB
			include : CyrCheShape [DivFrame 1] CAP (1 - HBarPos) BODY.STRAIGHT serifs
				yBarOffset -- (DToothlessRise * ([HSwToV : 1.2 * Stroke] / (Middle - SB) - 1))
			include : FlipAround Middle (CAP / 2)

		create-glyph "cyrl/Hwe.\(suffix)" : glyph-proc
			include [refer-glyph "cyrl/Shha.\(suffix)"] AS_BASE ALSO_METRICS
			eject-contour 'strokeR'
			eject-contour 'serifRB'
			include : TopHook.toRight.lBarInner SB 0 CAP
			include : LeaningAnchor.Above.VBar.l SB

	select-variant 'cyrl/Shha' 0x4BA (follow -- 'H')
	select-variant 'cyrl/Shha/descBase' (shapeFrom -- 'cyrl/Shha') (follow -- 'H/descBase')
	select-variant 'cyrl/Hwe' 0xA694 (follow -- 'HHookTop')

	derive-composites 'cyrl/ShhaDescender' 0x526 'cyrl/Shha/descBase' [CyrDescender.rSideJut RightSB 0]
