/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/cssom/translate_function.h"

#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/cssom/calc_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/transform_function_visitor.h"

namespace cobalt {
namespace cssom {


TranslateFunction::OffsetType TranslateFunction::offset_type() const {
  if (offset_->GetTypeId() == base::GetTypeId<LengthValue>()) {
    return kLength;
  } else if (offset_->GetTypeId() == base::GetTypeId<PercentageValue>()) {
    return kPercentage;
  } else if (offset_->GetTypeId() == base::GetTypeId<CalcValue>()) {
    return kCalc;
  } else {
    NOTREACHED();
    return kLength;
  }
}

scoped_refptr<LengthValue> TranslateFunction::offset_as_length() const {
  DCHECK_EQ(kLength, offset_type());
  return scoped_refptr<LengthValue>(
      base::polymorphic_downcast<LengthValue*>(offset_.get()));
}

scoped_refptr<PercentageValue> TranslateFunction::offset_as_percentage() const {
  DCHECK_EQ(kPercentage, offset_type());
  return scoped_refptr<PercentageValue>(
      base::polymorphic_downcast<PercentageValue*>(offset_.get()));
}

scoped_refptr<CalcValue> TranslateFunction::offset_as_calc() const {
  DCHECK_EQ(kCalc, offset_type());
  return scoped_refptr<CalcValue>(
      base::polymorphic_downcast<CalcValue*>(offset_.get()));
}

float TranslateFunction::length_component_in_pixels() const {
  switch (offset_type()) {
    case kLength:
      DCHECK_EQ(kPixelsUnit, offset_as_length()->unit());
      return offset_as_length()->value();
    case kPercentage:
      return 0.0f;
    case kCalc:
      DCHECK_EQ(kPixelsUnit, offset_as_calc()->length_value()->unit());
      return offset_as_calc()->length_value()->value();
  }
  NOTREACHED();
  return 0.0f;
}

float TranslateFunction::percentage_component() const {
  switch (offset_type()) {
    case kLength:
      return 0.0f;
    case kPercentage:
      return offset_as_percentage()->value();
    case kCalc:
      return offset_as_calc()->percentage_value()->value();
  }
  NOTREACHED();
  return 0.0f;
}

void TranslateFunction::Accept(TransformFunctionVisitor* visitor) const {
  visitor->VisitTranslate(this);
}

std::string TranslateFunction::ToString() const {
  char axis = 'X';
  switch (axis_) {
    case kXAxis:
      axis = 'X';
      break;
    case kYAxis:
      axis = 'Y';
      break;
    case kZAxis:
      axis = 'Z';
      break;
    default:
      axis = ' ';
      NOTREACHED();
      break;
  }
  std::string result = "translate";
  result.push_back(axis);
  result.push_back('(');
  if (offset_) {
    result.append(offset_->ToString());
  }
  result.push_back(')');
  return result;
}

}  // namespace cssom
}  // namespace cobalt
