<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=512636
-->
<head>
  <title>Test SVGTransform behavior</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=512636">Mozilla Bug 512636</a>
<p id="display"></p>
<div id="content">

  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="1" id="svg">
    <g id="g" transform="translate(10, 20)"/>
  </svg>

</div>
<pre id="test">
<script class="testbody" type="text/javascript">
<![CDATA[

SimpleTest.waitForExplicitFinish();

function run()
{
  var g, svg, t, m, m2;

  svg = $('svg');
  g = $('g');

  t = g.transform.baseVal.getItem(0);
  m = t.matrix;

  // test that the SVGTransform correctly reflects the translate()
  checkTransform(t, SVGTransform.SVG_TRANSFORM_TRANSLATE,
                 1, 0,
                 0, 1,
                 10, 20,
                 0, "translate");

  // set the SVGTransform to be a scale()
  t.setScale(2, 3);

  // test that the matrix is live and now reflects the scale()
  checkTransform(t, SVGTransform.SVG_TRANSFORM_SCALE,
                 2, 0,
                 0, 3,
                 0, 0,
                 0, "scale");

  // set the SVGTransform to be a matrix()
  m2 = svg.createSVGMatrix();
  m2.a = 1;
  m2.b = 2;
  m2.c = 3;
  m2.d = 4;
  m2.e = 5;
  m2.f = 6;
  t.setMatrix(m2);

  // check that setMatrix() took a copy of m
  ok(m != m2, 't.matrix identity');

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_MATRIX,
                 1, 2,
                 3, 4,
                 5, 6,
                 0, "matrix");

  // set the SVGTransform to be a translate() then convert to a matrix
  t.setTranslate(0, 10);
  m.a = 2;

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_MATRIX,
                 2, 0,
                 0, 1,
                 0, 10,
                 0, "matrix");
                 
  // If ty is not supplied it is assumed to be zero
  g.setAttribute("transform", "translate(5)");                

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_TRANSLATE,
                 1, 0,
                 0, 1,
                 5, 0,
                 0, "transform");

  // set the SVGTransform to be a rotate()
  t.setRotate(90, 0, 0);

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_ROTATE,
                 Math.cos(Math.PI/2), Math.sin(Math.PI/2),
                 -Math.sin(Math.PI/2), Math.cos(Math.PI/2),
                 0, 0,
                 90, "rotate");

  // set the SVGTransform to be a skewX()
  t.setSkewX(45);

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_SKEWX,
                 1, 0,
                 Math.tan(Math.PI/4), Math.tan(Math.PI/4),
                 0, 0,
                 45, "skewX");

  // set the SVGTransform to be a skewY()
  t.setSkewY(45);

  // test that the SVGTransform now reflects the matrix value
  checkTransform(t, SVGTransform.SVG_TRANSFORM_SKEWY,
                 Math.tan(Math.PI/4), Math.tan(Math.PI/4),
                 0, 1,
                 0, 0,
                 45, "skewY");

  // check angle is reset after changing type
  t.setTranslate(10, 20);
  is(t.angle, 0, "Angle not reset after changing to translate type");

  // check read-only properties
  t.angle = 40;
  is(t.angle, 0, "t.angle should be read-only");
  t.type = 7;
  is(t.type, SVGTransform.SVG_TRANSFORM_TRANSLATE,
     "t.type should be read-only");
  t.matrix = m2;
  ok(t.matrix != m2 && t.matrix.b == 0, "t.matrix should be read-only");

  // check transform object identity after manipulation
  ok(t === g.transform.baseVal.getItem(0),
     "Got different transform objects after manipulation");
  ok(t.matrix === m,
     "Got different matrix objects after manipulation");

  testCreateTransform();

  SimpleTest.finish();
}

function testCreateTransform()
{
  svg = $('svg');
  var t = svg.createSVGTransform();
  ok(t != svg.createSVGTransform(),
     "Got identical objects when creating new transform");
  checkTransform(t, SVGTransform.SVG_TRANSFORM_MATRIX,
                 1, 0, 0, 1, 0, 0, 0, "createSVGTransform");

  var m = svg.createSVGMatrix();
  m.a = 1;
  m.b = 2;
  m.c = 3;
  m.d = 4;
  m.e = 5;
  m.f = 6;
  t = svg.createSVGTransformFromMatrix(m);
  ok(t.matrix != m,
     'createSVGTransformFromMatrix should copy matrix not adopt it');
  m.a = 7; // Just to be sure, changing m should not affect t
  checkTransform(t, SVGTransform.SVG_TRANSFORM_MATRIX,
                 1, 2, 3, 4, 5, 6, 0, "createSVGTransformFromMatrix");
}

function checkTransform(transform, type, a, b, c, d, e, f, angle, forWhat)
{
  var m = transform.matrix;
  is(transform.type, type, 'transform.type for ' + forWhat);
  roughlyEqual(m.a, a, 'matrix.a for ' + forWhat);
  roughlyEqual(m.b, b, 'matrix.b for ' + forWhat);
  roughlyEqual(m.c, c, 'matrix.c for ' + forWhat);
  roughlyEqual(m.d, d, 'matrix.d for ' + forWhat);
  roughlyEqual(m.e, e, 'matrix.e for ' + forWhat);
  roughlyEqual(m.f, f, 'matrix.f for ' + forWhat);
  is(transform.angle, angle, 'transform.angle for ' + forWhat);
}

function roughlyEqual(value, expected, msg)
{
  const tolerance = 1 / 65535;
  ok(Math.abs(value - expected) < tolerance,
     msg + ' - got ' + value + ', expected ' + expected);
}

window.addEventListener("load", run, false);

]]>
</script>
</pre>
</body>
</html>