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