//=====================================================================//
// Program by Anna Shleyfman
// CS 8803e -- Geomorph
// Project 1
//=====================================================================//

import java.io.*;
import javax.vecmath.*;

public class LineSegment extends Point2d
{
    private Point2d a;      // 2 points that define line in 2d
    private Point2d b; 
    private double m;       // slope of the line

    //======================================================================
    //                          Constructors
    //======================================================================
    /**
     * Default constructor
     */ 

    public void LineSegment()
    {
	a = new Point2d();
	b = new Point2d();
	//try this
    }
    //======================================================================
    /**
     * @param p1, p2 -- the endpoints of line segment
     */
    public void initSegment( Point2d p1, Point2d p2 )
    {
	a = p1;
	b = p2;
	computeSlope();
    }

    //======================================================================
    //                          Accessors
    //======================================================================

    public Point2d getA()
    {
	return a;
    }

    //======================================================================

    public Point2d getB()
    {
	return b;
    }

    //======================================================================

    public double getSlope()
    {
	return m;
    }

    //======================================================================
    //                          other methods
    //======================================================================

    /** 
     * if m == -2, line is vertical;  if m == 0, line is parallel
     */
    private void computeSlope()
    {
	if( b.x == a.x )
	    m = -2;   // line is vertical
	else
	    m = (b.y - a.y) / (b.x - a.x);
    }// computeSlope

    //======================================================================

    public double getPerpSlope()
    {
	if( m == -2 )
	    return 0;
	if( m == 0 )
	    return -2;

	return ( - 1.0 / m);

    }//getPerpSlope

    //======================================================================

    public Point2d findMidpoint( )
    {
	Point2d mid = new Point2d();
	mid.set( a ); 

	mid.add( b );
	mid.scale( 0.5 );
	return mid;

    }//findMidpoint

    //======================================================================
    /**
     * Returns linesegment that is perpendicular to this
     */
    public LineSegment buildPerpThruCentr()
    {
	LineSegment N = new LineSegment();
	Point2d cntr = findMidpoint();
	Point2d p2 = new Point2d();
	Point2d vector = new Point2d( a.y - b.y, b.x - a.x );

	p2.set( cntr );                     
	p2.add( vector );

	N.initSegment( cntr, p2 );
	return N;
    }//buildPerpThruCentr
    
    //======================================================================

    public String toString()
    {
	 return ("Line Segment ab -- a: " + getA() + 
		 " b: " +  getB() + "\n" + "Slope: " + m );
    }//toString

    //======================================================================

    /**
     * assume that lines are not parallel
     * @return point of intersection of lines through this and L2
     */
    public Point2d findIntersection( LineSegment L2 )
    {
	Point2d a2 = L2.getA();    // endpoints of second line
	double m2 = L2.getSlope();
	double x, y;               // coordinates of intersection point

	//if m == -2, line is vertical;  if m == 0, line is parallel

	if( m2 == -2 ){           //2nd line is verticle
	    x = a2.x;
	    if( m == 0)           // 1st line is horisontal
		y = a.y;
	    else
		y = m * (x - a.x) + a.y;

	}else if( m == -2 ){      //1st line is verticle
	    x = a.x;
	    if( m2 == 0)          // 2nd line is horisontal
		y = a2.y;
	    else
		y = m2 * (x - a2.x) + a2.y;

	}else if( m2 == 0 ){      //2nd line is horisontal
	    y = a2.y;
	    if( m == -2 )         //1st line is verticle
		x = a.x;
	    else
		x = (y - a.y)/m + a.x;

	}else if( m == 0 ){       //1st line is horisontal
	    y = a.y;
	    if( m2 == -2 )        //2nd line is verticle
		x = a2.x;
	    else
		x = (y - a2.y)/m2 + a2.x;
		
	}else{
	    x = (m * a.x - m2 * a2.x + a2.y - a.y) / (m - m2);
	    y = m * (x - a.x) + a.y;
	}

	return (new Point2d( x, y )); 
    }//findIntersection

    //======================================================================

    /**
     * Main is for testing purposes only
     */
    public static void main( String argv[] )
    {
	Point2d p1 = new Point2d(0, 1);
	Point2d p2 = new Point2d(1, 2);
	Point2d p3 = new Point2d(1.5, 0);

	LineSegment N1, N2;
	LineSegment l1 = new LineSegment();
	l1.initSegment( p1, p2 ); 

	LineSegment l2 = new LineSegment();
	l2.initSegment( p2, p3 ); 

	N1 = l1.buildPerpThruCentr();
	System.out.println( "line 1: " + N1 );
	N2 = l2.buildPerpThruCentr();
	System.out.println( "line 2: " + N2 );

	Point2d o = N1.findIntersection( N2 );
	System.out.println( "Point of Intersection: " + o );

	System.out.println( "distance p1 o = " + p1.distance( o ));
	System.out.println( "distance p2 o = " + p2.distance( o ));
	System.out.println( "distance p3 o = " + p3.distance( o ));
    }//main

}// class Line
