/*******************************************************************************
 * Copyright (c) 2000, 2004 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.jdt.internal.compiler.parser.diagnose;

import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;

public class RangeUtil {
	
	// flags
	public static final int NO_FLAG = 0;
	public static final int LBRACE_MISSING = 1;
	public static final int IGNORE = 2;
	
	static class RangeResult {
		private static final int INITIAL_SIZE = 10;
		int pos;
		int[] intervalStarts;
		int[] intervalEnds;
		int[] intervalFlags;
		
		RangeResult() {
			this.pos = 0;
			this.intervalStarts = new int[INITIAL_SIZE];
			this.intervalEnds = new int[INITIAL_SIZE];
			this.intervalFlags = new int[INITIAL_SIZE];
		}
		
		void addInterval(int start, int end){
			addInterval(start, end, NO_FLAG);
		}
		
		void addInterval(int start, int end, int flags){
			if(pos >= intervalStarts.length) {
				System.arraycopy(intervalStarts, 0, intervalStarts = new int[pos * 2], 0, pos);
				System.arraycopy(intervalEnds, 0, intervalEnds = new int[pos * 2], 0, pos);
				System.arraycopy(intervalFlags, 0, intervalFlags = new int[pos * 2], 0, pos);
			}
			intervalStarts[pos] = start;
			intervalEnds[pos] = end;
			intervalFlags[pos] = flags;
			pos++;
		}
		
		int[][] getRanges() {
			int[] resultStarts = new int[pos];
			int[] resultEnds = new int[pos];
			int[] resultFlags = new int[pos];
			
			System.arraycopy(intervalStarts, 0, resultStarts, 0, pos);
			System.arraycopy(intervalEnds, 0, resultEnds, 0, pos);
			System.arraycopy(intervalFlags, 0, resultFlags, 0, pos);

			if (resultStarts.length > 1) {
				quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1);
			}
			return new int[][]{resultStarts, resultEnds, resultFlags};
		}
		
		private void quickSort(int[] list, int[] list2, int[] list3, int left, int right) {
			int original_left= left;
			int original_right= right;
			int mid= list[(left + right) / 2];
			do {
				while (compare(list[left], mid) < 0) {
					left++;
				}
				while (compare(mid, list[right]) < 0) {
					right--;
				}
				if (left <= right) {
					int tmp= list[left];
					list[left]= list[right];
					list[right]= tmp;
					
					tmp = list2[left];
					list2[left]= list2[right];
					list2[right]= tmp;
					
					tmp = list3[left];
					list3[left]= list3[right];
					list3[right]= tmp;
					
					left++;
					right--;
				}
			} while (left <= right);
			
			if (original_left < right) {
				quickSort(list, list2, list3, original_left, right);
			}
			if (left < original_right) {
				quickSort(list, list2, list3, left, original_right);
			}
		}
		
		private int compare(int i1, int i2) {
			return i1 - i2;
		}
	}
	
	
	
	public static boolean containsErrorInSignature(AbstractMethodDeclaration method){
		return method.sourceEnd + 1 == method.bodyStart	|| method.bodyEnd == method.declarationSourceEnd;
	}

	public static int[][] computeDietRange(TypeDeclaration[] types) {
		if(types == null || types.length == 0) {
			return new int[3][0];
		} else {
			RangeResult result = new RangeResult();
			computeDietRange0(types, result);
			return result.getRanges();
		}
	}
	
	private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) {
		for (int j = 0; j < types.length; j++) {
			//members
			TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes;
			if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) {
				computeDietRange0(types[j].memberTypes, result);
			}
			//methods
			AbstractMethodDeclaration[] methods = types[j].methods;
			if (methods != null) {
				int length = methods.length;
				for (int i = 0; i < length; i++) {
					AbstractMethodDeclaration method = methods[i];
					if(containsIgnoredBody(method)) {
						if(containsErrorInSignature(method)) {
							method.errorInSignature = true;
							result.addInterval(method.declarationSourceStart, method.declarationSourceEnd, IGNORE);
						} else {
							int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG;
							result.addInterval(method.bodyStart, method.bodyEnd, flags);
						}
					}
				}
			}
	
			//initializers
			FieldDeclaration[] fields = types[j].fields;
			if (fields != null) {
				int length = fields.length;
				for (int i = 0; i < length; i++) {
					if (fields[i] instanceof Initializer) {
						Initializer initializer = (Initializer)fields[i];
						if(initializer.declarationSourceEnd == initializer.bodyEnd && initializer.declarationSourceStart != initializer.declarationSourceEnd){
							initializer.errorInSignature = true;
							result.addInterval(initializer.declarationSourceStart, initializer.declarationSourceEnd, IGNORE);
						} else {
							result.addInterval(initializer.bodyStart, initializer.bodyEnd);
						}
					}
				}
			}
		}
	}
	
	public static boolean isInInterval(int start, int end, int[] intervalStart, int[] intervalEnd) {
		int length = intervalStart.length;
		for (int i = 0; i < length; i++) {
			if(intervalStart[i] <= start && intervalEnd[i] >= end) {
				return true;
			} else if(intervalStart[i] > end) {
				return false;
			}
		}
		return false;
	}
	
	public static int getPreviousInterval(int start, int end, int[] intervalStart, int[] intervalEnd) {
		int length = intervalStart.length;
		for (int i = 0; i < length; i++) {
			if(intervalStart[i] > end) {
				return i - 1;
			}
		}
		return length - 1;
	}
	
	public static boolean containsIgnoredBody(AbstractMethodDeclaration method){
		return !method.isDefaultConstructor()
			&& !method.isClinit()
			&& (method.modifiers & CompilerModifiers.AccSemicolonBody) == 0;
	}
}
