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

#include "base/lazy_instance.h"
#include "cobalt/cssom/media_feature_keyword_value_names.h"
#include "cobalt/cssom/property_value_visitor.h"

namespace cobalt {
namespace cssom {

struct MediaFeatureKeywordValue::NonTrivialStaticFields {
  NonTrivialStaticFields()
      : interlace_value(
            new MediaFeatureKeywordValue(MediaFeatureKeywordValue::kInterlace)),
        landscape_value(
            new MediaFeatureKeywordValue(MediaFeatureKeywordValue::kLandscape)),
        portrait_value(
            new MediaFeatureKeywordValue(MediaFeatureKeywordValue::kPortrait)),
        progressive_value(new MediaFeatureKeywordValue(
            MediaFeatureKeywordValue::kProgressive)) {}

  const scoped_refptr<MediaFeatureKeywordValue> interlace_value;
  const scoped_refptr<MediaFeatureKeywordValue> landscape_value;
  const scoped_refptr<MediaFeatureKeywordValue> portrait_value;
  const scoped_refptr<MediaFeatureKeywordValue> progressive_value;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

namespace {

base::LazyInstance<MediaFeatureKeywordValue::NonTrivialStaticFields>
    non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;

}  // namespace


const scoped_refptr<MediaFeatureKeywordValue>&
MediaFeatureKeywordValue::GetInterlace() {
  return non_trivial_static_fields.Get().interlace_value;
}

const scoped_refptr<MediaFeatureKeywordValue>&
MediaFeatureKeywordValue::GetLandscape() {
  return non_trivial_static_fields.Get().landscape_value;
}

const scoped_refptr<MediaFeatureKeywordValue>&
MediaFeatureKeywordValue::GetPortrait() {
  return non_trivial_static_fields.Get().portrait_value;
}

const scoped_refptr<MediaFeatureKeywordValue>&
MediaFeatureKeywordValue::GetProgressive() {
  return non_trivial_static_fields.Get().progressive_value;
}

void MediaFeatureKeywordValue::Accept(PropertyValueVisitor* visitor) {
  visitor->VisitMediaFeatureKeywordValue(this);
}

std::string MediaFeatureKeywordValue::ToString() const {
  switch (value_) {
    case kInterlace:
      return kInterlaceMediaFeatureKeywordValueName;
    case kLandscape:
      return kLandscapeMediaFeatureKeywordValueName;
    case kPortrait:
      return kPortraitMediaFeatureKeywordValueName;
    case kProgressive:
      return kProgressiveMediaFeatureKeywordValueName;
    default:
      NOTREACHED();
      return "";
  }
}

}  // namespace cssom
}  // namespace cobalt
