1package color
2
3import (
4	"fmt"
5	"io"
6	"log"
7	"strings"
8)
9
10// SetTerminal by given code.
11func SetTerminal(code string) error {
12	if !Enable || !SupportColor() {
13		return nil
14	}
15
16	_, err := fmt.Fprintf(output, SettingTpl, code)
17	return err
18}
19
20// ResetTerminal terminal setting.
21func ResetTerminal() error {
22	if !Enable || !SupportColor() {
23		return nil
24	}
25
26	_, err := fmt.Fprint(output, ResetSet)
27	return err
28}
29
30/*************************************************************
31 * print methods(will auto parse color tags)
32 *************************************************************/
33
34// Print render color tag and print messages
35func Print(a ...interface{}) {
36	Fprint(output, a...)
37}
38
39// Printf format and print messages
40func Printf(format string, a ...interface{}) {
41	Fprintf(output, format, a...)
42}
43
44// Println messages with new line
45func Println(a ...interface{}) {
46	Fprintln(output, a...)
47}
48
49// Fprint print rendered messages to writer
50// Notice: will ignore print error
51func Fprint(w io.Writer, a ...interface{}) {
52	_, err := fmt.Fprint(w, Render(a...))
53	saveInternalError(err)
54
55	// if isLikeInCmd {
56	// 	renderColorCodeOnCmd(func() {
57	// 		_, _ = fmt.Fprint(w, Render(a...))
58	// 	})
59	// } else {
60	// 	_, _ = fmt.Fprint(w, Render(a...))
61	// }
62}
63
64// Fprintf print format and rendered messages to writer.
65// Notice: will ignore print error
66func Fprintf(w io.Writer, format string, a ...interface{}) {
67	str := fmt.Sprintf(format, a...)
68	_, err := fmt.Fprint(w, ReplaceTag(str))
69	saveInternalError(err)
70}
71
72// Fprintln print rendered messages line to writer
73// Notice: will ignore print error
74func Fprintln(w io.Writer, a ...interface{}) {
75	str := formatArgsForPrintln(a)
76	_, err := fmt.Fprintln(w, ReplaceTag(str))
77	saveInternalError(err)
78}
79
80// Lprint passes colored messages to a log.Logger for printing.
81// Notice: should be goroutine safe
82func Lprint(l *log.Logger, a ...interface{}) {
83	l.Print(Render(a...))
84}
85
86// Render parse color tags, return rendered string.
87// Usage:
88//	text := Render("<info>hello</> <cyan>world</>!")
89//	fmt.Println(text)
90func Render(a ...interface{}) string {
91	if len(a) == 0 {
92		return ""
93	}
94
95	return ReplaceTag(fmt.Sprint(a...))
96}
97
98// Sprint parse color tags, return rendered string
99func Sprint(a ...interface{}) string {
100	if len(a) == 0 {
101		return ""
102	}
103
104	return ReplaceTag(fmt.Sprint(a...))
105}
106
107// Sprintf format and return rendered string
108func Sprintf(format string, a ...interface{}) string {
109	return ReplaceTag(fmt.Sprintf(format, a...))
110}
111
112// String alias of the ReplaceTag
113func String(s string) string {
114	return ReplaceTag(s)
115}
116
117// Text alias of the ReplaceTag
118func Text(s string) string {
119	return ReplaceTag(s)
120}
121
122/*************************************************************
123 * helper methods for print
124 *************************************************************/
125
126// new implementation, support render full color code on pwsh.exe, cmd.exe
127func doPrintV2(code, str string) {
128	_, err := fmt.Fprint(output, RenderString(code, str))
129	saveInternalError(err)
130
131	// if isLikeInCmd {
132	// 	renderColorCodeOnCmd(func() {
133	// 		_, _ = fmt.Fprint(output, RenderString(code, str))
134	// 	})
135	// } else {
136	// 	_, _ = fmt.Fprint(output, RenderString(code, str))
137	// }
138}
139
140// new implementation, support render full color code on pwsh.exe, cmd.exe
141func doPrintlnV2(code string, args []interface{}) {
142	str := formatArgsForPrintln(args)
143	_, err := fmt.Fprintln(output, RenderString(code, str))
144	saveInternalError(err)
145}
146
147// if use Println, will add spaces for each arg
148func formatArgsForPrintln(args []interface{}) (message string) {
149	if ln := len(args); ln == 0 {
150		message = ""
151	} else if ln == 1 {
152		message = fmt.Sprint(args[0])
153	} else {
154		message = fmt.Sprintln(args...)
155		// clear last "\n"
156		message = message[:len(message)-1]
157	}
158	return
159}
160
161/*************************************************************
162 * helper methods
163 *************************************************************/
164
165// is on debug mode
166// func isDebugMode() bool {
167// 	return debugMode == "on"
168// }
169
170func debugf(f string, v ...interface{}) {
171	if debugMode {
172		fmt.Print("COLOR_DEBUG: ")
173		fmt.Printf(f, v...)
174		fmt.Println()
175	}
176}
177
178// equals: return ok ? val1 : val2
179func compareVal(ok bool, val1, val2 uint8) uint8 {
180	if ok {
181		return val1
182	}
183	return val2
184}
185
186func saveInternalError(err error) {
187	if err != nil {
188		debugf("inner error: %s", err.Error())
189		innerErrs = append(innerErrs, err)
190	}
191}
192
193func stringToArr(str, sep string) (arr []string) {
194	str = strings.TrimSpace(str)
195	if str == "" {
196		return
197	}
198
199	ss := strings.Split(str, sep)
200	for _, val := range ss {
201		if val = strings.TrimSpace(val); val != "" {
202			arr = append(arr, val)
203		}
204	}
205	return
206}
207