#ifndef __anime_h
#define __anime_h
#include <vector>
#include <map>
#include "date.h"
#include "window.h"
#include "progress.h"

enum AnimeWatchingStatus {
	CURRENT,
	PLANNING,
	COMPLETED,
	DROPPED,
	PAUSED,
	REPEATING
};

enum AnimeAiringStatus {
	FINISHED,
	RELEASING,
	NOT_YET_RELEASED,
	CANCELLED,
	HIATUS
};

enum AnimeFormat {
	TV,
	TV_SHORT,
	MOVIE,
	SPECIAL,
	OVA,
	ONA,
	MUSIC,
	MANGA,
	NOVEL,
	ONE_SHOT
};

enum AnimeSeason {
	UNKNOWN,
	WINTER,
	SPRING,
	SUMMER,
	FALL
};

class Anime {
	public:
		Anime();
		Anime(const Anime& a);
		/* List-specific data */
		enum AnimeWatchingStatus status;
		int progress;
		int score;
		Date started;
		Date completed;
		int updated; /* this should be 64-bit */
		std::string notes;

		/* Useful information */
		int id;
		struct {
			std::string romaji;
			std::string english;
			std::string native;
		} title;
		std::vector<std::string> synonyms;
		int episodes;
		enum AnimeAiringStatus airing;
		Date air_date;
		std::vector<std::string> genres;
		std::vector<std::string> producers;
		enum AnimeFormat type;
		enum AnimeSeason season;
		int audience_score;
		std::string synopsis;
		int duration;
		
		std::string GetUserPreferredTitle();
		std::vector<std::string> GetTitleSynonyms();
};

/* This is a simple wrapper on a vector that provides 
   methods to make it easier to search the list. */
class AnimeList {
	public:
		AnimeList();
		AnimeList(const AnimeList& l);
		AnimeList& operator=(const AnimeList& l);
		~AnimeList();
		void Add(Anime& anime);
		void Insert(size_t pos, Anime& anime);
		void Delete(size_t index);
		void Clear();
		std::vector<Anime>::iterator begin() noexcept;
		std::vector<Anime>::iterator end() noexcept;
		std::vector<Anime>::const_iterator cbegin() noexcept;
		std::vector<Anime>::const_iterator cend() noexcept;
		size_t Size() const;
		Anime* AnimeById(int id);
		int GetAnimeIndex(Anime& anime) const;
		bool AnimeInList(int id);
		Anime& operator[](size_t index);
		const Anime& operator[](size_t index) const;
		std::string name;

	protected:
		std::vector<Anime> anime_list;
		std::map<int, Anime*> anime_id_to_anime;
};

extern std::map<enum AnimeSeason, std::string> AnimeSeasonToStringMap;
extern std::map<enum AnimeFormat, std::string> AnimeFormatToStringMap;
extern std::map<enum AnimeWatchingStatus, std::string> AnimeWatchingToStringMap;
extern std::map<enum AnimeAiringStatus, std::string> AnimeAiringToStringMap;
#endif // __anime_h