/* Copyright 2003 gnome-vfsmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#ifndef _LIBGNOMEVFSMM_MIME_HANDLERS_H
#define _LIBGNOMEVFSMM_MIME_HANDLERS_H

#include <glibmm.h>

#include <libgnomevfsmm/enums.h>
#include <libgnomevfsmm/exception.h>
#include <libgnomevfsmm/mime-application.h>
#include <libgnomevfsmm/mime-action.h>

namespace Gnome
{

namespace Vfs
{

//TODO: Explain when/how someone might use this stuff.
//TODO: Consider renaming this to MimeDatabase or something similar. Murray.
//e.g. Direct people to
//- get_registered_types() to discover all MIME types.
//- get_description() to get a human-readable description of a MIME type.
//- get_all_applications() to get a list of applications that can handle the MIME type.
//TODO: Tell them how to get the MIME type for a file.
namespace Mime
{

typedef Glib::ListHandle<Gnome::Vfs::MimeApplication*> ListHandleApps;
// TODO: once Bonobo_ServerInfo is wrapped, I can change this to the C++ equivalent...
typedef GList* ListHandleComps;
typedef Glib::ListHandle<Glib::ustring> ListHandleStrings;

/*
 * Accessor functions
 */

//TODO: The result is either APPLICATION or COMPONENT. These don't sound like actions,
//      so my explanation seems necessary. Murray.
/** Get a default action type for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return An enum value representing what to do for this MIME type.
 */
MimeActionType get_default_action_type(const Glib::ustring& mime_type);

/** Get the default application for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return An MimeApplication representing the default application for this MIME type.
 */
MimeApplication get_default_application(const Glib::ustring& mime_type);

/** Get the default action for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return An MimeAction representing the default action for this MIME type.
 */
GnomeVFSMimeAction* get_default_action(const Glib::ustring& mime_type);

// TODO: Figure out how the heck to wrap this Bonobo_ServerInfo thingy...
Bonobo_ServerInfo* get_default_component(const Glib::ustring& mime_type);

//TODO: What determines whether an application is in the short list or the all list? Murray.
//TODO: This is a list of pointers. Who deletes them? Murray
/** Get a short list of applications for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return A short list of MimeApplications for this MIME type.
 */
ListHandleApps get_short_list_applications(const Glib::ustring& mime_type);

//TODO: This is a list of pointers. Who deletes them? Murray.
/** Get the entire list of applications for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return A list of all MimeApplications for this MIME type.
 */
ListHandleApps get_all_applications(const Glib::ustring& mime_type);

/** Get a short list of actions for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return A short list of MimeAction 's for this MIME type.
 */
ListHandleComps get_short_list_components(const Glib::ustring& mime_type);

/** Get the entire list of actions for specified @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @return A list of all MimeAction 's for this MIME type.
 */
ListHandleComps get_all_components(const Glib::ustring& mime_type);

//TODO: If this is just a convenience function, then we should say so. Murray.
/** Test if an application ID is in a list of applications.
 * @param id A string containing the application ID.
 * @param applications A list of MimeApplications.
 * @return <tt>true</tt> if the ID is in this application list; <tt>false</tt> otherwise.
 */
bool id_in_application_list(const Glib::ustring& id, const ListHandleApps& applications);

//TODO: If this is just a convenience function, then we should say so. Murray.
/** Get a list of IDs corresponding to the applications in a list.
 * @param applications A list of MimeApplications.
 * @return A list of strings corresponding to the ID of each application in @a applications.
 */
ListHandleStrings id_list_from_application_list(const ListHandleApps& applications);

//TODO: If this is just a convenience function, then we should say so. Murray.
/** Test if a component id is in a list of components.
 * @param iid A string containing a component's OAF IID.
 * @param components  A GList* whose nodes are Bonobo_ServerInfos, such as the result of gnome_vfs_mime_get_short_list_components().
 * @return <tt>true</tt> if the id is in this component list; <tt>false</tt> otherwise.
 */
bool id_in_component_list(const Glib::ustring& iid, ListHandleComps components);

//TODO: If this is just a convenience function, then we should say so. Murray.
/** Get a list of OAF IID's corresponding to the Bonobo_ServerInfos in a list.
 * @param components A GList* of Bonobo_ServerInfos.
 * @return A list of strings corresponding to the iid of each component in @a components.
 */
ListHandleStrings id_list_from_component_list(ListHandleComps components);

