{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Data.Char.BoxDrawing (
  -- * Box border type
  Drawing,
  render,
  lookup,
  read,
  overlay,

  -- ** Box drawing styles
  BoxDrawingStyle,
  ascii,
  unicode,

  -- * Drawings

  -- ** Base primitives
  -- $primitives
  up,
  down,
  left,
  right,

  -- ** Combinations
  -- $combinations
  horizontal,
  vertical,
  cornerTL,
  cornerTR,
  cornerBR,
  cornerBL,
  intersectFull,
  intersectL,
  intersectR,
  intersectT,
  intersectB,

  -- ** Box drawing modifiers
  -- $modifiers
  heavy,
  heavyHoriz,
  heavyVert,
  dashed2,
  dashed3,
  double,
  doubleHoriz,
  doubleVert,
  rounded,
) where

import Data.Bits
import Data.Coerce
import Data.Maybe (fromMaybe)
import Data.Word (Word8)
import Text.Printf (printf)
import Prelude hiding (lookup, read)

--------------------------------------------------------------------------------
--

-- $primitives
--
-- Use the 'Semigroup' instance to combine box 'Drawing'.

up, left, right, down, cornerTL, cornerTR, cornerBR, cornerBL, horizontal, vertical, intersectL, intersectR, intersectT, intersectB, intersectFull :: Drawing
up :: Drawing
up = Drawing1 -> Drawing
bb Drawing1
BUp
left :: Drawing
left = Drawing1 -> Drawing
bb Drawing1
BLeft
right :: Drawing
right = Drawing1 -> Drawing
bb Drawing1
BRight
down :: Drawing
down = Drawing1 -> Drawing
bb Drawing1
BDown

-- $combinations
--
-- These are pre-made combinations of 'up', 'down', 'left', and 'right'.

cornerTL :: Drawing
cornerTL = Drawing1 -> Drawing
bb Drawing1
BDown Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BRight
cornerTR :: Drawing
cornerTR = Drawing1 -> Drawing
bb Drawing1
BDown Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BLeft
cornerBR :: Drawing
cornerBR = Drawing1 -> Drawing
bb Drawing1
BUp Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BLeft
cornerBL :: Drawing
cornerBL = Drawing1 -> Drawing
bb Drawing1
BUp Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BRight
horizontal :: Drawing
horizontal = Drawing1 -> Drawing
bb Drawing1
BLeft Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BRight
vertical :: Drawing
vertical = Drawing1 -> Drawing
bb Drawing1
BUp Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing1 -> Drawing
bb Drawing1
BDown
intersectL :: Drawing
intersectL = Drawing
vertical Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
right
intersectR :: Drawing
intersectR = Drawing
vertical Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
left
intersectT :: Drawing
intersectT = Drawing
horizontal Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
down
intersectB :: Drawing
intersectB = Drawing
horizontal Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
up
intersectFull :: Drawing
intersectFull = Drawing
horizontal Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
vertical

-- $modifiers
--
-- Combine these using the 'Semigroup' instance with another 'Drawing' to set
-- its style, such as heavy, dashed, etc. - only relevant for the style
-- 'unicode' and has no effect for the style 'ascii'.

double, doubleHoriz, doubleVert, heavy, dashed2, dashed3, dashed4, rounded, heavyHoriz, heavyVert :: Drawing
double :: Drawing
double = Style1 -> Drawing
style1 Style1
Double
doubleHoriz :: Drawing
doubleHoriz = Style1 -> Drawing
style1 Style1
DoubleHoriz
doubleVert :: Drawing
doubleVert = Style1 -> Drawing
style1 Style1
DoubleVert
heavy :: Drawing
heavy = Style1 -> Drawing
style1 Style1
Heavy
heavyHoriz :: Drawing
heavyHoriz = Style1 -> Drawing
style1 Style1
HeavyHoriz
heavyVert :: Drawing
heavyVert = Style1 -> Drawing
style1 Style1
HeavyVert
dashed2 :: Drawing
dashed2 = Style1 -> Drawing
style1 Style1
Dashed2
dashed3 :: Drawing
dashed3 = Style1 -> Drawing
style1 Style1
Dashed3
dashed4 :: Drawing
dashed4 = Style1 -> Drawing
style1 Style1
Dashed4
rounded :: Drawing
rounded = Style1 -> Drawing
style1 Style1
Rounded

bb :: Drawing1 -> Drawing
bb :: Drawing1 -> Drawing
bb = Drawing1 -> Drawing
boxBorderBits

--------------------------------------------------------------------------------

-- | A border style such as ASCII or unicode. Describes how to turn a
-- 'Drawing' into an actual character for rendering, or to lookup a character
-- from a buffer into a 'Drawing' for combining different border characters
data BoxDrawingStyle = BoxDrawingStyle
  { BoxDrawingStyle -> Drawing -> Char
render :: Drawing -> Char
  -- ^ Render a 'Drawing' given the style
  , BoxDrawingStyle -> Char -> Maybe Drawing
lookup :: Char -> Maybe Drawing
  -- ^ Lookup a character given the style
  }

--------------------------------------------------------------------------------
-- Generated code by using TH and then copy-pasting it back with -ddump-splices
--
-- Hopefully, there are no bugs in this ever :)
--

