/* Copyright (c) 2000-2006 ActiveState Software Inc.
   See the file LICENSE.txt for licensing information. */

#include "nsISupports.idl"
#include "nsIEnumerator.idl"
#include "nsIObserverService.idl"
#include "nsIObserver.idl"

interface koIFile;
interface koIObserverService;

// A serializable object. Writes itself to the specified file 
// -- usually as a stream of XML elements.
// Note: This interface should be split out into a separate IDL file
// and stored in a more "global" location.
[scriptable, uuid(41723bbe-8ffd-4d5b-8496-f1ce98e6f473)]
interface koISerializable : nsISupports {
  /**
   * The serialize method is now private
   * @deprecated since Komodo 7.0.0
   */
  [deprecated] void serialize(in koIFile file, in wstring basedir);
  /**
   * Serialize this object to the given file
   */
  void serializeToFile(in AString filename);
};

[scriptable, uuid(09195f7c-704a-44a0-885f-84d989441e0a)]
interface koISerializableFast : koISerializable {
  void serializeToFileFast(in AString filename);
};

/**
 * A generic preference container.  This will contain other preferences in some
 * unspecified way; see koIPreferenceSet and koIOrderedPreference.
 */
[scriptable, uuid(8d5ef051-16e1-462b-b91b-89630f1fda8f)]
interface koIPreferenceContainer : nsISupports {
  /**
   * The id of this preference; if this pref is contained by a preference set,
   * this can be reached by using that preference set's .getPref() method.
   */
  attribute AString id;

  /**
   * clone a copy of this preference and all child preferences.
   */
  koIPreferenceContainer clone();
  
  /**
   * update from another preference container object
   * presumably a modified clone!
   */
  void update(in koIPreferenceContainer source);

  /**
   * Dump this preference container to either stdout or a string
   * @note This is meant for debugging/unit tests; the string format is
   *    unspecified and may change at any time.
   * @param indent The number of spaces to indent
   * @param suppressPrint If false, also print to standard out
   */
  AString dump([optional] in long indent,
               [optional] in boolean suppressPrint);
};

/**
 * @deprecated since Komodo 9.0.0a1: This used to, in theory, represent any kind of preference.
 *    Except not the native types (long, string, etc.), so in practice it was only the containers.
 *    It has been renamed koIPreferenceContainer to make that explicit.
 */
[deprecated, scriptable, uuid(d5dd8948-824b-4835-8b8b-f8a37dce4d26)]
interface koIPreference : koIPreferenceContainer {
};

[scriptable, uuid(7f20bde7-8e58-4c6b-9a19-5570753e5b23)]
interface koIPreferenceSetObjectFactory : nsISupports {
  koIPreferenceContainer deserializeFile(in AString filename);
};

// Allows preference change notifications to be notified.  Re-use the
// nsIObserver interface for the notification.
[scriptable, uuid(0720887f-ebd3-45d8-a236-7a6c3585dfa0)]
interface koIPreferenceObserver: nsISupports {
    /**
     * Used to monitor preference changes. Can monitor individual preferences,
     * or all preferences when the preference name '' (empty string) is used.
     * The prefset id is sent as the data, and prefname as the topic.
     */
    readonly attribute koIObserverService prefObserverService;
};

// A set of preferences -- a dictionary-like object with
// strings as keys and preferences as values having a one-to-one
// relationship between keys and values.
[scriptable, uuid(c8990efd-e1cd-4b6e-be77-9767e9f4c14b)]
interface koIPreferenceSet : koIPreferenceContainer {
  /**
   * The parent preference set.  This was too confusingly named; while it is
   * supposed to mean the preference to inherit from, it was often mistaken to
   * mean the container preference.  Callers should use .inheritFrom or
   * .container, depending on whether this is a preference root or a preference
   * child.
   *
   * @deprecated since Komodo 9.0.0a1
   */
  [deprecated] attribute koIPreferenceContainer parent;

