/*
 *  This file is part of the KDE libraries
 *  Copyright (C) 2003 Apple Computer, Inc.
 *
 *  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; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#ifndef KJS_SCOPE_CHAIN_H
#define KJS_SCOPE_CHAIN_H

#include <assert.h>

namespace KJS {

    class JSObject;
    class ExecState;
    
    class ScopeChainNode {
    public:
        ScopeChainNode(ScopeChainNode *n, JSObject *o)
            : next(n), object(o), refCount(1) { }

        ScopeChainNode *next;
        JSObject *object;
        int refCount;
    };

    class ScopeChainIterator {
    public:
        ScopeChainIterator(ScopeChainNode *node) : m_node(node) {}

        JSObject * const & operator*() const { return m_node->object; }
        JSObject * const * operator->() const { return &(operator*()); }
    
        ScopeChainIterator& operator++() { m_node = m_node->next; return *this; }

        // postfix ++ intentionally omitted

        bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
        bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }

    private:
        ScopeChainNode *m_node;
    };

    class ScopeChain {
    public:
        ScopeChain() : _node(0) { }
        ~ScopeChain() { deref(); }

        ScopeChain(const ScopeChain &c) : _node(c._node)
            { if (_node) ++_node->refCount; }
        ScopeChain &operator=(const ScopeChain &);

        bool isEmpty() const { return !_node; }
        JSObject *top() const { return _node->object; }

        JSObject *bottom() const;

        ScopeChainIterator begin() const { return ScopeChainIterator(_node); }
        ScopeChainIterator end() const { return ScopeChainIterator(0); }

        void clear() { deref(); _node = 0; }
        void push(JSObject *);
        void push(const ScopeChain &);
        void pop();
        
        void mark();

#ifndef NDEBUG        
        void print();
#endif
        
    private:
        ScopeChainNode *_node;
        
        void deref() { if (_node && --_node->refCount == 0) release(); }
        void ref() const;
        
        void release();
    };

inline void ScopeChain::ref() const
{
    for (ScopeChainNode *n = _node; n; n = n->next) {
        if (n->refCount++ != 0)
            break;
    }
}

inline ScopeChain &ScopeChain::operator=(const ScopeChain &c)
{
    c.ref();
    deref();
    _node = c._node;
    return *this;
}

inline JSObject *ScopeChain::bottom() const
{
    ScopeChainNode *last = 0;
    for (ScopeChainNode *n = _node; n; n = n->next)
        last = n;
    if (!last)
        return 0;
    return last->object;
}

inline void ScopeChain::push(JSObject *o)
{
    assert(o);
    _node = new ScopeChainNode(_node, o);
}

inline void ScopeChain::pop()
{
    ScopeChainNode *oldNode = _node;
    assert(oldNode);
    ScopeChainNode *newNode = oldNode->next;
    _node = newNode;
    
    if (--oldNode->refCount != 0) {
        if (newNode)
            ++newNode->refCount;
    } else {
        delete oldNode;
    }
}

} // namespace KJS

#endif // KJS_SCOPE_CHAIN_H
