{-# LANGUAGE OverloadedStrings #-}

{-
IDEA: all of these modles could have been split up into their own modules:
Rdioh.Model.Artist etc etc.
Then we wouldn't have these scoping issues and all the fields could be normal names.

Downside: user has to import each module explicitly to use it.
-}

module Rdioh.Models where
import Data.Aeson
import Control.Applicative

data AlbumExtra = AlbumIframeUrl | AlbumIsCompilation | AlbumLabel | AlbumBigIcon | AlbumReleaseDateISO

instance Show AlbumExtra where
    show AlbumIframeUrl = "iframeUrl"
    show AlbumIsCompilation = "isCompilation"
    show AlbumLabel = "label"
    show AlbumBigIcon = "bigIcon"
    show AlbumReleaseDateISO = "releaseDateISO"

data Album = Album {
               albumName :: String,
               albumIcon :: String,
               albumBaseIcon :: String,
               albumUrl :: String,
               albumArtist :: String,
               albumArtistUrl :: String,
               isExplicit :: Bool,
               isClean :: Bool,
               albumLength :: Int,
               albumArtistKey :: String,
               trackKeys :: [String],
               price :: String,
               canStream :: Bool,
               canSample :: Bool,
               canTether :: Bool,
               albumShortUrl :: String,
               embedUrl :: String,
               displayDate :: String,
               albumKey :: String,
               releaseDate :: String,
               duration :: Int,
               iframeUrl :: Maybe String,
               isCompilation :: Maybe Bool,
               albumLabel :: Maybe String,
               albumBigIcon :: Maybe String,
               releaseDateISO :: Maybe String
} deriving (Show)

instance FromJSON Album where
  parseJSON (Object v) = Album <$> v .: "name"
                               <*> v .: "icon"
                               <*> v .: "baseIcon"
                               <*> v .: "url"
                               <*> v .: "artist"
                               <*> v .: "artistUrl"
                               <*> v .: "isExplicit"
                               <*> v .: "isClean"
                               <*> v .: "length"
                               <*> v .: "artistKey"
                               <*> v .: "trackKeys"
                               <*> v .: "price"
                               <*> v .: "canStream"
                               <*> v .: "canSample"
                               <*> v .: "canTether"
                               <*> v .: "shortUrl"
                               <*> v .: "embedUrl"
                               <*> v .: "displayDate"
                               <*> v .: "key"
                               <*> v .: "releaseDate"
                               <*> v .: "duration"
                               <*> v .:? "iframeUrl"
                               <*> v .:? "isCompilation"
                               <*> v .:? "label"
                               <*> v .:? "bigIcon"
                               <*> v .:? "releaseDateISO"

data ArtistExtra = ArtistAlbumCount

instance Show ArtistExtra where
    show ArtistAlbumCount = "albumCount"

data Artist = Artist {
            artistName :: String,
            artistKey :: String,
            artistUrl :: String,
            artistLength :: Int,
            artistIcon :: String,
            artistBaseIcon :: String,
            hasRadio :: Bool,
            artistShortUrl :: String,
            radioKey :: Maybe String,
            topSongsKey :: Maybe String,
            artistAlbumCount :: Maybe Int
} deriving (Show)

instance FromJSON Artist where
  parseJSON (Object v) = Artist <$> v .: "name"
                                <*> v .: "key"
                                <*> v .: "url"
                                <*> v .: "length"
                                <*> v .: "icon"
                                <*> v .: "baseIcon"
                                <*> v .: "hasRadio"
                                <*> v .: "shortUrl"
                                <*> v .:? "radioKey"
                                <*> v .:? "topSongsKey"
                                <*> v .:? "albumCount"

data Label = Label {
           labelName :: String,
           labelKey :: String,
           labelUrl :: String,
           labelShortUrl :: String,
           labelHasRadio :: Bool,
           labelRadioKey :: String
} deriving (Show)

instance FromJSON Label where
  parseJSON (Object v) = Label <$> v .: "name"
                               <*> v .: "key"
                               <*> v .: "url"
                               <*> v .: "shortUrl"
                               <*> v .: "hasRadio"
                               <*> v .: "radioKey"

data TrackExtra = IsInCollection | IsOnCompilation | Isrcs | TrackIframeUrl | PlayCount | TrackBigIcon

instance Show TrackExtra where
    show IsInCollection = "isInCollection"
    show IsOnCompilation = "isOnCompilation"
    show Isrcs = "isrcs"
    show TrackIframeUrl = "iframeUrl"
    show PlayCount = "playCount"
    show TrackBigIcon = "bigIcon"

data Track = Track {
           trackName :: String,
           trackArtist :: String,
           trackAlbum :: String,
           trackAlbumKey :: String,
           trackAlbumUrl :: String,
           trackArtistKey :: String,
           trackArtistUrl :: String,
           trackDuration :: Int,
           trackIsExplicit :: Bool,
           trackIsClean :: Bool,
           trackUrl :: String,
           trackBaseIcon :: String,
           trackCanDownload :: Bool,
           trackCanDownloadAlbumOnly :: Bool,
           trackCanStream :: Bool,
           trackCanTether :: Bool,
           trackCanSample :: Bool,
           trackPrice :: String,
           trackEmbedUrl :: String,
           trackKey :: String,
           trackIcon :: String,
           trackNum :: Int,
           trackAlbumArtist :: Maybe String,
           trackAlbumArtistKey :: Maybe String,
           isInCollection :: Maybe Bool,
           isOnCompilation :: Maybe Bool,
           isrcs :: Maybe [String],
           trackIframeUrl :: Maybe String,
           playCount :: Maybe Int,
           trackBigIcon :: Maybe String
} deriving (Show)

instance FromJSON Track where
  parseJSON (Object v) = Track <$> v .: "name"
                               <*> v .: "artist"
                               <*> v .: "album"
                               <*> v .: "albumKey"
                               <*> v .: "albumUrl"
                               <*> v .: "artistKey"
                               <*> v .: "artistUrl"
                               <*> v .: "duration"
                               <*> v .: "isExplicit"
                               <*> v .: "isClean"
                               <*> v .: "url"
                               <*> v .: "baseIcon"
                               <*> v .: "canDownload"
                               <*> v .: "canDownloadAlbumOnly"
                               <*> v .: "canStream"
                               <*> v .: "canTether"
                               <*> v .: "canSample"
                               <*> v .: "price"
                               <*> v .: "embedUrl"
                               <*> v .: "key"
                               <*> v .: "icon"
                               <*> v .: "trackNum"
                               <*> v .:? "albumArtist"
                               <*> v .:? "albumArtistKey"
                               <*> v .:? "isInCollection"
                               <*> v .:? "isOnCompilation"
                               <*> v .:? "isrcs"
                               <*> v .:? "iframeUrl"
                               <*> v .:? "playCount"
                               <*> v .:? "bigIcon"

data Reason = Viewable | UserPreference | OrderedAlbum | TooFewSongs deriving (Show)

instance FromJSON Reason where
  parseJSON (Number n)
      | n == 0 = return Viewable
      | n == 1 = return UserPreference
      | n == 2 = return OrderedAlbum
      | n == 3 = return TooFewSongs

data PlaylistExtra = PlIframeUrl | IsViewable | PlBigIcon | PlDescription | PlTracks | IsPublished | PlTrackKeys | ReasonNotViewable

instance Show PlaylistExtra where
    show PlIframeUrl = "iframeUrl"
    show IsViewable = "isViewable"
    show PlBigIcon = "bigIcon"
    show PlDescription = "description"
    show PlTracks = "tracks"
    show IsPublished = "isPublished"
    show PlTrackKeys = "trackKeys"
    show ReasonNotViewable = "reasonNotViewable"

data Playlist = Playlist {
              plName :: String,
              plUrl :: String,
              plOwner :: String,
              plOwnerUrl :: String,
              plOwnerKey :: String,
              plOwnerIcon :: String,
              plShortUrl :: String,
              plEmbedUrl :: String,
              plKey :: String,
              plLength :: Maybe Int,
              plIcon :: Maybe String,
              plBaseIcon :: Maybe String,
              lastUpdated :: Maybe Int,
              plIFrameUrl :: Maybe String,
              isViewable :: Maybe Bool,
              plBigIcon :: Maybe String,
              plDescription :: Maybe String,
              plTracks :: Maybe [Track],
              isPublished :: Maybe Bool,
              plTrackKeys :: Maybe [String],
              reasonNotViewable :: Maybe Reason
} deriving (Show)

instance FromJSON Playlist where
  parseJSON (Object v) = Playlist <$> v .: "name"
                                  <*> v .: "url"
                                  <*> v .: "owner"
                                  <*> v .: "ownerUrl"
                                  <*> v .: "ownerKey"
                                  <*> v .: "ownerIcon"
                                  <*> v .: "shortUrl"
                                  <*> v .: "embedUrl"
                                  <*> v .: "key"
                                  <*> v .:? "length"
                                  <*> v .:? "icon"
                                  <*> v .:? "baseIcon"
                                  <*> v .:? "lastUpdated"
                                  <*> v .:? "iframeUrl"
                                  <*> v .:? "isViewable"
                                  <*> v .:? "bigIcon"
                                  <*> v .:? "description"
                                  <*> v .:? "tracks"
                                  <*> v .:? "isPublished"
                                  <*> v .:? "trackKeys"
                                  <*> v .:? "reasonNotViewable"

data Gender = Male | Female deriving (Show)

data UserPlaylists = UserPlaylists {
                   upOwned :: [Playlist],
                   upCollab :: [Playlist],
                   upSubscribed :: [Playlist]
} deriving (Show)

instance FromJSON UserPlaylists where
  parseJSON (Object v) = UserPlaylists <$> v .: "owned"
                                       <*> v .: "collab"
                                       <*> v .: "subscribed"


instance FromJSON Gender where
  parseJSON (String s) = return (if s == "m" then Male else Female)

data User = User {
              userKey :: String,
              firstName :: String,
              lastName :: String,
              userIcon :: String,
              userBaseIcon :: String,
              libraryVersion :: Int,
              userUrl :: String,
              gender :: Gender,
              followingUrl :: Maybe String,
              isTrial :: Maybe Bool,
              artistCount :: Maybe Int,
              lastSongPlayed :: Maybe String,
              heavyRotationKey :: Maybe String,
              networkHeavyRotationKey :: Maybe String,
              albumCount :: Maybe Int,
              trackCount :: Maybe Int,
              lastSongPlayTime :: Maybe String,
              username :: Maybe String,
              reviewCount :: Maybe Int,
              collectionUrl :: Maybe String,
              playlistsUrl :: Maybe String,
              collectionKey :: Maybe String,
              followersUrl :: Maybe String,
              displayName :: Maybe String,
              isUnlimited :: Maybe Bool,
              isSubscriber :: Maybe Bool
} deriving (Show)

data UserExtra = FollowingUrl | IsTrial | ArtistCount | LastSongPlayed | HeavyRotationKey | NetworkHeavyRotationKey | AlbumCount | TrackCount | LastSongPlayTime | Username | ReviewCount | CollectionUrl | PlaylistsUrl | CollectionKey | FollowersUrl | DisplayName | IsUnlimited | IsSubscriber

instance Show UserExtra where
    show FollowingUrl = "followingUrl"
    show IsTrial = "isTrial"
    show ArtistCount = "artistCount"
    show LastSongPlayed = "lastSongPlayed"
    show HeavyRotationKey = "heavyRotationKey"
    show NetworkHeavyRotationKey = "networkHeavyRotationKey"
    show AlbumCount = "albumCount"
    show TrackCount = "trackCount"
    show LastSongPlayTime = "lastSongPlayTime"
    show Username = "username"
    show ReviewCount = "reviewCount"
    show CollectionUrl = "collectionUrl"
    show PlaylistsUrl = "playlistsUrl"
    show CollectionKey = "collectionkey"
    show FollowersUrl = "followersUrl"
    show DisplayName = "displayName"
    show IsUnlimited = "isUnlimited"
    show IsSubscriber = "isSubscriber"

instance FromJSON User where
  parseJSON (Object v) = User <$> v .: "key"
                              <*> v .: "firstName"
                              <*> v .: "lastName"
                              <*> v .: "icon"
                              <*> v .: "baseIcon"
                              <*> v .: "libraryVersion"
                              <*> v .: "url"
                              <*> v .: "gender"
                              <*> v .:? "followingUrl"
                              <*> v .:? "isTrial"
                              <*> v .:? "artistCount"
                              <*> v .:? "lastSongPlayed"
                              <*> v .:? "heavyRotationKey"
                              <*> v .:? "networkHeavyRotationKey"
                              <*> v .:? "albumCount"
                              <*> v .:? "trackCount"
                              <*> v .:? "lastSongPlayTime"
                              <*> v .:? "username"
                              <*> v .:? "reviewCount"
                              <*> v .:? "collectionUrl"
                              <*> v .:? "playlistsUrl"
                              <*> v .:? "collectionKey"
                              <*> v .:? "followersUrl"
                              <*> v .:? "displayName"
                              <*> v .:? "isUnlimited"
                              <*> v .:? "isSubscriber"

data CollectionAlbum = CollectionAlbum {
                          colName :: String,
                          colIcon :: String,
                          colBaseIcon :: String,
                          colUrl :: String,
                          colArtist :: String,
                          colAlbumArtistUrl :: String,
                          colIsExplicit :: Bool,
                          colIsClean :: Bool,
                          colLength :: Int,
                          colAlbumArtistKey :: String,
                          colTrackKeys :: [String],
                          colPrice :: String,
                          colCanStream :: Bool,
                          colCanSample :: Bool,
                          colCanTether :: Bool,
                          colShortUrl :: String,
                          colEmbedUrl :: String,
                          colDisplayDate :: String,
                          colKey :: String,
                          colReleaseDate :: String,
                          colDuration :: Int,
                          colUserKey :: String,
                          colUserName :: String,
                          colAlbumKey :: String,
                          colAlbumUrl :: String,
                          colCollectionUrl :: String,
                          colItemTrackKeys :: [String],
                          colIframeUrl :: Maybe String,
                          colUserGender :: Maybe Gender,
                          colIsCompilation :: Maybe Bool,
                          colLabel :: Maybe String,
                          colReleaseDateISO :: Maybe String,
                          colUpcs :: Maybe [String],
                          colBigIcon :: Maybe String
} deriving (Show)

instance FromJSON CollectionAlbum where
  parseJSON (Object v) = CollectionAlbum <$> v .: "name"
                                         <*> v .: "icon"
                                         <*> v .: "baseIcon"
                                         <*> v .: "url"
                                         <*> v .: "artist"
                                         <*> v .: "artistUrl"
                                         <*> v .: "isExplicit"
                                         <*> v .: "isClean"
                                         <*> v .: "length"
                                         <*> v .: "artistKey"
                                         <*> v .: "trackKeys"
                                         <*> v .: "price"
                                         <*> v .: "canStream"
                                         <*> v .: "canSample"
                                         <*> v .: "canTether"
                                         <*> v .: "shortUrl"
                                         <*> v .: "embedUrl"
                                         <*> v .: "displayDate"
                                         <*> v .: "key"
                                         <*> v .: "releaseDate"
                                         <*> v .: "duration"
                                         <*> v .: "userkey"
                                         <*> v .: "userName"
                                         <*> v .: "albumKey"
                                         <*> v .: "albumUrl"
                                         <*> v .: "collectionUrl"
                                         <*> v .: "itemTrackKeys"
                                         <*> v .:? "iframeUrl"
                                         <*> v .:? "userGender"
                                         <*> v .:? "isCompilation"
                                         <*> v .:? "label"
                                         <*> v .:? "releaseDateISO"
                                         <*> v .:? "upcs"
                                         <*> v .:? "bigIcon"

data CollectionArtist = CollectionArtist {
                          colArtistName :: String,
                          colArtistKey :: String,
                          colArtistUrl :: String,
                          colArtistLength :: Int,
                          colArtistIcon :: String,
                          colArtistBaseIcon :: String,
                          colArtistHasRadio :: Bool,
                          colArtistShortUrl :: String,
                          colArtistRadioKey :: String,
                          colArtistTopSongsKey :: [String],
                          colArtistUserKey :: String,
                          colArtistUserName :: String,
                          colArtistArtistKey :: String,
                          colArtistArtistUrl :: String,
                          colArtistCollectionUrl :: String,
                          colCount :: Maybe Int,
                          colAlbumCount :: Maybe Int
} deriving (Show)

instance FromJSON CollectionArtist where
  parseJSON (Object v) = CollectionArtist <$> v .: "name"
                                          <*> v .: "key"
                                          <*> v .: "url"
                                          <*> v .: "length"
                                          <*> v .: "icon"
                                          <*> v .: "baseIcon"
                                          <*> v .: "hasRadio"
                                          <*> v .: "shortUrl"
                                          <*> v .: "radioKey"
                                          <*> v .: "topSongsKey"
                                          <*> v .: "userKey"
                                          <*> v .: "userName"
                                          <*> v .: "artistKey"
                                          <*> v .: "artistUrl"
                                          <*> v .: "collectionUrl"
                                          <*> v .:? "count"
                                          <*> v .:? "albumCount"

data LabelStation = LabelStation {
                      lsCount :: Int,
                      lsLabelName :: String,
                      lsName :: String,
                      lsHasRadio :: Bool,
                      lsTracks :: [String],
                      lsLabelUrl :: String,
                      lsShortUrl :: String,
                      lsLength :: Int,
                      lsUrl :: String,
                      lsKey :: String,
                      lsRadioKey :: String,
                      lsReloadOnRepeat :: Bool,
                      lsTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON LabelStation where
  parseJSON (Object v) = LabelStation <$> v .: "count"
                                      <*> v .: "labelName"
                                      <*> v .: "name"
                                      <*> v .: "hasRadio"
                                      <*> v .: "tracks"
                                      <*> v .: "labelUrl"
                                      <*> v .: "shortUrl"
                                      <*> v .: "length"
                                      <*> v .: "url"
                                      <*> v .: "key"
                                      <*> v .: "radioKey"
                                      <*> v .: "reloadOnRepeat"
                                      <*> v .:? "trackKeys"

data ArtistStation = ArtistStation {
                       asRadioKey :: String,
                       asTopSongsKey :: String,
                       asBaseIcon :: String,
                       asTracks :: [String],
                       asArtistUrl :: String,
                       asKey :: String,
                       asReloadOnRepeat :: Bool,
                       asIcon :: String,
                       asCount :: Int,
                       asName :: String,
                       asHasRadio :: Bool,
                       asUrl :: String,
                       asArtistName :: String,
                       asShortUrl :: String,
                       asLength :: Int,
                       asAlbumCount :: Maybe Int,
                       asTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON ArtistStation where
  parseJSON (Object v) = ArtistStation <$> v .: "radioKey"
                                       <*> v .: "topSongsKey"
                                       <*> v .: "baseIcon"
                                       <*> v .: "tracks"
                                       <*> v .: "artistUrl"
                                       <*> v .: "key"
                                       <*> v .: "reloadOnRepeat"
                                       <*> v .: "icon"
                                       <*> v .: "count"
                                       <*> v .: "name"
                                       <*> v .: "hasRadio"
                                       <*> v .: "url"
                                       <*> v .: "artistName"
                                       <*> v .: "shortUrl"
                                       <*> v .: "length"
                                       <*> v .:? "albumCount"
                                       <*> v .:? "trackKeys"

data HeavyRotationStation = HeavyRotationStation {
                              hrsKey :: String,
                              hrsLength :: Int,
                              hrsTracks :: Int,
                              hrsReloadOnRepeat :: Bool,
                              hrsCount :: Int,
                              hrsUser :: String,
                              hrsBaseIcon :: String,
                              hrsIcon :: String,
                              hrsName :: String,
                              hrsTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON HeavyRotationStation where
  parseJSON (Object v) = HeavyRotationStation <$> v .: "key"
                                              <*> v .: "length"
                                              <*> v .: "tracks"
                                              <*> v .: "reloadOnRepeat"
                                              <*> v .: "count"
                                              <*> v .: "user"
                                              <*> v .: "baseIcon"
                                              <*> v .: "icon"
                                              <*> v .: "name"
                                              <*> v .:? "trackKeys"

data HeavyRotationUserStation = HeavyRotationUserStation {
                                  hrusKey :: String,
                                  hrusLength :: Int,
                                  hrusTracks :: Int,
                                  hrusReloadOnRepeat :: Bool,
                                  hrusCount :: Int,
                                  hrusUser :: String,
                                  hrusBaseIcon :: String,
                                  hrusIcon :: String,
                                  hrusName :: String,
                                  hrusTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON HeavyRotationUserStation where
  parseJSON (Object v) = HeavyRotationUserStation <$> v .: "key"
                                                  <*> v .: "length"
                                                  <*> v .: "tracks"
                                                  <*> v .: "reloadOnRepeat"
                                                  <*> v .: "count"
                                                  <*> v .: "user"
                                                  <*> v .: "baseIcon"
                                                  <*> v .: "icon"
                                                  <*> v .: "name"
                                                  <*> v .:? "trackKeys"

data ArtistTopSongsStation = ArtistTopSongsStation {
                               atssRadioKey :: String,
                               atssTopSongsKey :: String,
                               atssBaseIcon :: String,
                               atssTracks :: [String],
                               atssArtistUrl :: String,
                               atssKey :: String,
                               atssReloadOnRepeat :: Bool,
                               atssIcon :: String,
                               atssCount :: Int,
                               atssName :: String,
                               atssHasRadio :: Bool,
                               atssUrl :: String,
                               atssArtistName :: String,
                               atssShortUrl :: String,
                               atssLength :: Int,
                               atssAlbumCount :: Maybe Int,
                               atssTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON ArtistTopSongsStation where
  parseJSON (Object v) = ArtistTopSongsStation <$> v .: "radioKey"
                                               <*> v .: "topSongsKey"
                                               <*> v .: "baseIcon"
                                               <*> v .: "tracks"
                                               <*> v .: "artistUrl"
                                               <*> v .: "key"
                                               <*> v .: "reloadOnRepeat"
                                               <*> v .: "icon"
                                               <*> v .: "count"
                                               <*> v .: "name"
                                               <*> v .: "hasRadio"
                                               <*> v .: "url"
                                               <*> v .: "artistName"
                                               <*> v .: "shortUrl"
                                               <*> v .: "length"
                                               <*> v .:? "albumCount"
                                               <*> v .:? "trackKeys"

data UserCollectionStation = UserCollectionStation {
                               ucsKey :: String,
                               ucsLength :: Int,
                               ucsTracks :: [String],
                               ucsReloadOnRepeat :: Bool,
                               ucsCount :: Int,
                               ucsUser :: String,
                               ucsBaseIcon :: String,
                               ucsIcon :: String,
                               ucsName :: String,
                               ucsUrl :: String,
                               ucsTrackKeys :: Maybe [String]
} deriving (Show)

instance FromJSON UserCollectionStation where
  parseJSON (Object v) = UserCollectionStation <$> v .: "key"
                                               <*> v .: "length"
                                               <*> v .: "tracks"
                                               <*> v .: "reloadOnRepeat"
                                               <*> v .: "count"
                                               <*> v .: "user"
                                               <*> v .: "baseIcon"
                                               <*> v .: "icon"
                                               <*> v .: "name"
                                               <*> v .: "url"
                                               <*> v .:? "trackKeys"

data RdioResponse v = RdioResponse {
                      rdioStatus :: String,
                      rdioResult :: v
} deriving (Show)

instance FromJSON a => FromJSON (RdioResponse a) where
  parseJSON (Object v) = RdioResponse <$> v .: "status"
                                      <*> v .: "result"

data SearchResults v = SearchResults {
                      results :: [v]
} deriving (Show)

instance FromJSON a => FromJSON (SearchResults a) where
  parseJSON (Object v) = SearchResults <$> v .: "results"

data PlaylistType = Owned | Collab | Subscribed

instance Show PlaylistType where
    show Owned = "owned"
    show Collab = "collab"
    show Subscribed = "subscribed"

data CollaborationMode = NoCollaboration | CollaborationWithAll | CollaborationWithFollowed deriving (Show)

data Scope = UserScope | FriendScope | AllScope

instance Show Scope where
    show UserScope = "user"
    show FriendScope = "friends"
    show AllScope = "everyone"

data Activity = Activity {
                  activityUser :: User,
                  updates :: [Update]
} deriving (Show)

instance FromJSON Activity where
  parseJSON (Object v) = Activity <$> v .: "user"
                                  <*> v .: "updates"

data UpdateType = UTrackAddedToCollection | UTrackAddedToPlaylist | UFriendAdded | UUserJoined | UCommentOnTrack | UCommentOnAlbum | UCommentOnArtist | UCommentOnPlaylist | UTrackAddedViaMatchCollection | UUserSubscribed | UTrackSynced deriving (Show)

instance FromJSON UpdateType where
  parseJSON (Number n)
      | n == 0 = return UTrackAddedToCollection
      | n == 1 = return UTrackAddedToPlaylist
      | n == 3 = return UFriendAdded
      | n == 5 = return UUserJoined
      | n == 6 = return UCommentOnTrack
      | n == 7 = return UCommentOnAlbum
      | n == 8 = return UCommentOnArtist
      | n == 9 = return UCommentOnPlaylist
      | n == 10 = return UTrackAddedViaMatchCollection
      | n == 11 = return UUserSubscribed
      | n == 12 = return UTrackSynced
    
data Update = Update {
                owner :: User,
                date :: String,
                updateType :: UpdateType
} deriving (Show)

instance FromJSON Update where
  parseJSON (Object v) = Update <$> v .: "owner"
                                <*> v .: "date"
                                <*> v .: "update_type"

data Timeframe = ThisWeek | LastWeek | TwoWeeks

instance Show Timeframe where
    show ThisWeek = "thisweek"
    show LastWeek = "lastweek"
    show TwoWeeks = "twoweeks"