{-# LANGUAGE ForeignFunctionInterface #-} -- Copyright 2010 Evgeniy Vodolazskiy (waterlaz@gmail.com) -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. module Network.XMMS.Playlist( retrieveChange, Change (..), currentPos, currentActive, list, create, shuffle, sort, clear, remove, listEntries, insertID, insertURL, rInsert, rInsertEncoded, insertEncoded, addID, addURL, rAdd, rAddEncoded, addEncoded, moveEntry, removeEntry, broadcastChanged, broadcastCurrentPos, setNext, setNextRel, load )where import Foreign import Foreign.Ptr import Foreign.C.Types import Network.XMMS.UTF8Strings import Foreign.ForeignPtr import Foreign.Marshal.Alloc import Network.XMMS.Utilities import Network.XMMS.Constants import Network.XMMS.Types import Network.XMMS.Result import Network.XMMS.Value import Data.Map (Map) import qualified Data.Map as Map data Change = Add { position :: Int, name :: String, id :: Int } | Insert { position :: Int, name :: String, id :: Int } | Remove { position :: Int, name :: String} | Clear { name :: String } | Move { position :: Int, newPosition :: Int, name :: String, id :: Int } | Sort { name :: String } | Shuffle { name :: String } | Update { name :: String } | NoChange retrieveChange :: XMMSCV -> Change retrieveChange (XMMSDict dict) |changeType == playlistChangedAdd = Add position name id |changeType == playlistChangedInsert = Insert position name id |changeType == playlistChangedRemove = Remove position name |changeType == playlistChangedClear = Clear name |changeType == playlistChangedMove = Move position newPosition name id |changeType == playlistChangedSort = Sort name |changeType == playlistChangedShuffle = Shuffle name |changeType == playlistChangedUpdate = Update name |otherwise = NoChange where convFromJust (Just x) = x convFromJust _ = error $ "Failed on getting playlist change from dict: " ++ (show dict) name = xmmsString $ convFromJust $ Map.lookup "name" dict position = xmmsInt $ convFromJust $ Map.lookup "position" dict newPosition = xmmsInt $ convFromJust $ Map.lookup "newposition" dict id = xmmsInt $ convFromJust $ Map.lookup "id" dict changeType = fromIntegral $ xmmsInt $ convFromJust $ Map.lookup "type" dict --xmmsc_result_t * xmmsc_playlist_current_pos (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_current_pos" xmmsc_playlist_current_pos :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Retrive the current position in the playlist. currentPos :: Connection -> String -> IO Result currentPos connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_current_pos c c_name) connection) --xmmsc_result_t * xmmsc_playlist_current_active (xmmsc_connection_t *c) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_current_active" xmmsc_playlist_current_active :: Ptr C_xmmsc_connection -> IO (Ptr C_xmmsc_result) -- |Retrive the name of the active playlist. currentActive :: Connection -> IO Result currentActive = wrapCallResult xmmsc_playlist_current_active --xmmsc_result_t * xmmsc_playlist_list (xmmsc_connection_t *c) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_list" xmmsc_playlist_list :: Ptr C_xmmsc_connection -> IO (Ptr C_xmmsc_result) -- |List the existing playlists. list :: Connection -> IO Result list = wrapCallResult xmmsc_playlist_list --xmmsc_result_t * xmmsc_playlist_create (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_create" xmmsc_playlist_create :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Create a new empty playlist. create :: Connection -> String -> IO Result create connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_create c c_name) connection) --xmmsc_result_t * xmmsc_playlist_shuffle (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_shuffle" xmmsc_playlist_shuffle :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Shuffles the current playlist. shuffle :: Connection -> String -> IO Result shuffle connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_shuffle c c_name) connection) --xmmsc_result_t * xmmsc_playlist_sort (xmmsc_connection_t *c, const char *playlist, xmmsv_t *properties) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_sort" xmmsc_playlist_sort :: Ptr C_xmmsc_connection -> CString -> Ptr C_xmmsc_value -> IO (Ptr C_xmmsc_result) -- |Sorts the playlist according to the list of properties sort :: Connection -> String -> [String] -> IO Result sort connection name properties = withString name (\ c_name -> do let xmmsProperties = XMMSList $ map XMMSString properties c_properties <- convertValueHstoC xmmsProperties withForeignPtr c_properties (\c_properties_ptr -> wrapCallResult (\c -> xmmsc_playlist_sort c c_name c_properties_ptr) connection)) --xmmsc_result_t *xmmsc_playlist_clear (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_clear" xmmsc_playlist_clear :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Clears the current playlist. clear :: Connection -> String -> IO Result clear connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_clear c c_name) connection) --xmmsc_result_t * xmmsc_playlist_remove (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_remove" xmmsc_playlist_remove :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Remove the given playlist. remove :: Connection -> String -> IO Result remove connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_remove c c_name) connection) --xmmsc_result_t * xmmsc_playlist_list_entries (xmmsc_connection_t *c, const char *playlist) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_list_entries" xmmsc_playlist_list_entries :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |List current playlist. listEntries :: Connection -> String -> IO Result listEntries connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_list_entries c c_name) connection) --xmmsc_result_t *xmmsc_playlist_insert_id (xmmsc_connection_t *c, const char *playlist, int pos, int id) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_insert_id" xmmsc_playlist_insert_id :: Ptr C_xmmsc_connection -> CString -> CInt -> CInt -> IO (Ptr C_xmmsc_result) -- |Insert a medialib id at given position in playlist. insertID :: Connection -> String -> Int -> Int -> IO Result insertID connection name pos id = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_insert_id c c_name (fromIntegral pos) (fromIntegral pos)) connection) --xmmsc_result_t * xmmsc_playlist_insert_url (xmmsc_connection_t *c, const char *playlist, int pos, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_insert_url" xmmsc_playlist_insert_url :: Ptr C_xmmsc_connection -> CString -> Int -> CString -> IO (Ptr C_xmmsc_result) -- |Insert entry at given position in playlist. insertURL :: Connection -> String -> Int -> String -> IO Result insertURL connection name pos url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_insert_url c c_name (fromIntegral pos) c_url) connection free c_url return res) --xmmsc_result_t * xmmsc_playlist_rinsert (xmmsc_connection_t *c, const char *playlist, int pos, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_rinsert" xmmsc_playlist_rinsert :: Ptr C_xmmsc_connection -> CString -> Int -> CString -> IO (Ptr C_xmmsc_result) -- |Insert a directory recursivly at a given position in the playlist. rInsert :: Connection -> String -> Int -> String -> IO Result rInsert connection name pos url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_rinsert c c_name (fromIntegral pos) c_url) connection free c_url return res) --xmmsc_result_t * xmmsc_playlist_rinsert_encoded (xmmsc_connection_t *c, const char *playlist, int pos, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_rinsert_encoded" xmmsc_playlist_rinsert_encoded :: Ptr C_xmmsc_connection -> CString -> Int -> CString -> IO (Ptr C_xmmsc_result) -- |Insert a directory recursivly at a given position in the playlist. rInsertEncoded :: Connection -> String -> Int -> String -> IO Result rInsertEncoded connection name pos url = do withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_rinsert_encoded c c_name (fromIntegral pos) c_url) connection free c_url return res) {-xmmsc_result_t * xmmsc_playlist_insert_args (xmmsc_connection_t *c, const char *playlist, int pos, const char *url, int numargs, const char **args) Insert entry at given position in playlist with args. xmmsc_result_t * xmmsc_playlist_insert_full (xmmsc_connection_t *c, const char *playlist, int pos, const char *url, xmmsv_t *args) Insert entry at given position in playlist with args. xmmsc_result_t * xmmsc_playlist_insert_collection (xmmsc_connection_t *c, const char *playlist, int pos, xmmsv_coll_t *coll, xmmsv_t *order) Queries the medialib for media and inserts the matching ones to the current playlist at the given position. xmmsc_result_t * xmmsc_playlist_add_args (xmmsc_connection_t *c, const char *playlist, const char *url, int nargs, const char **args) Add the url to the playlist with arguments. xmmsc_result_t * xmmsc_playlist_add_full (xmmsc_connection_t *c, const char *playlist, const char *url, xmmsv_t *args) Add the url to the playlist with arguments. xmmsc_result_t * xmmsc_playlist_add_idlist (xmmsc_connection_t *c, const char *playlist, xmmsv_coll_t *coll) Adds media in idlist to a playlist. xmmsc_result_t * xmmsc_playlist_add_collection (xmmsc_connection_t *c, const char *playlist, xmmsv_coll_t *coll, xmmsv_t *order) Queries the medialib for media and adds the matching ones to the current playlist. -} --xmmsc_result_t * xmmsc_playlist_insert_encoded (xmmsc_connection_t *c, const char *playlist, int pos, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_insert_encoded" xmmsc_playlist_insert_encoded :: Ptr C_xmmsc_connection -> CString -> Int -> CString -> IO (Ptr C_xmmsc_result) -- |Insert entry at given position in playlist. insertEncoded :: Connection -> String -> Int -> String -> IO Result insertEncoded connection name pos url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_insert_encoded c c_name (fromIntegral pos) c_url) connection free c_url return res) --xmmsc_result_t * xmmsc_playlist_add_id (xmmsc_connection_t *c, const char *playlist, int id) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_add_id" xmmsc_playlist_add_id :: Ptr C_xmmsc_connection -> CString -> Int -> IO (Ptr C_xmmsc_result) -- |Add a medialib id to the playlist. addID :: Connection -> String -> Int -> IO Result addID connection name id = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_add_id c c_name (fromIntegral id)) connection) --xmmsc_result_t * xmmsc_playlist_add_url (xmmsc_connection_t *c, const char *playlist, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_add_url" xmmsc_playlist_add_url :: Ptr C_xmmsc_connection -> CString -> CString -> IO (Ptr C_xmmsc_result) -- |Add the url to the playlist. addURL :: Connection -> String -> String -> IO Result addURL connection name url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_add_url c c_name c_url) connection free c_url return res) --xmmsc_result_t * xmmsc_playlist_radd (xmmsc_connection_t *c, const char *playlist, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_radd" xmmsc_playlist_radd :: Ptr C_xmmsc_connection -> CString -> CString -> IO (Ptr C_xmmsc_result) -- |Adds a directory recursivly to the playlist. rAdd :: Connection -> String -> String -> IO Result rAdd connection name url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_radd c c_name c_url) connection free c_url return res) --xmmsc_result_t *xmmsc_playlist_radd_encoded (xmmsc_connection_t *c, const char *playlist, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_radd_encoded" xmmsc_playlist_radd_encoded :: Ptr C_xmmsc_connection -> CString -> CString -> IO (Ptr C_xmmsc_result) -- |Adds a directory recursivly to the playlist. rAddEncoded :: Connection -> String -> String -> IO Result rAddEncoded connection name url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_radd_encoded c c_name c_url) connection free c_url return res) --xmmsc_result_t* xmmsc_playlist_add_encoded (xmmsc_connection_t *c, const char *playlist, const char *url) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_add_encoded" xmmsc_playlist_add_encoded :: Ptr C_xmmsc_connection -> CString -> CString -> IO (Ptr C_xmmsc_result) -- |Add the url to the playlist. addEncoded :: Connection -> String -> String -> IO Result addEncoded connection name url = withString name (\ c_name -> do c_url <- newCString url res <- wrapCallResult (\c -> xmmsc_playlist_add_encoded c c_name c_url) connection free c_url return res) --xmmsc_result_t *xmmsc_playlist_move_entry (xmmsc_connection_t *c, const char *playlist, int cur_pos, int new_pos) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_move_entry" xmmsc_playlist_move_entry :: Ptr C_xmmsc_connection -> CString -> CInt -> CInt -> IO (Ptr C_xmmsc_result) -- |Move a playlist entry to a new position (absolute move). moveEntry :: Connection -> String -> Int -> Int -> IO Result moveEntry connection name curPos newPos = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_move_entry c c_name (fromIntegral curPos) (fromIntegral newPos)) connection) --xmmsc_result_t * xmmsc_playlist_remove_entry (xmmsc_connection_t *c, const char *playlist, int pos) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_remove_entry" xmmsc_playlist_remove_entry :: Ptr C_xmmsc_connection -> CString -> CInt -> IO (Ptr C_xmmsc_result) -- |Remove an entry from the playlist. removeEntry :: Connection -> String -> Int -> IO Result removeEntry connection name pos = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_remove_entry c c_name (fromIntegral pos)) connection) --xmmsc_result_t *xmmsc_broadcast_playlist_changed (xmmsc_connection_t *c) foreign import ccall safe "xmmsclient/xmmsclient.h xmmsc_broadcast_playlist_changed" xmmsc_broadcast_playlist_changed :: Ptr C_xmmsc_connection -> IO (Ptr C_xmmsc_result) -- |Request the playlist changed broadcast from the server. broadcastChanged :: Connection -> IO Result broadcastChanged = wrapCallResult xmmsc_broadcast_playlist_changed --xmmsc_result_t * xmmsc_broadcast_playlist_current_pos (xmmsc_connection_t *c) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_broadcast_playlist_current_pos" xmmsc_broadcast_playlist_current_pos :: Ptr C_xmmsc_connection -> IO (Ptr C_xmmsc_result) -- |Request the playlist current pos broadcast. broadcastCurrentPos :: Connection -> IO Result broadcastCurrentPos = wrapCallResult xmmsc_broadcast_playlist_current_pos --xmmsc_result_t *xmmsc_playlist_set_next (xmmsc_connection_t *c, int pos) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_set_next" xmmsc_playlist_set_next :: Ptr C_xmmsc_connection -> CInt -> IO (Ptr C_xmmsc_result) -- |Set next entry in the playlist. setNext :: Connection -> Int -> IO Result setNext connection pos = do wrapCallResult (\c -> xmmsc_playlist_set_next c (fromIntegral pos)) connection --xmmsc_result_t * xmmsc_playlist_set_next_rel (xmmsc_connection_t *c, int pos) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_set_next_rel" xmmsc_playlist_set_next_rel :: Ptr C_xmmsc_connection -> CInt -> IO (Ptr C_xmmsc_result) -- |Same as setNextRel but relative to the current postion. setNextRel :: Connection -> Int -> IO Result setNextRel connection pos = do wrapCallResult (\c -> xmmsc_playlist_set_next_rel c (fromIntegral pos)) connection --xmmsc_result_t *xmmsc_playlist_load (xmmsc_connection_t *c, const char *name) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_playlist_load" xmmsc_playlist_load :: Ptr C_xmmsc_connection -> CString -> IO (Ptr C_xmmsc_result) -- |Load a playlist as the current active playlist. load :: Connection -> String -> IO Result load connection name = withString name (\ c_name -> wrapCallResult (\c -> xmmsc_playlist_load c c_name) connection) --xmmsc_result_t *xmmsc_broadcast_playlist_loaded (xmmsc_connection_t *c) foreign import ccall unsafe "xmmsclient/xmmsclient.h xmmsc_broadcast_playlist_loaded" xmmsc_broadcast_playlist_loaded :: Ptr C_xmmsc_connection -> IO (Ptr C_xmmsc_result) -- |Request the playlist_loaded broadcast. broadcastLoaded :: Connection -> IO Result broadcastLoaded = wrapCallResult xmmsc_broadcast_playlist_loaded