@@ -7,16 +7,26 @@ import (
77 "fmt"
88 "github.com/charmbracelet/lipgloss"
99 "github.com/digitalghost-dev/poke-cli/connections"
10+ "github.com/disintegration/imaging"
11+ "github.com/lucasb-eyer/go-colorful"
1012 "golang.org/x/text/cases"
1113 "golang.org/x/text/language"
14+ "image"
15+ "net/http"
16+ "os"
1217 "strings"
1318)
1419
1520var (
1621 helpBorder = lipgloss .NewStyle ().
1722 BorderStyle (lipgloss .RoundedBorder ()).
1823 BorderForeground (lipgloss .Color ("#FFCC00" ))
19- styleBold = lipgloss .NewStyle ().Bold (true )
24+ styleBold = lipgloss .NewStyle ().Bold (true )
25+ errorColor = lipgloss .NewStyle ().Foreground (lipgloss .Color ("#F2055C" ))
26+ errorBorder = lipgloss .NewStyle ().
27+ BorderStyle (lipgloss .RoundedBorder ()).
28+ BorderForeground (lipgloss .Color ("#F2055C" ))
29+ styleItalic = lipgloss .NewStyle ().Italic (true )
2030)
2131
2232func header (header string ) {
@@ -30,28 +40,37 @@ func header(header string) {
3040 fmt .Println (HeaderBold )
3141}
3242
33- func SetupPokemonFlagSet () (* flag.FlagSet , * bool , * bool , * bool , * bool , * bool , * bool ) {
43+ func SetupPokemonFlagSet () (* flag.FlagSet , * bool , * bool , * string , * string , * bool , * bool , * bool , * bool ) {
3444 pokeFlags := flag .NewFlagSet ("pokeFlags" , flag .ExitOnError )
3545
3646 abilitiesFlag := pokeFlags .Bool ("abilities" , false , "Print the Pokémon's abilities" )
3747 shortAbilitiesFlag := pokeFlags .Bool ("a" , false , "Print the Pokémon's abilities" )
3848
49+ imageFlag := pokeFlags .String ("image" , "" , "Print the Pokémon's default sprite" )
50+ shortImageFlag := pokeFlags .String ("i" , "" , "Print the Pokémon's default sprite" )
51+
3952 statsFlag := pokeFlags .Bool ("stats" , false , "Print the Pokémon's base stats" )
4053 shortStatsFlag := pokeFlags .Bool ("s" , false , "Print the Pokémon's base stats" )
4154
4255 typesFlag := pokeFlags .Bool ("types" , false , "Print the Pokémon's typing" )
4356 shortTypesFlag := pokeFlags .Bool ("t" , false , "Prints the Pokémon's typing" )
4457
58+ hintMessage := styleItalic .Render ("options: [sm, md, lg]" )
59+
4560 pokeFlags .Usage = func () {
46- fmt .Println (
47- helpBorder .Render ("poke-cli pokemon <pokemon-name> [flags]" ,
48- styleBold .Render ("\n \n FLAGS:" ), "\n \t " , "-a, --abilities" , "\t " , "Prints out the Pokémon's abilities." ,
49- "\n \t " , "-t, --types" , "\t \t " , "Prints out the Pokémon's typing." , "\n \t " , "-s, --stats" , "\t \t " ,
50- "Prints out the Pokémon's base stats." ),
61+ helpMessage := helpBorder .Render ("poke-cli pokemon <pokemon-name> [flags]\n \n " ,
62+ styleBold .Render ("FLAGS:" ),
63+ fmt .Sprintf ("\n \t %-30s %s" , "-a, --abilities" , "Prints the Pokémon's abilities." ),
64+ fmt .Sprintf ("\n \t %-30s %s" , "-i=xx, --image=xx" , "Prints out the Pokémon's default sprite." ),
65+ fmt .Sprintf ("\n \t %5s%-15s" , "" , hintMessage ),
66+ fmt .Sprintf ("\n \t %-30s %s" , "-s, --stats" , "Prints the Pokémon's base stats." ),
67+ fmt .Sprintf ("\n \t %-30s %s" , "-t, --types" , "Prints the Pokémon's typing." ),
68+ fmt .Sprintf ("\n \t %-30s %s" , "-h, --help" , "Prints the help menu." ),
5169 )
70+ fmt .Println (helpMessage )
5271 }
5372
54- return pokeFlags , abilitiesFlag , shortAbilitiesFlag , statsFlag , shortStatsFlag , typesFlag , shortTypesFlag
73+ return pokeFlags , abilitiesFlag , shortAbilitiesFlag , imageFlag , shortImageFlag , statsFlag , shortStatsFlag , typesFlag , shortTypesFlag
5574}
5675
5776func AbilitiesFlag (endpoint string , pokemonName string ) error {
@@ -98,13 +117,85 @@ func AbilitiesFlag(endpoint string, pokemonName string) error {
98117 return nil
99118}
100119
120+ func ImageFlag (endpoint string , pokemonName string , size string ) error {
121+ baseURL := "https://pokeapi.co/api/v2/"
122+ pokemonStruct , _ , _ , _ , _ := connections .PokemonApiCall (endpoint , pokemonName , baseURL )
123+
124+ header ("Image" )
125+
126+ // Anonymous function to transform the image to a string
127+ // ToString generates an ASCII representation of the image with color
128+ ToString := func (width int , height int , img image.Image ) string {
129+ // Resize the image to the specified width, preserving aspect ratio
130+ img = imaging .Resize (img , width , height , imaging .NearestNeighbor )
131+ b := img .Bounds ()
132+ imageWidth := b .Max .X - 2 // Adjust width to exclude margins
133+ h := b .Max .Y - 4 // Adjust height to exclude margins
134+ str := strings.Builder {}
135+
136+ // Loop through the image pixels, two rows at a time
137+ for heightCounter := 2 ; heightCounter < h ; heightCounter += 2 {
138+ for x := 1 ; x < imageWidth ; x ++ {
139+ // Get the color of the current and next row's pixels
140+ c1 , _ := colorful .MakeColor (img .At (x , heightCounter ))
141+ color1 := lipgloss .Color (c1 .Hex ())
142+ c2 , _ := colorful .MakeColor (img .At (x , heightCounter + 1 ))
143+ color2 := lipgloss .Color (c2 .Hex ())
144+
145+ // Render the half-block character with the two colors
146+ str .WriteString (lipgloss .NewStyle ().
147+ Foreground (color1 ).
148+ Background (color2 ).
149+ Render ("▀" ))
150+ }
151+
152+ // Add a newline after each row
153+ str .WriteString ("\n " )
154+ }
155+
156+ return str .String ()
157+ }
158+
159+ imageResp , err := http .Get (pokemonStruct .Sprites .FrontDefault )
160+ if err != nil {
161+ fmt .Println ("Error downloading sprite image:" , err )
162+ os .Exit (1 )
163+ }
164+ defer imageResp .Body .Close ()
165+
166+ img , err := imaging .Decode (imageResp .Body )
167+ if err != nil {
168+ fmt .Println ("Error decoding image:" , err )
169+ os .Exit (1 )
170+ }
171+
172+ // Define size map
173+ sizeMap := map [string ][2 ]int {
174+ "lg" : {120 , 120 },
175+ "md" : {90 , 90 },
176+ "sm" : {55 , 55 },
177+ }
178+
179+ // Validate size
180+ dimensions , exists := sizeMap [strings .ToLower (size )]
181+ if ! exists {
182+ errMessage := errorBorder .Render (errorColor .Render ("Error!" ), "\n Invalid image size.\n Valid sizes are: lg, md, sm" )
183+ return fmt .Errorf ("%s" , errMessage )
184+ }
185+
186+ imgStr := ToString (dimensions [0 ], dimensions [1 ], img )
187+ fmt .Println (imgStr )
188+
189+ return nil
190+ }
191+
101192func StatsFlag (endpoint string , pokemonName string ) error {
102193 baseURL := "https://pokeapi.co/api/v2/"
103194 pokemonStruct , _ , _ , _ , _ := connections .PokemonApiCall (endpoint , pokemonName , baseURL )
104195
105196 header ("Base Stats" )
106197
107- // Helper function to map stat values to categories
198+ // Anonymous function to map stat values to categories
108199 getStatCategory := func (value int ) string {
109200 switch {
110201 case value < 20 :
0 commit comments