/***************************************************************************
                            KStandardDirs.java -  description
                             -------------------
    begin                : Sun Jan 27 16:22:17 2002
    copyright            : (C) 2000-2001 Lost Highway Ltd.
    email                : Richard_Dale@tipitina.demon.co.uk
    generated by         : duke@tipitina on Sun Jan 27 16:22:17 2002, using kalyptus 0.9.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
***************************************************************************/

package org.kde.koala;

import org.kde.qt.*;
import java.util.*;
import java.lang.Error;

/**


 This is one of the most central classes in kdelibs as
 it provides a basic service: It knows where the files
 reside on the user's hard disk. And it's meant to be the
 only one that knows -- to make the real location as
 transparent as possible to both the user and the applications.

 To this end it insulates the application from all information
 and applications always refer to a file with a resource type
 (e.g. icon) and a filename (e.g. khexdit.xpm). In an ideal world
 the application would make no assumption where this file is and
 leave it up to {@link KStandardDirs#findResource}
 to apply this knowledge to return /opt/kde/share/applnk/Home.desktop
 or locate("data", "kgame/background.jpg") to return
 /opt/kde/share/apps/kgame/background.jpg

 The main idea behind KStandardDirs is that there are several
 toplevel prefixes below which the files lie. One of these prefixes is
 the one where the user installed kdelibs, one is where the
 application was installed, and one is $HOME/.kde, but there
 may be even more. Under these prefixes there are several well
 defined suffixes where specific resource types are to be found.
 For example, for the resource type "html" the suffixes could be
 share/doc/HTML and share/doc/kde/HTML.
 So the search algorithm basicly appends to each prefix each registered
 suffix and tries to locate the file there.
 To make the thing even more complex, it's also possible to register
 absolute paths that KStandardDirs looks up after not finding anything
 in the former steps. They can be useful if the user wants to provide
 specific directories that aren't in his $HOME/.kde directory for,
 for example, icons.

 A type that is added by the class {@link KApplication} if you use it, is
 appdata. This one makes the use of the type data a bit easier as it
 appends the name of the application.
 So while you had to {@link #locate} so you can
 also write {@link #locate} if your KApplication instance
 is called "appname". Please note though that you cannot use the "appdata"
 type if you intend to use it in an applet for Kicker because 'appname' would
 be "Kicker" instead of the applet's name. Therefore, for applets, you've got
 to work around this by using {@link #locate}.

 @author Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org>

 @version $Id: KStandardDirs.java,v 1.5.2.1 2002/04/12 12:49:50 rdale Exp $

 @short Site-independent access to standard KDE directories.

*/
public class  KStandardDirs implements QtSupport {
	private long _qt;
	private boolean _allocatedInJavaWorld = true;

	protected KStandardDirs(Class dummy){}

