// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_PROPERTIES_H
#define OB_PROPERTIES_H

#include <OB/OBORB_fwd.h>
#include <OB/Properties_fwd.h>

#include <OB/Template.h>

namespace OB
{

class Properties : public RefCount, public JTCRecursiveMutex
{
    //
    // Hide copy-constructor and assignment operator
    //
    Properties(const Properties&);
    void operator=(const Properties&);

    static JTCMutex propertiesMutex_;
    static OB_IMPORT Properties_var defaultProperties_;

public:

    typedef StrSeq< int > KeySeq;

private:

    void merge(KeySeq&, const KeySeq&) const;

protected:

    //
    // Properties data
    //
    KeySeq props_;

    //
    // The default properties, if present
    //
    Properties_var defaults_;
    
public:

    //
    // Create an empty property set
    //
    Properties();

    //
    // Create a property set with the given defaults
    //
    Properties(Properties_ptr);

    ~Properties();

    static inline Properties_ptr _duplicate(Properties_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline Properties_ptr _nil()
    { return 0; }

    //
    // Get the default properties
    //
    static Properties_ptr getDefaultProperties();

    //
    // Set and get a property
    //
    void setProperty(const char*, const char*);
    const char* getProperty(const char*) const;

    //
    // Get all property keys starting with prefix
    // Get all property keys
    //
    KeySeq getKeys(const char* prefix) const;
    KeySeq getKeys() const;

    //
    // Load the properties from a file. Returns false if the file
    // could not be opened. The value of errno should be checked to
    // determine the cause of the error.
    //
    bool load(const char*);

#ifdef WIN32
    //
    // Load the properties from the registry. Returns false if the
    // registry key could not be opened.
    //
    bool load(HKEY, const char*, const char*);
#endif
};

} // End of namespace OB

namespace CORBA
{

inline void
release(OB::Properties_ptr p)
{
    if(p)
	p -> _OB_decRef();
}

inline Boolean
is_nil(OB::Properties_ptr p)
{
    return p == 0;
}

} // End of namespace CORBA

#endif
