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

#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "cobalt/base/source_location.h"
#include "cobalt/cssom/css_declaration_util.h"
#include "cobalt/cssom/css_parser.h"
#include "cobalt/cssom/css_rule_visitor.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/style_sheet_list.h"

namespace cobalt {
namespace cssom {
namespace {

struct NonTrivialStaticFields {
  NonTrivialStaticFields()
      : location(base::SourceLocation(CSSFontFaceRule::GetSourceLocationName(),
                                      1, 1)) {}

  const base::SourceLocation location;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields> non_trivial_static_fields =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

CSSFontFaceRule::CSSFontFaceRule() : data_(new CSSFontFaceDeclarationData) {}

CSSFontFaceRule::CSSFontFaceRule(
    const scoped_refptr<CSSFontFaceDeclarationData>& data)
    : data_(data) {
  DCHECK(data_.get());
}

std::string CSSFontFaceRule::css_text(
    script::ExceptionState* /*exception_state*/) const {
  std::string css_text;
  AppendPropertyDeclaration(GetPropertyName(kFontFamilyProperty),
                            data_->family(), &css_text);
  AppendPropertyDeclaration(GetPropertyName(kSrcProperty), data_->src(),
                            &css_text);
  AppendPropertyDeclaration(GetPropertyName(kFontStyleProperty), data_->style(),
                            &css_text);
  AppendPropertyDeclaration(GetPropertyName(kFontWeightProperty),
                            data_->weight(), &css_text);
  AppendPropertyDeclaration(GetPropertyName(kUnicodeRangeProperty),
                            data_->unicode_range(), &css_text);

  return css_text;
}

void CSSFontFaceRule::set_css_text(
    const std::string& css_text, script::ExceptionState* /*exception_state*/) {
  DCHECK(parent_style_sheet());
  scoped_refptr<CSSFontFaceDeclarationData> declaration =
      parent_style_sheet()->css_parser()->ParseFontFaceDeclarationList(
          css_text, non_trivial_static_fields.Get().location);

  if (declaration) {
    data_ = declaration;
    RecordMutation();
  }
}

std::string CSSFontFaceRule::family() const {
  return data_->family() ? data_->family()->ToString() : "";
}

void CSSFontFaceRule::set_family(const std::string& family) {
  SetPropertyValue(GetPropertyName(kFontFamilyProperty), family);
}

std::string CSSFontFaceRule::src() const {
  return data_->src() ? data_->src()->ToString() : "";
}

void CSSFontFaceRule::set_src(const std::string& src) {
  SetPropertyValue(GetPropertyName(kSrcProperty), src);
}

std::string CSSFontFaceRule::style() const {
  return data_->style() ? data_->style()->ToString() : "";
}

void CSSFontFaceRule::set_style(const std::string& style) {
  SetPropertyValue(GetPropertyName(kFontStyleProperty), style);
}

std::string CSSFontFaceRule::weight() const {
  return data_->weight() ? data_->weight()->ToString() : "";
}

void CSSFontFaceRule::set_weight(const std::string& weight) {
  SetPropertyValue(GetPropertyName(kFontWeightProperty), weight);
}

std::string CSSFontFaceRule::unicode_range() const {
  return data_->unicode_range() ? data_->unicode_range()->ToString() : "";
}

void CSSFontFaceRule::set_unicode_range(const std::string& unicode_range) {
  SetPropertyValue(GetPropertyName(kUnicodeRangeProperty), unicode_range);
}

void CSSFontFaceRule::Accept(CSSRuleVisitor* visitor) {
  visitor->VisitCSSFontFaceRule(this);
}

void CSSFontFaceRule::AttachToCSSStyleSheet(CSSStyleSheet* style_sheet) {
  set_parent_style_sheet(style_sheet);
}

std::string CSSFontFaceRule::GetPropertyValue(PropertyKey key) {
  return data_->GetPropertyValue(key) ? data_->GetPropertyValue(key)->ToString()
                                      : "";
}

void CSSFontFaceRule::SetPropertyValue(const std::string& property_name,
                                       const std::string& property_value) {
  DCHECK(parent_style_sheet());
  parent_style_sheet()->css_parser()->ParsePropertyIntoDeclarationData(
      property_name, property_value,
      base::SourceLocation(non_trivial_static_fields.Get().location),
      data_.get());

  RecordMutation();
}

// font-family and src are required for an @font-face rule to be valid:
//   https://www.w3.org/TR/css3-fonts/#descdef-font-family
//   https://www.w3.org/TR/css3-fonts/#descdef-src
bool CSSFontFaceRule::IsValid() const {
  return !family().empty() && !src().empty();
}

CSSFontFaceRule::~CSSFontFaceRule() {}

void CSSFontFaceRule::RecordMutation() {
  DCHECK(parent_style_sheet());
  DCHECK(parent_style_sheet()->ParentStyleSheetList());

  // Trigger layout update.
  parent_style_sheet()->ParentStyleSheetList()->OnCSSMutation();
}

}  // namespace cssom
}  // namespace cobalt
