/*******************************************************************************
 * Copyright (c) 2010 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.quickoutline;

import java.util.Vector;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.TextProcessor;

/**
 * Default Viewer Filter to be used by the {@link QuickOutlinePopupDialog}
 * <p>
 * Based on {@link org.eclipse.jdt.internal.ui.text.AbstractInformationControl.NamePatternFilter}
 * </p>
 */
public class StringPatternFilter extends ViewerFilter {

	private StringMatcher fStringMatcher;

	/*
	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	public boolean select(Viewer viewer, Object parentElement, Object element) {
		StringMatcher matcher = fStringMatcher;
		if (matcher == null || !(viewer instanceof TreeViewer))
			return true;
		TreeViewer treeViewer = (TreeViewer) viewer;

		String matchName = ((ILabelProvider) treeViewer.getLabelProvider()).getText(element);
		matchName = TextProcessor.deprocess(matchName);
		if (matchName != null && matcher.match(matchName))
			return true;

		return hasUnfilteredChild(treeViewer, element);
	}

	private boolean hasUnfilteredChild(TreeViewer viewer, Object element) {
		Object[] children=  ((ITreeContentProvider) viewer.getContentProvider()).getChildren(element);
		for (int i= 0; i < children.length; i++)
			if (select(viewer, element, children[i]))
				return true;
		return false;
	}

	public void updatePattern(String pattern) {
		if (pattern.length() == 0) {
			fStringMatcher = null;
		}
		else {
			fStringMatcher = new StringMatcher(pattern, pattern.toLowerCase().equals(pattern), false);
		}
		
	}

	public StringMatcher getStringMatcher() {
		return fStringMatcher;
	}

	/**
	 * String matcher based on {@link org.eclipse.ui.internal.misc.StringMatcher}
	 */
	static class StringMatcher {
		protected String fPattern;

	    protected int fLength; // pattern length

	    protected boolean fIgnoreWildCards;

	    protected boolean fIgnoreCase;

	    protected boolean fHasLeadingStar;

	    protected boolean fHasTrailingStar;

	    protected String fSegments[]; //the given pattern is split into * separated segments

	    /* boundary value beyond which we don't need to search in the text */
	    protected int fBound = 0;

	    protected static final char fSingleWildCard = '\u0000';

	    public static class Position {
	        int start; //inclusive

	        int end; //exclusive

	        public Position(int start, int end) {
	            this.start = start;
	            this.end = end;
	        }

	        public int getStart() {
	            return start;
	        }

	        public int getEnd() {
	            return end;
	        }
	    }

	    /**
	     * StringMatcher constructor takes in a String object that is a simple 
	     * pattern which may contain '*' for 0 and many characters and
	     * '?' for exactly one character.  
	     *
	     * Literal '*' and '?' characters must be escaped in the pattern 
	     * e.g., "\*" means literal "*", etc.
	     *
	     * Escaping any other character (including the escape character itself), 
	     * just results in that character in the pattern.
	     * e.g., "\a" means "a" and "\\" means "\"
	     *
	     * If invoking the StringMatcher with string literals in Java, don't forget
	     * escape characters are represented by "\\".
	     *
	     * @param pattern the pattern to match text against
	     * @param ignoreCase if true, case is ignored
	     * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
	     * 		  (everything is taken literally).
	     */
	    public StringMatcher(String pattern, boolean ignoreCase,
	            boolean ignoreWildCards) {
	        if (pattern == null) {
				throw new IllegalArgumentException();
			}
	        fIgnoreCase = ignoreCase;
	        fIgnoreWildCards = ignoreWildCards;
	        fPattern = pattern;
	        fLength = pattern.length();

	        if (fIgnoreWildCards) {
	            parseNoWildCards();
	        } else {
	            parseWildCards();
	        }
	    }

