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

<html>

<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="shortcut icon" href="{{ static_url('img/logo54x54.png') }}" type="image/x-icon" >
  <link href="{{ static_url('css/bootstrap.css') }}" rel="stylesheet">
  <style type="text/css">
    .log {
      font-family: "Inconsolata", "Monaco", "Courier New", "Courier";
      line-height:14px;
      font-size: 12px;
    }

    .invert {
      color: #FFFFFF;
      text-decoration: none;
      background: #000000;
    }
  </style>
  <script src="{{ static_url('js/jquery.min.js') }}"></script>
  <script src="{{ static_url('js/jquery.pailer.js') }}"></script>
</head>

<style type="text/css">
div.tight
{
  height:100%;
  overflow:scroll;
}
</style>

<title>Path {{ path }}</title>
<body>
<div> <strong> Path </strong> {{ path }} </div>
<div> <strong> dl </strong> <a href='{{ baseUrl }}/topologies/{{cluster}}/{{environ}}/{{topology}}/{{container}}/filedownload?path={{path}}'><font size=1>download</font></a> </div>
  <div style="position: absolute; left: 5px; top: 0px;">
    <p id="indicator" class="log invert"></p>
  </div>

  <div id="data" class="log" style="white-space:pre-wrap; background-color:#EEEEEE;"></div>

<script>
  function resize() {
    var margin_left = parseInt($('body').css('margin-left'));
    var margin_top = parseInt($('body').css('margin-top'));
    var margin_bottom = parseInt($('body').css('margin-bottom'));
    $('#data').width($(window).width() - margin_left);
    $('#data').height($(window).height() - margin_top - margin_bottom);
  }


  $(window).resize(resize);

  $(document).ready(function() {
    resize();

    $('#data').pailer({
      'read': function(options) {
        var settings = $.extend({
          'offset': -1,
          'length': -1
        }, options);

        var url = "{{ baseUrl }}/topologies/{{ cluster }}/{{ environ }}/{{ topology }}/{{ container }}/filedata" +
                   "?offset=" + settings.offset +
                   "&length=" + settings.length +
                   "&path={{ path }}";
        return $.getJSON(url);
      },
      'indicator': $('#indicator')
    });
  });
</script>
</body>
</html>
