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

import [mix fallback SuffixCfg] from "@iosevka/util"
import [MathSansSerif] from "@iosevka/glyph/relation"

glyph-module

glyph-block Letter-Latin-Upper-R : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Mark-Adjustment : LeaningAnchor
	glyph-block-import Letter-Shared : CreateTurnedLetter
	glyph-block-import Letter-Shared-Shapes : RightwardTailedBar RetroflexHook
	glyph-block-import Letter-Blackboard : BBS BBD
	glyph-block-import Letter-Latin-Upper-P : PShape RevPShape PBarPosY PRotundaShape BBPShape PShapeOutline
	glyph-block-export RConfig RevRShape RBarPos

	define LEG-SHAPE-CURLY    0
	define LEG-SHAPE-STRAIGHT 1
	define LEG-SHAPE-STANDING 2

	define [RLegTerminalX legShape right sw] : right - [if legShape (OX * 2) 0]
	define [RSlabExtraShift slab sw] : if slab ((-Jut) / 2 + [HSwToV : 0.5 * sw]) 0
	define [RLegDiagCor top bottom left right extraShift sw] : DiagCor (top - bottom) (right - left - extraShift) 0 sw

	define [RStandingLegFine sw] : sw * CThinB
	define [RStandingLegBend left right top bottom sw] : Math.min ((right - left) * 0.99) : Math.max (sw * 1.5) ((right - left) * 0.875)
	define [RStandingBottomOverflow slab] : if slab 0 (2 * OX)

	define [RLegShape-Straight] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local shift : RSlabExtraShift slab sw
		local xLeftTop : Math.max (PShape.BarPos + [HSwToV sw]) (left - [HSwToV : 0.5 * sw] + shift)
		local xRightBottom : [RLegTerminalX LEG-SHAPE-STRAIGHT right sw] + shift
		local xRightBottomSerifStart : xRightBottom - [HSwToV : 0.25 * sw]
		include : intersection
			Rect top bottom (-Width) [if slab xRightBottomSerifStart (2 * Width)]
			dispiro
				corner xLeftTop     top    [widths.lhs sw]
				corner xRightBottom bottom [widths.rhs sw]

		if slab : begin
			include : HSerif.rb xRightBottomSerifStart bottom (SideJut + Jut / 8) sw

	define [RLegShape-Curly] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local xRightBottom : RLegTerminalX LEG-SHAPE-CURLY right sw
		include : intersection
			Rect top bottom (-Width) (2 * Width)
			dispiro
				widths.center sw
				g4.up.start (xRightBottom - [HSwToV : 0.5 * sw]) bottom [heading Upward]
				quadControls 0 0.4 8
				g4 left top
		if slab : begin
			include : HSerif.rb right bottom (SideJut + Jut / 8) sw

	define [RLegShape-Standing] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local fine : RStandingLegFine sw
		local bend : RStandingLegBend left right top bottom sw
		local ytopRef : begin top
		local yTopStroke : top - sw / 2 + fine
		local yOffset : mix bottom top 0.2
		local xOverflow : RStandingBottomOverflow slab
		include : dispiro
			widths.rhs fine
			flat left yTopStroke [heading Rightward]
			curl (right - bend) yTopStroke [heading Rightward]
			archv
			flat (right + O) [Math.max (yOffset + 1) (ytopRef - bend * charTop / CAP)] [widths.rhs.heading sw Downward]
			curl (right + O) yOffset [heading Downward]
			curl (right + O - xOverflow) bottom  [heading Downward]
		if slab : include : HSerif.rb right bottom SideJut sw

	define RLegShapes { RLegShape-Curly RLegShape-Straight RLegShape-Standing }

	define [RevRLegTerminalX legShape left sw] : left + [if legShape (OX * 2) 0]

	define [RevRLegShape-Straight] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local shift : RSlabExtraShift slab sw
		local xLeftBottom : [RevRLegTerminalX LEG-SHAPE-STRAIGHT left sw] - shift
		local xLeftBottomSerifStart : xLeftBottom + [HSwToV : 0.25 * sw]
		local xRightTop : Math.min (RightSB - PShape.BarPos - [HSwToV sw]) (right + [HSwToV : 0.5 * sw] - shift)

		include : intersection
			Rect top bottom [if slab xLeftBottomSerifStart (-Width)] (2 * Width)
			dispiro
				corner xRightTop   top    [widths.rhs sw]
				corner xLeftBottom bottom [widths.lhs sw]
		if slab : begin
			include : HSerif.lb xLeftBottomSerifStart bottom (SideJut + Jut / 8) sw

	define [RevRLegShape-Curly] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local xLeftBottom : RevRLegTerminalX LEG-SHAPE-CURLY left sw
		include : intersection
			Rect top 0 (-Width) (2 * Width)
			dispiro
				widths.center sw
				g4.up.start (xLeftBottom + [HSwToV : 0.5 * sw]) bottom [heading Upward]
				quadControls 0 0.4 8
				g4 right top
		if slab : begin
			include : HSerif.lb left bottom (SideJut + Jut / 8) sw

	define [RevRLegShape-Standing] : with-params [top bottom left right charTop slab sw extraShift] : glyph-proc
		local fine : RStandingLegFine sw
		local bend : RStandingLegBend left right top bottom sw
		local ytopRef : begin top
		local yTopStroke : top - sw / 2 + fine
		local yOffset : mix bottom top 0.2
		local xOverflow : RStandingBottomOverflow slab
		include : dispiro
			widths.lhs fine
			flat right yTopStroke [heading Leftward]
			curl (left + bend) yTopStroke [heading Leftward]
			archv
			flat (left - O) [Math.max (yOffset + 1) (ytopRef - bend * charTop / CAP)] [widths.lhs.heading sw Downward]
			curl (left - O) yOffset [heading Downward]
			curl (left - O + xOverflow) bottom  [heading Downward]
		if slab : include : HSerif.lb left bottom SideJut sw

	define RevRLegShapes { RevRLegShape-Curly RevRLegShape-Straight RevRLegShape-Standing }


	define [RBarPos charTop slab] : begin PShape.BarPos
	define [RLegTop charTop sw bp] : (sw / 2) + [PBarPosY charTop sw bp]

	define [RShape] : with-params [legShape top bp [df [DivFrame 1]] [mul 1] [slab null] [legSlab false] [open false] [legBottom 0] [sw Stroke]] : glyph-proc
		local right : df.rightSB - O - [if slab (Jut / 8) 0]
		include : difference
			PShape top (df -- df) (mul -- mul) (overshoot -- O) (slab -- slab) (bp -- bp) (sw -- sw)
			if open [PShape.OpenGap (df -- df) (mul -- mul) (bp -- bp) (top -- top) (bot -- [if fSlabBot sw 0])] [glyph-proc]
		include : difference
			RLegShapes.(legShape) [RLegTop top sw bp] legBottom df.middle right top legSlab sw 0
			if open [PShape.OpenGap (df -- df) (mul -- mul) (bp -- bp) (top -- top) (bot -- 0)] [glyph-proc]

	define [RRotundaShape] : with-params [legShape top [df [DivFrame 1]] [mul 1] [pmRotunda 0] [endX df.middle] [hook Hook] [pBar 1] [slab null] [legSlab false] [sw Stroke]] : glyph-proc
		local bp : pBar * [RBarPos top false]
		local legTop : RLegTop top sw bp
		local right (df.rightSB - O - [if slab (Jut / 8) 0])
		local cor : RLegDiagCor legTop 0 endX right 0 sw
		local endX1 : endX - [if legShape (sw / 2 * [HSwToV cor]) (sw / 2)] + [if legShape [RSlabExtraShift SLAB sw] 0]
		include : PRotundaShape top (df -- df) (mul -- mul) (bp -- bp) (overshoot -- O) (slab -- false) (endX -- endX1) (hook -- hook) (sw -- sw)
		include : difference
			RLegShapes.(legShape) legTop 0 endX right top legSlab sw 0
			MaskLeft endX1

	define [RevRShape] : with-params [legShape top bp [df [DivFrame 1]] [slab null] [legSlab false] [mul 1] [tailedShape false] [open false] [sw Stroke]] : glyph-proc
		local left : df.leftSB + O + [if slab (Jut / 8) 0]
		include : difference
			RevPShape top (df -- df) (mul -- mul) (overshoot -- O) (slab -- slab) (bp -- bp) (sw -- sw)
			if open [RevPShape.OpenGap (df -- df) (mul -- mul) (bp -- bp) (top -- top) (bot -- [if fSlabBot sw 0])] [glyph-proc]
		include : difference
			RevRLegShapes.(legShape) [RLegTop top sw bp] 0 left df.middle top legSlab sw 0
			if open [RevPShape.OpenGap (df -- df) (mul -- mul) (bp -- bp) (top -- top) (bot -- 0)] [glyph-proc]
		if tailedShape : begin
			eject-contour 'strokeR'
			eject-contour 'serifRB'
			include : tagged 'strokeR' : RightwardTailedBar (df.width - df.leftSB * mul) 0 top

	define [StrikeAnchor] : glyph-proc
		set-base-anchor 'strike' Middle [mix [PBarPosY CAP Stroke : RBarPos CAP SLAB] CAP 0.5]

	define RConfig : SuffixCfg.weave
		object # Leg shape
			straight                 LEG-SHAPE-STRAIGHT
			curly                    LEG-SHAPE-CURLY
			standing                 LEG-SHAPE-STANDING
		object # openness
			""                       false
			open                     true
		object # tail
			""                       false
			tailed                   true
		object # serifs
			serifless                    { null                           null                                                                false }
			topLeftSerifed               { PShape.SlabMotion              RevPShape.SlabMotion                                                false }
			bottomRightSerifed           { null                           null                                                                true  }
			topLeftAndBottomRightSerifed { PShape.SlabMotion              RevPShape.SlabMotion                                                true  }
			serifed                      { PShape.SlabSymmetric           RevPShape.SlabSymmetric                                             true  }
			smallCyrl                    { PShape.SlabMotion              [if para.isItalic RevPShape.SlabCyrlItalic RevPShape.SlabSymmetric] true  }

	foreach { suffix { legShape fOpen fTailed {slabs revSlabs doLegSlab} } } [Object.entries RConfig] : begin
		local fMotion : slabs === PShape.SlabMotion
		local fSlabBot : slabs && slabs !== PShape.SlabMotion
		local bpCap : RBarPos CAP fSlabBot
		local bpXH  : RBarPos XH  fSlabBot

		create-glyph "R.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : StrikeAnchor
			include : RShape legShape CAP (slab -- slabs) (legSlab -- doLegSlab) (bp -- bpCap) (open -- fOpen)

		if (!fOpen) : create-glyph "RBar.\(suffix)" : glyph-proc
			include [refer-glyph "R.\(suffix)"] AS_BASE ALSO_METRICS
			include : HBar.m [mix 0 SB 0.3] (SB - O) ((CAP - Stroke) * [RBarPos CAP SLAB] + QuarterStroke)

		if (!fSlabBot) : create-glyph "RRTail.\(suffix)" : glyph-proc
			include [refer-glyph "R.\(suffix)"] AS_BASE ALSO_METRICS
			eject-contour 'serifLB'
			include : RetroflexHook.lExt SB 0

		create-glyph "smcpR.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : StrikeAnchor
			include : RShape legShape XH (slab -- slabs) (legSlab -- doLegSlab) (bp -- bpXH) (open -- fOpen)

		if (!slabs && !fOpen) : create-glyph "RRotunda.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : RRotundaShape legShape CAP (hook -- Hook) (pBar -- 0.9) (slab -- null) (legSlab -- doLegSlab)

		if (!slabs && !fOpen) : create-glyph "rRotunda.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : RRotundaShape legShape XH (hook -- AHook) (pBar -- 0.9) (slab -- null) (legSlab -- doLegSlab)

		create-glyph "cyrl/Ya.\(suffix)" : glyph-proc
			include : MarkSet.capital
			include : StrikeAnchor
			include : RevRShape legShape CAP (slab -- revSlabs) (legSlab -- doLegSlab) (bp -- bpCap) (open -- fOpen)

		create-glyph "cyrl/ya.\(suffix)" : glyph-proc
			include : MarkSet.e
			include : StrikeAnchor
			include : RevRShape legShape XH (slab -- revSlabs) (legSlab -- doLegSlab) (bp -- bpXH) (tailedShape -- fTailed) (open -- fOpen)

		create-glyph "Yr.\(suffix)" : glyph-proc
			include : MarkSet.capDesc
			local top : CAP * 0.825 + [if fSlabBot (-0.2125) 0.25  ] * Stroke
			local bp : (CAP * 0.25  + [if fSlabBot   0.8375  0.7125] * Stroke) / top
			include : LeaningAnchor.Above.VBar.l SB
			include : LeaningAnchor.Below.VBar.r RightSB

			include : VBar.l SB (top - 1) CAP
			include : RShape legShape top (legSlab -- doLegSlab) (bp -- bp) (open -- fOpen) (legBottom -- Descender)
			include : match slabs
				[Just PShape.SlabSymmetric] : PShape.SlabFullSymmetric CAP [DivFrame 1] Stroke 1
				[Just PShape.SlabMotion]    : PShape.SlabMotion        CAP [DivFrame 1] Stroke 1
				__                          : glyph-proc

		create-glyph "smcpRLongRightLeg.\(suffix)" : glyph-proc
			include : MarkSet.p
			include : StrikeAnchor
			include : LeaningAnchor.Below.VBar.r RightSB
			include : RShape legShape XH (slab -- slabs) (legSlab -- doLegSlab) (bp -- bpXH) (open -- fOpen) (legBottom -- Descender)

		if (!slabs && !fOpen) : create-glyph "currency/indianRupeeSign.\(suffix)" : glyph-proc
			define bp : RBarPos CAP 0
			include : intersection
				Rect CAP 0 SB Width
				with-transform [Translate ((-Width) / 8) 0]
					PShape CAP (bp -- bp) (withBar -- false)
			local right : RightSB - O - [if legShape 0 (Width / 16)]
			include : RLegShapes.(legShape) [RLegTop CAP Stroke bp] 0 (Width * 0.375) right CAP doLegSlab Stroke 0

			define sw : AdviceStroke2 2 4 CAP
			include : HBar.t SB RightSB CAP sw
			include : HBar.m SB RightSB [mix CAP [PBarPosY CAP Stroke bp] 0.5] sw

	select-variant 'R' 'R'
	link-reduced-variant 'R/sansSerif' 'R' MathSansSerif

	select-variant 'RBar' 0x24C
	select-variant 'RRTail' 0x2C64

	select-variant 'smcpR' 0x280 (follow -- 'R')
	CreateTurnedLetter 'turnSmapR' 0x1D1A 'smcpR' HalfAdvance (XH / 2)

	select-variant 'RRotunda' 0xA75A
	select-variant 'rRotunda' 0xA75B (follow -- 'RRotunda')

	select-variant 'cyrl/Ya' 0x42F
	select-variant 'cyrl/ya' 0x44F
	select-variant 'revSmcpR' 0x1D19 (shapeFrom -- 'cyrl/ya') (follow -- 'R')
	CreateTurnedLetter 'invSmcpR' 0x281 'revSmcpR' HalfAdvance (XH / 2)

	select-variant 'Yr' 0x1A6 (follow -- 'R')
	select-variant 'smcpRLongRightLeg' 0xAB46 (follow -- 'R')

	select-variant 'currency/indianRupeeSign' 0x20B9 (follow -- 'RRotunda')

	create-glyph 'mathbb/R' 0x211D : glyph-proc
		define [SingleLeg] : RLegShape-Straight ((CAP - BBS) * HBarPos) 0 Middle (RightSB - O) CAP false BBS (BBD / 2)
		define terminalX : RLegTerminalX LEG-SHAPE-STRAIGHT (RightSB - O) BBS
		include : MarkSet.capital
		include : BBPShape (mul -- 1) (overshoot -- O)
		include : difference
			union
				SingleLeg
				with-transform [ApparentTranslate (-BBD) 0] [SingleLeg]
				HBar.b (terminalX - BBD - [HSwToV BBS]) (terminalX - [HSwToV BBS]) 0 BBS
			PShapeOutline CAP (sw -- BBS) (mul -- 1) (overshoot -- O) (offset -- 1)
			MaskLeft (SB + BBD)