	    /**
	     * Find the first occurrence of the pattern between <code>start</code)(inclusive) 
	     * and <code>end</code>(exclusive).  
	     * @param text the String object to search in 
	     * @param start the starting index of the search range, inclusive
	     * @param end the ending index of the search range, exclusive
	     * @return an <code>StringMatcher.Position</code> object that keeps the starting 
	     * (inclusive) and ending positions (exclusive) of the first occurrence of the 
	     * pattern in the specified range of the text; return null if not found or subtext
	     * is empty (start==end). A pair of zeros is returned if pattern is empty string
	     * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
	     * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
	     */
	    public StringMatcher.Position find(String text, int start, int end) {
	        if (text == null) {
				throw new IllegalArgumentException();
			}

	        int tlen = text.length();
	        if (start < 0) {
				start = 0;
			}
	        if (end > tlen) {
				end = tlen;
			}
	        if (end < 0 || start >= end) {
				return null;
			}
	        if (fLength == 0) {
				return new Position(start, start);
			}
	        if (fIgnoreWildCards) {
	            int x = posIn(text, start, end);
	            if (x < 0) {
					return null;
				}
	            return new Position(x, x + fLength);
	        }

	        int segCount = fSegments.length;
	        if (segCount == 0) {
				return new Position(start, end);
			}

	        int curPos = start;
	        int matchStart = -1;
	        int i;
	        for (i = 0; i < segCount && curPos < end; ++i) {
	            String current = fSegments[i];
	            int nextMatch = regExpPosIn(text, curPos, end, current);
	            if (nextMatch < 0) {
					return null;
				}
	            if (i == 0) {
					matchStart = nextMatch;
				}
	            curPos = nextMatch + current.length();
	        }
	        if (i < segCount) {
				return null;
			}
	        return new Position(matchStart, curPos);
	    }

	    /**
	     * match the given <code>text</code> with the pattern 
	     * @return true if matched otherwise false
	     * @param text a String object 
	     */
	    public boolean match(String text) {
	    	if(text == null) {
				return false;
			}
	        return match(text, 0, text.length());
	    }

	    /**
	     * Given the starting (inclusive) and the ending (exclusive) positions in the   
	     * <code>text</code>, determine if the given substring matches with aPattern  
	     * @return true if the specified portion of the text matches the pattern
	     * @param text a String object that contains the substring to match 
	     * @param start marks the starting position (inclusive) of the substring
	     * @param end marks the ending index (exclusive) of the substring 
	     */
	    public boolean match(String text, int start, int end) {
	        if (null == text) {
				throw new IllegalArgumentException();
			}

	        if (start > end) {
				return false;
			}

	        if (fIgnoreWildCards) {
				return (end - start == fLength)
	                    && fPattern.regionMatches(fIgnoreCase, 0, text, start,
	                            fLength);
			}
	        int segCount = fSegments.length;
	        if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) {
				return true;
			}
	        if (start == end) {
				return fLength == 0;
			}
	        if (fLength == 0) {
				return start == end;
			}

	        int tlen = text.length();
	        if (start < 0) {
				start = 0;
			}
	        if (end > tlen) {
				end = tlen;
			}

	        int tCurPos = start;
	        int bound = end - fBound;
	        if (bound < 0) {
				return false;
			}
	        int i = 0;
	        String current = fSegments[i];
	        int segLength = current.length();

	        /* process first segment */
	        if (!fHasLeadingStar) {
	            if (!regExpRegionMatches(text, start, current, 0, segLength)) {
	                return false;
	            } else {
	                ++i;
	                tCurPos = tCurPos + segLength;
	            }
	        }
	        if ((fSegments.length == 1) && (!fHasLeadingStar)
	                && (!fHasTrailingStar)) {
	            // only one segment to match, no wildcards specified
	            return tCurPos == end;
	        }
	        /* process middle segments */
	        while (i < segCount) {
	            current = fSegments[i];
	            int currentMatch;
	            int k = current.indexOf(fSingleWildCard);
	            if (k < 0) {
	                currentMatch = textPosIn(text, tCurPos, end, current);
	                if (currentMatch < 0) {
						return false;
					}
	            } else {
	                currentMatch = regExpPosIn(text, tCurPos, end, current);
	                if (currentMatch < 0) {
						return false;
					}
	            }
	            tCurPos = currentMatch + current.length();
	            i++;
	        }

	        /* process final segment */
	        if (!fHasTrailingStar && tCurPos != end) {
	            int clen = current.length();
	            return regExpRegionMatches(text, end - clen, current, 0, clen);
	        }
	        return i == segCount;
	    }

	    /**
	     * This method parses the given pattern into segments seperated by wildcard '*' characters.
	     * Since wildcards are not being used in this case, the pattern consists of a single segment.
	     */
	    private void parseNoWildCards() {
	        fSegments = new String[1];
	        fSegments[0] = fPattern;
	        fBound = fLength;
	    }

	    /**
	     * Parses the given pattern into segments seperated by wildcard '*' characters.
	     * @param p, a String object that is a simple regular expression with '*' and/or '?'
	     */
	    private void parseWildCards() {
	        if (fPattern.startsWith("*")) { //$NON-NLS-1$
				fHasLeadingStar = true;
			}
	        if (fPattern.endsWith("*")) {//$NON-NLS-1$
	            /* make sure it's not an escaped wildcard */
	            if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
	                fHasTrailingStar = true;
	            }
	        }