-- | A basic box-drawing style that uses @|@, @+@, and @-@
ascii :: BoxDrawingStyle
ascii :: BoxDrawingStyle
ascii =
  ( \(Word8 -> Char
run :: Word8 -> Char)
     (Char -> Maybe Word8
runBack :: Char -> Maybe Word8) ->
        (Drawing -> Char) -> (Char -> Maybe Drawing) -> BoxDrawingStyle
BoxDrawingStyle ((Word8 -> Char) -> Drawing -> Char
forall a b. Coercible a b => a -> b
coerce Word8 -> Char
run) ((Char -> Maybe Word8) -> Char -> Maybe Drawing
forall a b. Coercible a b => a -> b
coerce Char -> Maybe Word8
runBack)
  )
    ( \case
        Word8
3 -> Char
'|'
        Word8
5 -> Char
'+'
        Word8
6 -> Char
'+'
        Word8
7 -> Char
'+'
        Word8
9 -> Char
'+'
        Word8
10 -> Char
'+'
        Word8
11 -> Char
'+'
        Word8
12 -> Char
'-'
        Word8
13 -> Char
'+'
        Word8
14 -> Char
'+'
        Word8
15 -> Char
'+'
        Word8
19 -> Char
'|'
        Word8
21 -> Char
'+'
        Word8
22 -> Char
'+'
        Word8
23 -> Char
'+'
        Word8
25 -> Char
'+'
        Word8
26 -> Char
'+'
        Word8
27 -> Char
'+'
        Word8
28 -> Char
'-'
        Word8
29 -> Char
'+'
        Word8
30 -> Char
'+'
        Word8
31 -> Char
'+'
        Word8
35 -> Char
'|'
        Word8
37 -> Char
'+'
        Word8
38 -> Char
'+'
        Word8
39 -> Char
'+'
        Word8
41 -> Char
'+'
        Word8
42 -> Char
'+'
        Word8
43 -> Char
'+'
        Word8
44 -> Char
'-'
        Word8
45 -> Char
'+'
        Word8
46 -> Char
'+'
        Word8
47 -> Char
'+'
        Word8
51 -> Char
'|'
        Word8
53 -> Char
'+'
        Word8
54 -> Char
'+'
        Word8
55 -> Char
'+'
        Word8
57 -> Char
'+'
        Word8
58 -> Char
'+'
        Word8
59 -> Char
'+'
        Word8
60 -> Char
'-'
        Word8
61 -> Char
'+'
        Word8
62 -> Char
'+'
        Word8
63 -> Char
'+'
        Word8
67 -> Char
'|'
        Word8
69 -> Char
'+'
        Word8
70 -> Char
'+'
        Word8
71 -> Char
'+'
        Word8
73 -> Char
'+'
        Word8
74 -> Char
'+'
        Word8
75 -> Char
'+'
        Word8
76 -> Char
'-'
        Word8
77 -> Char
'+'
        Word8
78 -> Char
'+'
        Word8
79 -> Char
'+'
        Word8
83 -> Char
'|'
        Word8
85 -> Char
'+'
        Word8
86 -> Char
'+'
        Word8
87 -> Char
'+'
        Word8
89 -> Char
'+'
        Word8
90 -> Char
'+'
        Word8
91 -> Char
'+'
        Word8
92 -> Char
'-'
        Word8
93 -> Char
'+'
        Word8
94 -> Char
'+'
        Word8
95 -> Char
'+'
        Word8
99 -> Char
'|'
        Word8
101 -> Char
'+'
        Word8
102 -> Char
'+'
        Word8
103 -> Char
'+'
        Word8
105 -> Char
'+'
        Word8
106 -> Char
'+'
        Word8
107 -> Char
'+'
        Word8
108 -> Char
'-'
        Word8
109 -> Char
'+'
        Word8
110 -> Char
'+'
        Word8
111 -> Char
'+'
        Word8
115 -> Char
'|'
        Word8
117 -> Char
'+'
        Word8
118 -> Char
'+'
        Word8
119 -> Char
'+'
        Word8
121 -> Char
'+'
        Word8
122 -> Char
'+'
        Word8
123 -> Char
'+'
        Word8
124 -> Char
'-'
        Word8
125 -> Char
'+'
        Word8
126 -> Char
'+'
        Word8
127 -> Char
'+'
        Word8
131 -> Char
'|'
        Word8
133 -> Char
'+'
        Word8
134 -> Char
'+'
        Word8
135 -> Char
'+'
        Word8
137 -> Char
'+'
        Word8
138 -> Char
'+'
        Word8
139 -> Char
'+'
        Word8
140 -> Char
'-'
        Word8
141 -> Char
'+'
        Word8
142 -> Char
'+'
        Word8
143 -> Char
'+'
        Word8
147 -> Char
'|'
        Word8
149 -> Char
'+'
        Word8
150 -> Char
'+'
        Word8
151 -> Char
'+'
        Word8
153 -> Char
'+'
        Word8
154 -> Char
'+'
        Word8
155 -> Char
'+'
        Word8
156 -> Char
'-'
        Word8
157 -> Char
'+'
        Word8
158 -> Char
'+'
        Word8
159 -> Char
'+'
        Word8
163 -> Char
'|'
        Word8
165 -> Char
'+'
        Word8
166 -> Char
'+'
        Word8
167 -> Char
'+'
        Word8
169 -> Char
'+'
        Word8
170 -> Char
'+'
        Word8
171 -> Char
'+'
        Word8
172 -> Char
'-'
        Word8
173 -> Char
'+'
        Word8
174 -> Char
'+'
        Word8
175 -> Char
'+'
        Word8
179 -> Char
'|'
        Word8
181 -> Char
'+'
        Word8
182 -> Char
'+'
        Word8
183 -> Char
'+'
        Word8
185 -> Char
'+'
        Word8
186 -> Char
'+'
        Word8
187 -> Char
'+'
        Word8
188 -> Char
'-'
        Word8
189 -> Char
'+'
        Word8
190 -> Char
'+'
        Word8
191 -> Char
'+'
        Word8
195 -> Char
'|'
        Word8
197 -> Char
'+'
        Word8
198 -> Char
'+'
        Word8
199 -> Char
'+'
        Word8
201 -> Char
'+'
        Word8
202 -> Char
'+'
        Word8
203 -> Char
'+'
        Word8
204 -> Char
'-'
        Word8
205 -> Char
'+'
        Word8
206 -> Char
'+'
        Word8
207 -> Char
'+'
        Word8
211 -> Char
'|'
        Word8
213 -> Char
'+'
        Word8
214 -> Char
'+'
        Word8
215 -> Char
'+'
        Word8
217 -> Char
'+'
        Word8
218 -> Char
'+'
        Word8
219 -> Char
'+'
        Word8
220 -> Char
'-'
        Word8
221 -> Char
'+'
        Word8
222 -> Char
'+'
        Word8
223 -> Char
'+'
        Word8
227 -> Char
'|'
        Word8
229 -> Char
'+'
        Word8
230 -> Char
'+'
        Word8
231 -> Char
'+'
        Word8
233 -> Char
'+'
        Word8
234 -> Char
'+'
        Word8
235 -> Char
'+'
        Word8
236 -> Char
'-'
        Word8
237 -> Char
'+'
        Word8
238 -> Char
'+'
        Word8
239 -> Char
'+'
        Word8
243 -> Char
'|'
        Word8
245 -> Char
'+'
        Word8
246 -> Char
'+'
        Word8
247 -> Char
'+'
        Word8
249 -> Char
'+'
        Word8
250 -> Char
'+'
        Word8
251 -> Char
'+'
        Word8
252 -> Char
'-'
        Word8
253 -> Char
'+'
        Word8
254 -> Char
'+'
        Word8
255 -> Char
'+'
        Word8
_ -> Char
' '
    )
    ( \case
        Char
'+' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
255
        Char
'-' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
252
        Char
'|' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
243
        Char
_ -> Maybe Word8
forall a. Maybe a
Nothing
    )

