<!--
   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>