// 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/cssom/complex_selector.h"

#include "base/logging.h"
#include "cobalt/cssom/combinator.h"
#include "cobalt/cssom/compound_selector.h"
#include "cobalt/cssom/selector_visitor.h"

namespace cobalt {
namespace cssom {

const int ComplexSelector::kCombinatorLimit = 32;

void ComplexSelector::Accept(SelectorVisitor* visitor) {
  visitor->VisitComplexSelector(this);
}

void ComplexSelector::AppendSelector(
    scoped_ptr<CompoundSelector> compound_selector) {
  DCHECK(!first_selector_);
  specificity_.AddFrom(compound_selector->GetSpecificity());
  first_selector_ = compound_selector.Pass();
  last_selector_ = first_selector_.get();
}

void ComplexSelector::AppendCombinatorAndSelector(
    scoped_ptr<Combinator> combinator,
    scoped_ptr<CompoundSelector> compound_selector) {
  DCHECK(first_selector_);
  DCHECK(last_selector_);

  if (combinator_count_ >= kCombinatorLimit) {
    if (!combinator_limit_exceeded_) {
      LOG(WARNING)
          << "Maximum number of calls to AppendCombinatorAndSelector exceeded."
             "  Ignoring additional selectors.";
      combinator_limit_exceeded_ = true;
    }
    return;
  }

  specificity_.AddFrom(compound_selector->GetSpecificity());

  combinator->set_left_selector(last_selector_);
  compound_selector->set_left_combinator(combinator.get());

  combinator->set_right_selector(compound_selector.Pass());
  last_selector_->set_right_combinator(combinator.Pass());

  last_selector_ = last_selector_->right_combinator()->right_selector();

  combinator_count_++;
}

}  // namespace cssom
}  // namespace cobalt