-- | An advanced box-drawing style that supports all the drawing primitives
-- provided in this module
unicode :: BoxDrawingStyle
unicode :: BoxDrawingStyle
unicode =
  ( \(Word8 -> Char
run :: Word8 -> Char)
     (Char -> Maybe Word8
runBack :: Char -> Maybe Word8) ->
        (Drawing -> Char) -> (Char -> Maybe Drawing) -> BoxDrawingStyle
BoxDrawingStyle ((Word8 -> Char) -> Drawing -> Char
forall a b. Coercible a b => a -> b
coerce Word8 -> Char
run) ((Char -> Maybe Word8) -> Char -> Maybe Drawing
forall a b. Coercible a b => a -> b
coerce Char -> Maybe Word8
runBack)
  )
    ( \case
        Word8
1 -> Char
'\9589'
        Word8
2 -> Char
'\9591'
        Word8
3 -> Char
'\9474'
        Word8
4 -> Char
'\9588'
        Word8
5 -> Char
'\9496'
        Word8
6 -> Char
'\9488'
        Word8
7 -> Char
'\9508'
        Word8
8 -> Char
'\9590'
        Word8
9 -> Char
'\9492'
        Word8
10 -> Char
'\9484'
        Word8
11 -> Char
'\9500'
        Word8
12 -> Char
'\9472'
        Word8
13 -> Char
'\9524'
        Word8
14 -> Char
'\9516'
        Word8
15 -> Char
'\9532'
        Word8
17 -> Char
'\9589'
        Word8
18 -> Char
'\9591'
        Word8
19 -> Char
'\9474'
        Word8
20 -> Char
'\9588'
        Word8
21 -> Char
'\9583'
        Word8
22 -> Char
'\9582'
        Word8
23 -> Char
'\9508'
        Word8
24 -> Char
'\9590'
        Word8
25 -> Char
'\9584'
        Word8
26 -> Char
'\9581'
        Word8
27 -> Char
'\9500'
        Word8
28 -> Char
'\9472'
        Word8
29 -> Char
'\9524'
        Word8
30 -> Char
'\9516'
        Word8
31 -> Char
'\9532'
        Word8
33 -> Char
'\9589'
        Word8
34 -> Char
'\9591'
        Word8
35 -> Char
'\9550'
        Word8
36 -> Char
'\9588'
        Word8
37 -> Char
'\9496'
        Word8
38 -> Char
'\9488'
        Word8
39 -> Char
'\9508'
        Word8
40 -> Char
'\9590'
        Word8
41 -> Char
'\9492'
        Word8
42 -> Char
'\9484'
        Word8
43 -> Char
'\9500'
        Word8
44 -> Char
'\9548'
        Word8
45 -> Char
'\9524'
        Word8
46 -> Char
'\9516'
        Word8
47 -> Char
'\9532'
        Word8
49 -> Char
'\9589'
        Word8
50 -> Char
'\9591'
        Word8
51 -> Char
'\9474'
        Word8
52 -> Char
'\9588'
        Word8
53 -> Char
'\9496'
        Word8
54 -> Char
'\9488'
        Word8
55 -> Char
'\9508'
        Word8
56 -> Char
'\9590'
        Word8
57 -> Char
'\9492'
        Word8
58 -> Char
'\9484'
        Word8
59 -> Char
'\9500'
        Word8
60 -> Char
'\9472'
        Word8
61 -> Char
'\9524'
        Word8
62 -> Char
'\9516'
        Word8
63 -> Char
'\9532'
        Word8
65 -> Char
'\9589'
        Word8
66 -> Char
'\9591'
        Word8
67 -> Char
'\9478'
        Word8
68 -> Char
'\9588'
        Word8
69 -> Char
'\9496'
        Word8
70 -> Char
'\9488'
        Word8
71 -> Char
'\9508'
        Word8
72 -> Char
'\9590'
        Word8
73 -> Char
'\9492'
        Word8
74 -> Char
'\9484'
        Word8
75 -> Char
'\9500'
        Word8
76 -> Char
'\9476'
        Word8
77 -> Char
'\9524'
        Word8
78 -> Char
'\9516'
        Word8
79 -> Char
'\9532'
        Word8
81 -> Char
'\9589'
        Word8
82 -> Char
'\9591'
        Word8
83 -> Char
'\9474'
        Word8
84 -> Char
'\9588'
        Word8
85 -> Char
'\9496'
        Word8
86 -> Char
'\9488'
        Word8
87 -> Char
'\9508'
        Word8
88 -> Char
'\9590'
        Word8
89 -> Char
'\9492'
        Word8
90 -> Char
'\9484'
        Word8
91 -> Char
'\9500'
        Word8
92 -> Char
'\9472'
        Word8
93 -> Char
'\9524'
        Word8
94 -> Char
'\9516'
        Word8
95 -> Char
'\9532'
        Word8
97 -> Char
'\9589'
        Word8
98 -> Char
'\9591'
        Word8
99 -> Char
'\9482'
        Word8
100 -> Char
'\9588'
        Word8
101 -> Char
'\9496'
        Word8
102 -> Char
'\9488'
        Word8
103 -> Char
'\9508'
        Word8
104 -> Char
'\9590'
        Word8
105 -> Char
'\9492'
        Word8
106 -> Char
'\9484'
        Word8
107 -> Char
'\9500'
        Word8
108 -> Char
'\9480'
        Word8
109 -> Char
'\9524'
        Word8
110 -> Char
'\9516'
        Word8
111 -> Char
'\9532'
        Word8
113 -> Char
'\9589'
        Word8
114 -> Char
'\9591'
        Word8
115 -> Char
'\9474'
        Word8
116 -> Char
'\9588'
        Word8
117 -> Char
'\9496'
        Word8
118 -> Char
'\9488'
        Word8
119 -> Char
'\9508'
        Word8
120 -> Char
'\9590'
        Word8
121 -> Char
'\9492'
        Word8
122 -> Char
'\9484'
        Word8
123 -> Char
'\9500'
        Word8
124 -> Char
'\9472'
        Word8
125 -> Char
'\9524'
        Word8
126 -> Char
'\9516'
        Word8
127 -> Char
'\9532'
        Word8
129 -> Char
'\9589'
        Word8
130 -> Char
'\9591'
        Word8
131 -> Char
'\9474'
        Word8
132 -> Char
'\9588'
        Word8
133 -> Char
'\9497'
        Word8
134 -> Char
'\9489'
        Word8
135 -> Char
'\9509'
        Word8
136 -> Char
'\9590'
        Word8
137 -> Char
'\9493'
        Word8
138 -> Char
'\9485'
        Word8
139 -> Char
'\9501'
        Word8
140 -> Char
'\9473'
        Word8
141 -> Char
'\9527'
        Word8
142 -> Char
'\9519'
        Word8
143 -> Char
'\9535'
        Word8
145 -> Char
'\9589'
        Word8
146 -> Char
'\9591'
        Word8
147 -> Char
'\9475'
        Word8
148 -> Char
'\9588'
        Word8
149 -> Char
'\9498'
        Word8
150 -> Char
'\9490'
        Word8
151 -> Char
'\9512'
        Word8
152 -> Char
'\9590'
        Word8
153 -> Char
'\9493'
        Word8
154 -> Char
'\9486'
        Word8
155 -> Char
'\9504'
        Word8
156 -> Char
'\9472'
        Word8
157 -> Char
'\9528'
        Word8
158 -> Char
'\9520'
        Word8
159 -> Char
'\9538'
        Word8
161 -> Char
'\9593'
        Word8
162 -> Char
'\9595'
        Word8
163 -> Char
'\9475'
        Word8
164 -> Char
'\9592'
        Word8
165 -> Char
'\9499'
        Word8
166 -> Char
'\9491'
        Word8
167 -> Char
'\9515'
        Word8
168 -> Char
'\9594'
        Word8
169 -> Char
'\9495'
        Word8
170 -> Char
'\9487'
        Word8
171 -> Char
'\9507'
        Word8
172 -> Char
'\9473'
        Word8
173 -> Char
'\9531'
        Word8
174 -> Char
'\9523'
        Word8
175 -> Char
'\9547'
        Word8
177 -> Char
'\9589'
        Word8
178 -> Char
'\9591'
        Word8
179 -> Char
'\9474'
        Word8
180 -> Char
'\9588'
        Word8
181 -> Char
'\9563'
        Word8
182 -> Char
'\9557'
        Word8
183 -> Char
'\9569'
        Word8
184 -> Char
'\9590'
        Word8
185 -> Char
'\9560'
        Word8
186 -> Char
'\9554'
        Word8
187 -> Char
'\9566'
        Word8
188 -> Char
'\9552'
        Word8
189 -> Char
'\9575'
        Word8
190 -> Char
'\9572'
        Word8
191 -> Char
'\9532'
        Word8
193 -> Char
'\9589'
        Word8
194 -> Char
'\9591'
        Word8
195 -> Char
'\9553'
        Word8
196 -> Char
'\9588'
        Word8
197 -> Char
'\9564'
        Word8
198 -> Char
'\9558'
        Word8
199 -> Char
'\9570'
        Word8
200 -> Char
'\9590'
        Word8
201 -> Char
'\9561'
        Word8
202 -> Char
'\9555'
        Word8
203 -> Char
'\9567'
        Word8
204 -> Char
'\9472'
        Word8
205 -> Char
'\9576'
        Word8
206 -> Char
'\9573'
        Word8
207 -> Char
'\9532'
        Word8
209 -> Char
'\9589'
        Word8
210 -> Char
'\9591'
        Word8
211 -> Char
'\9553'
        Word8
212 -> Char
'\9588'
        Word8
213 -> Char
'\9565'
        Word8
214 -> Char
'\9559'
        Word8
215 -> Char
'\9571'
        Word8
216 -> Char
'\9590'
        Word8
217 -> Char
'\9562'
        Word8
218 -> Char
'\9556'
        Word8
219 -> Char
'\9568'
        Word8
220 -> Char
'\9552'
        Word8
221 -> Char
'\9577'
        Word8
222 -> Char
'\9574'
        Word8
223 -> Char
'\9532'
        Word8
225 -> Char
'\9589'
        Word8
226 -> Char
'\9591'
        Word8
227 -> Char
'\9474'
        Word8
228 -> Char
'\9588'
        Word8
229 -> Char
'\9496'
        Word8
230 -> Char
'\9488'
        Word8
231 -> Char
'\9508'
        Word8
232 -> Char
'\9590'
        Word8
233 -> Char
'\9492'
        Word8
234 -> Char
'\9484'
        Word8
235 -> Char
'\9500'
        Word8
236 -> Char
'\9472'
        Word8
237 -> Char
'\9524'
        Word8
238 -> Char
'\9516'
        Word8
239 -> Char
'\9532'
        Word8
241 -> Char
'\9589'
        Word8
242 -> Char
'\9591'
        Word8
243 -> Char
'\9474'
        Word8
244 -> Char
'\9588'
        Word8
245 -> Char
'\9496'
        Word8
246 -> Char
'\9488'
        Word8
247 -> Char
'\9508'
        Word8
248 -> Char
'\9590'
        Word8
249 -> Char
'\9492'
        Word8
250 -> Char
'\9484'
        Word8
251 -> Char
'\9500'
        Word8
252 -> Char
'\9472'
        Word8
253 -> Char
'\9524'
        Word8
254 -> Char
'\9516'
        Word8
255 -> Char
'\9532'
        Word8
_ -> Char
' '
    )
    ( \case
        Char
'\9472' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
252
        Char
'\9473' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
172
        Char
'\9474' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
243
        Char
'\9475' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
163
        Char
'\9476' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
76
        Char
'\9478' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
67
        Char
'\9480' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
108
        Char
'\9482' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
99
        Char
'\9484' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
250
        Char
'\9485' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
138
        Char
'\9486' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
154
        Char
'\9487' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
170
        Char
'\9488' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
246
        Char
'\9489' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
134
        Char
'\9490' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
150
        Char
'\9491' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
166
        Char
'\9492' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
249
        Char
'\9493' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
153
        Char
'\9495' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
169
        Char
'\9496' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
245
        Char
'\9497' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
133
        Char
'\9498' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
149
        Char
'\9499' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
165
        Char
'\9500' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
251
        Char
'\9501' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
139
        Char
'\9504' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
155
        Char
'\9507' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
171
        Char
'\9508' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
247
        Char
'\9509' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
135
        Char
'\9512' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
151
        Char
'\9515' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
167
        Char
'\9516' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
254
        Char
'\9519' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
142
        Char
'\9520' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
158
        Char
'\9523' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
174
        Char
'\9524' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
253
        Char
'\9527' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
141
        Char
'\9528' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
157
        Char
'\9531' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
173
        Char
'\9532' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
255
        Char
'\9535' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
143
        Char
'\9538' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
159
        Char
'\9547' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
175
        Char
'\9548' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
44
        Char
'\9550' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
35
        Char
'\9552' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
220
        Char
'\9553' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
211
        Char
'\9554' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
186
        Char
'\9555' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
202
        Char
'\9556' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
218
        Char
'\9557' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
182
        Char
'\9558' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
198
        Char
'\9559' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
214
        Char
'\9560' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
185
        Char
'\9561' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
201
        Char
'\9562' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
217
        Char
'\9563' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
181
        Char
'\9564' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
197
        Char
'\9565' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
213
        Char
'\9566' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
187
        Char
'\9567' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
203
        Char
'\9568' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
219
        Char
'\9569' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
183
        Char
'\9570' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
199
        Char
'\9571' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
215
        Char
'\9572' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
190
        Char
'\9573' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
206
        Char
'\9574' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
222
        Char
'\9575' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
189
        Char
'\9576' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
205
        Char
'\9577' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
221
        Char
'\9581' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
26
        Char
'\9582' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
22
        Char
'\9583' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
21
        Char
'\9584' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
25
        Char
'\9588' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
244
        Char
'\9589' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
241
        Char
'\9590' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
248
        Char
'\9591' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
242
        Char
'\9592' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
164
        Char
'\9593' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
161
        Char
'\9594' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
168
        Char
'\9595' -> Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
162
        Char
_ -> Maybe Word8
forall a. Maybe a
Nothing
    )

