/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ant.internal.ui.preferences;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.ant.core.AntCorePreferences;
import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.ui.model.AntUtil;

public class ClasspathModel extends AbstractClasspathEntry {
	
	public static final int ANT_HOME= 0;
	public static final int GLOBAL_USER= 1;
	public static final int USER= 2;
	
	private GlobalClasspathEntries antHomeEntry;
	private GlobalClasspathEntries userGlobalEntry;
	
	public Object addEntry(Object entry) {
		if (entry instanceof GlobalClasspathEntries) {
			if (!childEntries.contains(entry)) {
				childEntries.add(entry);
				return entry;
			}
			return null;
		} else {
			ClasspathEntry newEntry= createEntry(entry, null);
			Iterator entries= childEntries.iterator();
			while (entries.hasNext()) {
				Object element = entries.next();
				if (element instanceof GlobalClasspathEntries) {
					if(((GlobalClasspathEntries)element).contains(newEntry)) {
						return null;
					}
				} else if (element.equals(newEntry)) {
					return null;
				}
			}
			childEntries.add(newEntry);
			return newEntry;
		}
	}
	
	public Object addEntry(int entryType, Object entry) {
		IClasspathEntry entryParent= null;
		switch (entryType) {
			case ANT_HOME :
				if (antHomeEntry == null) {
					String name= AntPreferencesMessages.getString("ClasspathModel.2"); //$NON-NLS-1$
					antHomeEntry= createGlobalEntry(new IAntClasspathEntry[0], name, false, true);
				}
				entryParent= antHomeEntry;
				break;
			case GLOBAL_USER :
				if (userGlobalEntry == null) {
					String name= AntPreferencesMessages.getString("ClasspathModel.3"); //$NON-NLS-1$
					userGlobalEntry= createGlobalEntry(new IAntClasspathEntry[0], name, true, true);
				}
				entryParent= userGlobalEntry;
				break;
			default :
				break;
		}
			
		ClasspathEntry newEntry= createEntry(entry, entryParent);
		Iterator entries= childEntries.iterator();
		while (entries.hasNext()) {
			Object element = entries.next();
			if (element instanceof GlobalClasspathEntries) {
				if(((GlobalClasspathEntries)element).contains(newEntry)) {
					return null;
				}
			} else if (element.equals(newEntry)) {
				return null;
			}
		}
		if (entryParent != null) {
			((GlobalClasspathEntries)entryParent).addEntry(newEntry);
		} else {
			childEntries.add(newEntry);
		}
		return newEntry;		
	}
	
	/**
	 * Returns entries of the specified kind, possibly empty.
	 * 
	 * @param entryType kind of entries to retrieve
	 * @return entries of the specified kind, possibly empty
	 */
	public IAntClasspathEntry[] getEntries(int entryType) {
		switch (entryType) {
			case ANT_HOME :
				if (antHomeEntry != null) {
					return antHomeEntry.getEntries();
				}
				break;
			case GLOBAL_USER :
				if (userGlobalEntry != null) {
					return userGlobalEntry.getEntries();
				}
				break;
			case USER : 
				return getUserEntries();
		}
		return new IAntClasspathEntry[0];
	}
	
	public void remove(Object entry) {
		childEntries.remove(entry);
		if (entry == userGlobalEntry) {
			userGlobalEntry= null;
		}
	}
	
	public ClasspathEntry createEntry(Object entry, IClasspathEntry entryParent) {
		if (entryParent == null) {
			entryParent= this;
		} 
		return new ClasspathEntry(entry, entryParent);
	}

	public void removeAll() {
		if (antHomeEntry != null) {
			antHomeEntry.removeAll();
		} 
		if (userGlobalEntry != null) {
			userGlobalEntry.removeAll();
		}
	}
	
	public void removeAll(int entryType) {
		switch (entryType) {
			case ANT_HOME :
				if (antHomeEntry != null) {
					antHomeEntry.removeAll();
				}
				break;
			case GLOBAL_USER :
				if (userGlobalEntry != null) {
					userGlobalEntry.removeAll();
				}
				break;
			default :
				break;
		}
	}
	
	public void removeAll(Object[] entries) {
		
		for (int i = 0; i < entries.length; i++) {
			Object object = entries[i];
			if (object instanceof ClasspathEntry) {
				IClasspathEntry entryParent= ((ClasspathEntry)object).getParent();
				if (entryParent instanceof GlobalClasspathEntries) {
					((GlobalClasspathEntries)entryParent).removeEntry((ClasspathEntry) object);
				} else {
					remove(object);
				}
			} else {
				remove(object);
			}
		}
	}

	public void setAntHomeEntries(IAntClasspathEntry[] entries) {
		if (antHomeEntry == null) {
			String name= AntPreferencesMessages.getString("ClasspathModel.2"); //$NON-NLS-1$
			antHomeEntry= createGlobalEntry(entries, name, false, true);
		} else {
			antHomeEntry.removeAll();
			for (int i = 0; i < entries.length; i++) {
				antHomeEntry.addEntry(new ClasspathEntry(entries[i], antHomeEntry));
			}
		}
	}

	private GlobalClasspathEntries createGlobalEntry(IAntClasspathEntry[] entries, String name, boolean canBeRemoved, boolean addEntry) {
		
		GlobalClasspathEntries global= new GlobalClasspathEntries(name, this, canBeRemoved);
		
		for (int i = 0; i < entries.length; i++) {
			global.addEntry(new ClasspathEntry(entries[i], global));
		}
		
		if (addEntry) {
			addEntry(global);
		}
		return global;
	}

