import java.awt.Color;
import java.awt.Graphics;

/** Represents a single vertical surface in the world. Every
 * surface in the world is essentially a right prism - that is,
 * the product of extending a two-dimensional shape up and down
 * the vertical dimension. */
public interface Surface {
	/** Returns the ray normal to the surface at the given
	 * coordinates. The parameter coordinates are assumed to
	 * represent a point on the surface. The returned ray
	 * should be based on the given coordinates, and its
	 * direction should be perpendicular to the tangent of the
	 * surface at this point. The returned direction can be
	 * either of the possible perpendicular unit directions
	 * (which are negations of each other).
	 *
	 * @param x the x-coordinate of the point in question.
	 * @param y the y-coordinate of the point in question.
	 * @return the ray normal to the surface at the
	 * requested point.
	 */
	public Ray getNormal(double x, double y);

	/** Returns the ``distance'' at which the surface is
	 * located along the given ray, or
	 * <code>Double.POSITIVE_INFINITY</code> if in fact the
	 * ray doesn't intersect the surface at all.
	 * The ray will start from some point
	 * (<var>x</var>,<var>y</var>) and have some direction
	 * (<var>dx</var>,<var>dy</var>).
	 * If the returned value <var>d</var> is finite, it should be
	 * a positive value for which
	 * (<var>x</var> + <var>d</var> * <var>dx</var>,
	 * <var>y</var> + <var>d</var> * <var>dy</var>)
	 * lies on this surface.
	 *
	 * @param ray the ray to look along in determining the
	 * distance.
	 * @return a positive number if the ray intersects with
	 * this surface, or <code>Double.POSITIVE_INFINITY</code>
	 * if it does not.
	 */
	public double getDistanceFrom(Ray ray);

	/** Returns the column of texture that appears on this
	 * surface at the given point. At the given coordinates is
	 * a vertical strip of this vertical surface, and the
	 * returned TextureColumn contains information about how to
	 * draw that vertical strip. The given coordinates are
	 * assumed to lie on this surface.
	 *
	 * @param x the x-coordinate of the point on the surface.
	 * @param y the y-coordinate of the point on the surface.
	 * @return a TextureColumn containing information about how
	 * to draw the vertical strip of the surface at this
	 * location.
	 */
	public TextureColumn getTextureColumn(double x, double y);

	/** Returns a bounding box describing the range of x- and
	 * y-coordinates occupied by the surface.
	 *
	 * @return the bounding box
	 **/
	public Bounds getBounds();
	
	/** Draws an overhead view of this surface. This will
	 * involve mapping the surface's actual coordinates to the
	 * drawing space's coordinates. The mapping is described by
	 * the <code>sx</code> and <code>sy</code> scaling factors
	 * and the <code>dx</code> and <code>dy</code> offsets. For
	 * example, an x-coordinate of <var>x</var> will map to
	 * the pixel at <code>dx</code> + <code>sx</code> * <var>x</var>.
	 *
	 * @param g the Graphics object with which to draw.
	 * @param dx the x-coordinate offset for drawing space.
	 * @param dy the y-coordinate offset for drawing space.
	 * @param sx the x-coordinate scaling factor for mapping from
	 * world space to drawing space.
	 * @param sy the y-coordinate scaling factor from mapping from
	 * world space to drawing space.
	 */
	public void draw(Graphics g, double dx, double dy, double sx, double sy);
}
