package visual.dynamic.sampled;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;


/**
 * An abstract implementation of the Superimposition interface.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public abstract class      AbstractSuperimposition 
                extends    AbstractFrameOp
                implements Superimposition
{
    private int             position;

//[constructor.
    
    /**
     * Explicit Value Constructor
     *
     * @param first     The first frame
     * @param duration  The duration (in frames)
     * @param position  The position
     */
    public AbstractSuperimposition(int first, 
                                   int duration, 
                                   int position)
    {
       super(first, duration);

       this.position = SwingConstants.SOUTH_EAST;
       if ((position == SwingConstants.NORTH)      ||
           (position == SwingConstants.NORTH_EAST) ||
           (position == SwingConstants.EAST)       ||
           (position == SwingConstants.SOUTH_EAST) ||
           (position == SwingConstants.SOUTH)      ||
           (position == SwingConstants.SOUTH_WEST) ||
           (position == SwingConstants.WEST)       ||
           (position == SwingConstants.NORTH_WEST) ||
           (position == SwingConstants.CENTER    )    )
       {
          this.position = position;
       }
    }
//]constructor.
//[calculateRegistrationPoint.

    /**
     * Calculate the registration point for the superimposition
     * based on its size, the frame size, and the desired position
     *
     * @param frameWidth    The width of the frame
     * @param frameHeight   The height of the frame
     * @param siWidth       The width of the superimposition
     * @param siHeight      The height of the superimposition
     */
    protected Point2D calculateRegistrationPoint(double frameWidth, 
                                                 double frameHeight,
                                                 double siWidth,
                                                 double siHeight)
    {
       double         left, top;
      
       top  = 0.0;
       left = 0.0;
       if       (position == SwingConstants.NORTH)
       {
          top  = siHeight;
          left = frameWidth/2.0 - siWidth/2.0;
       }
       else if  (position == SwingConstants.NORTH_EAST)
       {
          top  = siHeight;
          left = frameWidth - siWidth - 1;
       }
       else if  (position == SwingConstants.EAST)
       {
          top  = frameHeight/2.0 - siHeight/2.0;
          left = frameWidth - siWidth - 1;
       }
       else if  (position == SwingConstants.SOUTH_EAST)
       {
          top  = frameHeight - siHeight - 1;
          left = frameWidth - siWidth - 1;
       }
       else if  (position == SwingConstants.SOUTH)
       {
          top  = frameHeight - siHeight - 1;
          left = frameWidth/2.0 - siWidth/2.0;
       }
       else if  (position == SwingConstants.SOUTH_WEST)
       {
          top  = frameHeight - siHeight - 1;
          left = 0.0;
       }
       else if  (position == SwingConstants.WEST)
       {
          top  = frameHeight/2.0 - siHeight/2.0;
          left = 0.0;
       }
       else if  (position == SwingConstants.NORTH_WEST)
       {
          top  = siHeight;
          left = 0.0;
       }
       else if  (position == SwingConstants.CENTER)
       {
          top  = frameHeight/2.0 - siHeight/2.0;
          left = frameWidth/2.0 - siWidth/2.0;
       }

       return new Point2D.Double(left, top);       
    }
//]calculateRegistrationPoint.

    /**
     * Get the position
     * 
     * Possible values: javax.SwingConstants.NORTH, NORTH_EAST,
     * EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NORTH_WEST, or CENTER)
     * 
     * @return     The position
     */
    public int getPosition()
    {
       return position;
    }
    

    /**
     * Apply the post-rendering portion of
     * this Superimposition
     *
     * @param g      The rendering engine
     * @param frame  The current frame number
     */
    public abstract void postRendering(Graphics g, int frame);


    /**
     * Apply the pre-rendering portion of
     * this Superimposition
     *
     * @param g      The rendering engine
     * @param frame  The current frame number
     */
    public abstract void preRendering(Graphics g, int frame);

}