--------------------------------------------------------------------------------

-- | A box border which can be rendered to a terminal given a 'BoxDrawingStyle'
--
-- Use the 'Monoid' and 'Semigroup' instances to combine box borders.
--
-- The internal representation is just a 'Word8'; the least-significant four
-- bits specify the base directions of the box drawing (up, down, left, or
-- right), and the most-significant four bits specify the style (see 'rounded',
-- 'dashed2', etc) which has its own special logic for how styles can be
-- combined.
newtype Drawing = Drawing Word8
  deriving newtype (Drawing -> Drawing -> Bool
(Drawing -> Drawing -> Bool)
-> (Drawing -> Drawing -> Bool) -> Eq Drawing
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Drawing -> Drawing -> Bool
== :: Drawing -> Drawing -> Bool
$c/= :: Drawing -> Drawing -> Bool
/= :: Drawing -> Drawing -> Bool
Eq, Eq Drawing
Eq Drawing =>
(Drawing -> Drawing -> Ordering)
-> (Drawing -> Drawing -> Bool)
-> (Drawing -> Drawing -> Bool)
-> (Drawing -> Drawing -> Bool)
-> (Drawing -> Drawing -> Bool)
-> (Drawing -> Drawing -> Drawing)
-> (Drawing -> Drawing -> Drawing)
-> Ord Drawing
Drawing -> Drawing -> Bool
Drawing -> Drawing -> Ordering
Drawing -> Drawing -> Drawing
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Drawing -> Drawing -> Ordering
compare :: Drawing -> Drawing -> Ordering
$c< :: Drawing -> Drawing -> Bool
< :: Drawing -> Drawing -> Bool
$c<= :: Drawing -> Drawing -> Bool
<= :: Drawing -> Drawing -> Bool
$c> :: Drawing -> Drawing -> Bool
> :: Drawing -> Drawing -> Bool
$c>= :: Drawing -> Drawing -> Bool
>= :: Drawing -> Drawing -> Bool
$cmax :: Drawing -> Drawing -> Drawing
max :: Drawing -> Drawing -> Drawing
$cmin :: Drawing -> Drawing -> Drawing
min :: Drawing -> Drawing -> Drawing
Ord)