/** Query the MIME database for an icon representing the specified MIME type.
 * @param mime_type A string containing an MIME type.
 * @return The filename of the icon as listed in the MIME database. This is 
 * usually a filename without path information, e.g. &quot;i-chardev.png&quot;, and sometimes
 * does not have an extension, e.g. &quot;i-regular&quot; if the icon is supposed to be image
 * type agnostic between icon themes. Icons are generic, and not theme specific. These
 * will not necessarily match with the icons a user sees in Nautilus, you have been warned.
 */
Glib::ustring get_icon(const Glib::ustring& mime_type);

/** Query the MIME database for a description of the specified MIME type.
 * @param mime_type A string containing an MIME type.
 * @return A description of the MIME type.
 */
Glib::ustring get_description(const Glib::ustring& mime_type);

/** Test whether files of this MIME type might conceivably be executable.
 * Default for known types is <tt>false</tt>. Default for unknown types is <tt>true</tt>.
 * @param mime_type A string containing an MIME type.
 * @return <tt>true</tt> if some files of this MIME type are registered as being executable, and <tt>false</tt> otherwise.
 */
bool can_be_executable(const Glib::ustring& mime_type);

/** Test to see if @a mime_type is in the MIME database at all.
 * @param mime_type A string containing an MIME type.
 * @return <tt>true</tt> if anything is known about @a mime_type, otherwise <tt>false</tt>.
 */
bool type_is_known(const Glib::ustring& mime_type);

/** Get the file extensions associated with an MIME type.
 * @param mime_type A string containing an MIME type.
 * @return A list of strings of extensions.
 */
ListHandleStrings get_extensions_list(const Glib::ustring& mime_type);

/** Retrieves the extensions associated with @a mime_type.
 * @param mime_type A string containing an MIME type.
 * @param pretty Whether to format the returned string with spaces (<tt>false</tt>) or commas (<tt>true</tt>).
 * @return A string containing extensions for this mime-type, formatted based on @a pretty.
 */
Glib::ustring get_extensions_string(const Glib::ustring& mime_type, bool pretty = false);

/** Get a list of registered MIME types from the MIME database.
 * @return A list of strings containing the MIME types registered.
 */
ListHandleStrings get_registered_types();

//TODO: What happens if the key is invalid? Murray.
//TODO: What is a key? Murray.
//TODO: What is a GnomeMimeContext? Murray.
//TODO: What data does this return? Murray.
/** Retrieve the value associated with @a key in the given GnomeMimeContext.
 * @param mime_type A string containing an MIME type.
 * @param key A key to lookup for the given MIME type.
 * @return A string containing the data for the MIME type and key.
 */
Glib::ustring get_value(Glib::ustring& mime_type, Glib::ustring& key);

/** Retrieve a list of all keys associated with @a mime_type.
 * @param mime_type A string containing an MIME type to lookup.
 * @return A list of strings containing keys associated with @a mime_type.
 */
ListHandleStrings get_key_list(Glib::ustring& mime_type);

/*
 * Mutator functions
 * TODO: "Mutator" means nothing to me in this context. Murray.
 */

/** Sets the default action type to be performed on files of the specified MIME type.
 * @param mime_type A string containing an MIME type.
 * @param action_type An enum specifying the default action to perform.
 */ 
void set_default_action_type(const Glib::ustring& mime_type, MimeActionType action_type) throw(exception);

/** Sets the default application to run on files of the specified MIME type.
 * @param mime_type A string containing an MIME type.
 * @param application_id A string containing an ID of an application in the MIME database.
 */
void set_default_application(const Glib::ustring& mime_type, const Glib::ustring& application_id) throw(exception);

/** Sets the default component to use with files of the specified MIME type.
 * @param mime_type A string containing an MIME type.
 * @param iid A string containing an OAF IID of a component in the MIME database.
 */
void set_default_component(const Glib::ustring& mime_type, const Glib::ustring& iid) throw(exception);

/** Set the icon entry for a particular MIME type in the MIME database.
 * Note that icon entries need not necessarily contain the full path, and do not necessarily need to
 * specify an extension. So &quot;i-regular&quot;, &quot;my-special-icon.png&quot;, and &quot;some-icon&quot;
 * are all valid icon filenames.
 * @param mime_type A string containing an MIME type.
 * @param filename A string containing an image filename.
 */
void set_icon(const Glib::ustring& mime_type, const Glib::ustring& filename) throw(exception);

/** Set the description of this MIME type in the MIME database.
 * The description should be something like &quot;Gnumeric spreadsheet&quot;.
 * @param mime_type A string containing an MIME type.
 * @param description A description of this MIME type.
 */
void set_description(const Glib::ustring& mime_type, const Glib::ustring& description) throw(exception);

/** Set whether files of this MIME type might conceivably be executable.
 * @param mime_type A string containing an MIME type.
 * @param new_value A boolean value indicating whether @a mime_type could be executable.
 */
