//------------------------------------------------------------------------------
// 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.importing.wizards;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.export.wizards.ExportUIPreferences;
import org.eclipse.epf.importing.ImportPlugin;

import com.ibm.icu.util.StringTokenizer;


/**
* Manages the Publishing UI preferences.
* 
* @author Bingxue Xu
* @since 1.0
*/
public class ImportUIPreferences {

	/**
	 * The Publishing UI preference keys.
	 */
	public static final String LAST_IMPORT_PLUGIN_PATH = "lastImportPluginPath"; //$NON-NLS-1$
	
	/**
	 * last import config preference key
	 */
	public static final String LAST_IMPORT_CONFIG_PATH = "lastImportConfigPath"; 


	/**
	 * Returns the last import plugin path that was saved in a previous session.
	 * 
	 * @return The saved last import plugin path as <code>List</code>.
	 */
	public static List getLastImportPluginPaths() {
		List dirs = getPropertyList(LAST_IMPORT_PLUGIN_PATH);
		List result = new ArrayList();
		if (dirs.size() > 0) {
			for (Iterator it = dirs.iterator(); it.hasNext();) {
				String dir = (String) it.next();
				result.add(dir);
			}
		}
		return result;
	}
	
	/**
	 * Returns the last import plugin path that was saved in a previous session.
	 * 
	 * @return The saved last import plugin path as <code>List</code>.
	 */
	public static List getLastImportConfigPaths() {
		List dirs = getPropertyList(LAST_IMPORT_CONFIG_PATH);
		List result = new ArrayList();
		if (dirs.size() > 0) {
			for (Iterator it = dirs.iterator(); it.hasNext();) {
				String dir = (String) it.next();
				result.add(dir);
			}
		}
		return result;
	}

	/**
	 * Add the recently opened method plugin preference.
	 * 
	 * @param dir   import plugin dir
	 */
	public static void addRecentlyImportPluginDir(String dir) {
		if (dir == null || dir.length()==0) {
			return;
		}

		List dirs = getLastImportPluginPaths();

		addProperty(dirs, dir, LAST_IMPORT_PLUGIN_PATH);
	}
	
	/**
	 * Add the recently opened import config preference.
	 * 
	 * @param dir   import config dir
	 */
	public static void addRecentlyImportConfigDir(String dir) {
		if (dir == null || dir.length()==0) {
			return;
		}

		List dirs = getLastImportConfigPaths();

		addProperty(dirs, dir, LAST_IMPORT_CONFIG_PATH);
	}
	
	/**
	 * Add the property to the first position.
	 * 
	 * @param oldPropertyList   old property list
	 * @param newProperty       new property value 
	 * @param propertyKey       target property key
	 */
	private static void addProperty(List oldPropertyList, String newProperty, String propertyKey){
		List dirsResult = new ArrayList();
		
		if(oldPropertyList.contains(newProperty))
			oldPropertyList.remove(newProperty);
		
		dirsResult.add(0, newProperty);
		
		for (int i=0; i<oldPropertyList.size(); i++) {
			String path = (String) oldPropertyList.get(i);
			dirsResult.add(i+1, path);
		}
			
		if(dirsResult.size()>ExportUIPreferences.getListLength())
			dirsResult = dirsResult.subList(0, ExportUIPreferences.getListLength());
			
		setPropertyList(propertyKey, StrUtil.convertListToStrArray(dirsResult));
	}
	
	/**
	 * Returns the string values associated with the named preference as a
	 * <ocde>List</code>.
	 */
	private static List getPropertyList(String name) {
		List list = convertToList(ImportPlugin.getDefault().getPreferenceStore()
				.getString(name));
		int length = ExportUIPreferences.getListLength();
		if(list.size()>length){
			list = list.subList(0, length);
		}
		return list;
	}
	
	/**
	 * Saves the given string values associated with the named preference.
	 */
	private static void setPropertyList(String name, String[] items) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < items.length; i++) {
			buffer.append(items[i]);
			buffer.append(ExportUIPreferences.PREFERENCE_DELIMITER);
		}
		ImportPlugin.getDefault().getPreferenceStore().setValue(name,
				buffer.toString());
	}
	
	/**
	 * Converts the supplied PREFERENCE_DELIMITER delimited string into a
	 * <code>List</code> object.
	 */
	private static ArrayList convertToList(String preferenceValue) {
		ArrayList topics = new ArrayList();
		StringTokenizer tokenizer = new StringTokenizer(preferenceValue,
				ExportUIPreferences.PREFERENCE_DELIMITER);
		int tokenCount = tokenizer.countTokens();
		for (int i = 0; i < tokenCount; i++) {
			topics.add(tokenizer.nextToken());
		}
		return topics;
	}

}
