{#-
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
-#}
<!DOCTYPE html>
<!-- Server: {{g.server_name}} -->
{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
{% if g.theme.jinja_macros %}
    {% import g.theme.jinja_macros as theme_macros with context %}
{% endif %}
{% do g.register_forge_js('js/jquery-base.js', location='head_js') %}
{% do g.register_forge_js('js/jquery.notify.js') %}
{% do g.register_forge_js('js/jquery.tooltipster.js') %}
{% do g.register_forge_js('js/sylvester.js') %}
{% do g.register_forge_js('js/twemoji.min.js') %}
{% do g.register_forge_js('js/pb.transformie.min.js') %}
{% do g.register_forge_js('js/allura-base.js') %}
{% do g.register_forge_js('js/checklist.js') %}
{% do g.register_forge_css('css/forge/hilite.css') %}
{% do g.register_forge_css('css/forge/tooltipster.css') %}
{% do g.register_forge_css('css/font-awesome.min.css', compress=False) %}
{% do g.theme.require() %}
{% do g.register_forge_js('js/admin_modal.js') %}
{% do g.register_js('js/jquery.lightbox_me.js') %}
{% if h.has_access(c.project, 'admin')() %}
    {# this would be better placed in top_nav.html but that file is included later so its too late for it to register
       any css.  (Unlike other html files which are the top-level file and extend this master.html) #}
    {% do g.register_forge_css('css/navbar.css') %}
{% endif %}
{% do g.register_forge_js('js/memorable.js') %}
{% do g.resource_manager.register_widgets(c) %}


{# paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ #}
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]>-->
<html lang="en" class="no-js"> <!--<![endif]-->
<head>
    <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
    <title>{% block title %}Your title goes here{% endblock %}</title>
    {{ theme_macros.extra_header(g.theme_href('')) }}
    {% for blob in g.resource_manager.emit('head_css') %}
        {{ blob }}
    {% endfor %}
    {% for blob in g.resource_manager.emit('head_js') %}
        {{ blob }}
    {% endfor %}

    {% if c.project and c.project.neighborhood.css %}
        <style type="text/css">
            {{c.project.neighborhood.get_custom_css()|safe}}
        </style>
    {% elif neighborhood and neighborhood.css %}
        <style type="text/css">
            {{neighborhood.get_custom_css()}}
        </style>
    {% endif %}
    {% block extra_css %}{% endblock %}
    <style>.{{ g.antispam.honey_class }} {
        display: none
    }</style>

    {% block head %}
    {% endblock %}
    {% if g.production_mode %}{{ g.analytics.display() }}{% endif %}
    {% block head_bottom -%}
    {% endblock %}
</head>

<body{% block body_attrs %}{% endblock %} class="{% block body_css_class %}{% endblock %}" id="forge">
{% block body_top_js %}
    {% for blob in g.resource_manager.emit('body_top_js') %}
        {{ blob }}
    {% endfor %}
{% endblock %}

{% set flash = tg.flash_obj.render('flash', use_js=False) %}

{% call theme_macros.all_content_wrapper(login_url, logout_url) %}
    {{ theme_macros.header(g.login_url, '/auth/logout') }}
    {{ theme_macros.site_notification() }}
    {% block masthead %}{% endblock %}
    <section id="page-body" class="{{ g.document_class(neighborhood) }} {% block page_body_classes %}{% endblock %}">
        <div id="nav_menu_holder">
            {% if c.project and c.project.is_nbhd_project %}
                {% set neighborhood=c.project.neighborhood %}
                    {% include 'allura:templates/jinja_master/neigh_nav_menu.html' with context %}
            {% else %}
                {% block nav_menu %}
                    {% include g.theme.nav_menu %}
                {% endblock %}
            {% endif %}
        </div>
        <div id="top_nav" class="">
            {% block top_nav %}
                {% include g.theme.top_nav %}
            {% endblock %}
        </div>
        <div id="content_base">
            {% block content_base %}
                {% if not hide_left_bar %}
                    {% block sidebar_menu %}
                        {% include g.theme.sidebar_menu %}
                    {% endblock %}
                    {% set outer_width = 20 %}
                {% else %}
                    {% set outer_width = 24 %}
                {% endif %}
                {% if show_right_bar %}
                    {% set inner_width = outer_width - 8 %}
                {% else %}
                    {% set inner_width = outer_width %}
                {% endif %}
                <div class="grid-{{ outer_width }} pad">
                    <h2 class="dark{% block header_classes %} title{% endblock %}">{% block header %}{% endblock %}
                        <!-- actions -->
                        <small>
                            {% block actions %}{% endblock %}
                        </small>
                        <!-- /actions -->
                    </h2>
                    {% block edit_box %}{% endblock %}
                    <div{% if show_right_bar %}
                        class="{% block inner_grid scoped %}grid-{{ inner_width }}{% endblock %}"{% endif %}>
                        {% block before_content %}{% endblock %}
                        {% block content %}{% endblock %}
                    </div>
                    {% if show_right_bar %}
                        <div id="sidebar-right" class="grid-6 fright">
                            {% block right_content %}{% endblock %}
                        </div>
                    {% endif %}
                    {% block after_content %}{% endblock %}
                </div>
            {% endblock %}
        </div>
    </section>
    {{ theme_macros.footer(g.year(), g.theme_href('')) }}
{% endcall %}

<div id="messages">
    {% for n in h.pop_user_notifications() %}
        <section class="message {{ n.subject or 'info' }}">
            <header>Notification:</header>
            <div class="content">{{ n.text }}</div>
        </section>
    {% endfor %}
</div>
{% if c.show_login_overlay %}
    {{ theme_macros.login_overlay() }}
{% endif %}
{% for blob in g.resource_manager.emit('body_js') %}
    {{ blob }}
{% endfor %}
{% for blob in g.resource_manager.emit('body_js_tail') %}
    {{ blob }}
{% endfor %}
{% block extra_js %}{% endblock %}
{% if neighborhood %}
    {{ neighborhood.site_specific_html | safe }}
{% elif c.project.neighborhood %}
    {{ c.project.neighborhood.site_specific_html | safe }}
{% endif %}
{{ theme_macros.custom_js() }}
{% if flash %}
    <script type="text/javascript">{{ flash | safe }}</script>
{% endif %}
<script>
    $(document).ready(function () {
        $(".tooltip, .m-tooltip").tooltipster({
            animation: 'fade',
            delay: 200,
            theme: 'tooltipster-light',
            trigger: 'hover',
            position: 'right',
            iconCloning: false,
            maxWidth: 300
        }).focus(function () {
            $(this).tooltipster('show');
        }).blur(function () {
            $(this).tooltipster('hide');
        });

    });
</script>
</body>
</html>
