/*
 * Copyright (C) 2007, 2008, 2010, 2011, 2012 Apple Inc. All rights reserved.
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#ifndef SpaceSplitString_h
#define SpaceSplitString_h

#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"

namespace WebCore {

    class SpaceSplitStringData : public RefCounted<SpaceSplitStringData> {
    public:
        static PassRefPtr<SpaceSplitStringData> create(const AtomicString&);
        static PassRefPtr<SpaceSplitStringData> createUnique(const SpaceSplitStringData&);

        ~SpaceSplitStringData();

        bool contains(const AtomicString& string)
        {
            size_t size = m_vector.size();
            for (size_t i = 0; i < size; ++i) {
                if (m_vector[i] == string)
                    return true;
            }
            return false;
        }

        bool containsAll(SpaceSplitStringData&);

        void add(const AtomicString&);
        void remove(unsigned index);

        bool isUnique() const { return m_keyString.isNull(); } 
        size_t size() const { return m_vector.size(); }
        const AtomicString& operator[](size_t i) { ASSERT_WITH_SECURITY_IMPLICATION(i < size()); return m_vector[i]; }

    private:
        explicit SpaceSplitStringData(const AtomicString&);
        explicit SpaceSplitStringData(const SpaceSplitStringData&);

        void createVector(const String&);
        template <typename CharacterType>
        inline void createVector(const CharacterType*, unsigned);

        AtomicString m_keyString;
        Vector<AtomicString, 4> m_vector;
    };

    class SpaceSplitString {
    public:
        SpaceSplitString() { }
        SpaceSplitString(const AtomicString& string, bool shouldFoldCase) { set(string, shouldFoldCase); }

        bool operator!=(const SpaceSplitString& other) const { return m_data != other.m_data; }

        void set(const AtomicString&, bool shouldFoldCase);
        void clear() { m_data.clear(); }

        bool contains(const AtomicString& string) const { return m_data && m_data->contains(string); }
        bool containsAll(const SpaceSplitString& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); }
        void add(const AtomicString&);
        bool remove(const AtomicString&);

        size_t size() const { return m_data ? m_data->size() : 0; }
        bool isNull() const { return !m_data; }
        const AtomicString& operator[](size_t i) const { ASSERT_WITH_SECURITY_IMPLICATION(i < size()); return (*m_data)[i]; }

    private:
        void ensureUnique()
        {
            if (m_data && !m_data->isUnique())
                m_data = SpaceSplitStringData::createUnique(*m_data);
        }

        RefPtr<SpaceSplitStringData> m_data;
    };

} // namespace WebCore

#endif // SpaceSplitString_h