	public void setGlobalEntries(IAntClasspathEntry[] entries) {
		if (userGlobalEntry == null) {
			String name= AntPreferencesMessages.getString("ClasspathModel.3"); //$NON-NLS-1$
			userGlobalEntry= createGlobalEntry(entries, name, true, true);
		} else {
			userGlobalEntry.removeAll();
			for (int i = 0; i < entries.length; i++) {
				userGlobalEntry.addEntry(new ClasspathEntry(entries[i], userGlobalEntry));
			}
		}
	}
	
	private IAntClasspathEntry[] getUserEntries() {
		List userEntries= new ArrayList(childEntries.size());
		Iterator itr= childEntries.iterator();
		while (itr.hasNext()) {
			IClasspathEntry element = (IClasspathEntry) itr.next();
			if (element instanceof GlobalClasspathEntries) {
				continue;
			}
			userEntries.add(element);
		}
		return (IAntClasspathEntry[])userEntries.toArray(new IAntClasspathEntry[userEntries.size()]);
	}
	
	public String serializeClasspath(boolean defaultAntHome) {
		Iterator itr= childEntries.iterator();
		StringBuffer buff= new StringBuffer();
		while (itr.hasNext()) {
			IClasspathEntry element = (IClasspathEntry) itr.next();
			if (element instanceof GlobalClasspathEntries) {
				if (element == antHomeEntry) {
					if (!defaultAntHome || !isSameAsDefaultAntHome()) {
						IAntClasspathEntry[] antHomeEntries= antHomeEntry.getEntries();
						for (int i = 0; i < antHomeEntries.length; i++) {
							IAntClasspathEntry entry = antHomeEntries[i];
							buff.append('?');
							buff.append(entry.toString());
							buff.append(AntUtil.ATTRIBUTE_SEPARATOR);
						}
					} else {
						buff.append(AntUtil.ANT_HOME_CLASSPATH_PLACEHOLDER);
					}
				} else {
					buff.append(AntUtil.ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER);
				}
			} else {
				buff.append(element.toString());
			}
			buff.append(AntUtil.ATTRIBUTE_SEPARATOR);
		}
		if (buff.length() > 0) {
			return buff.substring(0, buff.length() - 1);
		} else {
			return ""; //$NON-NLS-1$
		}
	}
	
	private boolean isSameAsDefaultAntHome() {
		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
		IAntClasspathEntry[] defaultAntHomeEntries= prefs.getAntHomeClasspathEntries();
		IAntClasspathEntry[] antHomeEntries= antHomeEntry.getEntries();
		if (antHomeEntries.length != defaultAntHomeEntries.length) {
			return false;
		}
		
		for (int i = 0; i < antHomeEntries.length; i++) {
			IAntClasspathEntry entry = antHomeEntries[i];
			IAntClasspathEntry defaultEntry= defaultAntHomeEntries[i];
			if (!sameURL(entry, defaultEntry)) {
				return false;
			}
		}
		return true;
	}
	
	private boolean sameURL(IAntClasspathEntry first, IAntClasspathEntry second) {
		if (first == null || second == null) {
			return false;
		}
		File newFile= new File(first.getEntryURL().getFile());
		File existingFile= new File(second.getEntryURL().getFile());
		if (existingFile.equals(newFile)) {
			return true;
		}
		return false;
	}
	
	public ClasspathModel(String serializedClasspath, boolean customAntHome) {
		StringTokenizer tokenizer= new StringTokenizer(serializedClasspath, AntUtil.ATTRIBUTE_SEPARATOR);
		
		while (tokenizer.hasMoreTokens()) {
			String string = tokenizer.nextToken().trim();
			if (string.equals(AntUtil.ANT_HOME_CLASSPATH_PLACEHOLDER)) {
				IAntClasspathEntry[] antHomeEntries= new IAntClasspathEntry[0];
				if (!customAntHome) {
					antHomeEntries= AntCorePlugin.getPlugin().getPreferences().getAntHomeClasspathEntries();
				} 
				setAntHomeEntries(antHomeEntries);
			} else if (string.equals(AntUtil.ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER)) {
				setGlobalEntries(AntCorePlugin.getPlugin().getPreferences().getAdditionalClasspathEntries());
			} else {
				boolean isAntHomeEntry= false;
				Object entry= null;
				if (string.charAt(0) == '*') {
					//old customclasspath
					string= string.substring(1);
				}
				if (string.charAt(0) == '?') {
					//ant home entry
					string= string.substring(1);
					isAntHomeEntry= true;
				}
				try {
					entry=  new URL("file:" + string); //$NON-NLS-1$
				} catch (MalformedURLException e) {
					entry= string;
				}
				if (isAntHomeEntry) {
					addEntry(ANT_HOME, entry);
				} else {
					addEntry(entry);
				}
			}
		}
	}
	
	public ClasspathModel() {
		super();
	}

	/**
	 * @return
	 */
	public Object[] getRemovedGlobalEntries() {
		if (userGlobalEntry == null) {
			String name= AntPreferencesMessages.getString("ClasspathModel.3"); //$NON-NLS-1$
			return new Object[] {createGlobalEntry(new IAntClasspathEntry[0], name, true, false)};
		}
		return new Object[] {};
	}

	/**
	 * @return
	 */
	public Object getAntHomeEntry() {
		return antHomeEntry;
	}
}