<!--
   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.    
-->
<antlib>
    <scriptdef name="generate" language="javascript">
        <element name="fileset" type="fileset"/>
        <attribute name="destDir"/>
        <attribute name="checkUpToDate"/>
        <attribute name="printerFriendly"/>
        <![CDATA[
        importClass(java.io.File);

        filesets = elements.get("fileset")
        for (j=0; j<filesets.size(); j++) {
            fs = filesets.get(j);
            srcDir = fs.getDir(project);

            // Get the files (array) of that fileset
            ds = fs.getDirectoryScanner(project);
            srcFiles = ds.getIncludedFiles();

            // iterate over that array
            print('processing '+srcFiles.length+' source files...');
            for (i=0; i<srcFiles.length; i++) {

                // get the values via Java API
                var file = new File(fs.getDir(project), srcFiles[i]);

                var basedir = file.getParent();
                var filename = file.getName();
                var filepath = srcFiles[i].substring(0, srcFiles[i].lastIndexOf(project.getProperty("file.separator"))+1);

                if (attributes.get("checkuptodate") == "true") {
                    p = "xooki."+file.getAbsolutePath().replace(' ','_')+".uptodate";
                    upToDate = project.createTask("uptodate");
                    upToDate.setProperty(p);
                    upToDate.setSrcfile(file);
                    upToDate.setTargetFile(new File(attributes.get("destdir")+"/"+filepath+"/"+filename));
                    upToDate.perform();
                    if (project.getProperty(p) != null) {
                        self.log(srcFiles[i]+" is up to date", 3);
                        continue;
                    }
                }

                exec = project.createTask("exec");
                exec.setDir(new File(basedir));
                exec.setExecutable("jrunscript");
                exec.setTaskName("generate");
                exec.createArg().setValue(srcDir+"/xooki/xooki.js");
                exec.createArg().setValue(filename);
                exec.createArg().setValue(attributes.get("destdir")+"/"+filepath);
                if (attributes.get("printerfriendly") == "true") {
                    exec.createArg().setValue("print");
                }
                exec.perform();
            }
        }
        ]]>
    </scriptdef>
    <scriptdef name="print" language="javascript">
        <attribute name="src"/>
        <attribute name="dest"/>
        <attribute name="checkUpToDate"/>
        <![CDATA[
            importClass(java.io.File);

          var file = new File(attributes.get("src"));
          var destFile = new File(attributes.get("dest"));

      var basedir = file.getParent();
      var filename = file.getName();

      var perform = true;

            if (attributes.get("checkuptodate") == "true") {
                p = "xooki."+file.getAbsolutePath().replace(' ','_')+".uptodate";
                upToDate = project.createTask("uptodate");
                upToDate.setProperty(p);
                upToDate.setSrcfile(file);
                upToDate.setTargetFile(destFile);
                upToDate.perform();
                if (project.getProperty(p) != null) {
                    self.log(file+" is up to date", 3);
                    perform = false;
                }
            }

            if (perform) {
            exec = project.createTask("exec");
            exec.setDir(new File(basedir));
            exec.setExecutable("jrunscript");
            exec.setTaskName("print");
            exec.createArg().setValue(project.getProperty("basedir")+"/xooki/xooki.js");
            exec.createArg().setValue(filename);
            exec.createArg().setValue(destFile);
            exec.createArg().setValue("print");
            exec.perform();
          }
        ]]>
    </scriptdef>
</antlib>