/*
 * Copyright (c) 2013, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

#include "sky/engine/config.h"
#include "sky/engine/core/css/CSSCalculationValue.h"

#include "sky/engine/core/css/CSSPrimitiveValue.h"
#include "sky/engine/core/css/CSSToLengthConversionData.h"
#include "sky/engine/core/css/StylePropertySet.h"
#include "sky/engine/core/rendering/style/RenderStyle.h"
#include "sky/engine/core/rendering/style/StyleInheritedData.h"

#include <gtest/gtest.h>


namespace blink {

void PrintTo(const CSSLengthArray& lengthArray, ::std::ostream* os)
{
    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
        *os << lengthArray.at(i) << ' ';
}

}

using namespace blink;

namespace {

void testAccumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PassRefPtr<CSSCalcExpressionNode> expression, float expectedPixels, float expectedPercent)
{
    PixelsAndPercent value(0, 0);
    expression->accumulatePixelsAndPercent(conversionData, value);
    EXPECT_EQ(expectedPixels, value.pixels);
    EXPECT_EQ(expectedPercent, value.percent);
}

void initLengthArray(CSSLengthArray& lengthArray)
{
    lengthArray.resize(CSSPrimitiveValue::LengthUnitTypeCount);
    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
        lengthArray.at(i) = 0;
}

CSSLengthArray& setLengthArray(CSSLengthArray& lengthArray, String text)
{
    initLengthArray(lengthArray);
    RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
    propertySet->setProperty(CSSPropertyLeft, text);
    toCSSPrimitiveValue(propertySet->getPropertyCSSValue(CSSPropertyLeft).get())->accumulateLengthArray(lengthArray);
    return lengthArray;
}

bool lengthArraysEqual(CSSLengthArray& a, CSSLengthArray& b)
{
    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) {
        if (a.at(i) != b.at(i))
            return false;
    }
    return true;
}

TEST(CSSCalculationValue, RefCount)
{
    RefPtr<CalculationValue> calc = CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll);
    Length lengthA(calc);
    EXPECT_EQ(calc->refCount(), 2);

    Length lengthB;
    lengthB = lengthA;
    EXPECT_EQ(calc->refCount(), 3);

    Length lengthC(calc);
    lengthC = lengthA;
    EXPECT_EQ(calc->refCount(), 4);

    Length lengthD(CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll));
    lengthD = lengthA;
    EXPECT_EQ(calc->refCount(), 5);
}

TEST(CSSCalculationValue, RefCountLeak)
{
    RefPtr<CalculationValue> calc = CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll);
    Length lengthA(calc);

    Length lengthB = lengthA;
    for (int i = 0; i < 100; ++i)
        lengthB = lengthA;
    EXPECT_EQ(calc->refCount(), 3);

    Length lengthC(lengthA);
    for (int i = 0; i < 100; ++i)
        lengthC = lengthA;
    EXPECT_EQ(calc->refCount(), 4);

    Length lengthD(calc);
    for (int i = 0; i < 100; ++i)
        lengthD = lengthA;
    EXPECT_EQ(calc->refCount(), 5);

    lengthD = Length();
    EXPECT_EQ(calc->refCount(), 4);
}

TEST(CSSCalculationValue, AddToLengthUnitValues)
{
    CSSLengthArray expectation, actual;
    initLengthArray(expectation);
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "0")));

    expectation.at(CSSPrimitiveValue::UnitTypePixels) = 10;
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "10px")));

    expectation.at(CSSPrimitiveValue::UnitTypePixels) = 0;
    expectation.at(CSSPrimitiveValue::UnitTypePercentage) = 20;
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "20%%")));

    expectation.at(CSSPrimitiveValue::UnitTypePixels) = 30;
    expectation.at(CSSPrimitiveValue::UnitTypePercentage) = -40;
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(30px - 40%%)")));

    expectation.at(CSSPrimitiveValue::UnitTypePixels) = 90;
    expectation.at(CSSPrimitiveValue::UnitTypePercentage) = 10;
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(1in + 10%% - 6px)")));

    expectation.at(CSSPrimitiveValue::UnitTypePixels) = 15;
    expectation.at(CSSPrimitiveValue::UnitTypeFontSize) = 20;
    expectation.at(CSSPrimitiveValue::UnitTypePercentage) = -40;
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc((1 * 2) * (5px + 20em / 2) - 80%% / (3 - 1) + 5px)")));
}

}
