/*
 * Copyright (C) 2015 Andy VanWagoner (andy@vanwagoner.family)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#if ENABLE(INTL)

#include "JSDestructibleObject.h"

struct UCollator;

namespace JSC {

class IntlCollatorConstructor;
class JSBoundFunction;

class IntlCollator final : public JSDestructibleObject {
public:
    typedef JSDestructibleObject Base;

    static IntlCollator* create(VM&, Structure*);
    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);

    DECLARE_INFO;

    void initializeCollator(ExecState&, JSValue locales, JSValue optionsValue);
    JSValue compareStrings(ExecState&, StringView, StringView);
    JSObject* resolvedOptions(ExecState&);

    JSBoundFunction* boundCompare() const { return m_boundCompare.get(); }
    void setBoundCompare(VM&, JSBoundFunction*);

protected:
    IntlCollator(VM&, Structure*);
    void finishCreation(VM&);
    static void destroy(JSCell*);
    static void visitChildren(JSCell*, SlotVisitor&);

private:
    enum class Usage : uint8_t { Sort, Search };
    enum class Sensitivity : uint8_t { Base, Accent, Case, Variant };
    enum class CaseFirst : uint8_t { Upper, Lower, False };

    struct UCollatorDeleter {
        void operator()(UCollator*) const;
    };

    void createCollator(ExecState&);
    static ASCIILiteral usageString(Usage);
    static ASCIILiteral sensitivityString(Sensitivity);
    static ASCIILiteral caseFirstString(CaseFirst);

    String m_locale;
    String m_collation;
    WriteBarrier<JSBoundFunction> m_boundCompare;
    std::unique_ptr<UCollator, UCollatorDeleter> m_collator;
    Usage m_usage;
    Sensitivity m_sensitivity;
    CaseFirst m_caseFirst;
    bool m_numeric;
    bool m_ignorePunctuation;
    bool m_initializedCollator { false };
};

} // namespace JSC

#endif // ENABLE(INTL)
