/*******************************************************************************
 * 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.compare.internal;

import java.text.MessageFormat;
import java.util.StringTokenizer;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.IStatus;


public class CompareFilter {
	private static final char[][] NO_CHAR_CHAR= new char[0][];
	
	private char[][] fExtraResourceFileFilters;
	private String[] fExtraResourceFolderFilters;

	
	public CompareFilter() {
	}

	public boolean filter(String path0, boolean folder, boolean isArchive) {
		if (!folder && fExtraResourceFileFilters != null) {
			char[] name= path0.toCharArray();
			for (int i= 0, l= fExtraResourceFileFilters.length; i < l; i++)
				if (match(fExtraResourceFileFilters[i], name, true))
					return true;
		}
		if (folder && fExtraResourceFolderFilters != null) {
			for (int i= 0, l= fExtraResourceFolderFilters.length; i < l; i++)
				if (fExtraResourceFolderFilters[0].equals(path0))
					return true;
		}
		return false;
	}

	public static String validateResourceFilters(String text) {
		IWorkspace workspace= ResourcesPlugin.getWorkspace();
		String[] filters= getTokens(text, ","); //$NON-NLS-1$
		for (int i= 0; i < filters.length; i++) {
			String fileName= filters[i].replace('*', 'x');
			int resourceType= IResource.FILE;
			int lastCharacter= fileName.length() - 1;
			if (lastCharacter >= 0 && fileName.charAt(lastCharacter) == '/') {
				fileName= fileName.substring(0, lastCharacter);
				resourceType= IResource.FOLDER;
			}
			IStatus status= workspace.validateName(fileName, resourceType);
			if (status.matches(IStatus.ERROR)) {		
				String format= Utilities.getString("ComparePreferencePage.filter.invalidsegment.error"); //$NON-NLS-1$
				return MessageFormat.format(format, new String[] { status.getMessage() } );
			}
		}
		return null;
	}
	
	public void setFilters(String filterSequence) {
		char[][] filters= filterSequence != null && filterSequence.length() > 0
		? splitAndTrimOn(',', filterSequence.toCharArray())
		: null;
		if (filters == null) {
			fExtraResourceFileFilters= null;
			fExtraResourceFolderFilters= null;
		} else {
			int fileCount= 0, folderCount= 0;
			for (int i= 0, l= filters.length; i < l; i++) {
				char[] f= filters[i];
				if (f.length == 0)
					continue;
				if (f[f.length - 1] == '/')
					folderCount++;
				else
					fileCount++;
			}
			fExtraResourceFileFilters= new char[fileCount][];
			fExtraResourceFolderFilters= new String[folderCount];
			for (int i= 0, l= filters.length; i < l; i++) {
				char[] f= filters[i];
				if (f.length == 0)
					continue;
				if (f[f.length - 1] == '/')
					fExtraResourceFolderFilters[--folderCount]= new String(subarray(f, 0, f.length - 1));
				else
					fExtraResourceFileFilters[--fileCount]= f;
			}
		}
	}

	/////////
	
	private static String[] getTokens(String text, String separator) {
		StringTokenizer tok= new StringTokenizer(text, separator); //$NON-NLS-1$
		int nTokens= tok.countTokens();
		String[] res= new String[nTokens];
		for (int i= 0; i < res.length; i++)
			res[i]= tok.nextToken().trim();
		return res;
	}	
	
	/**
	 * Answers true if the pattern matches the given name, false otherwise.
	 * This char[] pattern matching accepts wild-cards '*' and '?'.
	 * 
	 * When not case sensitive, the pattern is assumed to already be
	 * lowercased, the name will be lowercased character per character as
	 * comparing. If name is null, the answer is false. If pattern is null, the
	 * answer is true if name is not null. <br><br>For example:
	 * <ol>
	 * <li>
	 * 
	 * <pre>
	 *  pattern = { '?', 'b', '*' } name = { 'a', 'b', 'c' , 'd' } isCaseSensitive = true result => true
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  pattern = { '?', 'b', '?' } name = { 'a', 'b', 'c' , 'd' } isCaseSensitive = true result => false
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  pattern = { 'b', '*' } name = { 'a', 'b', 'c' , 'd' } isCaseSensitive = true result => false
	 * </pre>
	 * 
	 * 
	 * </li>
	 * </ol>
	 * 
	 * @param pattern
	 *            the given pattern
	 * @param name
	 *            the given name
	 * @param isCaseSensitive
	 *            flag to know whether or not the matching should be case
	 *            sensitive
	 * @return true if the pattern matches the given name, false otherwise
	 */
	private boolean match(char[] pattern, char[] name, boolean isCaseSensitive) {
		if (name == null)
			return false; // null name cannot match
		if (pattern == null)
			return true; // null pattern is equivalent to '*'
		return match(pattern, 0, pattern.length, name, 0, name.length, isCaseSensitive);
	}

	/**
	 * Answers true if the a sub-pattern matches the subpart of the given name,
	 * false otherwise. char[] pattern matching, accepting wild-cards '*' and
	 * '?'. Can match only subset of name/pattern. end positions are
	 * non-inclusive. The subpattern is defined by the patternStart and
	 * pattternEnd positions. When not case sensitive, the pattern is assumed
	 * to already be lowercased, the name will be lowercased character per
	 * character as comparing. <br><br>For example:
	 * <ol>
	 * <li>
	 * 
	 * <pre>
	 *  pattern = { '?', 'b', '*' } patternStart = 1 patternEnd = 3 name = { 'a', 'b', 'c' , 'd' } nameStart = 1 nameEnd = 4 isCaseSensitive = true result => true
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  pattern = { '?', 'b', '*' } patternStart = 1 patternEnd = 2 name = { 'a', 'b', 'c' , 'd' } nameStart = 1 nameEnd = 2 isCaseSensitive = true result => false
	 * </pre>
	 * 
	 * 
	 * </li>
	 * </ol>
	 * 
	 * @param pattern
	 *            the given pattern
	 * @param patternStart
	 *            the given pattern start
	 * @param patternEnd
	 *            the given pattern end
	 * @param name
	 *            the given name
	 * @param nameStart
	 *            the given name start
	 * @param nameEnd
	 *            the given name end
	 * @param isCaseSensitive
	 *            flag to know if the matching should be case sensitive
	 * @return true if the a sub-pattern matches the subpart of the given name,
	 *         false otherwise
	 */
	private boolean match(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd,
			boolean isCaseSensitive) {
		if (name == null)
			return false; // null name cannot match
		if (pattern == null)
			return true; // null pattern is equivalent to '*'
		int iPattern= patternStart;
		int iName= nameStart;
		if (patternEnd < 0)
			patternEnd= pattern.length;
		if (nameEnd < 0)
			nameEnd= name.length;
		/* check first segment */
		char patternChar= 0;
		while ((iPattern < patternEnd) && (patternChar= pattern[iPattern]) != '*') {
			if (iName == nameEnd)
				return false;
			if (patternChar != (isCaseSensitive ? name[iName] : Character.toLowerCase(name[iName])) && patternChar != '?') {
				return false;
			}
			iName++;
			iPattern++;
		}
		/* check sequence of star+segment */
		int segmentStart;
		if (patternChar == '*') {
			segmentStart= ++iPattern; // skip star
		} else {
			segmentStart= 0; // force iName check
		}
		int prefixStart= iName;
		checkSegment : while (iName < nameEnd) {
			if (iPattern == patternEnd) {
				iPattern= segmentStart; // mismatch - restart current segment
				iName= ++prefixStart;
				continue checkSegment;
			}
			/* segment is ending */
			if ((patternChar= pattern[iPattern]) == '*') {
				segmentStart= ++iPattern; // skip start
				if (segmentStart == patternEnd) {
					return true;
				}
				prefixStart= iName;
				continue checkSegment;
			}
			/* check current name character */
			if ((isCaseSensitive ? name[iName] : Character.toLowerCase(name[iName])) != patternChar && patternChar != '?') {
				iPattern= segmentStart; // mismatch - restart current segment
				iName= ++prefixStart;
				continue checkSegment;
			}
			iName++;
			iPattern++;
		}
		return (segmentStart == patternEnd) || (iName == nameEnd && iPattern == patternEnd)
				|| (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
	}

	/**
	 * Return a new array which is the split of the given array using the given
	 * divider and triming each subarray to remove whitespaces equals to ' '.
	 * <br><br>For example:
	 * <ol>
	 * <li>
	 * 
	 * <pre>
	 *  divider = 'b' array = { 'a' , 'b', 'b', 'a', 'b', 'a' } result => { { 'a' }, { }, { 'a' }, { 'a' } }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  divider = 'c' array = { 'a' , 'b', 'b', 'a', 'b', 'a' } result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  divider = 'b' array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' } result => { { 'a' }, { }, { 'a' }, { 'a' } }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  divider = 'c' array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' } result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * </ol>
	 * 
	 * @param divider
	 *            the given divider
	 * @param array
	 *            the given array
	 * @return a new array which is the split of the given array using the
	 *         given divider and triming each subarray to remove whitespaces
	 *         equals to ' '
	 */
	private char[][] splitAndTrimOn(char divider, char[] array) {
		int length= array == null ? 0 : array.length;
		if (length == 0)
			return NO_CHAR_CHAR;
		int wordCount= 1;
		for (int i= 0; i < length; i++)
			if (array[i] == divider)
				wordCount++;
		char[][] split= new char[wordCount][];
		int last= 0, currentWord= 0;
		for (int i= 0; i < length; i++) {
			if (array[i] == divider) {
				int start= last, end= i - 1;
				while (start < i && array[start] == ' ')
					start++;
				while (end > start && array[end] == ' ')
					end--;
				split[currentWord]= new char[end - start + 1];
				System.arraycopy(array, start, split[currentWord++], 0, end - start + 1);
				last= i + 1;
			}
		}
		int start= last, end= length - 1;
		while (start < length && array[start] == ' ')
			start++;
		while (end > start && array[end] == ' ')
			end--;
		split[currentWord]= new char[end - start + 1];
		System.arraycopy(array, start, split[currentWord++], 0, end - start + 1);
		return split;
	}

	/**
	 * Answers a new array which is a copy of the given array starting at the
	 * given start and ending at the given end. The given start is inclusive
	 * and the given end is exclusive. Answers null if start is greater than
	 * end, if start is lower than 0 or if end is greater than the length of
	 * the given array. If end equals -1, it is converted to the array length.
	 * <br><br>For example:
	 * <ol>
	 * <li>
	 * 
	 * <pre>
	 *  array = { 'a' , 'b' } start = 0 end = 1 result => { 'a' }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * <li>
	 * 
	 * <pre>
	 *  array = { 'a', 'b' } start = 0 end = -1 result => { 'a' , 'b' }
	 * </pre>
	 * 
	 * 
	 * </li>
	 * </ol>
	 * 
	 * @param array
	 *            the given array
	 * @param start
	 *            the given starting index
	 * @param end
	 *            the given ending index
	 * @return a new array which is a copy of the given array starting at the
	 *         given start and ending at the given end
	 * @exception NullPointerException
	 *                if the given array is null
	 */
	private char[] subarray(char[] array, int start, int end) {
		if (end == -1)
			end= array.length;
		if (start > end)
			return null;
		if (start < 0)
			return null;
		if (end > array.length)
			return null;
		char[] result= new char[end - start];
		System.arraycopy(array, start, result, 0, end - start);
		return result;
	}
}
