package pb.remote;

// The supported message types
enum MsgType {
  UNKNOWN = 0;
  // Messages generally send from client to server
  CONNECT = 1;
  REQUEST_PLAYLISTS = 3;
  REQUEST_PLAYLIST_SONGS = 4;
  CHANGE_SONG = 5;
  SET_VOLUME = 6;
  SET_TRACK_POSITION = 7;
  INSERT_URLS = 8;
  REMOVE_SONGS = 9;
  OPEN_PLAYLIST = 10;
  CLOSE_PLAYLIST = 11;
  GET_LYRICS = 14;
  DOWNLOAD_SONGS = 15;
  SONG_OFFER_RESPONSE = 16;
  // Lastfm
  LOVE = 12;
  BAN = 13;
  STOP_AFTER = 17;
  GET_LIBRARY = 18;
  RATE_SONG = 19;

  // Messages send by both
  DISCONNECT = 2;
  PLAY = 20;
  PLAYPAUSE = 21;
  PAUSE = 22;
  STOP = 23;
  NEXT = 24;
  PREVIOUS = 25;
  SHUFFLE_PLAYLIST = 26;
  // Messages that contain the repeat or random mode
  // Either set by client or clementine
  REPEAT = 27;
  SHUFFLE = 28;

  // Messages send from server to client
  INFO = 40;
  CURRENT_METAINFO = 41;
  PLAYLISTS = 42;
  PLAYLIST_SONGS = 43;
  ENGINE_STATE_CHANGED = 44;
  KEEP_ALIVE = 45;
  UPDATE_TRACK_POSITION = 46;
  ACTIVE_PLAYLIST_CHANGED = 47;
  FIRST_DATA_SENT_COMPLETE = 48;
  LYRICS = 49;
  SONG_FILE_CHUNK = 50;
  DOWNLOAD_QUEUE_EMPTY = 51;
  LIBRARY_CHUNK = 52;
}

// Valid Engine states
enum EngineState {
  Empty = 0;
  Idle = 1;
  Playing = 2;
  Paused = 3;
}

// Song Metadata
message SongMetadata {
  optional int32 id = 1; // unique id of the song
  optional int32 index = 2; // Index of the current row of the active playlist
  optional string title = 3;
  optional string album = 4;
  optional string artist = 5;
  optional string albumartist = 6;
  optional int32 track = 7;
  optional int32 disc = 8;
  optional string pretty_year = 9;
  optional string genre = 10;
  optional int32 playcount = 11;
  optional string pretty_length = 12;
  optional bytes art = 13;
  optional int32 length = 14;
  optional bool is_local = 15;
  optional string filename = 16;
  optional int32 file_size = 17;
  optional float rating = 18; // 0 (0 stars) to 1 (5 stars)
}

// Playlist informations
message Playlist {
  optional int32 id = 1;
  optional string name = 2;
  optional int32 item_count = 3;
  optional bool active = 4;
  optional bool closed = 5;
}

// Valid Repeatmodes
enum RepeatMode {
  Repeat_Off = 0;
  Repeat_Track = 1;
  Repeat_Album = 2;
  Repeat_Playlist = 3;
}

// Valid Shuffle modes
enum ShuffleMode {
  Shuffle_Off = 0;
  Shuffle_All = 1;
  Shuffle_InsideAlbum = 2;
  Shuffle_Albums = 3;
}

message RequestPlaylists {
  optional bool include_closed = 1;
}

// A Client requests songs from a specific playlist
message RequestPlaylistSongs {
  optional int32 id = 1;
}

// Client want to change track
message RequestChangeSong {
  // In which playlist is the song?
  optional int32 playlist_id = 1;
  // And on which position?
  optional int32 song_index = 2;
}

// Set the volume
message RequestSetVolume {
  optional int32 volume = 1;
}

// Repeat and Random messages
message Repeat {
  optional RepeatMode repeat_mode = 1;
}

message Shuffle {
  optional ShuffleMode shuffle_mode = 1;
}

// Response from server
// General info
message ResponseClementineInfo {
  optional string version = 1;
  optional EngineState state = 2;
}

// The current song played
message ResponseCurrentMetadata {
  optional SongMetadata song_metadata = 1;
}

// The playlists in clementine
message ResponsePlaylists {
  repeated Playlist playlist = 1;
}

// A list of songs in a playlist
message ResponsePlaylistSongs {
  optional Playlist requested_playlist = 1;
  
  // The songs that are in the playlist
  repeated SongMetadata songs = 2;
}

