
import java.util.*;
import java.awt.Color;
import java.lang.*; 

public class Exon implements Comparable
{
	private int start_;
	private int end_;
	//private boolean overlaps_ = false;
	private static final Color HIGHLIGHT_COLOR = Color.red;

	private static final int LEFT_ = 0;
	private static final int RIGHT_ = 1;
	
	private int lastNearest_;
	private int lastNewEnd_=0;
	private boolean lastDir_=false;
	private boolean lastWithinExon_ = false;
	
	private String name_;
	
	private boolean dupl_=false;
	private boolean isCurrent_=false;


	
	public Exon (int start, int end)
	{
		if (start<end)
		{
			start_ = start;
			end_ = end;
		}
		else
		{
			start_ = end;
			end_ = start;
		}
	}

	public int compareTo(Object o)
	{
		Exon exon = (Exon)o;
		int res=0;
		if (exon.getEnd()<getEnd()) return -1;
		if (exon.getEnd()>getEnd()) return 1;
		return res;
	}
	
	public void expand(int start, int end)
	{
		if (start_>start) 
		start_=start;
		if (end_<end)
		end_=end;
	}
	
	public int getStart()
	{
		return start_;
	}
	
	public int getEnd()
	{
		return end_;
	}
/*	
	public boolean intervalOverlapsExon(int start, int end)
	{				
		if (withinExon(start)||withinExon(end))
		{
			overlaps_ = true;
		}
		else
		{
			overlaps_ = false;
		}
		return overlaps_;
	}
*/
	public boolean isCurrent(int point)
	{
		if (withinExon(point)) isCurrent_=true;
		else isCurrent_=false;
		return isCurrent_;
	}

	public void setCurrent(int point)
	{
		if (withinExon(point)) isCurrent_=true;
	}

	public boolean isDuplicate()
	{
		return dupl_;
	}
	
	public void setDuplicate()
	{
		dupl_ = true;
	}

	public boolean getStatus()
	{
		return lastWithinExon_;
	}
	
	public void setStatus(int point)
	{
		lastWithinExon_ = withinExon(point);
	}
	
	public boolean intervalOverlapsExon(int point)
	{				
		if (withinExon(point)||lastWithinExon_)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	private boolean getDirection(int newStart, int newEnd)
	{
		if (lastNewEnd_==0)
		{
			lastNewEnd_ = newStart;
		}

		if ((newEnd-lastNewEnd_)<0)
		{
			lastDir_ = false;
		}
		
		if ((newEnd-lastNewEnd_)>0)
		{
			lastDir_ = true;
		}
		
		lastNewEnd_ = newEnd;
		return lastDir_;
	}
	
	public String getName()
	{
		return name_;
	}

	public void modifyExon(int newStart, int newEnd)
	{
		boolean direction = getDirection(newStart, newEnd);
		
		//System.out.println("modifyExon: "+name_+" lastWithinExon_ = "+lastWithinExon_);
		
		// Which end of Exon?
		
		if ((getSide(newEnd)==LEFT_)&&lastWithinExon_)
		{
			//System.out.println("On the left");
			// Reduce Exon length?
			if (direction)
			{
				if (start_<newEnd)
				{
					start_=newEnd;
				}
			}
			// Increase Exon length
			if (!direction)
			{
				if (start_>newEnd)
				{
					start_=newEnd;
				}
			}
		}
		
		if ((getSide(newEnd)==RIGHT_)&&lastWithinExon_)
		{
			//System.out.println("On the right");
			// Reduce Exon length?
			if (!direction)
			{
				if (end_>newEnd)
				{
					end_=newEnd;
				}
			}
			// Increase Exon length?
			if (direction)
			{
				if (end_<newEnd)
				{
					end_=newEnd;
				}
			}
		}
		lastWithinExon_ = withinExon(newEnd);
		
	}
	
	private int getSide(int newEnd)
	{
		int p1 = Math.abs(newEnd-start_);
		int p2 = Math.abs(newEnd-end_);
		if (p1<p2)
		{
			lastNearest_ = LEFT_;
		}
		if (p2<p1)
		{
			lastNearest_ = RIGHT_;
		}
		return lastNearest_;
	}
	
	public void setName(String name)
	{
		name_ = name;
	}
	
	public void setCurrent()
	{
		lastWithinExon_ = true;
	}

	public boolean withinExon(int point)
	{
		//System.out.println("WithinExon: start_ = "+start_+" end_ = "+end_+" point = "+point);
		if ((start_ < point)&&(point < end_))
		{
			return true;
		}
		if (atEndPoints(point))
		{
			return true;
		}
		return false;
	}
	
	private boolean atEndPoints(int point)
	{
		//System.out.println("atEndPoints point="+point+" end_="+end_);
		if ((point==start_)||(point==end_))
		{
			return true;
		}
		return false;
	}
	
	public static void main(String[] args) {
	// test suite
	
	}
}

