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

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

glyph-module

glyph-block Symbol-Pictograph-Powerline-And-GUI : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Common-OShape-Variants : OvalShapeT
	glyph-block-import Shared-Symbol-Shapes : TriangleShape
	glyph-block-import Symbol-Pictograph-Stick-Figure : StickFigureKit PointingHandShape
	glyph-block-import Symbol-Geometric-Shared : GeometricDim

	define uiFigTop : mix ParenBot ParenTop 0.95
	define uiFigBot : mix ParenBot ParenTop 0.05

	create-glyph 'powerline/branch' 0xE0A0 : glyph-proc
		local fine : AdviceStroke 3.5
		local y1 : mix uiFigBot uiFigTop 0.8
		local y2 : mix uiFigBot uiFigTop 0.2
		include : VBar.l SB uiFigBot uiFigTop fine
		include : dispiro
			widths.rhs fine
			flat RightSB y1
			curl RightSB [mix y1 y2 0.4]
			g4 (SB + [HSwToV fine]) y2 [heading Leftward]
		include : DotAt (RightSB - [HSwToV fine] / 2) y1 [Math.max (fine * 1.5) PeriodRadius]

	create-glyph 'powerline/lock' 0xE0A2 : glyph-proc
		local fine : AdviceStroke 3.5
		local lockTop : mix uiFigBot uiFigTop 0.6
		local lockLeft : SB / 2
		local lockRight : Width - SB / 2
		local lockHoleWidth : 1 / 5
		local lockHoleLeft : mix lockLeft lockRight (1 / 2 - lockHoleWidth / 2)
		local lockHoleRight : mix lockLeft lockRight (1 / 2 + lockHoleWidth / 2)
		local lockHoleTop : mix uiFigBot lockTop 0.75
		local lockHoleBottom : mix uiFigBot lockTop 0.25
		include : union
			intersection
				spiro-outline
					corner 0 (2 * uiFigTop)
					corner Width (2 * uiFigTop)
					corner Width (lockTop - 1)
					corner 0 (lockTop - 1)
					close
				OShape uiFigTop uiFigBot SB RightSB fine (SmallArchDepthA) (SmallArchDepthB)
			difference
				spiro-outline
					corner lockLeft lockTop
					corner lockRight lockTop
					corner lockRight uiFigBot
					corner lockLeft uiFigBot
					close
				OShapeOutline lockHoleTop lockHoleBottom lockHoleLeft lockHoleRight fine (SmallArchDepthA * lockHoleWidth) (SmallArchDepthB * lockHoleWidth)

	define [KeyholeStroke t b l r sw circBot] : glyph-proc
		local trigTop : mix b t 1.5
		local trigClip : mix t circBot 0.5
		local mx : mix l r 0.5
		local circ : OvalShapeT dispiro t circBot l r sw
		local circMask : OvalShapeT spiro-outline t circBot l r
		local trig : intersection [MaskBelow trigClip]
			TriangleShape mx trigTop r b l b sw
		local trigMask : intersection [MaskBelow trigClip]
			spiro-outline [corner mx trigTop] [corner r b] [corner l b]

		include : difference
			union circMask trigMask
			union
				difference circMask circ
				difference trigMask trig

	create-glyph 'keyhole' 0x1CEB1 : glyph-proc
		local diameter : RightSB - SB - OX * 2
		include : KeyholeStroke (PictTop - O) PictBot (SB + OX) (RightSB - OX) GeometryStroke (PictTop - O - diameter)

	do "Progress Bar"
		define frameLeft  : mix SB RightSB DesignParameters.bracketOutside
		define frameRight : mix RightSB SB DesignParameters.bracketOutside
		define progressBarGap : Math.min ((TackTop - TackBot) / 6) (Width / 6) [AdviceStroke 5]

		create-glyph 'powerline/progressBarStartEmpty' 0xEE00 : glyph-proc
			include : VBar.l frameLeft TackTop TackBot GeometryStroke
			include : HBar.t frameLeft (Width - O) TackTop GeometryStroke
			include : HBar.b frameLeft (Width - O) TackBot GeometryStroke

		create-glyph 'powerline/progressBarMiddleEmpty' 0xEE01 : glyph-proc
			include : HBar.t O (Width - O) TackTop GeometryStroke
			include : HBar.b O (Width - O) TackBot GeometryStroke

		create-glyph 'powerline/progressBarEndEmpty' 0xEE02 : glyph-proc
			include : VBar.r frameRight TackTop TackBot GeometryStroke
			include : HBar.t O frameRight TackTop GeometryStroke
			include : HBar.b O frameRight TackBot GeometryStroke

		create-glyph 'powerline/progressBarStartFilled' 0xEE03 : glyph-proc
			include : refer-glyph 'powerline/progressBarStartEmpty' AS_BASE ALSO_METRICS
			include : Rect
				TackTop - GeometryStroke - progressBarGap
				TackBot + GeometryStroke + progressBarGap
				frameLeft + [HSwToV GeometryStroke] + [HSwToV progressBarGap]
				Width - O

		create-glyph 'powerline/progressBarMiddleFilled' 0xEE04 : glyph-proc
			include : refer-glyph 'powerline/progressBarMiddleEmpty' AS_BASE ALSO_METRICS
			include : Rect
				TackTop - GeometryStroke - progressBarGap
				TackBot + GeometryStroke + progressBarGap
				0 + O
				Width - O

		create-glyph 'powerline/progressBarEndFilled' 0xEE05 : glyph-proc
			include : refer-glyph 'powerline/progressBarEndEmpty' AS_BASE ALSO_METRICS
			include : Rect
				TackTop - GeometryStroke - progressBarGap
				TackBot + GeometryStroke + progressBarGap
				0 + O
				frameRight - [HSwToV GeometryStroke] - [HSwToV progressBarGap]

	for-width-kinds WideWidth4
		define Geom : GeometricDim MosaicUnitWidth MosaicWidth

		do "arrowheadShapedPointer"
			define scaffold : object
			set scaffold.top : mix uiFigBot uiFigTop 0.85
			set scaffold.bot : mix uiFigBot uiFigTop 0.15
			set scaffold.width   : (Middle - SB) * 2 * ((MosaicWidth / Width) ** 0.3)
			set scaffold.xMiddle : MosaicWidth / 2
			set scaffold.xLeft : scaffold.xMiddle - scaffold.width / 2
			set scaffold.xRight : scaffold.xMiddle + scaffold.width / 2
			create-glyph [MangleName 'arrowheadShapedPointer'] [MangleUnicode 0x1FBB0] : glyph-proc
				set-width MosaicWidth
				include : spiro-outline
					corner scaffold.xLeft scaffold.top
					corner scaffold.xRight [mix scaffold.bot scaffold.top (1 / 4)]
					corner [mix scaffold.xLeft scaffold.xRight (2 / 5)] [mix scaffold.bot scaffold.top (1 / 4)]
					corner scaffold.xLeft scaffold.bot

		do "Pointer"
			define pointerTop : mix uiFigBot uiFigTop (0.25 * MosaicWidthScalar)
			define fineStroke : AdviceStroke 3.5 : Math.sqrt (MosaicWidthScalar / 2)

			create-glyph [MangleName "whiteLowerLeftPointer"] [MangleUnicode 0x1CC86] : glyph-proc
				set-width MosaicWidth
				include : TriangleShape SB uiFigBot SB pointerTop (MosaicWidth - SB) uiFigBot fineStroke

			create-glyph [MangleName "whiteLowerRightPointer"] [MangleUnicode 0x1CC87] : glyph-proc
				set-width MosaicWidth
				include : TriangleShape SB uiFigBot (MosaicWidth - SB) pointerTop (MosaicWidth - SB) uiFigBot fineStroke

			create-glyph [MangleName "topLeftBlackSmallTriangleLeft"] [MangleUnicode 0x1CE07] : glyph-proc
				set-width MosaicWidth
				include : with-transform [ApparentTranslate (-MosaicWidth / 4) ((CAP - Geom.MidY) * 0.3 + AccentStackOffset / 2)] : refer-glyph : MangleName 'blackSmallTriangleLeft'

			if (MosaicWidthScalar == 1) : begin
				create-glyph "blackRightTriangleCaret" 0x1CEB3 : glyph-proc
					set-width 0
					include : HalfRectTriangle MosaicWidth ParenBot 0 [mix 0 ParenBot 0.2]

		do "Split graphics"
			define [BoxN n] : new Box uiFigTop uiFigBot SB (MosaicWidth * n - SB)

			define [MosaicWidthMask] : spiro-outline
				corner 0           [mix ParenBot ParenTop (-1)]
				corner MosaicWidth [mix ParenBot ParenTop (-1)]
				corner MosaicWidth [mix ParenBot ParenTop (+2)]
				corner 0           [mix ParenBot ParenTop (+2)]

			define [RunningManBody xOffset] : begin
				local Kit : StickFigureKit [BoxN 2] [Translate xOffset 0] [AdviceStroke 4]
				return : union
					Kit.RoundSeg (0 / 16) (3 / 8) (3 / 16) (5 / 8) 1 1
					Kit.RoundSeg (3 / 16) (5 / 8) (10 / 16) (5 / 8)
					Kit.RoundSeg (10 / 16) (5 / 8) (13 / 16) (7 / 8) 1 1
					Kit.RoundSeg (4 / 16) (3 / 8) (9 / 16) (3 / 8) 1 1
					Kit.RoundSeg (9 / 16) (3 / 8) (13 / 16) (0 / 8)
					Kit.RoundSeg (13 / 16) (0 / 8) (15 / 16) (0 / 8) 1 1
					Kit.RoundSeg (4 / 16) (6 / 16) (6 / 16) (3 / 16)
					Kit.RoundSeg (6 / 16) (3 / 16) (0 / 16) (3 / 16) 1 1
					Kit.RoundSeg (0 / 16) (3 / 16) (2 / 16) (0 / 8) 0 1
					Kit.Box (4 / 16) (6 / 16) (8 / 16) (5 / 8)

			define [RunningManHead xOffset] : begin
				local Kit : StickFigureKit [BoxN 2] [Translate xOffset 0] [AdviceStroke 4]
				return : Kit.Circ (6 / 16) (14 / 16) (5 / 32)

			create-glyph [MangleName 'runningManLeft'] [MangleUnicode 0x1FBB2] : glyph-proc
				set-width MosaicWidth
				include : RunningManHead 0
				include : intersection
					MosaicWidthMask
					RunningManBody 0

			create-glyph [MangleName 'runningManRight'] [MangleUnicode 0x1FBB3] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					RunningManBody (-MosaicWidth)

			define [FolderBody xOffset box] : begin
				local Kit : StickFigureKit box [Translate xOffset 0] [AdviceStroke 4]
				return : union
					Kit.RoundSeg (0 / 16) (1 / 8) (0 / 16) (11 / 16)
					Kit.RoundSeg (0 / 16) (11 / 16) (3 / 16) (7 / 8) 1 1
					Kit.RoundSeg (3 / 16) (7 / 8) (6 / 16) (7 / 8)
					Kit.RoundSeg (6 / 16) (7 / 8) (9 / 16) (11 / 16) 1 1
					Kit.RoundSeg (9 / 16) (11 / 16) (16 / 16) (11 / 16) 0 1
					Kit.RoundSeg (16 / 16) (11 / 16) (16 / 16) (1 / 8)
					Kit.RoundSeg (0 / 16) (1 / 8) (16 / 16) (1 / 8) 1 1

			create-glyph [MangleName 'folderLeft'] [MangleUnicode 0x1FBB9] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					FolderBody 0 [BoxN 2]

			create-glyph [MangleName 'folderRight'] [MangleUnicode 0x1FBBA] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					FolderBody (-MosaicWidth) [BoxN 2]

			create-glyph [MangleName 'folder'] [MangleUnicode 0x1F5C0] : glyph-proc
				set-width MosaicWidth
				local hbox : new Box
					mix SymbolMid uiFigTop (0.5 * MosaicWidthScalar)
					mix SymbolMid uiFigBot (0.5 * MosaicWidthScalar)
					SB * (0.5 * MosaicWidthScalar)
					MosaicWidth - SB * (0.5 * MosaicWidthScalar)
				include : FolderBody 0 hbox

			define [PointingHandBody xOffset] : begin
				return : PointingHandShape [BoxN 3] [Translate xOffset 0] [AdviceStroke 4]

			create-glyph [MangleName 'pointingHand1'] [MangleUnicode 0x1FBC1] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					PointingHandBody 0

			create-glyph [MangleName 'pointingHand2'] [MangleUnicode 0x1FBC2] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					PointingHandBody (-MosaicWidth)

			create-glyph [MangleName 'pointingHand3'] [MangleUnicode 0x1FBC3] : glyph-proc
				set-width MosaicWidth
				include : intersection
					MosaicWidthMask
					PointingHandBody (-MosaicWidth * 2)

		do "upPointingChevron"
			define scaffold : object
			set scaffold.top : mix uiFigBot uiFigTop 0.85
			set scaffold.bot : mix uiFigBot uiFigTop 0.15
			set scaffold.slope 0.6
			set scaffold.width   : (Middle - SB) * 2 * ((MosaicWidth / Width) ** 0.5)
			set scaffold.stroke  : AdviceStroke 3.5
			set scaffold.xMiddle : MosaicWidth / 2
			set scaffold.xLeft : scaffold.xMiddle - scaffold.width / 2
			set scaffold.xRight : scaffold.xMiddle + scaffold.width / 2
			set scaffold.xLeft2 : scaffold.xMiddle - scaffold.width
			set scaffold.xRight2 : scaffold.xMiddle + scaffold.width
			set scaffold.slopeRise : scaffold.slope * scaffold.width / 2

			define [ChevronUpperHalf flat] : intersection
				spiro-outline
					corner scaffold.xMiddle scaffold.top
					corner scaffold.xLeft   (scaffold.top - scaffold.slopeRise)
					corner scaffold.xLeft   (scaffold.bot + scaffold.stroke)
					if flat {} : list
						corner scaffold.xMiddle (scaffold.bot + scaffold.stroke + scaffold.slopeRise)
					corner scaffold.xRight  (scaffold.bot + scaffold.stroke)
					corner scaffold.xRight  (scaffold.top - scaffold.slopeRise)
				union
					VBar.l scaffold.xLeft scaffold.bot scaffold.top scaffold.stroke
					VBar.r scaffold.xRight scaffold.bot scaffold.top scaffold.stroke
					dispiro
						widths.lhs scaffold.stroke
						corner scaffold.xMiddle scaffold.top
						corner scaffold.xLeft   (scaffold.top - scaffold.slopeRise)
					dispiro
						widths.rhs scaffold.stroke
						corner scaffold.xMiddle scaffold.top
						corner scaffold.xRight  (scaffold.top - scaffold.slopeRise)

			create-glyph [MangleName "upPointingChevron"] [MangleUnicode 0x1FBCA] : glyph-proc
				set-width MosaicWidth
				include : ChevronUpperHalf false
				include : intersection
					spiro-outline
						corner scaffold.xLeft   scaffold.top
						corner scaffold.xLeft   (scaffold.bot - scaffold.stroke)
						corner scaffold.xRight  (scaffold.bot - scaffold.stroke)
						corner scaffold.xRight  scaffold.top
					union
						dispiro
							widths.lhs scaffold.stroke
							corner scaffold.xMiddle (scaffold.bot + scaffold.slopeRise + scaffold.stroke)
							corner scaffold.xLeft2  (scaffold.bot - scaffold.slopeRise + scaffold.stroke)
						dispiro
							widths.rhs scaffold.stroke
							corner scaffold.xMiddle (scaffold.bot + scaffold.slopeRise + scaffold.stroke)
							corner scaffold.xRight2 (scaffold.bot - scaffold.slopeRise + scaffold.stroke)

			create-glyph [MangleName "upPointingHouse"] [MangleUnicode 0x2302] : glyph-proc
				set-width MosaicWidth
				include : ChevronUpperHalf true
				include : HBar.b scaffold.xLeft scaffold.xRight scaffold.bot scaffold.stroke

		do "Segmented digits"
			define scaffold : object
			set scaffold.gap : Width / 16
			set scaffold.stroke : [AdviceStroke 2] / 2
			set scaffold.top   : [mix uiFigBot uiFigTop 0.9] - scaffold.stroke
			set scaffold.mid   : mix uiFigBot uiFigTop 0.5
			set scaffold.bot   : [mix uiFigBot uiFigTop 0.1] + scaffold.stroke
			set scaffold.width : (Middle - SB) * 2 * ((MosaicWidth / Width) ** 0.5)
			set scaffold.left  : (MosaicWidth / 2) - scaffold.width / 2 + scaffold.stroke / 2
			set scaffold.right : (MosaicWidth / 2) + scaffold.width / 2 - scaffold.stroke / 2

			define [StrokeV x yt yb] : spiro-outline
				corner x (yt - scaffold.gap)
				corner (x + scaffold.stroke) (yt - scaffold.gap - scaffold.stroke)
				corner (x + scaffold.stroke) (yb + scaffold.gap + scaffold.stroke)
				corner x (yb + scaffold.gap)
				corner (x - scaffold.stroke) (yb + scaffold.gap + scaffold.stroke)
				corner (x - scaffold.stroke) (yt - scaffold.gap - scaffold.stroke)
			define [StrokeH xl xr y s] : spiro-outline
				corner (xl + scaffold.gap) y
				corner (xl + scaffold.gap + scaffold.stroke) (y + scaffold.stroke)
				corner (xr - scaffold.gap - scaffold.stroke) (y + scaffold.stroke)
				corner (xr - scaffold.gap) y
				corner (xr - scaffold.gap - scaffold.stroke) (y - scaffold.stroke)
				corner (xl + scaffold.gap + scaffold.stroke) (y - scaffold.stroke)
			define [SegmentedDigit unicode a b c d e f g] : begin
				create-glyph [MangleName : NameUni unicode] [MangleUnicode unicode] : glyph-proc
					set-width MosaicWidth
					if a : include : StrokeH scaffold.left scaffold.right scaffold.top
					if b : include : StrokeV scaffold.left scaffold.top scaffold.mid
					if c : include : StrokeV scaffold.right scaffold.top scaffold.mid
					if d : include : StrokeH scaffold.left scaffold.right scaffold.mid
					if e : include : StrokeV scaffold.left scaffold.mid scaffold.bot
					if f : include : StrokeV scaffold.right scaffold.mid scaffold.bot
					if g : include : StrokeH scaffold.left scaffold.right scaffold.bot

			SegmentedDigit 0x1FBF0 1 1 1 0 1 1 1
			SegmentedDigit 0x1FBF1 0 0 1 0 0 1 0
			SegmentedDigit 0x1FBF2 1 0 1 1 1 0 1
			SegmentedDigit 0x1FBF3 1 0 1 1 0 1 1
			SegmentedDigit 0x1FBF4 0 1 1 1 0 1 0
			SegmentedDigit 0x1FBF5 1 1 0 1 0 1 1
			SegmentedDigit 0x1FBF6 1 1 0 1 1 1 1
			SegmentedDigit 0x1FBF7 1 1 1 0 0 1 0
			SegmentedDigit 0x1FBF8 1 1 1 1 1 1 1
			SegmentedDigit 0x1FBF9 1 1 1 1 0 1 1

		do "voidedGreekCross"
			create-glyph [MangleName "voidedGreekCross"] [MangleUnicode 0x1FBBB] : glyph-proc
				set-width MosaicWidth
				local sw : AdviceStroke 4
				local gap : [Math.max (Width / 8) (Width / 6 - sw / 2) ([AdviceStroke 3] - sw / 2)] / 2
				local mid : MosaicWidth / 2
				local size : [Math.min (MosaicWidth - SB * 2) (uiFigTop - uiFigBot)] / 2
				include : union
					VBar.r  (mid - gap) (SymbolMid + gap) (SymbolMid + size) sw
					VBar.r  (mid - gap) (SymbolMid - gap) (SymbolMid - size) sw
					VBar.l   (mid + gap) (SymbolMid + gap) (SymbolMid + size) sw
					VBar.l   (mid + gap) (SymbolMid - gap) (SymbolMid - size) sw
					HBar.b (mid - size) (mid - gap) (SymbolMid + gap) sw
					HBar.b (mid + size) (mid + gap) (SymbolMid + gap) sw
					HBar.t    (mid - size) (mid - gap) (SymbolMid - gap) sw
					HBar.t    (mid + size) (mid + gap) (SymbolMid - gap) sw
