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

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

        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(xookidir + "/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>