<!--
  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.
-->

{% assign prefix = site.attrs.base_url  %}
{% assign normalized_path = page.url | replace: ".html","" | remove_first: prefix %}
{% if page.toc != false %}
<nav class='left-nav' data-swiftype-index='false'>

    {% for guide in site.data.toc %}
    <li>
        {% if guide.items %}

        {% assign guide_class = 'collapsed' %}

        {% capture submenu %}
        {% for chapter in guide.items %}

        {% assign chapter_class = 'collapsed' %}
        {% assign normalized_chapter_url = chapter.url | prepend: "/" %}
        {% if normalized_path == normalized_chapter_url %}
        {% assign guide_class = 'expanded' %}
        {% assign chapter_class = 'expanded' %}
        {% endif %}

    <li>
        {% if chapter.items %}
        {% assign matching_items_count = chapter.items | where: 'url', normalized_path | size %}
        {% if matching_items_count != 0 %}
        {% assign chapter_class = 'expanded parent' %}
        {% endif %}
        <button
                type='button'
                class='{{chapter_class}} {% if normalized_path == normalized_chapter_url %}active{% endif %}'>
            {{chapter.title}}<img class="state-indicator" src="{{'assets/images/left-nav-arrow.svg' | relative_url}}">
        </button>
        <nav class="sub_pages {{chapter_class}}">

            {% for subpage in chapter.items %}
            {% assign normalized_subpage_url = subpage.url | prepend: "/" %}
            {% if normalized_path == normalized_subpage_url %}
            {% assign guide_class = 'expanded' %}
            {% assign chapter_class = 'expanded' %}
            {% endif %}

    <li><a href="{{prefix}}/{{subpage.url}}"
           class='{% if normalized_path == normalized_subpage_url %}active{% endif %}'>{{subpage.title}}</a></li>
    {% endfor %}
</nav>
{% else %}
<a href="{{prefix}}{{chapter.url|relative_url}}"

   class='{% if normalized_path == normalized_chapter_url %}active{% endif %}'
>{{chapter.title}}</a>
{% endif %}
</li>
{% endfor %}

{% endcapture %}

<button type='button' data-guide-url="{{guide.url}}"
        class='group-toggle {{guide_class}} {% if page.url contains guide.url %}parent{% endif %}'>{{guide.title}}<img
        class="state-indicator" src="{{'assets/images/left-nav-arrow.svg'|relative_url}}"></button>
<nav class='nav-group {{guide_class}}'>
    {{ submenu }}
</nav>
{% else %}

<a href="{{prefix}}{{guide.url|relative_url}}" class='{% if guide.url == normalized_path %}active{% endif %}'>{{guide.title}}</a>
{% endif %}
</li>
{% endfor %}
</nav>
<div class="left-nav__overlay"></div>
{% endif %}
