/*
 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
 *
 * 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 THE COPYRIGHT HOLDER “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 THE COPYRIGHT HOLDER 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.
 */

#include "config.h"

#include "CSSBasicShapes.h"
#include "CSSPrimitiveValueMappings.h"

#include <wtf/text/StringBuilder.h>

using namespace WTF;

namespace WebCore {

static String buildRectangleString(const String& x, const String& y, const String& width, const String& height, const String& radiusX, const String& radiusY)
{
    char opening[] = "rectangle(";
    char separator[] = ", ";
    StringBuilder result;
    // Compute the required capacity in advance to reduce allocations.
    result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) -1 )) + 1 + x.length() + y.length() + width.length() + height.length() + radiusX.length() + radiusY.length());
    result.appendLiteral(opening);
    result.append(x);
    result.appendLiteral(separator);
    result.append(y);
    result.appendLiteral(separator);
    result.append(width);
    result.appendLiteral(separator);
    result.append(height);
    if (!radiusX.isNull()) {
        result.appendLiteral(separator);
        result.append(radiusX);
        if (!radiusY.isNull()) {
            result.appendLiteral(separator);
            result.append(radiusY);
        }
    }
    result.append(')');
    return result.toString();
}

String CSSBasicShapeRectangle::cssText() const
{
    return buildRectangleString(m_x->cssText(),
        m_y->cssText(),
        m_width->cssText(),
        m_height->cssText(),
        m_radiusX.get() ? m_radiusX->cssText() : String(),
        m_radiusY.get() ? m_radiusY->cssText() : String());
}

bool CSSBasicShapeRectangle::equals(const CSSBasicShape& shape) const
{
    if (shape.type() != CSS_BASIC_SHAPE_RECTANGLE)
        return false;

    const CSSBasicShapeRectangle& other = static_cast<const CSSBasicShapeRectangle&>(shape);
    return compareCSSValuePtr(m_x, other.m_x)
        && compareCSSValuePtr(m_y, other.m_y)
        && compareCSSValuePtr(m_width, other.m_width)
        && compareCSSValuePtr(m_height, other.m_height)
        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
        && compareCSSValuePtr(m_radiusY, other.m_radiusY);
}

#if ENABLE(CSS_VARIABLES)
String CSSBasicShapeRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
{
    return buildRectangleString(m_x->serializeResolvingVariables(variables),
        m_y->serializeResolvingVariables(variables),
        m_width->serializeResolvingVariables(variables),
        m_height->serializeResolvingVariables(variables),
        m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
        m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String());
}

bool CSSBasicShapeRectangle::hasVariableReference() const
{
    return m_x->hasVariableReference()
        || m_y->hasVariableReference()
        || m_width->hasVariableReference()
        || m_height->hasVariableReference()
        || (m_radiusX.get() && m_radiusX->hasVariableReference())
        || (m_radiusY.get() && m_radiusY->hasVariableReference());
}
#endif

static String buildCircleString(const String& x, const String& y, const String& radius)
{
    return "circle(" + x + ", " + y + ", " + radius + ')';
}

String CSSBasicShapeCircle::cssText() const
{
    return buildCircleString(m_centerX->cssText(), m_centerY->cssText(), m_radius->cssText());
}

bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
{
    if (shape.type() != CSS_BASIC_SHAPE_CIRCLE)
        return false;

    const CSSBasicShapeCircle& other = static_cast<const CSSBasicShapeCircle&>(shape);
    return compareCSSValuePtr(m_centerX, other.m_centerX)
        && compareCSSValuePtr(m_centerY, other.m_centerY)
        && compareCSSValuePtr(m_radius, other.m_radius);
}

#if ENABLE(CSS_VARIABLES)
String CSSBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
{
    return buildCircleString(m_centerX->serializeResolvingVariables(variables),
        m_centerY->serializeResolvingVariables(variables),
        m_radius->serializeResolvingVariables(variables));
}

