import java.lang.*;
import SpacetimePoint;
import PhysicalObject;

public class ReferenceFrame extends Object
 {
  public String name;
  double x0,t0;       // origin of the frame
  double v;

  public ReferenceFrame()
   {
    this(0,0,0);
   }

  public ReferenceFrame(double x, double t, double v)
   {
    name = new String();
    x0 = x;
    t0 = t;
    this.v = v;
   }

  public ReferenceFrame(SpacetimePoint p, double abs_v)
   {
    this(p.x,p.t,abs_v);
   }

  public ReferenceFrame(PhysicalObject obj)
   {
    this(obj.abs_x(obj.initProperTime), obj.abs_t(obj.initProperTime),
         obj.velocity(obj.initProperTime));
   }

  public void setOrigin(SpacetimePoint p)
   {
    x0 = p.x;
    t0 = p.t;
   }

  public SpacetimePoint origin()
   {
    return new SpacetimePoint(x0,t0);
   }

  public double gamma()
   {
    return 1 / Math.sqrt(1 - v * v);
   }

  public double t(SpacetimePoint p)
   {
    return ((p.t - t0) - v * (p.x - x0)) * gamma();
   }

  public double x(SpacetimePoint p)
   {
    return ((p.x - x0) - v * (p.t - t0)) * gamma();
   }

  public double v(double vel)  // default -> frame velocity conversion
   {
    return (vel - v)/(1 - vel*v);
   }

  public double abs_dt(double dx, double dt)
   {
    return (dt + v*dx) * gamma();
   }

  public double abs_t(double x, double t)
   {
    return t0 + abs_dt(x,t);
   }

  public double abs_dx(double dx, double dt)
   {
    return (dx + v*dt) * gamma();
   }

  public double abs_x(double x, double t)
   {
    return x0 + abs_dx(x,t);
   }

  public SpacetimePoint location(double x, double t)
   {
    return new SpacetimePoint(abs_x(x,t), abs_t(x,t));
   }

  public double abs_v(double vel)
   {
    return (vel + v)/(1 + vel*v);
   }
 }
