// 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:
          // Position value couldn't take more than 4 elements.
          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