	private native void newKStandardDirs();

/** 
 KStandardDirs constructor. It just initializes the caches.

*/
	public KStandardDirs() {
		newKStandardDirs();
	}

/** 
 KStandardDirs destructor.
	 
*/
	protected native void finalize() throws InternalError;
	public native void dispose();
	public native boolean isDisposed();

/** 
 Adds another search dir to front of the <code>fsstnd</code> list.

*/
	public native void addPrefix( String dir);

/** 
 Adds suffixes for types.

 You may add as many as you need, but it is advised that there
 is exactly one to make writing definite.
 All basic types ({@link kde_default}) are added by {@link #addKDEDefaults},
 but for those you can add more relative paths as well.

 The later a suffix is added, the higher its priority. Note, that the
 suffix should end with / but doesn't have to start with one (as prefixes
 should end with one). So adding a suffix for app_pics would look
 like KGlobal.dirs().addResourceType("app_pics", "share/app/pics");

*/
	public native boolean addResourceType( String type, String relativename);

/** 
 Adds absolute path at the end of the search path for
 particular types (for example in case of icons where
 the user specifies extra paths).

 You shouldn't need this
 function in 99% of all cases besides adding user-given
 paths.

	 
*/
	public native boolean addResourceDir( String type, String absdir);

/** 
 Tries to find a resource in the following order:

 The filename should be a filename relative to the base dir
 for resources. So is a way to get the path to libkdecore.la
 to findResource("lib", "libkdecore.la"). KStandardDirs will
 then look into the subdir lib of all elements of all prefixes
 ($KDEDIRS) for a file libkdecore.la and return the path to
 the first one it finds (e.g. /opt/kde/lib/libkdecore.la)

*/
	public native String findResource( String type, String filename);

/** 
 Returns a number that identifies this version of the resource.
 When a change is made to the resource this number will change.

*/
	public native int calcResourceHash( String type, String filename, boolean deep);

/** 
 Tries to find all directories whose names consist of the
 specified type and a relative path. So would
 findDirs("apps", "Settings") return

 Note that it appends / to the end of the directories,
 so you can use this right away as directory names.

*/
	public native ArrayList findDirs( String type, String reldir);

/** 
 Tries to find the directory the file is in.
 It works the same as {@link #findResource}, but it doesn't
 return the filename but the name of the directory.

 This way the application can access a couple of files
 that have been installed into the same directory without
 having to look for each file.

 findResourceDir("lib", "libkdecore.la") would return the
 path of the subdir libkdecore.la is found first in
 (e.g. /opt/kde/lib/)

*/
	public native String findResourceDir( String type, String filename);

/** 
 Tries to find all resources with the specified type.

 The function will look into all specified directories
 and return all filenames in these directories.

*/
	public native ArrayList findAllResources( String type, String filter, boolean recursive, boolean uniq);

/** 
 Tries to find all resources with the specified type.

 The function will look into all specified directories
 and return all filenames (full and relative paths) in
 these directories.

*/
	public native ArrayList findAllResources( String type, String filter, boolean recursive, boolean uniq, String[] relPaths);

/** 
 This function adds the defaults that are used by the current
 KDE version.

 It's a series of {@link #addResourceTypes}
 and {@link #addPrefix} calls.
 You normally wouldn't call this function because it's called
 for you from {@link KGlobal}.
	 
*/
	public native void addKDEDefaults();

/** 
 Reads customized entries out of the given config object and add
 them via {@link #addResourceDirs}.

*/
	public native boolean addCustomized( KConfig config);

/** 
 This function is used internally by almost all other function as
 it serves and fills the directories cache.

*/
	public native ArrayList resourceDirs( String type);

/** 
 This function will return a list of all the types that KStandardDirs
 supports.

*/
	public native ArrayList allTypes();

/** 
 Finds a location to save files into for the given type
 in the user's home directory.

*/
	public native String saveLocation( String type, String suffix, boolean create);
	public String saveLocation( String type, String suffix) {
		return saveLocation(type, suffix, true);
	}
	public native String saveLocation( String type);

/** 
 Converts an absolute path to a path relative to a certain
 resource.

 If "abs = locate(resource, rel)"
 then "rel = relativeLocation(resource, abs)" and vice versa.

*/
	public native String relativeLocation( String type, String absPath);

/** 

	 
*/
	public native String kfsstnd_prefixes();

/** 

 Don't use this function if you can use locateLocal
	 
*/
	public native String localkdedir();

/** 
 Finds the executable in the system path.

 A valid executable must
 be a file and have its executable bit set.

*/
	public static native String findExe( String appname, String pathstr, boolean ignoreExecBit);
	public static native String findExe( String appname);

/** 
 Finds all occurences of an executable in the system path.

*/
	public static native int findAllExe( String[] list, String appname, String pathstr, boolean ignoreExecBit);
	public static native int findAllExe( String[] list, String appname);

/** 
 Recursively creates still-missing directories in the given path.

 The resulting permissions will depend on the current umask setting.
 permission = mode & ~umask.

*/
	public static native boolean makeDir( String dir, int mode);
	public static native boolean makeDir( String dir);

/** 
 This returns a default relative path for the standard KDE
 resource types. Below is a list of them so you get an idea
 of what this is all about.

*/
	public static native String kde_default( String type);

/** 
 checks for existence and accessability
 faster than creating a QFileInfo first
	 
*/
	public static native boolean exists( String fullPath);
/**
 * On The Usage Of 'locate' and 'locateLocal'
 *
 * Typical KDE applications use resource files in one out of
 * three ways:
 *
 * 1) A resource file is read but is never written. A system
 *    default is supplied but the user can override this
 *    default in his local .kde directory:
 *
 *    // Code example
 *    myFile = locate("appdata", "groups.lst");
 *    myData =  myReadGroups(myFile); // myFile may be null
 *
 * 2) A resource file is read and written. If the user has no
 *    local version of the file the system default is used.
 *    The resource file is always written to the users local
 *    .kde directory.
 *
 *    // Code example
 *    myFile = locate("appdata", "groups.lst")
 *    myData =  myReadGroups(myFile);
 *    ...
 *    doSomething(myData);
 *    ...
 *    myFile = locateLocal("appdata", "groups.lst");
 *    myWriteGroups(myFile, myData);
 *
 * 3) A resource file is read and written. No system default
 *    is used if the user has no local version of the file.
 *    The resource file is always written to the users local
 *    .kde directory.
 *
 *    // Code example
 *    myFile = locateLocal("appdata", "groups.lst");
 *    myData =  myReadGroups(myFile);
 *    ...
 *    doSomething(myData);
 *    ...
 *    myFile = locateLocal("appdata", "groups.lst");
 *    myWriteGroups(myFile, myData);
 **/

/**
 * This function is just for convenience. It simply calls
 * instance.dirs().findResource(type, filename).
 **/
public static String locate( String type, String filename, KInstance instance) {
	return instance.dirs().findResource(type, filename);
}

public static String locate( String type, String filename ) {
	return locate(type, filename, (KInstance) KGlobal.instance());
}

/**
 * This function is much like locate. However it returns a
 * filename suitable for writing to. No check is made if the
 * specified filename actually exists. Missing directories
 * are created. If filename is only a directory, without a
 * specific file, filename must have a trailing slash.
 *
 **/
public static String locateLocal( String type, String filename, KInstance instance) {
    // try to find slashes. If there are some, we have to
    // create the subdir first
    int slash = filename.lastIndexOf('/')+1;
    if (slash == 0) // only one filename
        return instance.dirs().saveLocation(type) + filename;

    // split path from filename
    String dir = filename.substring(0,slash);
    String file = filename.substring(slash);
    return instance.dirs().saveLocation(type, dir) + file;
}

public static String locateLocal( String type, String filename ) {
	return locateLocal(type, filename, (KInstance) KGlobal.instance());
}

}