instance Semigroup Drawing where
  <> :: Drawing -> Drawing -> Drawing
(<>) a :: Drawing
a@(Drawing Word8
ab) b :: Drawing
b@(Drawing Word8
bb) =
    Word8 -> Drawing
Drawing ((Word8
ab Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
bb) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0f) Drawing -> Style1 -> Drawing
`setStyle1` (Drawing -> Style1
getStyle1 Drawing
a Style1 -> Style1 -> Style1
forall a. Semigroup a => a -> a -> a
<> Drawing -> Style1
getStyle1 Drawing
b)

instance Monoid Drawing where
  mempty :: Drawing
mempty = Word8 -> Drawing
Drawing Word8
0

-- | A single box border component
data Drawing1
  = BUp
  | BDown
  | BLeft
  | BRight
  deriving stock (Int -> Drawing1 -> ShowS
[Drawing1] -> ShowS
Drawing1 -> String
(Int -> Drawing1 -> ShowS)
-> (Drawing1 -> String) -> ([Drawing1] -> ShowS) -> Show Drawing1
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Drawing1 -> ShowS
showsPrec :: Int -> Drawing1 -> ShowS
$cshow :: Drawing1 -> String
show :: Drawing1 -> String
$cshowList :: [Drawing1] -> ShowS
showList :: [Drawing1] -> ShowS
Show, ReadPrec [Drawing1]
ReadPrec Drawing1
Int -> ReadS Drawing1
ReadS [Drawing1]
(Int -> ReadS Drawing1)
-> ReadS [Drawing1]
-> ReadPrec Drawing1
-> ReadPrec [Drawing1]
-> Read Drawing1
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Drawing1
readsPrec :: Int -> ReadS Drawing1
$creadList :: ReadS [Drawing1]
readList :: ReadS [Drawing1]
$creadPrec :: ReadPrec Drawing1
readPrec :: ReadPrec Drawing1
$creadListPrec :: ReadPrec [Drawing1]
readListPrec :: ReadPrec [Drawing1]
Read, Drawing1 -> Drawing1 -> Bool
(Drawing1 -> Drawing1 -> Bool)
-> (Drawing1 -> Drawing1 -> Bool) -> Eq Drawing1
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Drawing1 -> Drawing1 -> Bool
== :: Drawing1 -> Drawing1 -> Bool
$c/= :: Drawing1 -> Drawing1 -> Bool
/= :: Drawing1 -> Drawing1 -> Bool
Eq, Eq Drawing1
Eq Drawing1 =>
(Drawing1 -> Drawing1 -> Ordering)
-> (Drawing1 -> Drawing1 -> Bool)
-> (Drawing1 -> Drawing1 -> Bool)
-> (Drawing1 -> Drawing1 -> Bool)
-> (Drawing1 -> Drawing1 -> Bool)
-> (Drawing1 -> Drawing1 -> Drawing1)
-> (Drawing1 -> Drawing1 -> Drawing1)
-> Ord Drawing1
Drawing1 -> Drawing1 -> Bool
Drawing1 -> Drawing1 -> Ordering
Drawing1 -> Drawing1 -> Drawing1
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Drawing1 -> Drawing1 -> Ordering
compare :: Drawing1 -> Drawing1 -> Ordering
$c< :: Drawing1 -> Drawing1 -> Bool
< :: Drawing1 -> Drawing1 -> Bool
$c<= :: Drawing1 -> Drawing1 -> Bool
<= :: Drawing1 -> Drawing1 -> Bool
$c> :: Drawing1 -> Drawing1 -> Bool
> :: Drawing1 -> Drawing1 -> Bool
$c>= :: Drawing1 -> Drawing1 -> Bool
>= :: Drawing1 -> Drawing1 -> Bool
$cmax :: Drawing1 -> Drawing1 -> Drawing1
max :: Drawing1 -> Drawing1 -> Drawing1
$cmin :: Drawing1 -> Drawing1 -> Drawing1
min :: Drawing1 -> Drawing1 -> Drawing1
Ord, Int -> Drawing1
Drawing1 -> Int
Drawing1 -> [Drawing1]
Drawing1 -> Drawing1
Drawing1 -> Drawing1 -> [Drawing1]
Drawing1 -> Drawing1 -> Drawing1 -> [Drawing1]
(Drawing1 -> Drawing1)
-> (Drawing1 -> Drawing1)
-> (Int -> Drawing1)
-> (Drawing1 -> Int)
-> (Drawing1 -> [Drawing1])
-> (Drawing1 -> Drawing1 -> [Drawing1])
-> (Drawing1 -> Drawing1 -> [Drawing1])
-> (Drawing1 -> Drawing1 -> Drawing1 -> [Drawing1])
-> Enum Drawing1
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Drawing1 -> Drawing1
succ :: Drawing1 -> Drawing1
$cpred :: Drawing1 -> Drawing1
pred :: Drawing1 -> Drawing1
$ctoEnum :: Int -> Drawing1
toEnum :: Int -> Drawing1
$cfromEnum :: Drawing1 -> Int
fromEnum :: Drawing1 -> Int
$cenumFrom :: Drawing1 -> [Drawing1]
enumFrom :: Drawing1 -> [Drawing1]
$cenumFromThen :: Drawing1 -> Drawing1 -> [Drawing1]
enumFromThen :: Drawing1 -> Drawing1 -> [Drawing1]
$cenumFromTo :: Drawing1 -> Drawing1 -> [Drawing1]
enumFromTo :: Drawing1 -> Drawing1 -> [Drawing1]
$cenumFromThenTo :: Drawing1 -> Drawing1 -> Drawing1 -> [Drawing1]
enumFromThenTo :: Drawing1 -> Drawing1 -> Drawing1 -> [Drawing1]
Enum, Drawing1
Drawing1 -> Drawing1 -> Bounded Drawing1
forall a. a -> a -> Bounded a
$cminBound :: Drawing1
minBound :: Drawing1
$cmaxBound :: Drawing1
maxBound :: Drawing1
Bounded)

