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

import [OCCURRENT_PRECISION] from "@iosevka/geometry/curve-util"
import [mix linreg clamp fallback] from "@iosevka/util"
import [DesignParameters] from "../../meta/aesthetics.mjs"

glyph-module

glyph-block Symbol-Geometric-Shared : begin
	glyph-block-export GeometricDim
	define [GeometricDim unitWidth fullWidth] : begin
		define s : fullWidth / unitWidth
		define sb : 0.625 * SB * (s ** 2) * ((unitWidth / Width) ** 2)
		define tallSize : 0.5 * para.arrowHeight * (unitWidth - sb) * [Math.cbrt s]
		define size : Math.min (0.5 * fullWidth - sb) tallSize
		return : object
			UnitWidth unitWidth
			Scalar    s
			Size      size
			TallSize  tallSize
			Width     fullWidth
			Left    : 0.5 * fullWidth - size
			MidX    : 0.5 * fullWidth
			Right   : 0.5 * fullWidth + size
			Top     : SymbolMid       + size
			MidY      SymbolMid
			Bot     : SymbolMid       - size

	glyph-block-export GeometricSizes
	define [GeometricSizes Geom] : object
		Large         {.size [DesignParameters.GeometricLargeX Geom.Width Geom.UnitWidth]}
		Medium        {.size DesignParameters.geometric_medium_x}
		MediumSmall   {.size DesignParameters.geometric_medium_small_x    .sw [Math.min GeometryStroke : AdviceStroke 5   Geom.Scalar]}
		Small         {.size DesignParameters.geometric_small_x           .sw [Math.min GeometryStroke : AdviceStroke 6   Geom.Scalar]}
		SlightlySmall {.size DesignParameters.geometric_slightly_small_x  .sw [Math.min GeometryStroke : AdviceStroke 6.5 Geom.Scalar]}
		VerySmall     {.size DesignParameters.geometric_very_small_x      .sw [Math.min GeometryStroke : AdviceStroke 7   Geom.Scalar]}
		Tiny          {.size DesignParameters.geometric_tiny_x            .sw [Math.min GeometryStroke : AdviceStroke 8   Geom.Scalar]}

		Oblique            {                                                  .sw [Math.min GeometryStroke : AdviceStroke 4.75 Geom.Scalar] }
		MediumOblique      { .size DesignParameters.geometric_medium_x        .sw [Math.min GeometryStroke : AdviceStroke 4.75 Geom.Scalar] }
		MediumSmallOblique { .size DesignParameters.geometric_medium_small_x  .sw [Math.min GeometryStroke : AdviceStroke 5.25 Geom.Scalar] }
		SmallOblique       { .size DesignParameters.geometric_small_x         .sw [Math.min GeometryStroke : AdviceStroke 6.25 Geom.Scalar] }
		VerySmallOblique   { .size DesignParameters.geometric_very_small_x    .sw [Math.min GeometryStroke : AdviceStroke 7.25 Geom.Scalar] }
		TinyOblique        { .size DesignParameters.geometric_tiny_x          .sw [Math.min GeometryStroke : AdviceStroke 8.25 Geom.Scalar] }

		ObliqueSA          {                                                  .sw (Math.SQRT2 * [Math.min GeometryStroke : AdviceStroke 4.75 Geom.Scalar]) }

		TinyInner   { .innerSize (1 / 4) }
		SmallInner  { .innerSize (1 / 3) }
		MediumInner { .innerSize (2 / 3) }

	glyph-block-export ConvexPolygonOutline
	define [pointsAreNotClose a b] : begin
		return : [Math.abs (a.x - b.x)] > OCCURRENT_PRECISION || [Math.abs (a.y - b.y)] > OCCURRENT_PRECISION
	define [ConvexPolygonOutline shape sw] : begin
		local outlines : glyph-proc
			set currentGlyph.gizmo : Translate 0 0
			foreach c [items-of : shape.geometry.toContours] : foreach j [range 0 c.length] : begin
				local a c.[if j (j - 1) (c.length - 1)]
				local b c.(j)
				if [pointsAreNotClose a b] : include : dispiro
					disable-contrast
					widths.center (sw * 2)
					corner [mix a.x b.x (-2)] [mix a.y b.y (-2)]
					corner [mix a.x b.x (+3)] [mix a.y b.y (+3)]

		return : intersection shape outlines