void set_can_be_executable(const Glib::ustring& mime_type, bool new_value) throw(exception);

/** Set the short list of applications for the specified MIME type.
 * The short list contains applications recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param application_ids A list of application IDs.
 */
void set_short_list_applications(const Glib::ustring& mime_type, ListHandleStrings& application_ids) throw(exception);

/** Set the short list of components for the specified MIME type.
 * The short list contains components recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param component_iids A list of OAF IID's.
 */
void set_short_list_components(const Glib::ustring& mime_type, ListHandleStrings& component_iids) throw(exception);

/** Add an application to the short list for the specified MIME type.
 * The short list contains applications recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param application_id A string containing the application's ID in the MIME database.
 */
void add_application_to_short_list(const Glib::ustring& mime_type, Glib::ustring& application_id) throw(exception);

/** Remove an application from the short list for the specified MIME type.
 * The short list contains applications recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param application_id A string containing the application's ID in the MIME database.
 */
void remove_application_from_short_list(const Glib::ustring& mime_type, Glib::ustring& application_id) throw(exception);

/** Add a component to the short list for the specified MIME type.
 * The short list contains components recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param component_iid A string containing the component's OAF IID in the MIME database.
 */
void add_component_to_short_list(const Glib::ustring& mime_type, Glib::ustring& component_iid) throw(exception);

/** Remove a component from the short list for the specified MIME type.
 * The short list contains components recommended for possible selection by the user.
 * @param mime_type A string containing an MIME type.
 * @param component_iid A string containing the component's OAF IID in the MIME database.
 */
void remove_component_from_short_list(const Glib::ustring& mime_type, Glib::ustring& component_iid) throw(exception);

/** Add a file extension to the specified MIME type in the database.
 * @param mime_type The mime type to add the extension to.
 * @param extension The extension to add.
 */
void add_extension(const Glib::ustring& mime_type, Glib::ustring& extension) throw(exception);

/** Removes a file extension from the specified MIME type in the database.
 * @param mime_type The mime type to remove the extension from.
 * @param extension The extension to remove.
 */
void remove_extension(const Glib::ustring& mime_type, Glib::ustring& extension) throw(exception);

/** Sets the extensions for a given mime type.
 * Overrides the previously set extensions.
 * @param mime_type A string containing an MIME type.
 * @param extensions_list A whitespace-separated list of the extensions to set for this MIME type.
 */
void set_extensions_list(const Glib::ustring& mime_type, const Glib::ustring& extensions_list) throw(exception);

/** Register @a mime_type as being handled by all applications listed in @a application_ids.
 * @param mime_type A string containing an MIME type.
 * @param application_ids A list of strings containing application ids.
 */
void extend_all_applications(const Glib::ustring& mime_type, ListHandleStrings& application_ids) throw(exception);

/** Remove @a mime_type as a handled type from every application in @a application_ids.
 * @param mime_type A string containing an MIME type.
 * @param application_ids A list of strings containing application ids.
 */
void remove_from_all_applications(const Glib::ustring& mime_type, ListHandleStrings& application_ids) throw(exception);

/** Delete an MIME type for the user who runs this command.
 * You can only undo this by calling Gnome::Vfs::Mime::reset().
 * @param mime_type A string containing the MIME type to delete.
 */
void registered_mime_type_delete(const Glib::ustring& mime_type);

/** Set the key data for the registered MIME type's hash table.
 * @param mime_type A string containing the MIME type.
 * @param key A string containing the key to set.
 * @param data A string containing the data to set for @a key.
 */
void set_registered_type_key(const Glib::ustring& mime_type, const Glib::ustring& key, const Glib::ustring& data) throw(exception);

/** Set the value associated with the key.
 * Will save it to the user's file if necessary.
 * @param mime_type A string containing the MIME type.
 * @param key A string containing the key to store the value in.
 * @param value A string containing the value to stor in the key.
 */
void set_value(const Glib::ustring& mime_type, const Glib::ustring& key, const Glib::ustring& value) throw(exception);

/*
 * Mime Control
 */

/** Freeze the MIME data so that you can do multiple
 * updates to the data in one batch without needing
 * to back-up the files to disk or rewind them.
 */
void freeze();

/** UnFreeze the MIME data after a freeze.
 */
void thaw();

/** Reload the MIME database from disk.
 * This als notifies any listeners holding active Gnome::Vfs::MimeMonitor objects.
 */
void info_reload();

/** Reset the user's MIME database to the system defaults.
 */
void reset();

} // namespace Mime
} // namespace Vfs
} // namespace Gnome

#endif /* _LIBGNOMEVFSMM_MIME_HANDLERS_H */