newtype StyleBits = StyleBits Word8

styleBits :: Drawing -> StyleBits
styleBits :: Drawing -> StyleBits
styleBits (Drawing Word8
fs) = Word8 -> StyleBits
StyleBits (Word8
fs Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`shiftR` Int
4)

setStyleBits :: Drawing -> StyleBits -> Drawing
setStyleBits :: Drawing -> StyleBits -> Drawing
setStyleBits (Drawing Word8
fs) (StyleBits Word8
s) = Word8 -> Drawing
Drawing ((Word8
fs Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0f) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
s Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`shiftL` Int
4))

setStyle1 :: Drawing -> Style1 -> Drawing
setStyle1 :: Drawing -> Style1 -> Drawing
setStyle1 Drawing
b Style1
s = Drawing -> StyleBits -> Drawing
setStyleBits Drawing
b (Style1 -> StyleBits
fromStyle1 Style1
s)

data Style1
  = Light
  | Rounded
  | Dashed2
  | Dashed2Heavy
  | Dashed3
  | Dashed3Heavy
  | Dashed4
  | Dashed4Heavy
  | HeavyHoriz
  | HeavyVert
  | Heavy
  | DoubleHoriz
  | DoubleVert
  | Double
  deriving stock (Int -> Style1 -> ShowS
[Style1] -> ShowS
Style1 -> String
(Int -> Style1 -> ShowS)
-> (Style1 -> String) -> ([Style1] -> ShowS) -> Show Style1
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Style1 -> ShowS
showsPrec :: Int -> Style1 -> ShowS
$cshow :: Style1 -> String
show :: Style1 -> String
$cshowList :: [Style1] -> ShowS
showList :: [Style1] -> ShowS
Show, Style1 -> Style1 -> Bool
(Style1 -> Style1 -> Bool)
-> (Style1 -> Style1 -> Bool) -> Eq Style1
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Style1 -> Style1 -> Bool
== :: Style1 -> Style1 -> Bool
$c/= :: Style1 -> Style1 -> Bool
/= :: Style1 -> Style1 -> Bool
Eq, Eq Style1
Eq Style1 =>
(Style1 -> Style1 -> Ordering)
-> (Style1 -> Style1 -> Bool)
-> (Style1 -> Style1 -> Bool)
-> (Style1 -> Style1 -> Bool)
-> (Style1 -> Style1 -> Bool)
-> (Style1 -> Style1 -> Style1)
-> (Style1 -> Style1 -> Style1)
-> Ord Style1
Style1 -> Style1 -> Bool
Style1 -> Style1 -> Ordering
Style1 -> Style1 -> Style1
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Style1 -> Style1 -> Ordering
compare :: Style1 -> Style1 -> Ordering
$c< :: Style1 -> Style1 -> Bool
< :: Style1 -> Style1 -> Bool
$c<= :: Style1 -> Style1 -> Bool
<= :: Style1 -> Style1 -> Bool
$c> :: Style1 -> Style1 -> Bool
> :: Style1 -> Style1 -> Bool
$c>= :: Style1 -> Style1 -> Bool
>= :: Style1 -> Style1 -> Bool
$cmax :: Style1 -> Style1 -> Style1
max :: Style1 -> Style1 -> Style1
$cmin :: Style1 -> Style1 -> Style1
min :: Style1 -> Style1 -> Style1
Ord, Int -> Style1
Style1 -> Int
Style1 -> [Style1]
Style1 -> Style1
Style1 -> Style1 -> [Style1]
Style1 -> Style1 -> Style1 -> [Style1]
(Style1 -> Style1)
-> (Style1 -> Style1)
-> (Int -> Style1)
-> (Style1 -> Int)
-> (Style1 -> [Style1])
-> (Style1 -> Style1 -> [Style1])
-> (Style1 -> Style1 -> [Style1])
-> (Style1 -> Style1 -> Style1 -> [Style1])
-> Enum Style1
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Style1 -> Style1
succ :: Style1 -> Style1
$cpred :: Style1 -> Style1
pred :: Style1 -> Style1
$ctoEnum :: Int -> Style1
toEnum :: Int -> Style1
$cfromEnum :: Style1 -> Int
fromEnum :: Style1 -> Int
$cenumFrom :: Style1 -> [Style1]
enumFrom :: Style1 -> [Style1]
$cenumFromThen :: Style1 -> Style1 -> [Style1]
enumFromThen :: Style1 -> Style1 -> [Style1]
$cenumFromTo :: Style1 -> Style1 -> [Style1]
enumFromTo :: Style1 -> Style1 -> [Style1]
$cenumFromThenTo :: Style1 -> Style1 -> Style1 -> [Style1]
enumFromThenTo :: Style1 -> Style1 -> Style1 -> [Style1]
Enum, Style1
Style1 -> Style1 -> Bounded Style1
forall a. a -> a -> Bounded a
$cminBound :: Style1
minBound :: Style1
$cmaxBound :: Style1
maxBound :: Style1
Bounded)

