/*******************************************************************************
 * Copyright (c) 2005, 2007 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
 *
 
 *******************************************************************************/
package org.eclipse.dltk.ruby.core.utils;

import java.util.regex.Pattern;

import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.internal.core.SourceRange;

public class RubySyntaxUtils {
	
	public static final String ARRAY_GET_METHOD = "[]".intern(); //$NON-NLS-1$
	
	public static final String ARRAY_PUT_METHOD = "[]=".intern(); //$NON-NLS-1$
	
	// FIXME Kalugin-WTF get the actual list from Andrey Tarantsov
	private static final String[] operatorMethods = 
		{"[]", "[]=", "**", "!", "~", "+", "-", "*",  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
		"/", "%", "<<", ">>", "&", "^", "|", "<=",  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
		">", "<", ">=", "<=>", "==", "===", "!=", "=~", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
		"+@", "-@"}; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * If position is located inside a operator method, returns full
	 * region correcponding to that operator.
	 * @param contents 
	 * @param pos
	 * @return range, if position is inside op., <code>null</code> if not
	 */
	public static ISourceRange insideMethodOperator (String contents, int pos) {
		for (int i = 0; i < operatorMethods.length; i++) {
			String op = operatorMethods[i];
			int opLength = op.length();
			for (int j = 0; j < opLength; j++) {
				try {
					int start = pos - j;
					int end = pos - j + opLength; 
					String piece = contents.substring(start, end);
					if (!piece.equals(op))
						continue;
					return new SourceRange(start, opLength);
				} catch (IndexOutOfBoundsException e) {
					continue;
				}
			}
		}
		return null;
	}
	
	// FIXME Kalugin-WTF what about ? and !
	// Re: they are specially processed, ?,!,=(yes, you forgot =) is not a name chars
	public static boolean isNameChar (char c) {
		return (Character.isLetterOrDigit(c) || c == '_');
	}
	
	/**
	 * Tries to find name enclosing given position.
	 * See isRubyName method for "name" definion.
	 * @param contents
	 * @param pos
	 * @return
	 */
	public static ISourceRange getEnclosingName (CharSequence contents, int pos) {
		if (pos < 0 || pos >= contents.length())
			return null;
		
		int start = pos - 1;
		int end = pos;
		
		while (start >= 0 && isNameChar(contents.charAt(start)))
			start--;
		if (start > 0) {
			if (contents.charAt(start) == '@') {
				start--;
				if (start > 0 && contents.charAt(start) == '@') 
					start--;
			} else if (contents.charAt(start) == '$')
				start--;			
		}
		
		end = start + 1;
		
		if (end < contents.length() && contents.charAt(end) == '@') {
			end++;
			if (end < contents.length() && contents.charAt(end) == '@') 
				end++;
		} else
			if (end < contents.length() && contents.charAt(end) == '$') 
				end++;
		
		while (end < contents.length() && isNameChar(contents.charAt(end)))
			end++;
		if (end < contents.length()) {
			char c = contents.charAt(end);
			if (c == '?' || c == '!' || c == '='){
				end++;
			} else {
				
			}
			
		}
		
		int actualStart = start + 1;
		int actualEnd = end - 1;
		if (actualStart > actualEnd)
			return null;
		
		return new SourceRange(actualStart, actualEnd - actualStart + 1);
	}
	
	/**
	 * Checks whether given name is an Ruby name. 
	 * It's name if it's operator or matches folling regexp:
	 * <pre>^(@{0,2}|\\$)[_a-zA-Z0-9]+[\\?!=]?$</pre>
	 * @param str
	 * @return
	 */
	public static boolean isRubyName (String str) {
		for (int i = 0; i < operatorMethods.length; i++) {
			if (operatorMethods[i].equals(str))
				return true;
		}				
		return str.matches("^(@{0,2}|\\$)[_a-zA-Z0-9]+[\\?!=]?$"); //$NON-NLS-1$
	}
	
