/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
 * All rights reserved.
 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * 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.
 */

#include "core/css/resolver/TransformBuilder.h"

#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "platform/heap/Handle.h"
#include "platform/transforms/Matrix3DTransformOperation.h"
#include "platform/transforms/MatrixTransformOperation.h"
#include "platform/transforms/PerspectiveTransformOperation.h"
#include "platform/transforms/RotateTransformOperation.h"
#include "platform/transforms/ScaleTransformOperation.h"
#include "platform/transforms/SkewTransformOperation.h"
#include "platform/transforms/TransformationMatrix.h"
#include "platform/transforms/TranslateTransformOperation.h"

namespace blink {

static Length convertToFloatLength(
    const CSSPrimitiveValue& primitiveValue,
    const CSSToLengthConversionData& conversionData) {
  return primitiveValue.convertToLength(conversionData);
}

static TransformOperation::OperationType getTransformOperationType(
    CSSValueID type) {
  switch (type) {
    case CSSValueScale:
      return TransformOperation::Scale;
    case CSSValueScaleX:
      return TransformOperation::ScaleX;
    case CSSValueScaleY:
      return TransformOperation::ScaleY;
    case CSSValueScaleZ:
      return TransformOperation::ScaleZ;
    case CSSValueScale3d:
      return TransformOperation::Scale3D;
    case CSSValueTranslate:
      return TransformOperation::Translate;
    case CSSValueTranslateX:
      return TransformOperation::TranslateX;
    case CSSValueTranslateY:
      return TransformOperation::TranslateY;
    case CSSValueTranslateZ:
      return TransformOperation::TranslateZ;
    case CSSValueTranslate3d:
      return TransformOperation::Translate3D;
    case CSSValueRotate:
      return TransformOperation::Rotate;
    case CSSValueRotateX:
      return TransformOperation::RotateX;
    case CSSValueRotateY:
      return TransformOperation::RotateY;
    case CSSValueRotateZ:
      return TransformOperation::RotateZ;
    case CSSValueRotate3d:
      return TransformOperation::Rotate3D;
    case CSSValueSkew:
      return TransformOperation::Skew;
    case CSSValueSkewX:
      return TransformOperation::SkewX;
    case CSSValueSkewY:
      return TransformOperation::SkewY;
    case CSSValueMatrix:
      return TransformOperation::Matrix;
    case CSSValueMatrix3d:
      return TransformOperation::Matrix3D;
    case CSSValuePerspective:
      return TransformOperation::Perspective;
    default:
      ASSERT_NOT_REACHED();
      // FIXME: We shouldn't have a type None since we never create them
      return TransformOperation::None;
  }
}

bool TransformBuilder::hasRelativeLengths(const CSSValueList& valueList) {
  for (auto& value : valueList) {
    const CSSFunctionValue* transformValue = toCSSFunctionValue(value.get());

    for (const CSSValue* item : *transformValue) {
      const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*item);

      // TODO(hs1217.lee) : to prevent relative unit like calc(10px + 1em).
      // but when calc() not take parameter of ralative unit like calc(1px +1
      // px),
      // shoud be return false;
      if (primitiveValue.isCalculated()) {
        return true;
      }

      if (CSSPrimitiveValue::isRelativeUnit(
              primitiveValue.typeWithCalcResolved())) {
        return true;
      }
    }
  }
  return false;
}

