<!DOCTYPE html>
<!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->

<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Indicium</title>
  <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
  <!-- <link rel="icon" type="image/png" href="/images/favicon.png"/> -->
  <!-- <script type="module" src="index.js"></script> -->
  <link rel="stylesheet" type="text/css" href="./index.css">
  <script src="helper.js"></script>

  <script type="module" src="log-file-reader.mjs"></script>
  <script type="module" src="map-panel.mjs"></script>
  <script type="module" src="timeline-panel.mjs"></script>
  <script type="module" src="ic-panel.mjs"></script>

  <script src="../splaytree.js"></script>
  <script src="../codemap.js"></script>
  <script src="../csvparser.js"></script>
  <script src="../consarray.js"></script>
  <script src="../profile.js"></script>
  <script src="../profile_view.js"></script>
  <script src="../logreader.js"></script>
  <script src="../arguments.js"></script>
  <script src="../SourceMap.js"></script>
  <script src="./map-processor.js"></script>
  <script src="./ic-processor.js"></script>
  <script src="./map-model.js"></script>
<style>
#instructions {
  padding: 10px 10px  60px 10px ;
  margin: auto;
  background-color: #121212;
  box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
}
kbd {
  background-color: #BB86FC;
  color:black;
  border-radius: 3px;
  border: 1px solid black;
  display: inline-block;
  font-size: .9em;
  font-weight: bold;
  padding: 0px 4px 2px 4px;
  white-space: nowrap;
}
dl {
  display: grid;
  grid-template-columns: min-content auto;
  grid-gap: 10px;
}
dt {
  text-align: right;
  white-space: nowrap;
}
dd {
  margin: 0;
}
</style>
<script>
'use strict';

// Event handlers
document.onkeydown = handleKeyDown;
function handleKeyDown(event) {
  stateGlobal.navigation = document.state.navigation;
  let nav = document.state.navigation;
  switch(event.key) {
    case "ArrowUp":
      event.preventDefault();
      if (event.shiftKey) {
        nav.selectPrevEdge();
      } else {
        nav.moveInChunk(-1);
      }
      return false;
    case "ArrowDown":
      event.preventDefault();
      if (event.shiftKey) {
        nav.selectNextEdge();
      } else {
        nav.moveInChunk(1);
      }
      return false;
    case "ArrowLeft":
      nav.moveInChunks(false);
      break;
    case "ArrowRight":
      nav.moveInChunks(true);
      break;
    case "+":
      nav.increaseTimelineResolution();
      break;
    case "-":
      nav.decreaseTimelineResolution();
      break;
  }
}


// Update application state
function updateDocumentState(){
    document.state = stateGlobal.state;
    try {
      document.state.timeline = stateGlobal.timeline;
    } catch (error) {
      console.log(error);
      console.log("cannot assign timeline to the state!");
    }
}

// Map event log processing
function handleLoadTextMapProcessor(text) {
    let mapProcessor = new MapProcessor();
    return mapProcessor.processString(text);
}

// IC event file reading and log processing

function loadFileIC(file) {
  let reader = new FileReader();
  reader.onload = function(evt) {
    let icProcessor = new CustomIcProcessor();
    icProcessor.processString(this.result);
    let entries = icProcessor.entries;
    $("ic-panel").countSelect.innerHTML = entries.length;
    $('#ic-panel').entries = entries;
  }
  reader.readAsText(file);
  $("ic-panel").initGroupKeySelect();
}

function $(id) { return document.querySelector(id); }

// holds the state of the application
let stateGlobal = Object.create(null);

// call when a new file uploaded
function globalDataUpload(e) {
  stateGlobal.timeline = e.detail;
  if(!e.detail) return;
  $('#container').style.display = 'block';
  // instantiate the app logic
  stateGlobal.fileData = e.detail;
  stateGlobal.state = new State('#map-panel','#timeline-panel');
  stateGlobal.timeline = handleLoadTextMapProcessor(stateGlobal.fileData.chunk);
  updateDocumentState();
  loadFileIC(stateGlobal.fileData.file);
}


function globalSearchBarEvent(e) {
  if(!e.detail.isValidMap) return;
  document.state.map = e.detail.map;
}

function handleSelectIcEvents(e){
  if(!e.detail) return;
  // Set selected IC events on the View
  document.state.filteredEntries = e.detail;
}

function showMaps(e) {
  if(!e.detail) return;
  // Show selected maps on the View
  document.state.view.transitionView.showMaps(e.detail);
}
</script>
</head>
<body>
  <div id="content">
    <section id="file-reader">
      <br></br>
      <log-file-reader id="log-file-reader" onchange="globalDataUpload(event)"></log-file-reader>
      <br></br>
    </section>
    <div id="container" style="display: none;">
      <timeline-panel id="timeline-panel"></timeline-panel>
      <map-panel id="map-panel" onclick="globalSearchBarEvent(event)" onchange="showMaps(event)"></map-panel>
      <ic-panel id="ic-panel" onchange="handleSelectIcEvents(event)"></ic-panel>
    </div>
  </div>

  <div id="instructions">
    <h2>Instructions</h2>
    <p>Unified web interface for analyzing the trace information of the Maps/ICs</p>
    <ul>
      <li> Visualize Map trees that have gathered</li>
      <li><code> /path/to/d8 --trace-maps $FILE</code></li>
      <li> Visualize IC events that have gathered</li>
      <li><code> /path/to/d8 --trace_ic $FILE (your_script.js) </code></li>
    </ul>
    <h3>Keyboard Shortcuts</h3>
    <dl>
      <dt><kbd>SHIFT</kbd> + <kbd>Arrow Up</kbd></dt>
      <dd>Follow Map transition forward (first child)</dd>

      <dt><kbd>SHIFT</kbd> + <kbd>Arrow Down</kbd></dt>
      <dd>Follow Map transition backwards</dd>

      <dt><kbd>Arrow Up</kbd></dt>
      <dd>Go to previous Map chunk</dd>

      <dt><kbd>Arrow Down</kbd></dt>
      <dd>Go to next Map in chunk</dd>

      <dt><kbd>Arrow Left</kbd></dt>
      <dd>Go to previous chunk</dd>

      <dt><kbd>Arrow Right</kbd></dt>
      <dd>Go to next chunk</dd>

      <dt><kbd>+</kbd></dt>
      <dd>Timeline zoom in</dd>

      <dt><kbd>-</kbd></dt>
      <dd>Timeline zoom out</dd>
    </dl>
  </div>
</body>
</html>
