<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/core/test_utils.html">
<link rel="import" href="/model/frame.html">
<link rel="import" href="/core/timeline_viewport.html">
<link rel="import" href="/core/tracks/drawing_container.html">
<link rel="import" href="/core/tracks/frame_track.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {
  var Frame = tr.model.Frame;
  var FrameTrack = tr.c.tracks.FrameTrack;
  var Selection = tr.c.Selection;
  var SelectionState = tr.model.SelectionState;
  var Viewport = tr.c.TimelineViewport;

  var newSliceNamed = tr.c.test_utils.newSliceNamed;

  var createFrames = function() {
    var frames = undefined;
    var model = tr.c.test_utils.newModel(function(model) {
      var process = model.getOrCreateProcess(1);
      var thread = process.getOrCreateThread(1);
      for (var i = 1; i < 5; i++) {
        var slice = newSliceNamed('work for frame', i * 20, 10);
        thread.sliceGroup.pushSlice(slice);
        var events = [slice];
        var threadTimeRanges =
            [{thread: thread, start: slice.start, end: slice.end}];
        process.frames.push(new Frame(events, threadTimeRanges));
      }
      frames = process.frames;
    });
    return frames;
  };

  test('instantiate', function() {
    var frames = createFrames();
    frames[1].selectionState = SelectionState.SELECTED;

    var div = document.createElement('div');
    var viewport = new Viewport(div);
    var drawingContainer = new tr.c.tracks.DrawingContainer(viewport);
    div.appendChild(drawingContainer);

    var track = FrameTrack(viewport);
    drawingContainer.appendChild(track);

    this.addHTMLOutput(div);
    drawingContainer.invalidate();

    track.frames = frames;
    var dt = new tr.c.TimelineDisplayTransform();
    dt.xSetWorldBounds(0, 50, track.clientWidth);
    track.viewport.setDisplayTransformImmediately(dt);

    assert.equal(track.items[0].start, 20);
  });

  test('modelMapping', function() {
    var frames = createFrames();

    var div = document.createElement('div');
    var viewport = new Viewport(div);
    var track = FrameTrack(viewport);
    track.frames = frames;

    var a0 = track.items[0].modelItem;
    assert.equal(a0, frames[0]);
  });

  test('selectionMapping', function() {
    var frames = createFrames();

    var div = document.createElement('div');
    var viewport = new Viewport(div);
    var track = FrameTrack(viewport);
    track.frames = frames;

    var selection = new Selection();
    track.items[0].addToSelection(selection);

    // select both frame, but not its component slice
    assert.equal(selection.length, 1);

    var frameCount = 0;
    var eventCount = 0;
    selection.forEach(function(event) {
      if (event instanceof Frame) {
        assert.equal(event, frames[0]);
        frameCount++;
      } else
        eventCount++;
    });
    assert.equal(frameCount, 1);
    assert.equal(eventCount, 0);
  });
});
</script>