	        Vector temp = new Vector();

	        int pos = 0;
	        StringBuffer buf = new StringBuffer();
	        while (pos < fLength) {
	            char c = fPattern.charAt(pos++);
	            switch (c) {
	            case '\\':
	                if (pos >= fLength) {
	                    buf.append(c);
	                } else {
	                    char next = fPattern.charAt(pos++);
	                    /* if it's an escape sequence */
	                    if (next == '*' || next == '?' || next == '\\') {
	                        buf.append(next);
	                    } else {
	                        /* not an escape sequence, just insert literally */
	                        buf.append(c);
	                        buf.append(next);
	                    }
	                }
	                break;
	            case '*':
	                if (buf.length() > 0) {
	                    /* new segment */
	                    temp.addElement(buf.toString());
	                    fBound += buf.length();
	                    buf.setLength(0);
	                }
	                break;
	            case '?':
	                /* append special character representing single match wildcard */
	                buf.append(fSingleWildCard);
	                break;
	            default:
	                buf.append(c);
	            }
	        }

	        /* add last buffer to segment list */
	        if (buf.length() > 0) {
	            temp.addElement(buf.toString());
	            fBound += buf.length();
	        }

	        fSegments = new String[temp.size()];
	        temp.copyInto(fSegments);
	    }

	    /** 
	     * @param text a string which contains no wildcard
	     * @param start the starting index in the text for search, inclusive
	     * @param end the stopping point of search, exclusive
	     * @return the starting index in the text of the pattern , or -1 if not found 
	     */
	    protected int posIn(String text, int start, int end) {//no wild card in pattern
	        int max = end - fLength;

	        if (!fIgnoreCase) {
	            int i = text.indexOf(fPattern, start);
	            if (i == -1 || i > max) {
					return -1;
				}
	            return i;
	        }

	        for (int i = start; i <= max; ++i) {
	            if (text.regionMatches(true, i, fPattern, 0, fLength)) {
					return i;
				}
	        }

	        return -1;
	    }

	    /** 
	     * @param text a simple regular expression that may only contain '?'(s)
	     * @param start the starting index in the text for search, inclusive
	     * @param end the stopping point of search, exclusive
	     * @param p a simple regular expression that may contains '?'
	     * @return the starting index in the text of the pattern , or -1 if not found 
	     */
	    protected int regExpPosIn(String text, int start, int end, String p) {
	        int plen = p.length();

	        int max = end - plen;
	        for (int i = start; i <= max; ++i) {
	            if (regExpRegionMatches(text, i, p, 0, plen)) {
					return i;
				}
	        }
	        return -1;
	    }

	    /**
	     * 
	     * @return boolean
	     * @param text a String to match
	     * @param start int that indicates the starting index of match, inclusive
	     * @param end</code> int that indicates the ending index of match, exclusive
	     * @param p String,  String, a simple regular expression that may contain '?'
	     * @param ignoreCase boolean indicating wether code>p</code> is case sensitive
	     */
	    protected boolean regExpRegionMatches(String text, int tStart, String p,
	            int pStart, int plen) {
	        while (plen-- > 0) {
	            char tchar = text.charAt(tStart++);
	            char pchar = p.charAt(pStart++);

	            /* process wild cards */
	            if (!fIgnoreWildCards) {
	                /* skip single wild cards */
	                if (pchar == fSingleWildCard) {
	                    continue;
	                }
	            }
	            if (pchar == tchar) {
					continue;
				}
	            if (fIgnoreCase) {
	                if (Character.toUpperCase(tchar) == Character
	                        .toUpperCase(pchar)) {
						continue;
					}
	                // comparing after converting to upper case doesn't handle all cases;
	                // also compare after converting to lower case
	                if (Character.toLowerCase(tchar) == Character
	                        .toLowerCase(pchar)) {
						continue;
					}
	            }
	            return false;
	        }
	        return true;
	    }

	    /** 
	     * @param text the string to match
	     * @param start the starting index in the text for search, inclusive
	     * @param end the stopping point of search, exclusive
	     * @param p a pattern string that has no wildcard
	     * @return the starting index in the text of the pattern , or -1 if not found 
	     */
	    protected int textPosIn(String text, int start, int end, String p) {

	        int plen = p.length();
	        int max = end - plen;

	        if (!fIgnoreCase) {
	            int i = text.indexOf(p, start);
	            if (i == -1 || i > max) {
					return -1;
				}
	            return i;
	        }

	        for (int i = start; i <= max; ++i) {
	            if (text.regionMatches(true, i, p, 0, plen)) {
					return i;
				}
	        }

	        return -1;
	    }
	}
}
