<!--
   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="xookidir"/>
        <attribute name="checkUpToDate"/>
        <![CDATA[
            importClass(java.io.File);

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

          var xookidir = attributes.get("xookidir");
          if (xookidir == null) {
              xookidir = project.getProperty("basedir") + "/xooki";
          }

      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(xookidir+"/xooki.js");
            exec.createArg().setValue(filename);
            exec.createArg().setValue(destFile);
            exec.createArg().setValue("print");
            exec.perform();
          }
        ]]>
    </scriptdef>
</antlib>