  /**
   * Returns the ids of all prefs stored in this preference set.
   * (This does not include inherited prefs.)
   */
  void getPrefIds([optional] out unsigned long count,
                  [retval, array, size_is(count)] out wstring ids);

  /**
   * Returns the ids of all prefs stored in this preference set,
   * *including* inherited preferences (recursively).
   */
  void getAllPrefIds([optional] out unsigned long count,
                     [retval, array, size_is(count)] out wstring ids);
  
  // Set a preference in the preference set. If the preference does not
  // currently exist then a new one with the given name is created. If
  // the preference is of a simple type then one of the set*Pref() methods
  // can be used. More complex preferences contain arbitrary objects and
  // provide serialize and deserialize methods for persisting themselves.
  // They must use setPref().
  
  // If any of these fail, use the lastErrorSvc to find out why
  void setPref(in AString prefName, in koIPreferenceContainer pref);
  void createPref(in AString prefName);
  void setString(in AString prefName, in AString pref);
  void setLong(in AString prefName, in long pref);
  void setDouble(in AString prefName, in double pref);
  void setBoolean(in AString prefName, in boolean pref);
  /**
   * @deprecated since Komodo 8.5
   * Use the shorter versions (setString, setLong, etc...)
   */
  [deprecated] void setStringPref(in AString prefName, in AString pref);
  [deprecated] void setLongPref(in AString prefName, in long pref);
  [deprecated] void setDoublePref(in AString prefName, in double pref);
  [deprecated] void setBooleanPref(in AString prefName, in boolean pref);
  
  // Retrieve a particular preference from the preference set.
  // It is an error to "get" a preference which does not exist or is of the
  // wrong type. Use "has*Pref" to ensure the pref exists.
  koIPreferenceContainer getPref(in AString prefName);
  wstring getPrefType(in AString prefName);
  AString getStringPref(in AString prefName);
  long getLongPref(in AString prefName);
  double getDoublePref(in AString prefName);
  boolean getBooleanPref(in AString prefName);
    
  /**
   * Return true iff a preference with the specified name and type exists
   * in this preference set, or inherits such a pref (recusively).
   */
  boolean hasPref(in AString prefName);
  boolean hasStringPref(in AString prefName);
  boolean hasLongPref(in AString prefName);
  boolean hasDoublePref(in AString prefName);
  boolean hasBooleanPref(in AString prefName);

  /**
   * Retrieve the given preference from this preferset set, or the inherited
   * preference if it does not exist here.  If it is not inherited either,
   * return the default default value provided. If no default value is provided,
   * the XPIDL default will be used instead (i.e. "", 0, 0.0, or False).
   */
  AString getString(in AString prefName, [optional] in AString defaultValue);
  long getLong(in AString prefName, [optional] in long defaultValue);
  double getDouble(in AString prefName, [optional] in double defaultValue);
  boolean getBoolean(in AString prefName, [optional] in boolean defaultValue);

  /**
   * Whether this preference set has a preference with the given name, ignoring
   * preferences found via inheritance.
   */
  boolean hasPrefHere(in AString prefName);

  /**
   * Remove a preference from this preference set.  Will not modify inherited
   * preferences.
   */
  void deletePref(in AString prefName);
  // Reset to an empty preference set.
  void reset();

  void setNonVital(in AString prefName);
  boolean isVital(in AString prefName);
  
  // validation related calls
  // 'validation' must be a python expression that refers to 'value'
  // and returns a true value if the value is corect.
  // e.g. "value > 3" or "positive(3)", where positive() is 
  // defined in koPrefs.py
  void setValidation(in AString prefName, in AString validation);
  // These return true if the proposed value is valid for the 
  // specified preference.  No preference change occurs.
  boolean validateLong(in AString prefName, in long value);
  boolean validateString(in AString prefName, in AString value);
};

