/*
  Copyright (c) 2000 Caldera Systems

  This program is free software; you can redistribute it and/or modify
  it 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.

  This program 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 this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __kxshared_h__
#define __kxshared_h__

#include <qshared.h>

#include <assert.h>

class KXShared : public QShared
{
public:
    KXShared() { m_kxshared_valid = true; }

    bool m_kxshared_valid;
};

/*
  CS: I had to introduce a dependency on KXDataBase into the copy constructor
  and the assigment operator. The assigment operator only copies the node
  reference, if it is set. This allows to copy e.g. KXMonitorData objects from
  the list of available monitors to the currently used monitor without losing
  information about the configuration file node, which stores the monitor
  information.

  The if ( other.node() ) setNode( other.node() ) is tricky, btw!
  If we copy over data from the global settings to a specific data object which
  corresponds to an existing entry/node in the config file, then we in fact do
  want to overwrite the actual data values but do not want to loose the reference
  to the associated config node. So yes, this if() check looks unnecessary, but
  in fact it isn't!

*/

#define KX_DECLARE_SHARED( t, priv )      \
                                          \
t ( const t &other )                      \
  : KXDataBase()                          \
{ d = new priv; *this = other; }          \
                                          \
~t()                                      \
{                                         \
    if ( d->deref() )                     \
        delete d;                         \
}                                         \
                                          \
t &operator=( const t &_other )           \
{                                         \
    t &other = const_cast<t &>( _other ); \
                                          \
    other.d->ref();                       \
                                          \
    if ( d->deref() )                     \
        delete d;                         \
                                          \
    d = other.d;                          \
                                          \
    if( other.node() )                    \
        setNode( other.node() );          \
    return *this;                         \
}                                         \
                                          \
bool isValid() const                      \
{                                         \
    return d->m_kxshared_valid;           \
}                                         \
                                          \
private:                                  \
                                          \
void detach()                             \
{                                         \
    if ( d->count == 1 )                  \
    {                                     \
        d->m_kxshared_valid = true;       \
        return;                           \
    }                                     \
                                          \
    d->deref();                           \
                                          \
    priv *old = d;                        \
    d = new priv;                         \
    *d = *old;                            \
}                                         \
                                          \
inline void chk() const                   \
{                                         \
    assert( d->m_kxshared_valid );        \
}                                         \
                                          \
priv *d;                                  \


#define KX_DECLARE_SHARED2( t, priv )     \
                                          \
t()                                       \
{                                         \
    d = new priv;                         \
    d->m_kxshared_valid = false;          \
}                                         \
                                          \
KX_DECLARE_SHARED( t, priv )


#endif
