<!DOCTYPE html>
<script src='../../../resources/testharness.js'></script>
<script src='../../../resources/testharnessreport.js'></script>
<style type='text/css'>
  #box {
    width: 100px;
    height: 100px;
    background: red;
    padding: 0px;
    margin: 0px;
  }

  td {
    padding: 0px;
  }

</style>

<table id='table1'>
  <tr><td><div id='box'></div></td></tr>
</table>
<div><input type='range' id='slider1' min = '0' max = '100' step = '10'></input></div>
<div><input type='range' id='slider2' min = '0' max = '100' step = '10' style='touch-action:none;'></div>
<div><input type='range' id='slider3' min = '0' max = '100' step = '10' style='-webkit-appearance: slider-vertical;'></div>
<table id = 'table2'><tbody /></table>

<script>
function forceLayoutUpdate() {
   document.body.offsetTop;
}

function buildPage() {
  var tbody1 = document.getElementById('table1').children[0];
  var tbody2 = document.getElementById('table2').children[0];
  var targetHeight = window.innerHeight;
  var targetWidth = window.innerWidth;
  var row = targetHeight / tbody1.offsetHeight;
  var col = targetWidth / tbody1.offsetWidth * 2;

  var i = 0;
  var j = 0;
  // Create some room at the top for scrolling.
  var tr = document.createElement('tr');
  for (j = 0; j < col; ++j) {
    var td = document.createElement('td');
    td.innerHTML = '<div id="box"></div>';
    tr.appendChild(td);
  }
  tbody1.appendChild(tr);
  // Take up enough space to overflow the page horizontally and vertically.
  for (i = 0; i < row; ++i) {
    var tr = document.createElement('tr');
    for (j = 0; j < col; ++j) {
      var td = document.createElement('td');
      td.innerHTML = '<div id="box"></div>';
      tr.appendChild(td);
    }
    tbody2.appendChild(tr);
  }
}

forceLayoutUpdate();
buildPage();
forceLayoutUpdate();

var slider1 = document.getElementById('slider1');
var slider2 = document.getElementById('slider2');
var slider3 = document.getElementById('slider3')
var container1 = internals.shadowRoot(slider1).children[0];
var container2 = internals.shadowRoot(slider2).children[0];
var container3 = internals.shadowRoot(slider3).children[0];
const touchSourceType = 1;


var isMac = navigator.platform.indexOf('Mac') == 0;
if (!isMac) {
  testSlider1H();
} else {
  testTouchAction();
}

function testSlider1H() {
  var testSlider1H = async_test('Changes the value of a horizontal slider.');
  testSlider1H.step(function () {
    var offsetX = window.pageXOffset;
    var offsetY = window.pageYOffset;
    var w = slider1.clientWidth;
    var h = slider1.clientHeight;
    var x = slider1.offsetLeft + w / 2 - offsetX;
    var y = slider1.offsetTop + h / 2 - offsetY;
    assert_equals(parseInt(slider1.value), 50);
  // Perform a left drag with a bit up on the thumb.
  chrome.gpuBenchmarking.smoothDrag(x, y, x - w, y - w / 2,
    function() {
      // Should set slider1's value to 0.
      assert_equals(parseInt(slider1.value), 0);
      // Should not drag the page vertically.
      assert_approx_equals(window.pageYOffset, offsetY, 10);
      // Should not drag the page horizontally.
      assert_approx_equals(window.pageXOffset, offsetX, 0);
      testSlider1V();
      testSlider1H.done();
    }, touchSourceType);
});
}

function testSlider1V() {
  var testSlider1V = async_test('Drags up on a horizontal slider.');
  testSlider1V.step(function () {
    var offsetX = window.pageXOffset;
    var offsetY = window.pageYOffset;
    var w = slider1.clientWidth;
    var h = slider1.clientHeight;
    var x = slider1.offsetLeft - offsetX;
    var y = slider1.offsetTop - offsetY;
    assert_equals(parseInt(slider1.value), 0);
  // Perform an up drag with a bit right on the thumb.
  chrome.gpuBenchmarking.smoothDrag(x, y, x + 10, y - 100,
    function() {
      // Should not change slider1's value.
      assert_equals(parseInt(slider1.value), 0);
      // Should drag the page upwards.
      assert_approx_equals(window.pageYOffset, offsetY + 85, 10);
      // Should not drag the page horizontally.
      assert_approx_equals(window.pageXOffset, offsetX, 0);
      testSlider2();
      testSlider1V.done();
    }, touchSourceType);
});
}

