/*
 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006 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 SKY_ENGINE_CORE_CSS_PAIR_H_
#define SKY_ENGINE_CORE_CSS_PAIR_H_

#include "sky/engine/core/css/CSSPrimitiveValue.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/RefCounted.h"
#include "sky/engine/wtf/text/StringBuilder.h"

namespace blink {

// A primitive value representing a pair.  This is useful for properties like border-radius, background-size/position,
// and border-spacing (all of which are space-separated sets of two values).  At the moment we are only using it for
// border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use
// it (eliminating some extra -webkit- internal properties).
class Pair final : public RefCounted<Pair> {
public:
    enum IdenticalValuesPolicy { DropIdenticalValues, KeepIdenticalValues };

    static PassRefPtr<Pair> create(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second,
        IdenticalValuesPolicy identicalValuesPolicy)
    {
        return adoptRef(new Pair(first, second, identicalValuesPolicy));
    }

    CSSPrimitiveValue* first() const { return m_first.get(); }
    CSSPrimitiveValue* second() const { return m_second.get(); }
    IdenticalValuesPolicy identicalValuesPolicy() const { return m_identicalValuesPolicy; }

    void setFirst(PassRefPtr<CSSPrimitiveValue> first) { m_first = first; }
    void setSecond(PassRefPtr<CSSPrimitiveValue> second) { m_second = second; }
    void setIdenticalValuesPolicy(IdenticalValuesPolicy identicalValuesPolicy) { m_identicalValuesPolicy = identicalValuesPolicy; }

    String cssText() const
    {
        return generateCSSString(first()->cssText(), second()->cssText(), m_identicalValuesPolicy);
    }

    bool equals(const Pair& other) const
    {
        return compareCSSValuePtr(m_first, other.m_first)
            && compareCSSValuePtr(m_second, other.m_second)
            && m_identicalValuesPolicy == other.m_identicalValuesPolicy;
    }

private:
    Pair()
        : m_first(nullptr)
        , m_second(nullptr)
        , m_identicalValuesPolicy(DropIdenticalValues) { }

    Pair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second, IdenticalValuesPolicy identicalValuesPolicy)
        : m_first(first)
        , m_second(second)
        , m_identicalValuesPolicy(identicalValuesPolicy) { }

    static String generateCSSString(const String& first, const String& second, IdenticalValuesPolicy identicalValuesPolicy)
    {
        if (identicalValuesPolicy == DropIdenticalValues && first == second)
            return first;
        return first + ' ' + second;
    }

    RefPtr<CSSPrimitiveValue> m_first;
    RefPtr<CSSPrimitiveValue> m_second;
    IdenticalValuesPolicy m_identicalValuesPolicy;
};

} // namespace

#endif  // SKY_ENGINE_CORE_CSS_PAIR_H_
