{#-
       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.
-#}
{% import 'allura:templates/jinja_master/lib.html' as lib with context %}

<div{{ {'id': div_id}|xmlattr }}>
  <table class="forum-list clear">
    <thead> 
      <tr> 
        <th><span class="ico ico-mail" title="Subscriptions" data-icon="M"></span></th> 
        <th class="topic">Topic</th> 
        <th>Posts</th> 
        <th>Views</th> 
        <th>Last Post</th> 
      </tr> 
    </thead> 
    <tbody class="forum-list"> 
      {% for thread in value %}
      <tr>
        <td>
          <input type="checkbox" name="threads-{{loop.index0}}.subscription"
                 {% if thread.subscription %}checked="checked"{% endif %}/>
          <input type="hidden" name="threads-{{loop.index0}}._id" value="{{thread._id}}"/>
        </td>
        {% if not thread.first_post %}
        <td class="topic">
          {% if 'flags' in thread and 'Sticky' in thread.flags %}
                <a href="{{thread.url()}}" class="btn"><b data-icon="{{g.icons['pin'].char}}" class="ico {{g.icons['pin'].css}}"></b> <span>Sticky</span></a>
          {% endif %}
          <h3><a href="{{thread.url()}}">{{thread.subject and h.text.truncate(thread.subject, 72) or '(no subject)'}}</a></h3>
        </td>
        {% else %}
        <td class="topic">
          {% set author = thread.first_post.author() %}
          {% if 'flags' in thread and 'Sticky' in thread.flags %}
            <a href="{{thread.url()}}" class="btn ico"><b data-icon="{{g.icons['pin'].char}}" class="ico {{g.icons['pin'].css}}"></b> <span>Sticky</span></a>
          {% endif %}
          <h3><a href="{{thread.url()}}">{{thread.subject and h.text.truncate(thread.subject, 72) or '(no subject)'}}</a></h3>

          <span>By <a href="{{author.url()}}">{{author.display_name}}</a></span> on {{thread.first_post.timestamp.strftime('%a %b %d, %Y %I:%M %p')}}
        </td> 
        {% endif %}
        <td>{{thread.num_replies}}</td> 
        <td>{{thread.num_views}}</td>
        {% if not thread.last_post %}
        <td>&nbsp;</td>
        {% else %}
          {% set author = thread.last_post.author() %}
          <td>
          <p class="gravatar sm">
            By {{lib.gravatar(author, size=16)}}<a href="{{author.url()}}">{{author.display_name}}</a><br />on {{thread.last_post.timestamp.strftime('%a %b %d, %Y %I:%M %p')}}
          </p>
          </td> 
        {% endif %}
      </tr> 
      {% endfor %}
    </tbody> 
  </table>

</div>