instance Monoid Style1 where
  mempty :: Style1
mempty = Style1
Light

instance Semigroup Style1 where
  <> :: Style1 -> Style1 -> Style1
(<>) Style1
DoubleHoriz Style1
DoubleVert = Style1
Double
  (<>) Style1
DoubleVert Style1
DoubleHoriz = Style1
Double
  (<>) Style1
HeavyHoriz Style1
HeavyVert = Style1
Heavy
  (<>) Style1
HeavyVert Style1
HeavyHoriz = Style1
Heavy
  (<>) Style1
Heavy Style1
Dashed2 = Style1
Dashed2Heavy
  (<>) Style1
Dashed2 Style1
Heavy = Style1
Dashed2Heavy
  (<>) Style1
Heavy Style1
Dashed3 = Style1
Dashed3Heavy
  (<>) Style1
Dashed3 Style1
Heavy = Style1
Dashed3Heavy
  (<>) Style1
Heavy Style1
Dashed4 = Style1
Dashed4Heavy
  (<>) Style1
Dashed4 Style1
Heavy = Style1
Dashed4Heavy
  (<>) Style1
a Style1
b = Style1 -> Style1 -> Style1
forall a. Ord a => a -> a -> a
max Style1
a Style1
b

style1 :: Style1 -> Drawing
style1 :: Style1 -> Drawing
style1 Style1
s = Drawing -> StyleBits -> Drawing
setStyleBits Drawing
forall a. Monoid a => a
mempty (Style1 -> StyleBits
fromStyle1 Style1
s)