// The current state of the play engine
message ResponseEngineStateChanged {
  optional EngineState state = 1;
}

// Sends the current position of the track
message ResponseUpdateTrackPosition {  
  optional int32 position = 1;
}

// The connect message containing the authentication code
message RequestConnect {
  optional int32 auth_code = 1;
  optional bool send_playlist_songs = 2;
  optional bool downloader = 3;
}

// Respone, why the connection was closed
enum ReasonDisconnect {
  Server_Shutdown = 1;
  Wrong_Auth_Code = 2;
  Not_Authenticated = 3;
  Download_Forbidden = 4;
}
message ResponseDisconnect {
  optional ReasonDisconnect reason_disconnect = 1;
}

message ResponseActiveChanged {
  optional int32 id = 1;
}

// A client requests a new track position
// position in seconds!
message RequestSetTrackPosition {
  optional int32 position = 1;
}

message RequestInsertUrls {
  // In which playlist should the urls be inserted?
  optional int32 playlist_id = 1;
  repeated string urls = 2;
  optional int32 position = 3 [default=-1];
  optional bool play_now = 4 [default=false];
  optional bool enqueue = 5 [default=false];
}

// Client want to change track
message RequestRemoveSongs {
  // In which playlist is the songs?
  optional int32 playlist_id = 1;
  // And on which position?
  repeated int32 songs = 2;
}

// Messages for opening / closing playlists
message RequestOpenPlaylist {
  optional int32 playlist_id = 1;
}
message RequestClosePlaylist {
  optional int32 playlist_id = 1;
}

// Message containing lyrics
message ResponseLyrics {
  repeated Lyric lyrics = 1;
}
message Lyric {
  optional string id = 1;
  optional string title = 2;
  optional string content = 3;
}

// Message request for downloading songs
enum DownloadItem {
  CurrentItem = 1;
  ItemAlbum = 2;
  APlaylist = 3;
}
message RequestDownloadSongs {
  optional DownloadItem download_item = 1;
  optional int32 playlist_id = 2;
}

message ResponseSongFileChunk {
  optional int32 chunk_number = 1;
  optional int32 chunk_count = 2;
  optional int32 file_number = 3;
  optional int32 file_count = 4;
  optional SongMetadata song_metadata = 6; // only sent with first chunk!
  optional bytes data = 7;
  optional int32 size = 8;
  optional bytes file_hash = 9;
}

message ResponseLibraryChunk {
  optional int32 chunk_number = 1;
  optional int32 chunk_count = 2;
  optional bytes data = 3;
  optional int32 size = 4;
  optional bytes file_hash = 5;
}

message ResponseSongOffer {
  optional bool accepted = 1; // true = client wants to download item
}

message RequestRateSong {
  optional float rating = 1; // 0 to 1
}

// The message itself
message Message {
  optional int32 version = 1 [default=14];
  optional MsgType type = 2 [default=UNKNOWN]; // What data is in the message?

  optional RequestConnect request_connect = 21;
  optional RequestPlaylists request_playlists = 27;
  optional RequestPlaylistSongs request_playlist_songs = 10;
  optional RequestChangeSong request_change_song = 11;
  optional RequestSetVolume request_set_volume = 12;
  optional RequestSetTrackPosition request_set_track_position = 23;
  optional RequestInsertUrls request_insert_urls = 25;
  optional RequestRemoveSongs request_remove_songs = 26;
  optional RequestOpenPlaylist request_open_playlist = 28;
  optional RequestClosePlaylist request_close_playlist = 29;
  optional RequestDownloadSongs request_download_songs = 31;
  optional RequestRateSong request_rate_song = 35;
  
  optional Repeat repeat = 13;
  optional Shuffle shuffle = 14;
  
  optional ResponseClementineInfo response_clementine_info = 15;
  optional ResponseCurrentMetadata response_current_metadata = 16;
  optional ResponsePlaylists response_playlists = 17;
  optional ResponsePlaylistSongs response_playlist_songs = 18;
  optional ResponseEngineStateChanged response_engine_state_changed = 19;
  optional ResponseUpdateTrackPosition response_update_track_position = 20;
  optional ResponseDisconnect response_disconnect = 22;
  optional ResponseActiveChanged response_active_changed = 24;
  optional ResponseLyrics response_lyrics = 30;
  optional ResponseSongFileChunk response_song_file_chunk = 32;
  optional ResponseSongOffer response_song_offer = 33;
  optional ResponseLibraryChunk response_library_chunk = 34;
}
