package org.expasy.minitools.util;

import javax.swing.ImageIcon;
import java.awt.GridBagConstraints;
import java.awt.Toolkit;
import java.io.*;
import java.net.URL;

/**
 * Title:        FileUtils<br>
 * Description:  <br>
 * Copyright:    Copyright (c) 2003<br>
 * Company:      SIB<br>
 * Date:         24 avr. 2003<br>
 * Time:         13:53:32<br>
 * @author Celine Hernandez (chernand)<br>
 * @version 1.0 <br>
 */


public class FileUtils {

    /**
     * Enforce non-instanciability of this class.
     */
    private FileUtils() {
    }

    //////////////////////////////////////////////////////////////////////////////

    /**
     * Finds an image using different methods to retrieve its location:
     * first
     * <code>java.net.URL url = UIManager.class.getResource("../../images/name.gif");</code>
     * then
     * <code>java.net.URL url = ClassLoader.getSystemClassLoader().getResource("images/name.gif");</code>
     * @param name The name of the image.
     * @return The image found, or null if not found.
     */
    public static ImageIcon findImage(final String name) {
        //Works for locale versions of the application (no jar)
        java.net.URL url = FileUtils.class.getResource("../../../../../../resources/images/"+name);
        if(url==null) {
            //Works in jar files
            url = ClassLoader.getSystemClassLoader().getResource("images/"+name);
        }
        if(url!=null) {
            return new ImageIcon(Toolkit.getDefaultToolkit().getImage(url));
        }
        return null;
    }

    /**
     * Similar to the <code>findImage</code> method, but dedicated to files.
     * This method is not effective when trying to retrieve files in jar archives,
     * as they do not exist any more as "files". In that case, use findFileAsStream instead.
     * Have to replace '%20' in the url by space characters.
     * @param name Name of the file to find.
     * @return The desired file if found, or null.
     */
    public static URL findImagePath(final String name) {
        //Works for locale versions of the application (no jar)
        URL url = FileUtils.class.getResource("../../../../../../resources/images/" + name);
        if (url == null) {
            //Works in jar files
            url = ClassLoader.getSystemClassLoader().getResource("images/" + name);
        }
        return url;
    }

    /**
     * Similar to the <code>findImage</code> method, but dedicated to files.
     * This method is effective when trying to retrieve files between system files AND
     * in jar archives.
     * @param name Name of the file to find.
     * @return The desired file if found, or null.
     */
    private static InputStream findFileAsStreamNotInJar(final String name) {
        InputStream inputStream = FileUtils.class.getResourceAsStream("../../data/"+name);
        if(inputStream==null) {
            inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("data/"+name);
        }
//        System.out.println("inputStream found " + name+" "+inputStream);
        return inputStream;
    }

    /**
     * Similar to the <code>findImage</code> method, but dedicated to files.
     * This method is effective when trying to retrieve files between system files AND
     * in jar archives.
     * @param name Name of the file to find.
     * @return The desired file if found, or null.
     */
    public static InputStream findFileAsStream(final String name) {
        final URL objectURL = findImagePath("OpenDir16.gif");
        final String objectExternalURL = objectURL.toExternalForm();
        if (!objectExternalURL.startsWith("jar:file:")) {
            return findFileAsStreamNotInJar(name);
        }

        String objectPath = objectExternalURL.substring(10);
        final StringBuffer filePath = new StringBuffer(objectPath);
        int index;
        while( (index=filePath.toString().indexOf("%20")) !=-1 ) {
            filePath.replace(index, index+3, " ");
        }
        objectPath = filePath.toString();
        int startJarIndex = objectPath.indexOf("!");
        if (startJarIndex == -1) startJarIndex = objectPath.length();

        objectPath = objectPath.substring(0, startJarIndex);
//        System.out.println("jar file name =" + objectPath);
        startJarIndex = objectPath.lastIndexOf('/');
        objectPath = objectPath.substring(0, startJarIndex);
        startJarIndex = objectPath.lastIndexOf('/');
        objectPath = objectPath.substring(0, startJarIndex + 1)+"data";
//        System.out.println("jar dir=" + objectPath);
        final String pathName = objectPath +File.separatorChar+name;
//        System.out.println("pathName = " + pathName);
        FileInputStream in = null;
        try {
            in = new FileInputStream(new File(pathName));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return new BufferedInputStream(in);
    }

    ////////////////////////////////////////////////////////////////////////////////////
    //

    /**
     * Test is the executed application has been zipped in a jar.
     * @return
     */
    public static boolean isInJar() {
        return findImagePath("OpenDir16.gif").toExternalForm().startsWith("jar:file:");
    }

    /**
     * Extension for aldente project files (*.prj)
     */
    public static final String ALDENTE_PROJECT_EXTENSION = "prj";

    /**
     * Get the extension of a file.
     */
    public static String getExtension(final File f) {
        String ext = null;
        final String s = f.getName();
        final int i = s.lastIndexOf('.');

        if (i > 0 && i < s.length() - 1) {
            ext = s.substring(i + 1).toLowerCase();
        }
        return ext;
    }

    /**
     * Add contraints to the display of an element in a panel using GridBagLayout.
     *
     * @param c The constraints object containing all the informations to use.
     * @param gridx Location on the x-axis (up-left hand corner of the element).
     * @param gridy Location on the y-axis (up-left hand corner of the element).
     * @param gridwidth
     * @param gridheight
     * @param weightx
     * @param weighty
     * @param ipadx
     * @param ipady
     * @param fill
     * @param anchor Place of the element in the case of grid (east, west, north, south, center)
     */
    public static void addConstraints(GridBagConstraints c, int gridx, int gridy,
                                int gridwidth, int gridheight, double weightx, double weighty,
                                int ipadx, int ipady, int fill, int anchor) {
        c.gridx = gridx;
        c.gridy = gridy;
        c.gridwidth = gridwidth;
        c.gridheight = gridheight;
        c.weightx = weightx;
        c.weighty = weighty;
        c.fill = fill;
        c.anchor = anchor;
        c.ipadx = ipadx;
        c.ipady = ipady;
    }
}// End of class FileUtils
