package output import ( "fmt" "strings" "time" ) // --------------------------------------------------------------------- // SKYFEED ASCII LOGO // --------------------------------------------------------------------- var SkyfeedLogoLines = []string{ " ______ ___ __", " / __/ /____ __/ _/__ ___ ___/ /", " _\\ \\/ '_/ // / _/ -_) -_) _ / ", "/___/_/\\_\\\\_, /_/ \\__/\\__/\\_,_/ ", " /___/ ", } // --------------------------------------------------------------------- // ANSI HELPERS // --------------------------------------------------------------------- func ansi(r, g, b int) string { return fmt.Sprintf("\033[38;2;%d;%d;%dm", r, g, b) } func reset() string { return "\033[0m" } // --------------------------------------------------------------------- // TIME-OF-DAY PALETTES (MATCHING PYTHON LOGIC) // --------------------------------------------------------------------- // // Python version used a function _get_time_phase() which returned // two hex colours: primary (top) and secondary (bottom). // We reproduce that behaviour exactly here. // type PhaseColors struct { Primary [3]int // top colour Secondary [3]int // bottom colour } func getTimePhaseColors() PhaseColors { h := time.Now().Hour() switch { case h >= 5 && h < 8: // Dawn return PhaseColors{ Primary: [3]int{255, 180, 120}, Secondary: [3]int{140, 100, 160}, } case h >= 8 && h < 17: // Noon return PhaseColors{ Primary: [3]int{70, 150, 255}, Secondary: [3]int{120, 190, 255}, } case h >= 17 && h < 20: // Sunset return PhaseColors{ Primary: [3]int{255, 110, 60}, Secondary: [3]int{100, 60, 120}, } default: // Night return PhaseColors{ Primary: [3]int{50, 60, 100}, Secondary: [3]int{20, 30, 60}, } } } // --------------------------------------------------------------------- // WEATHER TONE MAPPING (ANSI-256 FOREGROUND) // // These match the Python "tone_color_map" used for verbose mode, // but here they are used as coloration tint. // --------------------------------------------------------------------- var weatherToneMap = map[string][3]int{ "sunny": {255, 215, 0}, // yellow(ish) "clear": {255, 215, 0}, "cloudy": {180, 180, 180}, "mostly_cloudy": {180, 180, 180}, "rain": {40, 110, 200}, "drizzle": {40, 110, 200}, "snow": {230, 230, 240}, "fog": {130, 130, 140}, "mist": {130, 130, 140}, "thunderstorm": {200, 120, 255}, "smoke": {140, 120, 100}, } // Normalize a condition to a known tone key. func normalizeCondition(cond string) string { c := strings.ToLower(cond) switch { case strings.Contains(c, "sun"): return "sunny" case strings.Contains(c, "clear"): return "clear" case strings.Contains(c, "snow"): return "snow" case strings.Contains(c, "storm"): return "thunderstorm" case strings.Contains(c, "rain"): return "rain" case strings.Contains(c, "drizzle"): return "drizzle" case strings.Contains(c, "fog"): return "fog" case strings.Contains(c, "mist"): return "fog" case strings.Contains(c, "cloud"): return "cloudy" case strings.Contains(c, "smoke"): return "smoke" } return "clear" } // --------------------------------------------------------------------- // BLENDING FUNCTIONS // --------------------------------------------------------------------- func blend(a, b [3]int, factor float64) [3]int { return [3]int{ int(float64(a[0])*(1-factor) + float64(b[0])*factor), int(float64(a[1])*(1-factor) + float64(b[1])*factor), int(float64(a[2])*(1-factor) + float64(b[2])*factor), } } // --------------------------------------------------------------------- // RENDER LOGO: RETURNS A STRING // --------------------------------------------------------------------- func RenderLogoString(weatherCond string) string { phase := getTimePhaseColors() toneKey := normalizeCondition(weatherCond) tone := weatherToneMap[toneKey] var b strings.Builder total := len(SkyfeedLogoLines) for i, line := range SkyfeedLogoLines { // Vertical gradient: bottom → top factor := float64(i) / float64(total-1) // Blend primary→secondary vertically lineCol := blend(phase.Secondary, phase.Primary, factor) // Weather tint applied lightly (0.0 → 0.25) tintFactor := 0.25 tinted := blend(lineCol, tone, tintFactor) b.WriteString(ansi(tinted[0], tinted[1], tinted[2])) b.WriteString(line) b.WriteString(reset()) b.WriteString("\n") } return b.String() } // --------------------------------------------------------------------- // PRINT LOGO — For CLI / debug-logo command // --------------------------------------------------------------------- func PrintLogo(weatherCond string) { fmt.Print(RenderLogoString(weatherCond)) }