/*
 * Copyright 2015 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/css_parser/position_parse_structures.h"

#include "cobalt/cssom/keyword_value.h"

namespace cobalt {
namespace css_parser {

namespace {

enum Direction {
  kHorizontal,
  kVertical,
  kCenter,
  kNone,
};

Direction ConvertToDirection(
    const scoped_refptr<cssom::PropertyValue>& element) {
  if (element == cssom::KeywordValue::GetLeft() ||
      element == cssom::KeywordValue::GetRight()) {
    return kHorizontal;
  } else if (element == cssom::KeywordValue::GetTop() ||
             element == cssom::KeywordValue::GetBottom()) {
    return kVertical;
  } else if (element == cssom::KeywordValue::GetCenter()) {
    return kCenter;
  } else {
    return kNone;
  }
}

}  // namespace

PositionParseStructure::PositionParseStructure()
    : is_horizontal_specified_(false),
      is_vertical_specified_(false),
      previous_is_non_center_keyword_(false),
      number_of_center_keyword_(0) {
  position_builder_.reserve(4);
}

bool PositionParseStructure::PushBackElement(
    const scoped_refptr<cssom::PropertyValue>& element) {
  Direction direction = ConvertToDirection(element);

  switch (direction) {
    case kHorizontal: {
      if (is_horizontal_specified_) {
        // Horizontal value has been specified.
        return false;
      }

      is_horizontal_specified_ = true;
      previous_is_non_center_keyword_ = true;
      break;
    }
    case kVertical: {
      if (is_vertical_specified_) {
        // Vertical value has been specified.
        return false;
      }

      is_vertical_specified_ = true;
      previous_is_non_center_keyword_ = true;
      break;
    }
    case kCenter: {
      if (number_of_center_keyword_ >= 2) {
        // More than 2 center keywords.
        return false;
      }

      ++number_of_center_keyword_;
      previous_is_non_center_keyword_ = false;
      break;
    }
    case kNone: {
      switch (position_builder_.size()) {
        case 0: {
          // A length or percentage as the first value represents the horizontal
          // position (or offset).
          is_horizontal_specified_ = true;
          break;
        }
        case 1: {
          if (!previous_is_non_center_keyword_) {
            // A length or percentage as the second value represents the
            // vertical position (or offset).
            is_vertical_specified_ = true;
          }

          previous_is_non_center_keyword_ = false;
          break;
        }
        case 2:  // fall-through
        case 3: {
          if (!previous_is_non_center_keyword_) {
            // The offset should be specified for a non center keyword.
            return false;
          }

          previous_is_non_center_keyword_ = false;
          break;
        }
        default:
          NOTREACHED();
          return false;
      }
      break;
    }
    default:
      NOTREACHED();
      return false;
  }

  position_builder_.push_back(element);
  return true;
}

bool PositionParseStructure::IsPositionValidOnSizeTwo() {
  // Check for the special case that a pair of keywords can be reordered while
  // a combination of keyword and length or percentage cannot. eg. 'top center'
  // is valid while 'top 50%' is not.
  DCHECK_EQ(2, position_builder_.size());

  Direction first_direction = ConvertToDirection(position_builder_[0]);
  Direction second_direction = ConvertToDirection(position_builder_[1]);

  // If two values have one center keyword, the other value can be any
  // keyword, length or percentage.
  if (first_direction == kCenter || second_direction == kCenter) {
    return true;
  }

  if (first_direction == kVertical && !is_horizontal_specified_) {
    return false;
  }

  if (second_direction == kHorizontal && !is_vertical_specified_) {
    return false;
  }

  return true;
}

}  // namespace css_parser
}  // namespace cobalt