	private static final Pattern RE_METHOD_NAME = Pattern
			.compile("[_a-zA-Z0-9]+[\\?!=]?"); //$NON-NLS-1$

	/**
	 * Checks whether given name is a Ruby method name.
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isRubyMethodName(String str) {
		return RE_METHOD_NAME.matcher(str).matches();
	}

	public static boolean isLessStrictIdentifierCharacter(char ch) {
		return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '@' || ch == '$';
	}
	
	public static boolean isStrictIdentifierCharacter(char ch) {
		return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '@' || ch == '$';
	}
	
	public static boolean isIdentifierCharacter(char ch) {
		return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '?' || ch == '!'
			|| ch == '@' || ch == '$';
	}

	public static int getInclusiveStartOfIdentifierEndingAt(CharSequence document, int inclusiveEndOffset) {
		char ch = document.charAt(inclusiveEndOffset);
		if (!isIdentifierCharacter(ch))
			return -1;
		for (int offset = inclusiveEndOffset - 1; offset >= 0; offset--)
			if (!isIdentifierCharacter(document.charAt(offset)))
				return offset + 1;
		return 0;
	}

	public static boolean isValidRegexpModifier(char ch) {
	    switch (ch) {
	    case 'i':
	    case 'x':
	    case 'm':
	    case 'o':
	    case 'n':
	    case 'e':
	    case 's':
	    case 'u':
	    	return true;
	    default:
	    	return false;
	    }
	}

	public static boolean isValidPercentStringStarter(char ch) {
		switch (ch) {
	    case 'Q':
	    case 'q':
	    case 'W':
	    case 'w':
	    case 'x':
	    case 'r':
	    case 's':
			return true;
		default:
			return false;
		}
	}

	public static char getPercentStringTerminator(char leader) {
		switch (leader) {
		case '(':
			return ')';
		case '[':
			return ']';
		case '{':
			return '}';
		case '<':
			return '>';
		case '!':
		case '@':
		case '#':
		case '$':
		case '%':
		case '^':
		case '&':
		case '*':
		case ')':
		case '-':
		case '_':
		case '=':
		case '+':
		case ']':
		case '}':
		case ';':
		case ':':
		case '\'':
		case '"':
		case '\\':
		case '|':
		case ',':
		case '.':
		case '>':
		case '/':
		case '?':
		case '`':
		case '~':
			return leader;
		default:
			return (char) 0;
		}
	}
	
	public static int skipWhitespaceForward(char[] content, final int offset) {
		return skipWhitespaceForward(content, offset, content.length);
	}
	
	public static int skipWhitespaceForward(char[] content, final int offset, final int end) {
		for (int result = offset; result < end; result++) {
			if (result < 0 || result >= content.length)
				break;
			if (!isWhitespace(content[result]))
				return result;
		}
		return -1;
	}
	
	public static boolean isWhitespace(char ch) {
		switch(ch) {
		case ' ':
		case '\t':
		case '\n':
		case '\r':
			return true;
		default:
			return false;
		}
	}
	
	public static boolean isNonNewLineWhitespace(char ch) {
		switch(ch) {
		case ' ':
		case '\t':
			return true;
		default:
			return false;
		}
	}
	
	public static boolean isRubyOperator(String op) {
		for (int i = 0; i < operatorMethods.length; i++) {
			if (op.equals(operatorMethods[i]))
				return true;
		}
		return false;
	}

	public static boolean isValidConstant(String input) {
		boolean result = input.matches("[A-Z][a-zA-Z0-9_]*"); //$NON-NLS-1$

		return result;
	}

	public static boolean isValidClass(String input) {
		boolean result = false;

		if (input.indexOf("::") != -1) { //$NON-NLS-1$
			String[] tokens = input.split("::"); //$NON-NLS-1$
			for (int cnt = 0, max = tokens.length; cnt < max; cnt++) {
				result = isValidConstant(tokens[cnt]);

				if (result != true) {
					break;
				}
			}
		} else {
			result = isValidConstant(input);
		}

		return result;
	}

}
