// (c) MIT 2003.  All rights reserved.

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	WArc.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
// DATE:	Mar 99
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Arc widget
//
// HISTORY:     Mar 99  archon  created
//
////////////////////////////////////////////////////////////////////////////////

package rec.core.widgets;

import java.awt.*;
import rec.util.*;
import rec.geo.*;
import rec.sys.*;

public class WArc extends VisibleWidget
{
  public WArc( Squiggle s )
  {
    setEnglishName( "Arc" );
    int num = s.getNumberOfPoints();

    Assert.check( num >= 3, "need at least 3 points to create an arc" );

    GPoint first = s.getFirstPoint();
    GPoint last = s.getLastPoint();
    GPoint cen = (new GSegment( first, last )).getMidpoint();

    GPoint mid = null;

    if( num % 2 == 0 ) {
      mid = s.getPointAt( num / 2 );
    }
    else {

      GPoint m1 = s.getPointAt( num / 2 );
      GPoint m2 = s.getPointAt( (num / 2) + 1 );

      mid = new GPoint( (m1.x + m2.x) / 2.0, (m1.y + m2.y) / 2.0 );
    }

    // Set the proper major axis.

    double alen = Geometry.distance( cen, first );
    double blen = Geometry.distance( cen, mid );
    double tmp = -1.0;

    if( alen < blen ) {
      tmp = alen;
      alen = blen;
      blen = tmp;
    }

    double angle = Geometry.angle( cen, last );

    if( tmp != -1.0 )
      angle -= Math.PI / 2.0;

    double beginRadians = Math.PI;
    double endRadians = 0.0;

    double a1 = Geometry.angle( cen, first );
    double a2 = Geometry.angle( cen, last );
    double a3 = Geometry.angle( cen, mid );

    if( Radian.isBetween( a1, a2, a3 ) ) {

      if( tmp != -1.0 ) {
	beginRadians = Math.PI * 3.0 / 2.0;
	endRadians = Math.PI / 2.0;
      }
    }
    else {

      if( tmp == -1.0 ) {
	beginRadians = 0.0;
	endRadians = Math.PI;
      }
      else {
	beginRadians = Math.PI / 2.0;
	endRadians = Math.PI * 3.0 / 2.0;
      }
    }

    m_Arc = new GArc( cen, angle, alen, blen, beginRadians, endRadians );
  }

  public WArc( WArc a )
  {
    m_Arc = (GArc)a.m_Arc.copy();
  }

  /////////////////////////////////////////////////////////////////////////////

  public double size()
  {
    return( m_Arc.size() );
  }

  public void resize( double scaleFactor )
  {
    m_Arc.resize( scaleFactor );
  }

  /////////////////////////////////////////////////////////////////////////////

  public void draw( Graphics g )
  {
    m_Arc.display( g );
  }

  /////////////////////////////////////////////////////////////////////////////

  public boolean includes( GPoint gp, double offset )
  {
    return( m_Arc.includes( gp, offset ) );
  }

  public boolean contains( GPoint gp )
  {
    return( m_Arc.contains( gp ) );
  }


  /////////////////////////////////////////////////////////////////////////////

  public void move( GPoint gp )
  {
    m_Arc.translate( getLocation().getCenter(), gp );
  }

  public void translate( GPoint gp )
  {
    m_Arc.translate( gp.x, gp.y );
  }

  public void rotate( GPoint gp, double angle )
  {
    m_Arc.rotate( gp, angle );
  }

  //////////////////////////////////////////////////////////////////////////////

  public Location getLocation()
  {
    return( new Location( m_Arc.getBounds() ) );
  }

  public Rectangle getBounds()
  {
    return( m_Arc.getBounds() );
  }

  /////////////////////////////////////////////////////////////////////////////

  public Object clone()
  {
    return( new WArc( this ) );
  }

  /////////////////////////////////////////////////////////////////////////////

  public GArc getArc( )
  {
    return (GArc)m_Arc.copy();
  }

  /////////////////////////////////////////////////////////////////////////////

  private GArc m_Arc;
}

////////////////////////////////////////////////////////////////////////////////