fromStyle1 :: Style1 -> StyleBits
fromStyle1 :: Style1 -> StyleBits
fromStyle1 = Word8 -> StyleBits
StyleBits (Word8 -> StyleBits) -> (Style1 -> Word8) -> Style1 -> StyleBits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a. Enum a => Int -> a
toEnum (Int -> Word8) -> (Style1 -> Int) -> Style1 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Style1 -> Int
forall a. Enum a => a -> Int
fromEnum

dropStyleBits :: Drawing -> Drawing
dropStyleBits :: Drawing -> Drawing
dropStyleBits (Drawing Word8
w) = Word8 -> Drawing
Drawing (Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0f)

getStyle1 :: Drawing -> Style1
getStyle1 :: Drawing -> Style1
getStyle1 (Drawing Word8
w)
  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Style1 -> Int
forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
maxBound @Style1) = Int -> Style1
forall a. Enum a => Int -> a
toEnum Int
i
  | Bool
otherwise = Style1
forall a. Monoid a => a
mempty
  where
    !i :: Int
i = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
w Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`shiftR` Int
4)

getBorderBitField :: Drawing -> Word8
getBorderBitField :: Drawing -> Word8
getBorderBitField (Drawing Word8
fs) = Word8
fs

bitsToDrawing :: Drawing -> [Drawing1]
bitsToDrawing :: Drawing -> [Drawing1]
bitsToDrawing (Drawing Word8
fs) = [[Drawing1]] -> [Drawing1]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat do
  !Drawing1
b1 <- [Drawing1
forall a. Bounded a => a
minBound .. forall a. Bounded a => a
maxBound @Drawing1]
  [Drawing1] -> [[Drawing1]]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Drawing1
b1 | Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
fs (Drawing1 -> Int
forall a. Enum a => a -> Int
fromEnum Drawing1
b1)]

boxBorderBits :: Drawing1 -> Drawing
boxBorderBits :: Drawing1 -> Drawing
boxBorderBits = Word8 -> Drawing
Drawing (Word8 -> Drawing) -> (Drawing1 -> Word8) -> Drawing1 -> Drawing
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a. Bits a => Int -> a
bit (Int -> Word8) -> (Drawing1 -> Int) -> Drawing1 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Drawing1 -> Int
forall a. Enum a => a -> Int
fromEnum

-- | Given a box drawing style and a character, determine what 'Drawing' the
-- character is. On error, returns an empty 'Drawing'
read :: BoxDrawingStyle -> Char -> Drawing
read :: BoxDrawingStyle -> Char -> Drawing
read BoxDrawingStyle
style Char
ch = Drawing -> Maybe Drawing -> Drawing
forall a. a -> Maybe a -> a
fromMaybe Drawing
forall a. Monoid a => a
mempty (BoxDrawingStyle -> Char -> Maybe Drawing
lookup BoxDrawingStyle
style Char
ch)

-- | Get the character that best represents visually overlaying the given box
-- drawing and a character.
overlay :: BoxDrawingStyle -> Drawing -> Char -> Char
overlay :: BoxDrawingStyle -> Drawing -> Char -> Char
overlay BoxDrawingStyle
style Drawing
next Char
cur = BoxDrawingStyle -> Drawing -> Char
render BoxDrawingStyle
style (BoxDrawingStyle -> Char -> Drawing
read BoxDrawingStyle
style Char
cur Drawing -> Drawing -> Drawing
forall a. Semigroup a => a -> a -> a
<> Drawing
next)