package orc.error;

import java.io.File;
import java.io.Serializable;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 
 * A source location, with file, line, and column information.
 * 
 * @author quark, dkitchin
 *
 */
public class SourceLocation implements Serializable {
	public Integer line;
	public Integer column;
	public Integer endLine;
	public Integer endColumn;
	public File file;
	private Boolean fileFound = false;
	
	public static final SourceLocation UNKNOWN = new SourceLocation(null, 0, 0, 0, 0) {
		public String toString() {
			return "<unknown source location>";
		}
		public boolean isUnknown() {
			return true;
		}
	};
	
	public boolean isUnknown() {
		return false;
	}
	
	/** No-arg constructor so that this can be serialized to XML by JAXB */
	public SourceLocation() {}
	
	public SourceLocation(File filename,
			Integer line, Integer column,
			Integer endLine, Integer endColumn) {
		this.file = filename;
		this.line = line;
		this.column = column;
		this.endLine = endLine;
		this.endColumn = endColumn;
	}
	
	/**
	 * Create a new source location that overlaps both this location
	 * and the argument location. Both locations must be in the same file;
	 * returns UNKNOWN if the filenames are not equal. 
	 */
	public SourceLocation overlap(SourceLocation that) {
		
		if (!this.file.equals(that.file)) {
			return UNKNOWN;
		}
		
		Integer newBeginLine;
		Integer newBeginColumn;
		Integer newEndLine;
		Integer newEndColumn;
	
		// Find the lex order minimum
		if (this.line < that.line) {
			newBeginLine = this.line;
			newBeginColumn = this.column;
		}
		else if (that.line < this.line) {
			newBeginLine = that.line;
			newBeginColumn = that.column;
		}
		else {
			newBeginLine = this.line;
			newBeginColumn = (this.column < that.column ? this.column : that.column);
		}
		
		// Find the lex order maximum
		if (this.line > that.line) {
			newEndLine = this.line;
			newEndColumn = this.column;
		}
		else if (that.line > this.line) {
			newEndLine = that.line;
			newEndColumn = that.column;
		}
		else {
			newEndLine = this.line;
			newEndColumn = (this.column > that.column ? this.column : that.column);
		}
	
		return new SourceLocation(this.file, newBeginLine, newBeginColumn, newEndLine, newEndColumn);
	}
	
	public String toString() {
		FileReader reader;
		String locStr = file + ":" + line + ":" + column + "-" +
		(endLine != line ? endLine + ":" : "") + endColumn;
		try{
			reader = new FileReader(file);
		} catch (FileNotFoundException e){
			return locStr;
		}
		BufferedReader input = new BufferedReader(reader);
		String str = "";
		try{
			for(int i = 0; i < line; i++)
				str = input.readLine();
		} catch (IOException e){
			return locStr;
		}
		
		fileFound = true;
		return locStr + ": "+ str;
	}
	
	/*
	 * returns a string which is the carrot to denote the start of the error on the console.
	 * might return null to denote the file wasn't found.
	 */
	public String getCarrot(){
		
		if(!fileFound)
			return null;
		
		String locStr = file + ":" + line + ":" + column + "-" +
		(endLine != line ? endLine + ":" : "") + endColumn;
		int len = locStr.length();
		len += column;
		String carrotString = "";
		for(int i = 0; i < len; i++){
			carrotString += " ";
		}
		carrotString += " ^";
		return carrotString;
	}
}

@@ -228,16 +228,24 @@
 th file,
+ offset,
  line, a
@@ -359,16 +359,40 @@
 zable %7B%0A
+%09public Integer offset;%0A
 %09public 
@@ -425,24 +425,51 @@
 ger column;%0A
+%09public Integer endOffset;%0A
 %09public Inte
@@ -644,16 +644,22 @@
 0, 0, 0,
+ 0, 0,
  0) %7B%0A%09%09
@@ -984,24 +984,40 @@
 %0A%09%09%09Integer 
+offset, Integer 
 line, Intege
@@ -1033,24 +1033,43 @@
 %0A%09%09%09Integer 
+endOffset, Integer 
 endLine, Int
@@ -1110,16 +1110,40 @@
 lename;%0A
+%09%09this.offset = offset;%0A
 %09%09this.l
@@ -1178,16 +1178,46 @@
 column;%0A
+%09%09this.endOffset = endOffset;%0A
 %09%09this.e
@@ -1591,16 +1591,42 @@
 %0A%09%09%7D%0A%09%09%0A
+%09%09Integer newBeginOffset;%0A
 %09%09Intege
@@ -1667,16 +1667,40 @@
 Column;%0A
+%09%09Integer newEndOffset;%0A
 %09%09Intege
@@ -1737,16 +1737,242 @@
 Column;%0A
+%09%09%0A%09%09// Find minimum begin offset...%0A%09%09newBeginOffset = this.offset %3C that.offset ? this.offset : that.offset;%0A%09%09// ...and maximum end offset%0A%09%09newEndOffset = this.endOffset %3E that.endOffset ? this.endOffset : that.endOffset;%0A
 %09%0A%09%09// F
@@ -2696,16 +2696,32 @@
 is.file,
+ newBeginOffset,
  newBegi
@@ -2742,16 +2742,30 @@
 nColumn,
+ newEndOffset,
  newEndL

Add file offsets to SourceLocation