TransformOperations TransformBuilder::createTransformOperations(
    const CSSValue& inValue,
    const CSSToLengthConversionData& conversionData) {
  TransformOperations operations;
  if (!inValue.isValueList()) {
    DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone);
    return operations;
  }

  float zoomFactor = conversionData.zoom();
  for (auto& value : toCSSValueList(inValue)) {
    const CSSFunctionValue* transformValue = toCSSFunctionValue(value.get());
    TransformOperation::OperationType transformType =
        getTransformOperationType(transformValue->functionType());

    const CSSPrimitiveValue& firstValue =
        toCSSPrimitiveValue(transformValue->item(0));

    switch (transformType) {
      case TransformOperation::Scale:
      case TransformOperation::ScaleX:
      case TransformOperation::ScaleY: {
        double sx = 1.0;
        double sy = 1.0;
        if (transformType == TransformOperation::ScaleY) {
          sy = firstValue.getDoubleValue();
        } else {
          sx = firstValue.getDoubleValue();
          if (transformType != TransformOperation::ScaleX) {
            if (transformValue->length() > 1) {
              const CSSPrimitiveValue& secondValue =
                  toCSSPrimitiveValue(transformValue->item(1));
              sy = secondValue.getDoubleValue();
            } else {
              sy = sx;
            }
          }
        }
        operations.operations().append(
            ScaleTransformOperation::create(sx, sy, 1.0, transformType));
        break;
      }
      case TransformOperation::ScaleZ:
      case TransformOperation::Scale3D: {
        double sx = 1.0;
        double sy = 1.0;
        double sz = 1.0;
        if (transformType == TransformOperation::ScaleZ) {
          sz = firstValue.getDoubleValue();
        } else {
          sx = firstValue.getDoubleValue();
          sy = toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue();
          sz = toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue();
        }
        operations.operations().append(
            ScaleTransformOperation::create(sx, sy, sz, transformType));
        break;
      }
      case TransformOperation::Translate:
      case TransformOperation::TranslateX:
      case TransformOperation::TranslateY: {
        Length tx = Length(0, Fixed);
        Length ty = Length(0, Fixed);
        if (transformType == TransformOperation::TranslateY)
          ty = convertToFloatLength(firstValue, conversionData);
        else {
          tx = convertToFloatLength(firstValue, conversionData);
          if (transformType != TransformOperation::TranslateX) {
            if (transformValue->length() > 1) {
              const CSSPrimitiveValue& secondValue =
                  toCSSPrimitiveValue(transformValue->item(1));
              ty = convertToFloatLength(secondValue, conversionData);
            }
          }
        }

        operations.operations().append(
            TranslateTransformOperation::create(tx, ty, 0, transformType));
        break;
      }
      case TransformOperation::TranslateZ:
      case TransformOperation::Translate3D: {
        Length tx = Length(0, Fixed);
        Length ty = Length(0, Fixed);
        double tz = 0;
        if (transformType == TransformOperation::TranslateZ) {
          tz = firstValue.computeLength<double>(conversionData);
        } else {
          tx = convertToFloatLength(firstValue, conversionData);
          ty = convertToFloatLength(
              toCSSPrimitiveValue(transformValue->item(1)), conversionData);
          tz = toCSSPrimitiveValue(transformValue->item(2))
                   .computeLength<double>(conversionData);
        }

        operations.operations().append(
            TranslateTransformOperation::create(tx, ty, tz, transformType));
        break;
      }
      case TransformOperation::RotateX:
      case TransformOperation::RotateY:
      case TransformOperation::RotateZ: {
        double angle = firstValue.computeDegrees();
        double x = transformType == TransformOperation::RotateX;
        double y = transformType == TransformOperation::RotateY;
        double z = transformType == TransformOperation::RotateZ;
        operations.operations().append(
            RotateTransformOperation::create(x, y, z, angle, transformType));
        break;
      }
      case TransformOperation::Rotate3D: {
        const CSSPrimitiveValue& secondValue =
            toCSSPrimitiveValue(transformValue->item(1));
        const CSSPrimitiveValue& thirdValue =
            toCSSPrimitiveValue(transformValue->item(2));
        const CSSPrimitiveValue& fourthValue =
            toCSSPrimitiveValue(transformValue->item(3));
        double x = firstValue.getDoubleValue();
        double y = secondValue.getDoubleValue();
        double z = thirdValue.getDoubleValue();
        double angle = fourthValue.computeDegrees();
        operations.operations().append(
            RotateTransformOperation::create(x, y, z, angle, transformType));
        break;
      }
      case TransformOperation::Skew:
      case TransformOperation::SkewX:
      case TransformOperation::SkewY: {
        double angleX = 0;
        double angleY = 0;
        double angle = firstValue.computeDegrees();
        if (transformType == TransformOperation::SkewY)
          angleY = angle;
        else {
          angleX = angle;
          if (transformType == TransformOperation::Skew) {
            if (transformValue->length() > 1) {
              const CSSPrimitiveValue& secondValue =
                  toCSSPrimitiveValue(transformValue->item(1));
              angleY = secondValue.computeDegrees();
            }
          }
        }
        operations.operations().append(
            SkewTransformOperation::create(angleX, angleY, transformType));
        break;
      }
      case TransformOperation::Matrix: {
        double a = firstValue.getDoubleValue();
        double b =
            toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue();
        double c =
            toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue();
        double d =
            toCSSPrimitiveValue(transformValue->item(3)).getDoubleValue();
        double e =
            zoomFactor *
            toCSSPrimitiveValue(transformValue->item(4)).getDoubleValue();
        double f =
            zoomFactor *
            toCSSPrimitiveValue(transformValue->item(5)).getDoubleValue();
        operations.operations().append(
            MatrixTransformOperation::create(a, b, c, d, e, f));
        break;
      }
      case TransformOperation::Matrix3D: {
        TransformationMatrix matrix(
            toCSSPrimitiveValue(transformValue->item(0)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(3)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(4)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(5)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(6)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(7)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(8)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(9)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(10)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(11)).getDoubleValue(),
            zoomFactor *
                toCSSPrimitiveValue(transformValue->item(12)).getDoubleValue(),
            zoomFactor *
                toCSSPrimitiveValue(transformValue->item(13)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(14)).getDoubleValue(),
            toCSSPrimitiveValue(transformValue->item(15)).getDoubleValue());
        operations.operations().append(
            Matrix3DTransformOperation::create(matrix));
        break;
      }
      case TransformOperation::Perspective: {
        double p = firstValue.computeLength<double>(conversionData);
        ASSERT(p >= 0);
        operations.operations().append(
            PerspectiveTransformOperation::create(p));
        break;
      }
      default:
        ASSERT_NOT_REACHED();
        break;
    }
  }
  return operations;
}

}  // namespace blink
