package org.gimp.jgimp.ant;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import java.io.*;
import java.util.*;

/**
 * Custom ant task to build a constants file for the C-portion of
 * JGimp. Nothing to see here... keep moving on...
 */
public class JGimpCConstantsTask extends Task {
    private final static String CONSTANTS_FILE_NAME = "../jgimp_constants.h";
    private final static String HEADER_FILE_NAME = "./org/gimp/jgimp/ant/constants_header.h";
    private final static String FOOTER_FILE_NAME = "./org/gimp/jgimp/ant/constants_footer.h";

    public void execute() throws BuildException {
        try {
            File baseDir = new File("./org/gimp/jgimp/");
            File[] classNames = getClassNames(baseDir, null);
            int maxWordLength = 0;
            for (int i = 0; i < classNames.length; i++) {
                File thisFile = classNames[i];
                String constantName = convertToConstantDef(thisFile.getName());
                maxWordLength = Math.max(constantName.length(), maxWordLength);
            }

            String newLine = System.getProperty("line.separator");
            StringBuffer fileContents = new StringBuffer();
            fileContents.append("/* JGimp classes */" + newLine);
            for (int i = 0; i < classNames.length; i++) {
                File thisFile = classNames[i];
                String constantName = convertToConstantDef(thisFile.getName());
                String jniStringRef = convertToJNIStringRef(thisFile);
                fileContents.append("#define " + constantName + " ");
                for (int j = 0; j < (maxWordLength - constantName.length()); j++) {
                    fileContents.append(" ");
                }
                fileContents.append(jniStringRef + newLine);
            }

            FileInputStream headerFile = new FileInputStream(HEADER_FILE_NAME);
            FileInputStream footerFile = new FileInputStream(FOOTER_FILE_NAME);
            FileOutputStream os = new FileOutputStream(CONSTANTS_FILE_NAME);
            byte[] buffer = new byte[1024];
            int amountRead = 0;
            while ((amountRead = headerFile.read(buffer)) > 0) {
                os.write(buffer, 0, amountRead);
            }
            os.write(fileContents.toString().getBytes());
            while ((amountRead = footerFile.read(buffer)) > 0) {
                os.write(buffer, 0, amountRead);
            }
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BuildException(e);
        }
    }
    private File[] getClassNames(File directory, Vector searchedDirectories) throws BuildException {
        if (searchedDirectories == null) {
            searchedDirectories = new Vector();
        }
        if (searchedDirectories.contains(directory)) {
            return new File[0];
        }
        searchedDirectories.add(directory);
        Vector theseFiles = new Vector();
        try {
            File[] files = directory.listFiles();
            for (int i = 0; i < files.length; i++) {
                File thisFile = files[i];
                if (thisFile.isDirectory()) {
                    if (thisFile.getName().equals("CVS")) {
                        continue;
                    }
                    File[] results = getClassNames(thisFile, searchedDirectories);
                    for (int j = 0; j < results.length; j++) {
                        theseFiles.add(results[j]);
                    }
                } else {
                    if (thisFile.getName().endsWith(".java")) {
                        theseFiles.add(thisFile);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BuildException(e);
        }
        return (File[])theseFiles.toArray(new File[0]);
    }

    private static String convertToConstantDef(String fileName) {
        StringBuffer finalFileName = new StringBuffer();
        fileName = fileName.substring(0, fileName.indexOf(".java"));
        fileName = fileName.replaceAll("PDB", "Pdb");
        for (int i = 0; i < fileName.length(); i++) {
            if (i < 2) {
                finalFileName.append(Character.toUpperCase(fileName.charAt(i)));
            } else {
                char thisChar = fileName.charAt(i);
                if (Character.isUpperCase(thisChar)) {
                    finalFileName.append("_");
                }
                finalFileName.append(Character.toUpperCase(thisChar));
            }
        }
        finalFileName.append("_CLASS");
        return finalFileName.toString();
    }

    private static String convertToJNIStringRef(File file) throws IOException {
        String fileSeparator = System.getProperty("file.separator");
        String name = file.getCanonicalPath();
        name = name.replace(fileSeparator.charAt(0), '/');
        name = name.substring(0, name.indexOf(".java"));
        name = name.substring(name.lastIndexOf("org/gimp/jgimp"));
        return "\"" + name + "\"";
    }

    public static void main(String[] args) {
        Task t = new JGimpCConstantsTask();
        try {
            t.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