/**
 * A preference root.  This describes the root of a preference tree.
 * When looking up preferences, if a preference is not found in a preference
 * set, the matching preference set in the preference tree the preference root
 * inherits from is consulted.
 */
[scriptable, uuid(20347097-c019-4270-b4dc-b91b119a347c)]
interface koIPreferenceRoot : koIPreferenceSet {
  /**
   * A reference to the preference tree this preference tree inherits
   * preferences from.  When looking up a preference, if this preference set
   * does not contain the requested value, the lookup is done on the matching
   * preference set in the preference tree this tree inherits from.
   */
  attribute koIPreferenceRoot inheritFrom;
};

[scriptable, uuid(ff21046e-7c2c-4900-b497-a7536504c615)]
interface koIPreferenceChild : koIPreferenceContainer {
  /**
   * The container preference set.  The container is either a koIPreferenceSet
   * (in whic case .container.getPrf(.id) is this prefset) or a
   * koIOrderedPreference (in which case .container.getPref(?) is used).
   */
  readonly attribute koIPreferenceContainer container;

  /**
   * Whether the container preference should be notified of preference change
   * notifications.
   */
  attribute boolean chainNotifications;
};

// Project preferences - to allow checking if a prefset is project based.
[scriptable, uuid(a716cfc4-5eb0-4e39-8a5c-48d6b7712477)]
interface koIProjectPreferenceSet : koIPreferenceRoot {
};

// File preferences - to allow checking if a prefset is file based.
[scriptable, uuid(97552021-3a33-4ae1-b5c5-1e3695ffa901)]
interface koIFilePreferenceSet : koIPreferenceRoot {
};

/* A preference set cache - a collection of preference sets that can
   be indexed by a unique ID, and automatically maintains a maximum
   size.

*/
[scriptable, uuid(7d095530-d432-4e0c-9575-2405a5cc47b5)]
interface koIPreferenceCache : koIPreferenceContainer {
    void setPref(in koIPreferenceSet pref);
    koIPreferenceSet getPref(in AString id);
    boolean hasPref(in AString id);
    attribute unsigned long length;
    attribute unsigned long max_length; // defaults to 0, meaning no max size.
    nsISimpleEnumerator enumPreferences();
};

// A service to manage preference roots.
// There is one implicit "global" pref root that can be accessed via
// the "prefs" attribute, or as a named pref root called "global".
// We should have some decent way of "registering" well known
// preference sets, but have punted for now.  See
// |koGlobalPreferenceDefinition| in koPrefs.py
[scriptable, uuid(213246d1-16c4-4c84-8b51-ca218008b013)]
interface koIPrefService : nsISupports {
  
  // Get a well-known preference set.
  koIPreferenceContainer getPrefs(in AString name);

  // Get the global preference set.  Equivalent to |getPrefs("global")|
  readonly attribute koIPreferenceRoot prefs;
  
  // Reset a well-known preference set and return it.
  koIPreference resetPrefs(in AString name);

  // integrates project preferences in a way that is easy for most code points
  // in Komodo to reach.  This will return the current project prefs if there
  // is a current project, otherwise, returns the global prefs above.  The parent
  // of project prefs is always global prefs.
  readonly attribute koIPreferenceRoot effectivePrefs;

  // Save the global preference sets to disk - Equivilent to |savePrefs("global")|
  void saveState();

  // Save the named preference set to disk.
  void savePrefsState(in AString prefName);

  void saveWhenIdle();
};

/**
 * A preference serlializer - helper interface.
 *
 * A class/object can implement this interface, and use a generic serializer
 * to easily save/store preference values, see './pref_serialization.py'.
 */
[scriptable, uuid(c929dc80-3c37-4ba9-acaa-bc2d4e609a8e)]
interface koIPreferenceSerializer : nsISupports {
  koIPreferenceContainer serializeToPreference();
  void unserializeFromPreference(in koIPreferenceContainer pref);
};
