package main import ( "fmt" "os" "sort" "time" "github.com/StevanFreeborn/pokedexcli/internal/pokeapi" "github.com/StevanFreeborn/pokedexcli/internal/pokecache" ) type context struct { commands map[string]cliCommand client *pokeapi.Client prevOffset int nextOffset int args []string } func (r *context) register(c cliCommand) { if c.name != "" { r.commands[c.name] = c } } func NewContext() *context { var exitCommand = cliCommand{ name: "exit", description: "Exit the Pokedex", callback: commandExit, } helpCommand := cliCommand{ name: "help", description: "Displays a help message", callback: commandHelp, } mapCommand := cliCommand{ name: "map", description: "Displays the names of the next 20 location areas", callback: commandMap, } mapBackCommand := cliCommand{ name: "mapb", description: "Displays the names of the previous 20 location areas", callback: commandMapBack, } exploreCommand := cliCommand{ name: "explore", description: "Displays a list of pokemon in the area", callback: commandExplore, } c := &context{ commands: map[string]cliCommand{}, client: pokeapi.NewClient(pokecache.NewCache(5 * time.Second)), prevOffset: 0, nextOffset: 0, } c.register(exitCommand) c.register(helpCommand) c.register(mapCommand) c.register(mapBackCommand) c.register(exploreCommand) return c } type commandFunc func(c *context) error type cliCommand struct { name string description string callback commandFunc } func commandExit(c *context) error { fmt.Println("Closing the Pokedex... Goodbye!") os.Exit(0) return nil } func commandHelp(c *context) error { fmt.Println("Welcome to the Pokedex!") fmt.Println("Usage:") fmt.Println("") sortedKeys := []string{} for k := range c.commands { sortedKeys = append(sortedKeys, k) } sort.Strings(sortedKeys) for _, key := range sortedKeys { command := c.commands[key] fmt.Printf("%s: %s\n", command.name, command.description) } return nil } func getMaps(c *context, offset int) error { page, err := c.client.Locations.List(offset) if err != nil { fmt.Println("Unable to get locations") return err } c.prevOffset = page.GetPreviousOffset() c.nextOffset = page.GetNextOffset() if len(page.Results) == 0 { fmt.Println("No locations found") } else { locationsPerPage := 20 currentPage := (offset / locationsPerPage) + 1 totalPages := page.Count / locationsPerPage fmt.Printf("Displaying page %d of %d page(s)\n", currentPage, totalPages) } for _, location := range page.Results { fmt.Printf("%s\n", location.Name) } return nil } func commandMap(c *context) error { return getMaps(c, c.nextOffset) } func commandMapBack(c *context) error { if c.prevOffset == 0 && (c.nextOffset == 0 || c.nextOffset == 20) { fmt.Println("You're on the first page") return nil } return getMaps(c, c.prevOffset) } func commandExplore(c *context) error { if len(c.args) < 1 { fmt.Println("Please provide area name. i.e. explore ") return nil } area, err := c.client.Locations.Get(c.args[0]) if err != nil { return err } for _, encounter := range area.PokemonEncounters { fmt.Println(encounter.Pokemon.Name) } return nil }