//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.layout;

import java.io.File;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.LibraryPlugin;

import com.ibm.icu.util.Calendar;


/**
 * a utility class to handle layout related resources.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class LayoutResources {

	private static ResourceBundle resourceBundle;

	private static ResourceBundle shapeiconBundle;

	private static String TEMP_LAYOUT_DIR = ""; //$NON-NLS-1$
	static {
		try {
			String pkg = LayoutResources.class.getPackage().getName();
			String resource = LayoutResources.class.getName();
			resourceBundle = ResourceBundle.getBundle(resource);
			shapeiconBundle = ResourceBundle.getBundle(pkg
					+ ".DefaultShapeicons"); //$NON-NLS-1$

			/*
			 * TEMP_LAYOUT_DIR = getString("temp_layout_dir"); if (
			 * TEMP_LAYOUT_DIR != null ) { TEMP_LAYOUT_DIR =
			 * TEMP_LAYOUT_DIR.replace('/', File.separatorChar); }
			 */

			// Multiple instances of EPF running different libs are sharing the same layout directory
			// use timestamp to identify each instance
			// we need to clean the files when the application exit			
			String userHome = System.getProperty("user.home"); //$NON-NLS-1$
			TEMP_LAYOUT_DIR = userHome + File.separator
					+ "EPF" + File.separator + "layout" + File.separator //$NON-NLS-1$ //$NON-NLS-2$
					+ Long.toHexString(Calendar.getInstance().getTimeInMillis()) + File.separator;
			
			File rupTmpDir = new File(TEMP_LAYOUT_DIR);
			if (!rupTmpDir.exists()) {
				rupTmpDir.mkdirs();
			} else {
				FileUtil.deleteAllFiles(rupTmpDir.getAbsolutePath());
			}

		} catch (MissingResourceException x) {
			x.printStackTrace();
			resourceBundle = null;
		}
	}

	/**
	 * call this when the application exit
	 */
	public static void clear()
	{
		try {
			FileUtil.deleteAllFiles(TEMP_LAYOUT_DIR);
			
			// also delete the folder
			new File(TEMP_LAYOUT_DIR).delete();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * get the default publish path
	 */
	public static String getDefaultPublishDir() {
		return TEMP_LAYOUT_DIR;
	}

	/**
	 * get the xsl uri for the given keys
	 * @param key String
	 * @param secondKey String
	 * @return String
	 */
	public static String getXslUri(String key, String secondKey) {
		String url = getString(resourceBundle, key.toLowerCase());
		if ((url == null) && (secondKey != null)) {
			url = getString(resourceBundle, secondKey.toLowerCase());
		}

		if (url == null) {
			url = getString(resourceBundle, "default"); //$NON-NLS-1$
		}

		if (url != null) {
			// resolve the file
			return LibraryPlugin.getDefault().getLayoutXslPath() + url;
		}

		return ""; //$NON-NLS-1$
	}

	/**
	 * get the default shape icon url
	 * @param key String
	 * @return String
	 */
	public static String getDefaultShapeiconUrl(String key) {
		String url = getString(shapeiconBundle, key);
		if (url == null) {
			url = getString(shapeiconBundle, "general"); //$NON-NLS-1$
		}

		return url;
	}

	private static String getString(ResourceBundle bundle, String key) {
		try {
			return (bundle != null) ? bundle.getString(key) : null;
		} catch (MissingResourceException e) {
			return null;
		}
	}

	/**
	 * get resource string for the key
	 * @param key
	 * @return String
	 */
	public static String getString(String key) {
		return getString(resourceBundle, key);
	}

	/**
	 * copy files from one dir to another
	 * @param fromDir String
	 * @param toDir String
	 */
	public static void copyDir(String fromDir, String toDir) {

		String includes = "*.*, **/css/*.*, **/icons/*.*, **/images/*.*, **/resources/*.*, **/stylesheets/*.*, **/scripts/*.*"; //$NON-NLS-1$
		copyDir(fromDir, toDir, includes, null);
	}

	/**
	 * copy files from one dir to another, with filters
	 * @param fromDir String
	 * @param toDir String
	 * @param includes String
	 * @param excludes String
	 */
	public static void copyDir(String fromDir, String toDir, String includes,
			String excludes) {
		copyDir(new File(fromDir), new File(toDir), includes, excludes);
	}

	/**
	 * copy dir
	 * 
	 * @param fromDir File
	 * @param toDir File
	 * @param includes String
	 * @param excludes String
	 */
	public static void copyDir(File fromDir, File toDir, String includes,
			String excludes)
	{
		copyDir(fromDir, toDir, includes, excludes, false);
	}
	
	/**
	 * copy dir
	 * @param fromDir File
	 * @param toDir File
	 * @param includes String
	 * @param excludes String
	 * @param overwrite boolean true to override existing files
	 */
	public static void copyDir(File fromDir, File toDir, String includes,
			String excludes, boolean overwrite) {
		Copy cp = new Copy();
		cp.setOverwrite(overwrite); // only cpoy new files or newer files
		if (includes != null || excludes != null) {
			FileSet set = new FileSet();
			if (includes != null) {
				set.setIncludes(includes);
			}

			if (excludes != null) {
				set.setExcludes(excludes);
			}

			set.setDir(fromDir);
			cp.addFileset(set);
		}

		cp.setTodir(toDir);
		cp.setProject(new Project());
		cp.execute();

	}

	/**
	 * copy the layout files from the library layout path to the specified
	 * publish folder
	 * 
	 * @param toDir
	 */
	public static void copyLayoutFiles(String toDir) {
		// copy the layout files to the temp folder
		String sourceDir = LibraryPlugin.getDefault().getLayoutPath();
		copyDir(sourceDir, toDir);

		try {
			LibraryPlugin.getDefault().copyLocalizedFiles(
					LibraryPlugin.LAYOUT_SCRIPTS_PATH,
					new File(toDir, LibraryPlugin.LAYOUT_SCRIPTS_FOLDER), true,
					false);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public static void unzip(File zipFile, File toDir) {
		Expand exp = new Expand();
		exp.setOverwrite(true); 
		exp.setSrc(zipFile);
		exp.setDest(toDir);
		exp.setProject(new Project());
		exp.execute();

	}
}
