// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sky/engine/core/animation/LengthStyleInterpolation.h"

#include "sky/engine/core/css/CSSPrimitiveValue.h"
#include "sky/engine/core/css/StylePropertySet.h"

#include <gtest/gtest.h>

namespace blink {

class AnimationLengthStyleInterpolationTest : public ::testing::Test {
protected:
    static PassOwnPtr<InterpolableValue> lengthToInterpolableValue(CSSValue* value)
    {
        return LengthStyleInterpolation::lengthToInterpolableValue(value);
    }

    static PassRefPtr<CSSValue> interpolableValueToLength(InterpolableValue* value, ValueRange range)
    {
        return LengthStyleInterpolation::interpolableValueToLength(value, range);
    }

    static PassRefPtr<CSSValue> roundTrip(PassRefPtr<CSSValue> value)
    {
        return interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeAll);
    }

    static void testPrimitiveValue(RefPtr<CSSValue> value, double doubleValue, CSSPrimitiveValue::UnitType unitType)
    {
        EXPECT_TRUE(value->isPrimitiveValue());
        EXPECT_EQ(doubleValue, toCSSPrimitiveValue(value.get())->getDoubleValue());
        EXPECT_EQ(unitType, toCSSPrimitiveValue(value.get())->primitiveType());
    }

    static PassOwnPtr<InterpolableList> createInterpolableLength(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
    {
        OwnPtr<InterpolableList> list = InterpolableList::create(10);
        list->set(0, InterpolableNumber::create(a));
        list->set(1, InterpolableNumber::create(b));
        list->set(2, InterpolableNumber::create(c));
        list->set(3, InterpolableNumber::create(d));
        list->set(4, InterpolableNumber::create(e));
        list->set(5, InterpolableNumber::create(f));
        list->set(6, InterpolableNumber::create(g));
        list->set(7, InterpolableNumber::create(h));
        list->set(8, InterpolableNumber::create(i));
        list->set(9, InterpolableNumber::create(j));

        return list.release();
    }

    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_F(AnimationLengthStyleInterpolationTest, ZeroLength)
{
    RefPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX));
    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);

    value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_EMS));
    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);
}

TEST_F(AnimationLengthStyleInterpolationTest, SingleUnit)
{
    RefPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX));
    testPrimitiveValue(value, 10, CSSPrimitiveValue::CSS_PX);

    value = roundTrip(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PERCENTAGE));
    testPrimitiveValue(value, 30, CSSPrimitiveValue::CSS_PERCENTAGE);

    value = roundTrip(CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS));
    testPrimitiveValue(value, -10, CSSPrimitiveValue::CSS_EMS);
}

TEST_F(AnimationLengthStyleInterpolationTest, SingleClampedUnit)
{
    RefPtr<CSSValue> value = CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS);
    value = interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeNonNegative);
    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_EMS);
}

TEST_F(AnimationLengthStyleInterpolationTest, MultipleUnits)
{
    CSSLengthArray actual, expectation;
    initLengthArray(expectation);
    OwnPtr<InterpolableList> list = createInterpolableLength(0, 10, 0, 10, 0, 10, 0, 10, 0, 10);
    toCSSPrimitiveValue(interpolableValueToLength(list.get(), ValueRangeAll).get())->accumulateLengthArray(expectation);
    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(10%% + 10ex + 10ch + 10vh + 10vmax)")));
}

}