bool CSSBasicShapeCircle::hasVariableReference() const
{
    return m_centerX->hasVariableReference()
        || m_centerY->hasVariableReference()
        || m_radius->hasVariableReference();
}
#endif

static String buildEllipseString(const String& x, const String& y, const String& radiusX, const String& radiusY)
{
    return "ellipse(" + x + ", " + y + ", " + radiusX + ", " + radiusY + ')';
}

String CSSBasicShapeEllipse::cssText() const
{
    return buildEllipseString(m_centerX->cssText(), m_centerY->cssText(), m_radiusX->cssText(), m_radiusY->cssText());
}

bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
{
    if (shape.type() != CSS_BASIC_SHAPE_ELLIPSE)
        return false;

    const CSSBasicShapeEllipse& other = static_cast<const CSSBasicShapeEllipse&>(shape);
    return compareCSSValuePtr(m_centerX, other.m_centerX)
        && compareCSSValuePtr(m_centerY, other.m_centerY)
        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
        && compareCSSValuePtr(m_radiusY, other.m_radiusY);
}

#if ENABLE(CSS_VARIABLES)
String CSSBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
{
    return buildEllipseString(m_centerX->serializeResolvingVariables(variables),
        m_centerY->serializeResolvingVariables(variables),
        m_radiusX->serializeResolvingVariables(variables),
        m_radiusY->serializeResolvingVariables(variables));
}

bool CSSBasicShapeEllipse::hasVariableReference() const
{
    return m_centerX->hasVariableReference()
        || m_centerY->hasVariableReference()
        || m_radiusX->hasVariableReference()
        || m_radiusY->hasVariableReference();
}
#endif

static String buildPolygonString(const WindRule& windRule, const Vector<String>& points)
{
    ASSERT(!(points.size() % 2));

    StringBuilder result;
    char evenOddOpening[] = "polygon(evenodd, ";
    char nonZeroOpening[] = "polygon(nonzero, ";
    char commaSeparator[] = ", ";
    COMPILE_ASSERT(sizeof(evenOddOpening) == sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
    
    // Compute the required capacity in advance to reduce allocations.
    size_t length = sizeof(evenOddOpening) - 1;
    for (size_t i = 0; i < points.size(); i += 2) {
        if (i)
            length += (sizeof(commaSeparator) - 1);
        // add length of two strings, plus one for the space separator.
        length += points[i].length() + 1 + points[i + 1].length();
    }
    result.reserveCapacity(length);

    if (windRule == RULE_EVENODD)
        result.appendLiteral(evenOddOpening);
    else
        result.appendLiteral(nonZeroOpening);

    for (size_t i = 0; i < points.size(); i += 2) {
        if (i)
            result.appendLiteral(commaSeparator);
        result.append(points[i]);
        result.append(' ');
        result.append(points[i + 1]);
    }

    result.append(')');

    return result.toString();
}

String CSSBasicShapePolygon::cssText() const
{
    Vector<String> points;
    points.reserveInitialCapacity(m_values.size());

    for (size_t i = 0; i < m_values.size(); ++i)
        points.append(m_values.at(i)->cssText());

    return buildPolygonString(m_windRule, points);
}

bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
{
    if (shape.type() != CSS_BASIC_SHAPE_POLYGON)
        return false;

    const CSSBasicShapePolygon& rhs = static_cast<const CSSBasicShapePolygon&>(shape);
    return compareCSSValueVector<CSSPrimitiveValue>(m_values, rhs.m_values);
}

#if ENABLE(CSS_VARIABLES)
String CSSBasicShapePolygon::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
{
    Vector<String> points;
    points.reserveInitialCapacity(m_values.size());

    for (size_t i = 0; i < m_values.size(); ++i)
        points.append(m_values.at(i)->serializeResolvingVariables(variables));

    return buildPolygonString(m_windRule, points);
}

bool CSSBasicShapePolygon::hasVariableReference() const
{
    for (size_t i = 0; i < m_values.size(); ++i) {
        if (m_values.at(i)->hasVariableReference())
            return true;
    }
    return false;
}
#endif

} // namespace WebCore

