/*
 * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
 *
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "SettingsBase.h"
#include <wtf/RefCounted.h>

namespace WebCore {

class Page;

class Settings : public SettingsBase, public RefCounted<Settings> {
    WTF_MAKE_NONCOPYABLE(Settings); WTF_MAKE_FAST_ALLOCATED;
public:
    static Ref<Settings> create(Page*);
    ~Settings();

<%- for @setting in @unconditionalSetting do -%>
    <%- if @setting.hasComplexGetter? -%>
    WEBCORE_EXPORT <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const;
    <%- else -%>
    <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const { return m_<%= @setting.name %>; } 
    <%- end -%>
    <%- if @setting.hasComplexSetter? -%>
    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %>);
    <%- else -%>
    void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %> <%= @setting.name %>) { m_<%= @setting.name %> = <%= @setting.name %>; }
    <%- end -%>
<%- end -%>

<%- for @conditional in @conditionals do -%>
#if ENABLE(<%= @conditional.condition %>)
<%- for @setting in @conditional.settings do -%>
    <%- if @setting.hasComplexGetter? -%>
    WEBCORE_EXPORT <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const;
    <%- else -%>
    <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const { return m_<%= @setting.name %>; } 
    <%- end -%>
    <%- if @setting.hasComplexSetter? -%>
    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %>);
    <%- else -%>
    void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %> <%= @setting.name %>) { m_<%= @setting.name %> = <%= @setting.name %>; }
    <%- end -%>
<%- end -%>
#endif

<%- end -%>
<%- for @setting in @inspectorOverrideSettings do -%>
    <%- if @setting.hasComplexSetter? -%>
    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>InspectorOverride(Optional<<%= @setting.parameterType %>>);
    <%- else -%>
    void <%= @setting.setterFunctionName %>InspectorOverride(Optional<<%= @setting.parameterType %>> <%= @setting.name %>InspectorOverride) { m_<%= @setting.name %>InspectorOverride = <%= @setting.name %>InspectorOverride; }
    <%- end -%>
<%- end -%>

private:
    explicit Settings(Page*);

<%- for @setting in @inspectorOverrideSettings do -%>
    Optional<<%= @setting.type %>> m_<%= @setting.name %>InspectorOverride;
<%- end -%>

<%- for @setting in @unconditionalNonBoolSetting do -%>
    <%= @setting.type %> m_<%= @setting.name %>;
<%- end -%>

<%- for @conditional in @conditionals do -%>
<%- if @conditional.nonBoolSettings.length != 0 -%>
#if ENABLE(<%= @conditional.condition %>)
<%- for @setting in @conditional.nonBoolSettings -%>
    <%= @setting.type %> m_<%= @setting.name %>;
<%- end -%>
#endif
<%- end -%>
<%- end -%>

<%- for @setting in @unconditionalBoolSetting do -%>
    <%= @setting.type %> m_<%= @setting.name %> : 1;
<%- end -%>

<%- for @conditional in @conditionals do -%>
<%- if @conditional.boolSettings.length != 0 -%>
#if ENABLE(<%= @conditional.condition %>)
<%- for @setting in @conditional.boolSettings -%>
    <%= @setting.type %> m_<%= @setting.name %> : 1;
<%- end -%>
#endif
<%- end -%>
<%- end -%>
};

}
