/* 
 *
 *   File: mtp.h
 *
 *   Copyright (C) 2009-2013 Darran Kartaschew
 *
 *   This file is part of the gMTP package.
 *
 *   gMTP is free software; you can redistribute it and/or modify
 *   it under the terms of the BSD License as included within the
 *   file 'COPYING' located in the root directory
 *
 */

#ifndef _MTP_H
#define _MTP_H

#ifdef  __cplusplus
extern "C" {
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif 

#include <glib.h>
#include <libmtp.h>

    enum MTP_ERROR {
        MTP_SUCCESS,
        MTP_NO_DEVICE,
        MTP_GENERAL_FAILURE,
        MTP_DEVICE_FULL,
        MTP_NO_MTP_DEVICE
    };

    enum MTP_PLAYLIST_INSTANCES {
        MTP_PLAYLIST_ALL_INSTANCES,
        MTP_PLAYLIST_FIRST_INSTANCE,
        MTP_PLAYLIST_LAST_INSTANCE
    };

#define MTP_DEVICE_SINGLE_STORAGE -1

    gboolean AlbumErrorIgnore;

    typedef struct {
        gchar* file_extension;
        LIBMTP_filetype_t file_type;
    } MTP_file_ext_struct;

    /**
     * Attempt to connect to a device.
     * @return 0 if successful, otherwise error code.
     */
    guint deviceConnect();
    /**
     * Disconnect from the currently connected device.
     * @return 0 if successful, otherwise error code.
     */
    guint deviceDisconnect();
    /**
     * Get the properties of the connected device. These properties are stored in 'DeviceMgr'.
     */
    void deviceProperties();
    /**
     * Deallocates the complete chain of the filelist.
     * @param filelist
     */
    void clearDeviceFiles(LIBMTP_file_t * filelist);
    /**
     * Deallocates the complete chain of Album information.
     * @param albumlist
     */
    void clearAlbumStruc(LIBMTP_album_t * albumlist);
    /**
     * Deallocates the complete chain of all Playlists.
     * @param playlist_list
     */
    void clearDevicePlaylist(LIBMTP_playlist_t * playlist_list);
    /**
     * Deallocates the complete chain of all Track information.
     * @param tracklist
     */
    void clearDeviceTracks(LIBMTP_track_t * tracklist);
    /**
     * Perform a rescan of the device, recreating any device properties or device information.
     */
    void deviceRescan();
    /**
     * Get the list of files for the device.
     */
    void filesUpateFileList();
    /**
     * Rename a single file on the device.
     * @param filename - New name to be given to the file.
     * @param ObjectID - The ID of the object.
     */
    void filesRename(gchar* filename, uint32_t ObjectID);
    /**
     * Add a single file to the current connected device.
     * @param filename
     */
    void filesAdd(gchar* filename);
    /**
     * Delete a single file from the connected device.
     * @param filename
     * @param objectID
     */
    void filesDelete(gchar* filename, uint32_t objectID);
    /**
     * Download a file from the device to local storage.
     * @param filename
     * @param objectID
     */
    void filesDownload(gchar* filename, uint32_t objectID);
    /**
     * Check to see if this file already exists within the current folder on the device.
     * @param filename
     * @return
     */
    gboolean fileExists(gchar* filename);
    /**
     * Check to see if this file already exists within the current folder on the device.
     * @param filename
     * @return
     */
    uint32_t getFile(gchar* filename, uint32_t folderID);
    /**
     * Create a folder on the current connected device.
     * @param foldername
     * @return Object ID of new folder, otherwise 0 if failed.
     */
    guint32 folderAdd(gchar* foldername);
    /**
     * Delete a single folder from the currently connected device.
     * @param folderptr
     * @param level Set to 0 as default.
     */
    void folderDelete(LIBMTP_folder_t* folderptr, guint level);
    /**
     * Delete all files from the specified folder on the device.
     * @param folderID
     */
    void folderDeleteChildrenFiles(guint folderID);
    /**
     * Download the defined folder to the local device.
     * @param foldername Name of the folder to be downloaded
     * @param folderID ID of the folder on the device
     * @param isParent TRUE, if this is the parent folder to download (eg ignore any folder siblings).
     */
    void folderDownload(gchar * foldername, uint32_t folderID, gboolean isParent);
    /**
     * Determine if the folder name exists in the given folder (based on ID)
     * @param foldername The name of the folder.
     * @param folderID The ID of the folder whose contents are to be checked.
     */
    gboolean folderExists(gchar *foldername, uint32_t folderID);
    /**
     * Get the folderID based on the folder name that exists in the given folder (based on ID)
     * @param foldername The name of the folder.
     * @param folderID The ID of the folder whose contents are to be checked.
     * @return The ID of the folder.
     */
    uint32_t getFolder(gchar *foldername, uint32_t folderID);
    /**
     * Add the specified track to an album, and return that album information.
     * @param albuminfo
     * @param trackinfo
     */
    void albumAddTrackToAlbum(LIBMTP_album_t* albuminfo, LIBMTP_track_t* trackinfo);
    /**
     * Add album artfile to be associated with an album.
     * @param album_id
     * @param filename
     */
    void albumAddArt(guint32 album_id, gchar* filename);
    /**
     * Delete the album art for the given object id. (were object id the album)
     * @param album_id
     */
    void albumDeleteArt(guint32 album_id);
    /**
     * Retrieves the raw image data for the selected album
     * @return Pointer to the image data.
     */
    LIBMTP_filesampledata_t * albumGetArt(LIBMTP_album_t* selectedAlbum);
    /**
     * Set the friendly name of the current connected device.
     * @param devicename
     */
    void setDeviceName(gchar* devicename);
    /**
     * Generate a list of all the folder IDs in the current storage pool.
     */
    void buildFolderIDs(GSList **list, LIBMTP_folder_t * folderptr);
    /**
     * Find the ID of the parent folder.
     * @param tmpfolder
     * @param currentFolderID
     * @return
     */
    uint32_t getParentFolderID(LIBMTP_folder_t *tmpfolder, uint32_t currentFolderID);
    /**
     * Find the structure of the parent MTP Folder based on the currentID.
     * @param tmpfolder
     * @param currentFolderID
     * @return
     */
    LIBMTP_folder_t* getParentFolderPtr(LIBMTP_folder_t *tmpfolder, uint32_t currentFolderID);
    /**
     * Find the structure of the MTP Folder based on the currentID.
     * @param tmpfolder
     * @param FolderID
     * @return
     */
    LIBMTP_folder_t* getCurrentFolderPtr(LIBMTP_folder_t *tmpfolder, uint32_t FolderID);
    /**
     * Find the file type based on extension
     * @param filename
     * @return
     */
    LIBMTP_filetype_t find_filetype(const gchar * filename);
    /**
     * Get the file extension  based on filetype
     * @param filetype
     * @return
     */
    gchar* find_filetype_ext(LIBMTP_filetype_t filetype);
    /**
     * Find the ptr to the current storage structure.
     * @param StorageID
     * @return
     */
    LIBMTP_devicestorage_t* getCurrentDeviceStoragePtr(gint StorageID);
    /**
     * Updates the parent FolderID for a given object within the device.
     * @param objectID - The object to be updated.
     * @param folderID - The new parent folder ID for the object.
     * @return 0 on success, any other value means failure.
     */
    int setNewParentFolderID(uint32_t objectID, uint32_t folderID);

    // Playlist support.
    /**
     * Retrieve all Playlists from the device.
     * @return Linked list of all playlists.
     */
    LIBMTP_playlist_t* getPlaylists(void);
    /**
     * Retrieve all Tracks from the device.
     * @return Linked list of all tracks.
     */
    LIBMTP_track_t* getTracks(void);
    /**
     * Create a new playlist on the device.
     * @param playlistname
     */
    void playlistAdd(gchar* playlistname);
    /**
     * Delete the selected playlist from the device.
     * @param tmpplaylist
     */
    void playlistDelete(LIBMTP_playlist_t * tmpplaylist);
    /**
     * Update the selected playlist with the new information.
     * @param tmpplaylist
     */
    void playlistUpdate(LIBMTP_playlist_t * tmpplaylist);
    /**
     * Add the assigned track to the nominated playlist.
     * @param playlist
     * @param track
     */
    void playlistAddTrack(LIBMTP_playlist_t* playlist, LIBMTP_track_t* track);
    /**
     * Remove the assigned track from a playlist.
     * @param playlist
     * @param track
     */
    void playlistRemoveTrack(LIBMTP_playlist_t* playlist, LIBMTP_track_t* track, uint32_t instances);
    /**
     * Import a playlist into the current device.
     * @param filename Filename of the playlist to import.
     * @return The Playlist Name as stored in the file. Caller to free when no longer needed.
     */
    gchar* playlistImport(gchar * filename);
    /**
     * Export a playlist.
     * @param filename Filename of the playlist to import.
     * @param playlist Pointer to Playlist to export.
     */
    void playlistExport(gchar * filename, LIBMTP_playlist_t * playlist);

    /**
     * Format the current active device/storage partition.
     */
    void formatStorageDevice();

    /**
     * Return the full filename including path of the selected MTP file object
     * @param trackid MTP file objectID
     * @return
     */
    gchar* getFullFilename(uint32_t item_id);
    /**
     * Find the file within the device.
     * @param filename Name of the file to search for.
     * @param ignorepath Ignore any path information that may be present.
     * @return Object ID or 0 if not found.
     */
    uint32_t getFileID(gchar* filename, gboolean ignorepath);
    /**
     * Find the folder within the device.
     * @param folderptr Folder Structure to search in.
     * @param foldername Name of the folder to find.
     * @return Object ID or -1 if not found.
     */
    uint32_t getFolderID(LIBMTP_folder_t* folderptr, gchar* foldername);
    /**
     * Returns the string holding the full path name for the given folderid.
     * @param folderid - the selected path to be returned.
     * @return The full path name.
     */
    gchar* getFullFolderPath(uint32_t folderid);
    /**
     * Returns a list of files/folders that have been found on the device.
     * @param searchstring - string to search
     * @param searchfiles - search files/folder names.
     * @param searchmeta - search file metadata.
     * @return
     */
    GSList *filesSearch(gchar *searchstring, gboolean searchfiles, gboolean searchmeta);
    /**
     * Search the folder hier for the foldername.
     * @param pspec - foldername to search
     * @param list - the GSList to append found items.
     * @param folderptr - the MTP folder struc to search.
     */
    void folderSearch(GPatternSpec *pspec, GSList **list, LIBMTP_folder_t* folderptr);
#ifdef  __cplusplus
}
#endif

#endif  /* _MTP_H */
