<?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.

-->
<!-- ========================================================================= -->
<!-- This test checks that the various RGB values read from the SVGColor       -->
<!-- interface return accurate values.                                         -->
<!--                                                                           -->
<!-- @author vincent.hardy@sun.com                                             -->
<!-- @author shillion@ilog.fr                                                  -->
<!-- @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="450" height="500" viewBox="0 0 450 500"
     onload="runTest(evt)">

  <test:testResult id="testResult" />

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

   function runTest() {
     var result = document.getElementById("testResult");

     var elt = document.getElementById("targetElement");
     result.setAttributeNS(null, "result", "failed");

     if (elt == null){
        result.setAttributeNS(null, "errorCode", "cannot.find.test.element");
        var entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "missing.element.id");
        entry.setAttributeNS(null, "value", "targetElement");
        result.appendChild(entry);
        return;
     }

     var decl = elt.getStyle();

     if (decl == null){
        result.setAttributeNS(null, "errorCode", "getStyle() returned null");
        return;
     }

     var val = decl.getPropertyCSSValue("fill");

     if ( val == null ){
        result.setAttributeNS(null, "errorCode", "CSSStyleDeclaration.getPropertyCSSValue returned null");
        return;
     }

     val = val.getRGBColor()

     if (val.red.cssText != "1"){
        result.setAttributeNS(null, "errorCode", "invalid red component");
        var entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "expected.red");
        entry.setAttributeNS(null, "value", "1");
        result.appendChild(entry);
        entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "found.red");
        entry.setAttributeNS(null, "value", "" + val.red);
        result.appendChild(entry);
        return;
     }

     if (val.green.cssText != "2"){
        result.setAttributeNS(null, "errorCode", "invalid green component");
        var entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "expected.green");
        entry.setAttributeNS(null, "value", "2");
        result.appendChild(entry);
        entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "found.green");
        entry.setAttributeNS(null, "value", "" + val.green);
        result.appendChild(entry);
        return;
     }

     if (val.blue.cssText != "3"){
        result.setAttributeNS(null, "errorCode", "invalid blue component");
        var entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "expected.blue");
        entry.setAttributeNS(null, "value", "3");
        result.appendChild(entry);
        entry = document.createElementNS(testNS, "errorDescriptionEntry");
        entry.setAttributeNS(null, "id", "found.blue");
        entry.setAttributeNS(null, "value", "" + val.blue);
        result.appendChild(entry);
        return;
     }

    result.setAttributeNS(null, "result", "passed");
   }
  ]]></script>

  <g fill="blue">
    <rect x="10%" y="10%" width="80%" height="80%"
          style="opacity:0.5; fill: rgb(1,2,3)" id="targetElement"/>
  </g>
</svg>

