/*
 * Copyright 2016 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_CSS_DECLARED_STYLE_DATA_H_
#define COBALT_CSSOM_CSS_DECLARED_STYLE_DATA_H_

#include <bitset>
#include <functional>
#include <string>

#include "base/compiler_specific.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "cobalt/base/unused.h"
#include "cobalt/cssom/css_declaration_data.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/property_value.h"

namespace cobalt {
namespace cssom {

// CSSDeclaredStyleData which has PropertyValue type properties only used
// internally and it is not exposed to JavaScript.
class CSSDeclaredStyleData : public CSSDeclarationData {
 public:
  CSSDeclaredStyleData();

  typedef base::hash_map<PropertyKey, scoped_refptr<PropertyValue> >
      PropertyValues;

  // The length attribute must return the number of CSS declarations in the
  // declarations.
  //   https://www.w3.org/TR/cssom/#dom-cssstyledeclaration-length
  unsigned int length() const;

  // The item(index) method must return the property name of the CSS declaration
  // at position index.
  //  https://www.w3.org/TR/cssom/#dom-cssstyledeclaration-item
  const char* Item(unsigned int index) const;

  // From CSSDeclarationData
  //
  bool IsSupportedPropertyKey(PropertyKey key) const OVERRIDE;

  scoped_refptr<PropertyValue> GetPropertyValue(PropertyKey key) const OVERRIDE;

  void SetPropertyValueAndImportance(
      PropertyKey key, const scoped_refptr<PropertyValue>& property_value,
      bool important) OVERRIDE;

  // Sets the specified property value to NULL and importance to false.  This
  // may be called on longhand properties as well as shorthand properties.
  void ClearPropertyValueAndImportance(PropertyKey key) OVERRIDE;

  // Rest of public methods.

  // Returns true if the property is explicitly declared in this style, as
  // opposed to implicitly inheriting from its parent or the initial value.
  bool IsDeclared(const PropertyKey key) const {
    return declared_properties_[key];
  }

  // This returns the value of the given property if that value is declared, or
  // an empty string if the property does not have a declared value.
  // Declarations in linked ancestor styles will not be considered.
  std::string GetPropertyValueString(const PropertyKey key) const;

  void AssignFrom(const CSSDeclaredStyleData& rhs);

  bool IsAnyDeclaredPropertyImportant() const {
    return important_properties_.any();
  }

  bool IsDeclaredPropertyImportant(PropertyKey key) const {
    return important_properties_[key];
  }

  // This returns the result of serializing a CSS declaration block.
  // The current implementation does not handle shorthands.
  //   https://www.w3.org/TR/cssom/#serialize-a-css-declaration-block
  std::string SerializeCSSDeclarationBlock() const;

  bool operator==(const CSSDeclaredStyleData& that) const;

  const PropertyValues& declared_property_values() const {
    return declared_property_values_;
  }

 private:
  // Helper function that can be called by ClearPropertyValueAndImportance().
  void ClearPropertyValueAndImportanceForLonghandProperty(PropertyKey key);

  PropertyValues::const_iterator Find(PropertyKey key) const;
  PropertyValues::iterator Find(PropertyKey key);

  LonghandPropertiesBitset declared_properties_;
  PropertyValues declared_property_values_;
  LonghandPropertiesBitset important_properties_;
};

}  // namespace cssom
}  // namespace cobalt

#endif  // COBALT_CSSOM_CSS_DECLARED_STYLE_DATA_H_
