PassOwnPtrWillBeRawPtr<InterpolableValue> ShadowStyleInterpolation::toInterpolableValue(const CSSValue& value, NonInterpolableType& nonInterpolableData)
{
    OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(5);
    const CSSShadowValue* shadowValue = toCSSShadowValue(&value);
    ASSERT(shadowValue);

    result->set(0, lengthToInterpolableValue(shadowValue->x));
    result->set(1, lengthToInterpolableValue(shadowValue->y));
    result->set(2, lengthToInterpolableValue(shadowValue->blur));
    result->set(3, lengthToInterpolableValue(shadowValue->spread));

    if (shadowValue->color && ColorStyleInterpolation::canCreateFrom(*shadowValue->color))
        result->set(4, ColorStyleInterpolation::colorToInterpolableValue(*shadowValue->color));

    if (shadowValue->style)
        nonInterpolableData = (shadowValue->style->getValueID() == CSSValueInset);
    else
        nonInterpolableData = false;

    return result.release();
}
PassOwnPtrWillBeRawPtr<InterpolableValue> LengthStyleInterpolation::lengthToInterpolableValue(CSSValue* value)
{
    OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(CSSPrimitiveValue::LengthUnitTypeCount);
    CSSPrimitiveValue* primitive = toCSSPrimitiveValue(value);

    CSSLengthArray array;
    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
        array.append(0);
    primitive->accumulateLengthArray(array);

    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
        result->set(i, InterpolableNumber::create(array.at(i)));

    return result.release();
}
TEST_F(AnimationInterpolableValueTest, NestedList)
{
    OwnPtrWillBeRawPtr<InterpolableList> listA = InterpolableList::create(3);
    listA->set(0, InterpolableNumber::create(0));
    OwnPtrWillBeRawPtr<InterpolableList> subListA = InterpolableList::create(1);
    subListA->set(0, InterpolableNumber::create(100));
    listA->set(1, subListA.release());
    listA->set(2, InterpolableBool::create(false));

    OwnPtrWillBeRawPtr<InterpolableList> listB = InterpolableList::create(3);
    listB->set(0, InterpolableNumber::create(100));
    OwnPtrWillBeRawPtr<InterpolableList> subListB = InterpolableList::create(1);
    subListB->set(0, InterpolableNumber::create(50));
    listB->set(1, subListB.release());
    listB->set(2, InterpolableBool::create(true));

    RefPtrWillBeRawPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.5);
    InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
    EXPECT_FLOAT_EQ(50, toInterpolableNumber(outList->get(0))->value());
    EXPECT_FLOAT_EQ(75, toInterpolableNumber(toInterpolableList(outList->get(1))->get(0))->value());
    EXPECT_TRUE(toInterpolableBool(outList->get(2))->value());
}
PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableList::interpolate(const InterpolableValue &to, const double progress) const
{
    const InterpolableList* toList = toInterpolableList(&to);
    ASSERT(toList->m_size == m_size);

    if (!progress) {
        return create(*this);
    }
    if (progress == 1) {
        return InterpolableList::create(*toList);
    }

    OwnPtrWillBeRawPtr<InterpolableList> result = create(m_size);
    for (size_t i = 0; i < m_size; i++) {
        ASSERT(m_values[i]);
        ASSERT(toList->m_values[i]);
        result->set(i, m_values[i]->interpolate(*(toList->m_values[i]), progress));
    }
    return result.release();
}
TEST_F(AnimationInterpolableValueTest, SimpleList)
{
    OwnPtrWillBeRawPtr<InterpolableList> listA = InterpolableList::create(3);
    listA->set(0, InterpolableNumber::create(0));
    listA->set(1, InterpolableNumber::create(42));
    listA->set(2, InterpolableNumber::create(20.5));

    OwnPtrWillBeRawPtr<InterpolableList> listB = InterpolableList::create(3);
    listB->set(0, InterpolableNumber::create(100));
    listB->set(1, InterpolableNumber::create(-200));
    listB->set(2, InterpolableNumber::create(300));

    RefPtrWillBeRawPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.3);
    InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
    EXPECT_FLOAT_EQ(30, toInterpolableNumber(outList->get(0))->value());
    EXPECT_FLOAT_EQ(-30.6f, toInterpolableNumber(outList->get(1))->value());
    EXPECT_FLOAT_EQ(104.35f, toInterpolableNumber(outList->get(2))->value());
}