/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-6 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__
#define __JUCE_PROPERTIESFILE_JUCEHEADER__

#include "../../juce_core/io/files/juce_File.h"
#include "../../juce_core/containers/juce_PropertySet.h"
#include "../events/juce_Timer.h"
#include "../events/juce_ChangeBroadcaster.h"


//==============================================================================
/** Wrapper on a file that stores a list of key/value data pairs.

    Useful for storing application settings, etc. See the PropertySet class for
    the interfaces that read and write values.

    Not designed for very large amounts of data, as it keeps all the values in
    memory and writes them out to disk lazily when they are changed.

    ChangeListeners can be attached to be told when a value changes.

    @see PropertySet
*/
class JUCE_API  PropertiesFile  : public PropertySet,
                                  public ChangeBroadcaster,
                                  private Timer
{
public:
    //==============================================================================
    /**
        Creates a PropertiesFile object.

        @param file                         the file to use
        @param millisecondsBeforeSaving     if this is zero or greater, then after a value
                                            is changed, the object will wait for this amount
                                            of time and then save the file. If zero, the file
                                            will be written to disk immediately on being changed, and
                                            if less than zero, the file won't be saved.
        @param ignoreCaseOfKeyNames         if true, the names of properties are compared in a
                                            case-insensitive way
        @param useCompression               if true, the file will be gzipped when being saved
    */
    PropertiesFile (const File& file,
                    const int millisecondsBeforeSaving = 5000,
                    const bool ignoreCaseOfKeyNames = false,
                    const bool useCompression = false);

    /** Destructor.

        When deleted, the file will first call ensureWrittenToFile() to flush any changes to disk.
    */
    ~PropertiesFile();

    //==============================================================================
    /** This will flush all the values to disk if they've changed since the last
        time they were saved.

        Returns false if it fails to write to the file for some reason (maybe because
        it's read-only or the directory doesn't exist or something).
    */
    bool ensureWrittenToFile();

    //==============================================================================
    /** Returns the file that's being used. */
    const File getFile() const throw();

    //==============================================================================
    /** Handy utility to create a properties file in whatever the standard OS-specific
        location is for these things.

        So on a Mac, this will create a file called:
        ~/Library/Preferences/[folderName]/[applicationName].[fileNameSuffix]

        On Windows it'll create something like:
        C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[fileNameSuffix]

        On Linux it'll create
        ~/.[folderName]/[applicationName].[fileNameSuffix]

        If you pass an empty string as the folder name, it'll use the app name for this (or
        omit the folder name on the Mac).
    */
    static PropertiesFile* createDefaultAppPropertiesFile (const String& applicationName,
                                                           const String& fileNameSuffix,
                                                           const String& folderName,
                                                           const int millisecondsBeforeSaving,
                                                           const bool ignoreCaseOfKeyNames,
                                                           const bool useCompression);

    //==============================================================================
    juce_UseDebuggingNewOperator


protected:
    virtual void propertyChanged();

private:
    //==============================================================================
    File file;
    int timerInterval;
    bool needsWriting, useCompression;

    void timerCallback();

    PropertiesFile (const PropertiesFile&);
    const PropertiesFile& operator= (const PropertiesFile&);
};

#endif   // __JUCE_PROPERTIESFILE_JUCEHEADER__
