1//
2// Copyright (c) 2016-2020 The Aurora Authors. All rights reserved.
3// This program is free software. It comes without any warranty,
4// to the extent permitted by applicable law. You can redistribute
5// it and/or modify it under the terms of the Unlicense. See LICENSE
6// file for more details or see below.
7//
8
9//
10// This is free and unencumbered software released into the public domain.
11//
12// Anyone is free to copy, modify, publish, use, compile, sell, or
13// distribute this software, either in source code form or as a compiled
14// binary, for any purpose, commercial or non-commercial, and by any
15// means.
16//
17// In jurisdictions that recognize copyright laws, the author or authors
18// of this software dedicate any and all copyright interest in the
19// software to the public domain. We make this dedication for the benefit
20// of the public at large and to the detriment of our heirs and
21// successors. We intend this dedication to be an overt act of
22// relinquishment in perpetuity of all present and future rights to this
23// software under copyright law.
24//
25// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31// OTHER DEALINGS IN THE SOFTWARE.
32//
33// For more information, please refer to <http://unlicense.org/>
34//
35
36package aurora
37
38// Colorize wraps given value into Value with
39// given colors. For example
40//
41//    s := Colorize("some", BlueFg|GreenBg|BoldFm)
42//
43// returns a Value with blue foreground, green
44// background and bold. Unlike functions like
45// Red/BgBlue/Bold etc. This function clears
46// all previous colors and formats. Thus
47//
48//    s := Colorize(Red("some"), BgBlue)
49//
50// clears red color from value
51func Colorize(arg interface{}, color Color) Value {
52	if val, ok := arg.(value); ok {
53		val.color = color
54		return val
55	}
56	return value{arg, color, 0}
57}
58
59// Reset wraps given argument returning Value
60// without formats and colors.
61func Reset(arg interface{}) Value {
62	if val, ok := arg.(Value); ok {
63		return val.Reset()
64	}
65	return value{value: arg}
66}
67
68//
69// Formats
70//
71
72// Bold or increased intensity (1).
73func Bold(arg interface{}) Value {
74	if val, ok := arg.(Value); ok {
75		return val.Bold()
76	}
77	return value{value: arg, color: BoldFm}
78}
79
80// Faint decreases intensity (2).
81// The Faint rejects the Bold.
82func Faint(arg interface{}) Value {
83	if val, ok := arg.(Value); ok {
84		return val.Faint()
85	}
86	return value{value: arg, color: FaintFm}
87}
88
89// DoublyUnderline or Bold off, double-underline
90// per ECMA-48 (21).
91func DoublyUnderline(arg interface{}) Value {
92	if val, ok := arg.(Value); ok {
93		return val.DoublyUnderline()
94	}
95	return value{value: arg, color: DoublyUnderlineFm}
96}
97
98// Fraktur is rarely supported (20).
99func Fraktur(arg interface{}) Value {
100	if val, ok := arg.(Value); ok {
101		return val.Fraktur()
102	}
103	return value{value: arg, color: FrakturFm}
104}
105
106// Italic is not widely supported, sometimes
107// treated as inverse (3).
108func Italic(arg interface{}) Value {
109	if val, ok := arg.(Value); ok {
110		return val.Italic()
111	}
112	return value{value: arg, color: ItalicFm}
113}
114
115// Underline (4).
116func Underline(arg interface{}) Value {
117	if val, ok := arg.(Value); ok {
118		return val.Underline()
119	}
120	return value{value: arg, color: UnderlineFm}
121}
122
123// SlowBlink makes text blink less than
124// 150 per minute (5).
125func SlowBlink(arg interface{}) Value {
126	if val, ok := arg.(Value); ok {
127		return val.SlowBlink()
128	}
129	return value{value: arg, color: SlowBlinkFm}
130}
131
132// RapidBlink makes text blink 150+ per
133// minute. It is not widely supported (6).
134func RapidBlink(arg interface{}) Value {
135	if val, ok := arg.(Value); ok {
136		return val.RapidBlink()
137	}
138	return value{value: arg, color: RapidBlinkFm}
139}
140
141// Blink is alias for the SlowBlink.
142func Blink(arg interface{}) Value {
143	return SlowBlink(arg)
144}
145
146// Reverse video, swap foreground and
147// background colors (7).
148func Reverse(arg interface{}) Value {
149	if val, ok := arg.(Value); ok {
150		return val.Reverse()
151	}
152	return value{value: arg, color: ReverseFm}
153}
154
155// Inverse is alias for the Reverse
156func Inverse(arg interface{}) Value {
157	return Reverse(arg)
158}
159
160// Conceal hides text, preserving an ability to select
161// the text and copy it. It is not widely supported (8).
162func Conceal(arg interface{}) Value {
163	if val, ok := arg.(Value); ok {
164		return val.Conceal()
165	}
166	return value{value: arg, color: ConcealFm}
167}
168
169// Hidden is alias for the Conceal
170func Hidden(arg interface{}) Value {
171	return Conceal(arg)
172}
173
174// CrossedOut makes characters legible, but
175// marked for deletion (9).
176func CrossedOut(arg interface{}) Value {
177	if val, ok := arg.(Value); ok {
178		return val.CrossedOut()
179	}
180	return value{value: arg, color: CrossedOutFm}
181}
182
183// StrikeThrough is alias for the CrossedOut.
184func StrikeThrough(arg interface{}) Value {
185	return CrossedOut(arg)
186}
187
188// Framed (51).
189func Framed(arg interface{}) Value {
190	if val, ok := arg.(Value); ok {
191		return val.Framed()
192	}
193	return value{value: arg, color: FramedFm}
194}
195
196// Encircled (52).
197func Encircled(arg interface{}) Value {
198	if val, ok := arg.(Value); ok {
199		return val.Encircled()
200	}
201	return value{value: arg, color: EncircledFm}
202}
203
204// Overlined (53).
205func Overlined(arg interface{}) Value {
206	if val, ok := arg.(Value); ok {
207		return val.Overlined()
208	}
209	return value{value: arg, color: OverlinedFm}
210}
211
212//
213// Foreground colors
214//
215//
216
217// Black foreground color (30)
218func Black(arg interface{}) Value {
219	if val, ok := arg.(Value); ok {
220		return val.Black()
221	}
222	return value{value: arg, color: BlackFg}
223}
224
225// Red foreground color (31)
226func Red(arg interface{}) Value {
227	if val, ok := arg.(Value); ok {
228		return val.Red()
229	}
230	return value{value: arg, color: RedFg}
231}
232
233// Green foreground color (32)
234func Green(arg interface{}) Value {
235	if val, ok := arg.(Value); ok {
236		return val.Green()
237	}
238	return value{value: arg, color: GreenFg}
239}
240
241// Yellow foreground color (33)
242func Yellow(arg interface{}) Value {
243	if val, ok := arg.(Value); ok {
244		return val.Yellow()
245	}
246	return value{value: arg, color: YellowFg}
247}
248
249// Brown foreground color (33)
250//
251// Deprecated: use Yellow instead, following specification
252func Brown(arg interface{}) Value {
253	return Yellow(arg)
254}
255
256// Blue foreground color (34)
257func Blue(arg interface{}) Value {
258	if val, ok := arg.(Value); ok {
259		return val.Blue()
260	}
261	return value{value: arg, color: BlueFg}
262}
263
264// Magenta foreground color (35)
265func Magenta(arg interface{}) Value {
266	if val, ok := arg.(Value); ok {
267		return val.Magenta()
268	}
269	return value{value: arg, color: MagentaFg}
270}
271
272// Cyan foreground color (36)
273func Cyan(arg interface{}) Value {
274	if val, ok := arg.(Value); ok {
275		return val.Cyan()
276	}
277	return value{value: arg, color: CyanFg}
278}
279
280// White foreground color (37)
281func White(arg interface{}) Value {
282	if val, ok := arg.(Value); ok {
283		return val.White()
284	}
285	return value{value: arg, color: WhiteFg}
286}
287
288//
289// Bright foreground colors
290//
291
292// BrightBlack foreground color (90)
293func BrightBlack(arg interface{}) Value {
294	if val, ok := arg.(Value); ok {
295		return val.BrightBlack()
296	}
297	return value{value: arg, color: BrightFg | BlackFg}
298}
299
300// BrightRed foreground color (91)
301func BrightRed(arg interface{}) Value {
302	if val, ok := arg.(Value); ok {
303		return val.BrightRed()
304	}
305	return value{value: arg, color: BrightFg | RedFg}
306}
307
308// BrightGreen foreground color (92)
309func BrightGreen(arg interface{}) Value {
310	if val, ok := arg.(Value); ok {
311		return val.BrightGreen()
312	}
313	return value{value: arg, color: BrightFg | GreenFg}
314}
315
316// BrightYellow foreground color (93)
317func BrightYellow(arg interface{}) Value {
318	if val, ok := arg.(Value); ok {
319		return val.BrightYellow()
320	}
321	return value{value: arg, color: BrightFg | YellowFg}
322}
323
324// BrightBlue foreground color (94)
325func BrightBlue(arg interface{}) Value {
326	if val, ok := arg.(Value); ok {
327		return val.BrightBlue()
328	}
329	return value{value: arg, color: BrightFg | BlueFg}
330}
331
332// BrightMagenta foreground color (95)
333func BrightMagenta(arg interface{}) Value {
334	if val, ok := arg.(Value); ok {
335		return val.BrightMagenta()
336	}
337	return value{value: arg, color: BrightFg | MagentaFg}
338}
339
340// BrightCyan foreground color (96)
341func BrightCyan(arg interface{}) Value {
342	if val, ok := arg.(Value); ok {
343		return val.BrightCyan()
344	}
345	return value{value: arg, color: BrightFg | CyanFg}
346}
347
348// BrightWhite foreground color (97)
349func BrightWhite(arg interface{}) Value {
350	if val, ok := arg.(Value); ok {
351		return val.BrightWhite()
352	}
353	return value{value: arg, color: BrightFg | WhiteFg}
354}
355
356//
357// Other
358//
359
360// Index of pre-defined 8-bit foreground color
361// from 0 to 255 (38;5;n).
362//
363//       0-  7:  standard colors (as in ESC [ 30–37 m)
364//       8- 15:  high intensity colors (as in ESC [ 90–97 m)
365//      16-231:  6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
366//     232-255:  grayscale from black to white in 24 steps
367//
368func Index(n uint8, arg interface{}) Value {
369	if val, ok := arg.(Value); ok {
370		return val.Index(n)
371	}
372	return value{value: arg, color: (Color(n) << shiftFg) | flagFg}
373}
374
375// Gray from 0 to 24.
376func Gray(n uint8, arg interface{}) Value {
377	if val, ok := arg.(Value); ok {
378		return val.Gray(n)
379	}
380	if n > 23 {
381		n = 23
382	}
383	return value{value: arg, color: (Color(232+n) << shiftFg) | flagFg}
384}
385
386//
387// Background colors
388//
389//
390
391// BgBlack background color (40)
392func BgBlack(arg interface{}) Value {
393	if val, ok := arg.(Value); ok {
394		return val.BgBlack()
395	}
396	return value{value: arg, color: BlackBg}
397}
398
399// BgRed background color (41)
400func BgRed(arg interface{}) Value {
401	if val, ok := arg.(Value); ok {
402		return val.BgRed()
403	}
404	return value{value: arg, color: RedBg}
405}
406
407// BgGreen background color (42)
408func BgGreen(arg interface{}) Value {
409	if val, ok := arg.(Value); ok {
410		return val.BgGreen()
411	}
412	return value{value: arg, color: GreenBg}
413}
414
415// BgYellow background color (43)
416func BgYellow(arg interface{}) Value {
417	if val, ok := arg.(Value); ok {
418		return val.BgYellow()
419	}
420	return value{value: arg, color: YellowBg}
421}
422
423// BgBrown background color (43)
424//
425// Deprecated: use BgYellow instead, following specification
426func BgBrown(arg interface{}) Value {
427	return BgYellow(arg)
428}
429
430// BgBlue background color (44)
431func BgBlue(arg interface{}) Value {
432	if val, ok := arg.(Value); ok {
433		return val.BgBlue()
434	}
435	return value{value: arg, color: BlueBg}
436}
437
438// BgMagenta background color (45)
439func BgMagenta(arg interface{}) Value {
440	if val, ok := arg.(Value); ok {
441		return val.BgMagenta()
442	}
443	return value{value: arg, color: MagentaBg}
444}
445
446// BgCyan background color (46)
447func BgCyan(arg interface{}) Value {
448	if val, ok := arg.(Value); ok {
449		return val.BgCyan()
450	}
451	return value{value: arg, color: CyanBg}
452}
453
454// BgWhite background color (47)
455func BgWhite(arg interface{}) Value {
456	if val, ok := arg.(Value); ok {
457		return val.BgWhite()
458	}
459	return value{value: arg, color: WhiteBg}
460}
461
462//
463// Bright background colors
464//
465
466// BgBrightBlack background color (100)
467func BgBrightBlack(arg interface{}) Value {
468	if val, ok := arg.(Value); ok {
469		return val.BgBrightBlack()
470	}
471	return value{value: arg, color: BrightBg | BlackBg}
472}
473
474// BgBrightRed background color (101)
475func BgBrightRed(arg interface{}) Value {
476	if val, ok := arg.(Value); ok {
477		return val.BgBrightRed()
478	}
479	return value{value: arg, color: BrightBg | RedBg}
480}
481
482// BgBrightGreen background color (102)
483func BgBrightGreen(arg interface{}) Value {
484	if val, ok := arg.(Value); ok {
485		return val.BgBrightGreen()
486	}
487	return value{value: arg, color: BrightBg | GreenBg}
488}
489
490// BgBrightYellow background color (103)
491func BgBrightYellow(arg interface{}) Value {
492	if val, ok := arg.(Value); ok {
493		return val.BgBrightYellow()
494	}
495	return value{value: arg, color: BrightBg | YellowBg}
496}
497
498// BgBrightBlue background color (104)
499func BgBrightBlue(arg interface{}) Value {
500	if val, ok := arg.(Value); ok {
501		return val.BgBrightBlue()
502	}
503	return value{value: arg, color: BrightBg | BlueBg}
504}
505
506// BgBrightMagenta background color (105)
507func BgBrightMagenta(arg interface{}) Value {
508	if val, ok := arg.(Value); ok {
509		return val.BgBrightMagenta()
510	}
511	return value{value: arg, color: BrightBg | MagentaBg}
512}
513
514// BgBrightCyan background color (106)
515func BgBrightCyan(arg interface{}) Value {
516	if val, ok := arg.(Value); ok {
517		return val.BgBrightCyan()
518	}
519	return value{value: arg, color: BrightBg | CyanBg}
520}
521
522// BgBrightWhite background color (107)
523func BgBrightWhite(arg interface{}) Value {
524	if val, ok := arg.(Value); ok {
525		return val.BgBrightWhite()
526	}
527	return value{value: arg, color: BrightBg | WhiteBg}
528}
529
530//
531// Other
532//
533
534// BgIndex of 8-bit pre-defined background color
535// from 0 to 255 (48;5;n).
536//
537//       0-  7:  standard colors (as in ESC [ 40–47 m)
538//       8- 15:  high intensity colors (as in ESC [100–107 m)
539//      16-231:  6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
540//     232-255:  grayscale from black to white in 24 steps
541//
542func BgIndex(n uint8, arg interface{}) Value {
543	if val, ok := arg.(Value); ok {
544		return val.BgIndex(n)
545	}
546	return value{value: arg, color: (Color(n) << shiftBg) | flagBg}
547}
548
549// BgGray from 0 to 24.
550func BgGray(n uint8, arg interface{}) Value {
551	if val, ok := arg.(Value); ok {
552		return val.BgGray(n)
553	}
554	if n > 23 {
555		n = 23
556	}
557	return value{value: arg, color: (Color(n+232) << shiftBg) | flagBg}
558}
559