function testSlider2() {
  var testSlider2 = async_test('Drags up on a horizontal slider with touch-action=none.');
  testSlider2.step(function () {
    var offsetX = window.pageXOffset;
    var offsetY = window.pageYOffset;
    var w = slider2.clientWidth;
    var h = slider2.clientHeight;
    var x = slider2.offsetLeft + w / 2 - offsetX;
    var y = slider2.offsetTop + h / 2 - offsetY;
    assert_equals(parseInt(slider2.value), 50);
  // Perform an up drag with a bit right on the thumb.
  chrome.gpuBenchmarking.smoothDrag(x, y, x + 10, y - 100,
    function() {
      // Should not change slider2's value.
      assert_equals(parseInt(slider2.value), 50);
      // Should not drag the page vertically.
      assert_approx_equals(window.pageYOffset, offsetY, 10);
      // Should not drag the page horizontally.
      assert_approx_equals(window.pageXOffset, offsetX, 10);
      testSlider3V();
      testSlider2.done();
    }, touchSourceType);
});
}

function testSlider3V() {
  var testSlider3V = async_test('Changes value of a vertical slider.');
  testSlider3V.step(function () {
    var offsetX = window.pageXOffset;
    var offsetY = window.pageYOffset;
    var w = slider3.clientWidth;
    var h = slider3.clientHeight;
    var x = slider3.offsetLeft + w / 2 - offsetX;
    var y = slider3.offsetTop + h / 2 - offsetY;
    assert_equals(parseInt(slider3.value), 50);
  // Perform an up drag with a bit left on the thumb.
  chrome.gpuBenchmarking.smoothDrag(x, y, x - h / 2, y - h,
    function() {
      // Should set slider3' value to 100.
      assert_equals(parseInt(slider3.value), 100);
      // Should not drag the page vertically.
      assert_approx_equals(window.pageYOffset, offsetY, 10);
      // Should not drag the page horizontally.
      assert_approx_equals(window.pageXOffset, offsetX, 10);
      testSlider3H();
      testSlider3V.done();
    }, touchSourceType);
});
}

function testSlider3H() {
  var testSlider3H = async_test('Drags left on a vertical slider.');
  testSlider3H.step(function () {
    var offsetX = window.pageXOffset;
    var offsetY = window.pageYOffset;
    var w = slider3.clientWidth;
    var h = slider3.clientHeight;
    var x = slider3.offsetLeft - offsetX;
    var y = slider3.offsetTop - offsetY;
    assert_equals(parseInt(slider3.value), 100);
  // Perform a left drag with a bit down on the thumb.
  chrome.gpuBenchmarking.smoothDrag(x, y, x - 100, slider2.offsetTop + 10,
    function() {
      // Should not change slider3' value.
      assert_equals(parseInt(slider3.value), 100);
      // Should not drag the page vertically.
      assert_approx_equals(window.pageYOffset, offsetY, 10);
      // Should drag the page leftwards.
      assert_approx_equals(window.pageXOffset, offsetX + 85, 10);
      testTouchAction();
      testSlider3H.done();
    }, touchSourceType);
});
}

function testTouchAction() {
  test(() => {
    assert_equals(getComputedStyle(container1).touchAction, 'pan-y');
    assert_equals(getComputedStyle(container2).touchAction, 'pan-y');
    assert_equals(getComputedStyle(container3).touchAction, 'pan-x');
    assert_equals(getComputedStyle(slider2).touchAction, 'none');

    slider1.style='-webkit-appearance: slider-vertical;';
    slider3.style='';
    forceLayoutUpdate();
    assert_equals(getComputedStyle(container1).touchAction, 'pan-x');
    assert_equals(getComputedStyle(container3).touchAction, 'pan-y');
  }, 'Tests that each <input range="type"> has the correct pan-x or pan-y touch-action inside its shadow element: container. This touch-action is under the user-specified touch-action, and will update with the -webkit-appearance.');
}
</script>
