// Copyright 2015 The Cobalt Authors. 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>::DestructorAtExit
    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
