@@ -6,15 +6,19 @@ import (
66 "flag"
77 "fmt"
88 "github.com/charmbracelet/lipgloss"
9+ "github.com/charmbracelet/lipgloss/table"
910 "github.com/digitalghost-dev/poke-cli/connections"
1011 "github.com/digitalghost-dev/poke-cli/styling"
1112 "github.com/disintegration/imaging"
1213 "golang.org/x/text/cases"
1314 "golang.org/x/text/language"
1415 "image"
1516 "io"
17+ "log"
1618 "net/http"
1719 "os"
20+ "sort"
21+ "strconv"
1822 "strings"
1923)
2024
@@ -33,7 +37,7 @@ func header(header string) string {
3337 return output .String ()
3438}
3539
36- func SetupPokemonFlagSet () (* flag.FlagSet , * bool , * bool , * string , * string , * bool , * bool , * bool , * bool ) {
40+ func SetupPokemonFlagSet () (* flag.FlagSet , * bool , * bool , * string , * string , * bool , * bool , * bool , * bool , * bool , * bool ) {
3741 pokeFlags := flag .NewFlagSet ("pokeFlags" , flag .ExitOnError )
3842
3943 abilitiesFlag := pokeFlags .Bool ("abilities" , false , "Print the Pokémon's abilities" )
@@ -42,6 +46,9 @@ func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool
4246 imageFlag := pokeFlags .String ("image" , "" , "Print the Pokémon's default sprite" )
4347 shortImageFlag := pokeFlags .String ("i" , "" , "Print the Pokémon's default sprite" )
4448
49+ moveFlag := pokeFlags .Bool ("moves" , false , "Print the Pokémon's learnable moves" )
50+ shortMoveFlag := pokeFlags .Bool ("m" , false , "Print the Pokémon's learnable moves" )
51+
4552 statsFlag := pokeFlags .Bool ("stats" , false , "Print the Pokémon's base stats" )
4653 shortStatsFlag := pokeFlags .Bool ("s" , false , "Print the Pokémon's base stats" )
4754
@@ -56,14 +63,15 @@ func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool
5663 fmt .Sprintf ("\n \t %-30s %s" , "-a, --abilities" , "Prints the Pokémon's abilities." ),
5764 fmt .Sprintf ("\n \t %-30s %s" , "-i=xx, --image=xx" , "Prints out the Pokémon's default sprite." ),
5865 fmt .Sprintf ("\n \t %5s%-15s" , "" , hintMessage ),
66+ fmt .Sprintf ("\n \t %-30s %s" , "-m, --moves" , "Prints the Pokemon's learnable moves." ),
5967 fmt .Sprintf ("\n \t %-30s %s" , "-s, --stats" , "Prints the Pokémon's base stats." ),
6068 fmt .Sprintf ("\n \t %-30s %s" , "-t, --types" , "Prints the Pokémon's typing." ),
6169 fmt .Sprintf ("\n \t %-30s %s" , "-h, --help" , "Prints the help menu." ),
6270 )
6371 fmt .Println (helpMessage )
6472 }
6573
66- return pokeFlags , abilitiesFlag , shortAbilitiesFlag , imageFlag , shortImageFlag , statsFlag , shortStatsFlag , typesFlag , shortTypesFlag
74+ return pokeFlags , abilitiesFlag , shortAbilitiesFlag , imageFlag , shortImageFlag , moveFlag , shortMoveFlag , statsFlag , shortStatsFlag , typesFlag , shortTypesFlag
6775}
6876
6977func AbilitiesFlag (w io.Writer , endpoint string , pokemonName string ) error {
@@ -198,6 +206,117 @@ func ImageFlag(w io.Writer, endpoint string, pokemonName string, size string) er
198206 return nil
199207}
200208
209+ func MovesFlag (w io.Writer , endpoint string , pokemonName string ) error {
210+ baseURL := "https://pokeapi.co/api/v2/"
211+ pokemonStruct , _ , _ , _ , _ , _ := connections .PokemonApiCall (endpoint , pokemonName , baseURL )
212+
213+ _ , err := fmt .Fprintln (w , header ("Learnable Moves" ))
214+ if err != nil {
215+ return err
216+ }
217+
218+ type MoveInfo struct {
219+ Accuracy int
220+ Level int
221+ Name string
222+ Power int
223+ Type string
224+ }
225+
226+ var moves []MoveInfo
227+
228+ for _ , pokeMove := range pokemonStruct .Moves {
229+ for _ , detail := range pokeMove .VersionGroupDetails {
230+ if detail .VersionGroup .Name != "scarlet-violet" || detail .MoveLearnedMethod .Name != "level-up" {
231+ continue
232+ }
233+
234+ moveName := pokeMove .Move .Name
235+ moveStruct , _ , err := connections .MoveApiCall ("move" , moveName , baseURL )
236+ if err != nil {
237+ log .Printf ("Error fetching move %s: %v" , moveName , err )
238+ continue
239+ }
240+
241+ capitalizedMove := cases .Title (language .English ).String (strings .ReplaceAll (moveName , "-" , " " ))
242+ capitalizedType := cases .Title (language .English ).String (moveStruct .Type .Name )
243+
244+ moves = append (moves , MoveInfo {
245+ Accuracy : moveStruct .Accuracy ,
246+ Level : detail .LevelLearnedAt ,
247+ Name : capitalizedMove ,
248+ Power : moveStruct .Power ,
249+ Type : capitalizedType ,
250+ })
251+ }
252+ }
253+
254+ if len (moves ) == 0 {
255+ _ , err := fmt .Fprintln (w , "No level-up moves found for Scarlet & Violet." )
256+ if err != nil {
257+ return err
258+ }
259+ return nil
260+ }
261+
262+ // Sort by level
263+ sort .Slice (moves , func (i , j int ) bool {
264+ return moves [i ].Level < moves [j ].Level
265+ })
266+
267+ // Convert to table rows
268+ var rows [][]string
269+ for _ , m := range moves {
270+ styledType := lipgloss .
271+ NewStyle ().
272+ Bold (true ).
273+ Foreground (lipgloss .Color (styling .ColorMap [strings .ToLower (m .Type )])).
274+ Render (m .Type )
275+
276+ rows = append (rows , []string {
277+ m .Name ,
278+ strconv .Itoa (m .Level ),
279+ styledType ,
280+ strconv .Itoa (m .Accuracy ),
281+ strconv .Itoa (m .Power ),
282+ })
283+ }
284+
285+ // Build and print table
286+ color := lipgloss.AdaptiveColor {Light : "#4B4B4B" , Dark : "#D3D3D3" }
287+
288+ t := table .New ().
289+ Border (lipgloss .NormalBorder ()).
290+ BorderStyle (lipgloss .NewStyle ().Foreground (color )).
291+ StyleFunc (func (row , column int ) lipgloss.Style {
292+ var style lipgloss.Style
293+
294+ switch column {
295+ case 0 :
296+ style = style .Width (18 )
297+ case 1 :
298+ style = style .Width (8 )
299+ case 2 :
300+ style = style .Width (10 )
301+ case 3 :
302+ style = style .Width (10 )
303+ case 4 :
304+ style = style .Width (8 )
305+ }
306+
307+ return style
308+ }).
309+ Headers ("Name" , "Level" , "Type" , "Accuracy" , "Power" ).
310+ Rows (rows ... )
311+
312+ _ , err = fmt .Fprintln (w , t )
313+ if err != nil {
314+ return err
315+ }
316+
317+ return nil
318+ }
319+
201320func StatsFlag (w io.Writer , endpoint string , pokemonName string ) error {
202321 baseURL := "https://pokeapi.co/api/v2/"
203322 pokemonStruct , _ , _ , _ , _ , _ := connections .PokemonApiCall (endpoint , pokemonName , baseURL )
@@ -298,35 +417,14 @@ func TypesFlag(w io.Writer, endpoint string, pokemonName string) error {
298417 baseURL := "https://pokeapi.co/api/v2/"
299418 pokemonStruct , _ , _ , _ , _ , _ := connections .PokemonApiCall (endpoint , pokemonName , baseURL )
300419
301- colorMap := map [string ]string {
302- "normal" : "#B7B7A9" ,
303- "fire" : "#FF4422" ,
304- "water" : "#3499FF" ,
305- "electric" : "#FFCC33" ,
306- "grass" : "#77CC55" ,
307- "ice" : "#66CCFF" ,
308- "fighting" : "#BB5544" ,
309- "poison" : "#AA5699" ,
310- "ground" : "#DEBB55" ,
311- "flying" : "#889AFF" ,
312- "psychic" : "#FF5599" ,
313- "bug" : "#AABC22" ,
314- "rock" : "#BBAA66" ,
315- "ghost" : "#6666BB" ,
316- "dragon" : "#7766EE" ,
317- "dark" : "#775544" ,
318- "steel" : "#AAAABB" ,
319- "fairy" : "#EE99EE" ,
320- }
321-
322420 // Print the header from header func
323421 _ , err := fmt .Fprintln (w , header ("Typing" ))
324422 if err != nil {
325423 return err
326424 }
327425
328426 for _ , pokeType := range pokemonStruct .Types {
329- colorHex , exists := colorMap [pokeType .Type .Name ]
427+ colorHex , exists := styling . ColorMap [pokeType .Type .Name ]
330428 if exists {
331429 color := lipgloss .Color (colorHex )
332430 style := lipgloss .NewStyle ().Bold (true ).Foreground (color )
0 commit comments