/*
 * Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include <wtf/Optional.h>
#include <wtf/spi/cf/CFStringSPI.h>

namespace WTF {

class TextBreakIteratorCF {
    WTF_MAKE_FAST_ALLOCATED;
public:
    enum class Mode {
        Caret,
        Delete
    };

    TextBreakIteratorCF(StringView string, Mode mode)
        : m_string(string.createCFStringWithoutCopying())
    {
        switch (mode) {
        case Mode::Caret:
            m_type = kCFStringComposedCharacterCluster;
            break;
        case Mode::Delete:
            m_type = kCFStringBackwardDeletionCluster;
            break;
        }
    }

    TextBreakIteratorCF() = delete;
    TextBreakIteratorCF(const TextBreakIteratorCF&) = delete;
    TextBreakIteratorCF(TextBreakIteratorCF&&) = default;
    TextBreakIteratorCF& operator=(const TextBreakIteratorCF&) = delete;
    TextBreakIteratorCF& operator=(TextBreakIteratorCF&&) = default;

    void setText(StringView string)
    {
        m_string = string.createCFStringWithoutCopying();
    }

    Optional<unsigned> preceding(unsigned location) const
    {
        if (!location)
            return { };
        auto length = static_cast<unsigned long>(CFStringGetLength(m_string.get()));
        if (location > length)
            return length;
        auto range = CFStringGetRangeOfCharacterClusterAtIndex(m_string.get(), location - 1, m_type);
        return range.location;
    }

    Optional<unsigned> following(unsigned location) const
    {
        if (location >= static_cast<unsigned long>(CFStringGetLength(m_string.get())))
            return { };
        auto range = CFStringGetRangeOfCharacterClusterAtIndex(m_string.get(), location, m_type);
        return range.location + range.length;
    }

    bool isBoundary(unsigned location) const
    {
        if (location == static_cast<unsigned long>(CFStringGetLength(m_string.get())))
            return true;
        auto range = CFStringGetRangeOfCharacterClusterAtIndex(m_string.get(), location, m_type);
        return static_cast<unsigned long>(range.location) == location;
    }

private:
    RetainPtr<CFStringRef> m_string;
    CFStringCharacterClusterType m_type;
};

}
