<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">


<!--

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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.

-->
<!-- ========================================================================= -->
<!--                                                                           -->
<!-- @author vincent.hardy@sun.com                                             -->
<!-- @version $Id$          -->
<!-- ========================================================================= -->

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     xmlns:test="http://xml.apache.org/batik/test"
     width="350" height="350" onload="runTest(evt)" >

    <test:testResult id="testResult" result="failed" code="invalid.path.seg.value"/>

    <script type="text/ecmascript"><![CDATA[
   var testNS = "http://xml.apache.org/batik/test";
   var svgNS = "http://www.w3.org/2000/svg";

   function runTest() {
       var result = document.getElementById("testResult");
       var path = document.createElementNS(svgNS, "path");
       var svgPathSegArcRel = path.createSVGPathSegArcRel(1, 2, 3, 4, 5, false, false);
       if (svgPathSegArcRel.getR1() != 3 
           || svgPathSegArcRel.getR2() != 4) {
          return;
       } 

       var svgPathSegArcAbs = path.createSVGPathSegArcAbs(1,2,3,4,5,false,false);
       if (svgPathSegArcAbs.getR1() != 3 
           || svgPathSegArcAbs.getR2() != 4) {
          return;
       }
    
       var p = document.getElementById("path");
       if (p == null) {
           return;
       }

       var psl = p.pathSegList;

       if (psl == null) {
          return;
       }

       if (psl.numberOfItems != 3) {
           result.setAttributeNS(null, "code", "wrong.number.of.path.seg");
           return;
       }

       var ps = psl.getItem(0);
       if (ps == null || ps.pathSegType != 2) {
           result.setAttributeNS(null, "code", "wrong.first.seg.type.0.M.vs." + ps.pathSegType);
           return;
       }

       ps = psl.getItem(1);
       if (ps == null || ps.pathSegType != 10) {
           result.setAttributeNS(null, "code", "wrong.first.seg.type.1.A.vs." + ps.pathSegType);
           return;
       }

       if (ps.r1 != 2 || ps.r2 != 3) {
           result.setAttributeNS(null, "code", "wrong.r1.2.vs." + ps.r1 + " or r2.3.vs." + ps.r2);
           return;
       }

       ps = psl.getItem(2);
       if (ps == null || ps.pathSegType != 1) {
           result.setAttributeNS(null, "code", "wrong.first.seg.type.2.Z.vs." + ps.pathSegType);
           return;
       }

       var t = document.getElementById("text"); 
       t.setAttributeNS(null, "fill", "#0F0");
       result.setAttributeNS(null, "result", "passed");
   }

]]></script>

    <text id="text" x="50%" y="50%" text-anchor="middle" fill="red">This string is red if test failed, green otherwise</text>
    <path d="M 0 0 A 2 3 0 0 0 4 5 Z" id="path"/>
</svg>
