// 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.

#ifndef COBALT_CSSOM_COMPOUND_SELECTOR_H_
#define COBALT_CSSOM_COMPOUND_SELECTOR_H_

#include <string>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/cssom/selector.h"
#include "cobalt/cssom/simple_selector.h"
#include "cobalt/cssom/specificity.h"

namespace cobalt {
namespace cssom {

class Combinator;
class PseudoElement;
class SelectorVisitor;

// A compound selector is a chain of simple selectors that are not separated by
// a combinator.
//   https://www.w3.org/TR/selectors4/#compound
class CompoundSelector : public Selector {
 public:
  typedef ScopedVector<SimpleSelector> SimpleSelectors;

  CompoundSelector();
  ~CompoundSelector() OVERRIDE;

  // From Selector.
  void Accept(SelectorVisitor* visitor) OVERRIDE;
  CompoundSelector* AsCompoundSelector() OVERRIDE { return this; }
  Specificity GetSpecificity() const OVERRIDE { return specificity_; }

  // Rest of public methods.

  void AppendSelector(scoped_ptr<SimpleSelector> selector);
  const SimpleSelectors& simple_selectors() { return simple_selectors_; }
  PseudoElement* pseudo_element() {
    if (has_pseudo_element_) {
      for (SimpleSelectors::iterator iter = simple_selectors_.begin();
           iter != simple_selectors_.end(); ++iter) {
        if ((*iter)->AsPseudoElement()) {
          return (*iter)->AsPseudoElement();
        }
      }
    }
    return NULL;
  }

  Combinator* left_combinator() { return left_combinator_; }
  void set_left_combinator(Combinator* combinator) {
    left_combinator_ = combinator;
  }

  Combinator* right_combinator() { return right_combinator_.get(); }
  void set_right_combinator(scoped_ptr<Combinator> combinator);

  bool requires_rule_matching_verification_visit() const {
    return requires_rule_matching_verification_visit_;
  }

  bool operator<(const CompoundSelector& that) const {
    if (simple_selectors_.size() < that.simple_selectors_.size()) {
      return true;
    }
    if (simple_selectors_.size() > that.simple_selectors_.size()) {
      return false;
    }

    for (size_t i = 0; i < simple_selectors_.size(); ++i) {
      if (simple_selectors_[i]->type() < that.simple_selectors_[i]->type()) {
        return true;
      }
      if (simple_selectors_[i]->type() > that.simple_selectors_[i]->type()) {
        return false;
      }
      if (simple_selectors_[i]->prefix() <
          that.simple_selectors_[i]->prefix()) {
        return true;
      }
      if (simple_selectors_[i]->prefix() >
          that.simple_selectors_[i]->prefix()) {
        return false;
      }
      if (simple_selectors_[i]->text() < that.simple_selectors_[i]->text()) {
        return true;
      }
      if (simple_selectors_[i]->text() > that.simple_selectors_[i]->text()) {
        return false;
      }
    }

    return false;
  }

 private:
  Combinator* left_combinator_;
  scoped_ptr<Combinator> right_combinator_;
  SimpleSelectors simple_selectors_;
  Specificity specificity_;
  bool has_pseudo_element_;
  // This flag tracks whether or not during rule matching, after the initial
  // candidate gathering phase, the simple selectors require additional checks
  // during the verification phase to determine a match; otherwise, the act of
  // being gathered itself proves the match.
  // There are two cases where the selectors require a visit:
  // 1. There are multiple selectors. Gathering only tests against the first
  //    selector and the later selectors must also be verified to match.
  // 2. The single selector's AlwaysRequiresRuleMatchingVerificationVisit() call
  //    returns true. This indicates that being gathered as a candidate is not
  //    sufficient to prove a match and that additional verification checks are
  //    required.
  bool requires_rule_matching_verification_visit_;

  DISALLOW_COPY_AND_ASSIGN(CompoundSelector);
};

}  // namespace cssom
}  // namespace cobalt

#endif  // COBALT_CSSOM_COMPOUND_SELECTOR_H_
