package Rectangles;

import Rectangles.IFCConstants;

public class Segment implements IFCConstants, Cloneable {
	private Point _start;
	private Point _end;
	private char _direction = _CSTAY;

	public Segment( int x, int y ) throws Exception {
		_start = new Point( x, y );
		_end = new Point( x, y );
	}

	public Segment( Point start ) throws Exception {
		_start = new Point( start.xpos(), start.ypos() );
		_end = new Point( start.xpos(), start.ypos() );
	}

	private Segment( Point start, Point end, char direction ) throws Exception {
		_start = ( Point )start.clone();
		_end = ( Point )end.clone();
		_direction = direction;
	}

	protected Object clone() throws CloneNotSupportedException {
		try {
			return( new Segment( _start, _end, _direction ) );
		}
		catch( Exception e ) {
			throw new CloneNotSupportedException( e.toString() );
		}
	}

	public char direction() {
		return( _direction );
	}

	public void changeDirection( char newDirection ) {
		_direction = newDirection;
	}

	public Point start() {
		return( _start );
	}

	public Point end() {
		return( _end );
	}

	public int length() throws Exception {
		return( _start.distanceTo( _end ) );
	}

	public boolean isHorizontal() {
		return( direction() == _CEAST || direction() == _CWEST );
	}

	public boolean isVertical() {
		return( direction() == _CNORTH || direction() == _CSOUTH );
	}

	public boolean isPoint() {
		return( direction() == _CSTAY );
	}

	public Point closestPoint( Point point ) throws Exception {
		return( closestPoint( point.xpos(), point.ypos() ) );
	}

	public Point closestPoint( int x, int y ) throws Exception {
		switch( direction() ) {
			case _CEAST:
				if( x < _start.xpos() ) {
					return( _start );
				}
				else if( x > _end.xpos() ) {
					return( _end );
				}

				return( new Point( x, _start.ypos() ) );
			case _CWEST:
				if( x > _start.xpos() ) {
					return( _start );
				}
				else if( x < _end.xpos() ) {
					return( _end );
				}

				return( new Point( x, _start.ypos() ) );
			case _CNORTH:
				if( y > _start.ypos() ) {
					return( _start );
				}
				else if( y < _end.ypos() ) {
					return( _end );
				}

				return( new Point( _start.xpos(), y ) );
			case _CSOUTH:
				if( y < _start.ypos() ) {
					return( _start );
				}
				else if( y > _end.ypos() ) {
					return( _end );
				}

				return( new Point( _start.xpos(), y ) );
			default:
		};

		return( _start );
	}

	public int shortestDistanceTo( Point point ) throws Exception {
		return( shortestDistanceTo( point.xpos(), point.ypos() ) );
	}

	public int shortestDistanceTo( int x, int y ) throws Exception {
		return( closestPoint( x, y ).distanceTo( x, y ) );
	}
}
