import java.awt.*;
import java.io.*;

/**
 * A train containing one Car.
 
 * You will modify this class.
 */
 
public class Train {

    public final static int FORWARD = 1;
    public final static int STOPPED = 0;
    public final static int BACKWARD = -1;

    // The direction this train is moving.
    private int movingDirection;
   
    // The track this train is running on.
    private Track myTrack;
        
    // The location of this train on its track
    // measured in character locations from the top frame border
    // for trains on north/south tracks or from the left frame border for
    // trains on east/west tracks.
    private int trainLocation;
    
    // The initial direction of movement of this train.
    private int initialDirection;
        
    // Number of cars in this train.
    private int numberOfCars;
    
    // You will change the following code to handle trains
    // of several cars and different railcar types.
    private Car aCar;
    
    // This train's length measured in characters.
    private int trainLength;
    
    // Representation invariant:
    
    // - movingDirection is either FORWARD, BACKWARD or STOPPED.
    // - myTrack is the track this train is on.
    // - trainLocation is between trainLength and TrainFrame.bottomEdge 
    //   for a train on a NS track 
    //   or between trainLength and TrainFrame.rightEdge
    //   for a train on an EW track. 
    // - initialDirection is either FORWARD or BACKWARD.
    // - numberOfCars is greater than 0.
    // - aCar is the Car in this train.
    // - trainLength is numberOfCars * CARLENGTH.

    /**
     * Constructs a new train.
     
     * @param track  Track The track this train is running on.
     */

    public Train(Track track) {
    
        myTrack = track;
        movingDirection = STOPPED;
    }
    

    /**
     * Sets the instance variables for this train from input file data.
     *
     * @param  in  MyStreamTokenizer containing tokens describing
     *         a train.
     * 
     * Tokens are read for the following:
     * Starting location of this train.
     * Starting direction of movement of this train.
     * Number of cars in this train.
     
     * (The complete format of the file is describe in the 
     * TrainSetDriver class file.)
     */
     
    public void addDetails(MyStreamTokenizer in) throws
        IOException {
        
        int tokenType = in.nextToken();
        trainLocation = in.nval.intValue();
        
        tokenType = in.nextToken();
        if (in.sval.equals("forward"))
            initialDirection = FORWARD;
        else 
            initialDirection = BACKWARD;
        
        tokenType = in.nextToken();
        numberOfCars = in.nval.intValue();
        trainLength = numberOfCars * Car.CARLENGTH;

        // You will need to modify the following statements
        // to store trains of several cars and different railcar types.
        // This starter program assumes the number of cars read is 1.
        aCar = new Car(trainLocation, this);
        aCar.addDetails(in);
    }
    

    /**
     * Gets the location of my track.
     
     * @return  The location of my track.
     */
     
     public int getTrackLocation() {
         return myTrack.getLocation();
     }
        

    /**
     * Gets the direction of my track.
     
     * @return  The direction of my track.
     */
     
     public int getTrackDirection() {
         return myTrack.getDirection();
     }


    /**
     * Draws this train.
     *
     * @param  g  the graphics context in which to draw this train.
     */    
     
    public void draw(Graphics g) {
    
        // You will have to modify the following code.
        aCar.draw(g);        
    }
        
    /*
     * Starts this train moving in its initial direction.
     */
     
    public void start() {
        movingDirection = initialDirection;
        // You will have to modify the following code.
        aCar.updateMovementDirection(movingDirection);
        move();
    }
    
    /*
     * Stops this train.
     */
     
    public void stop() {
        movingDirection = STOPPED;
        // You will have to modify the following code.
        aCar.updateMovementDirection(movingDirection);
    }
    
    /*
     * Moves this train along one step.
     * May also change the direction of movement of this train
     * if the train has reached the border of the display.
     */
     
    public void move() {
        if (atBoundary()) {
            // Reverse the movement direction.
            movingDirection = -1 * movingDirection;
            // You will have to modify the following code.
            aCar.updateMovementDirection(movingDirection);
        }
        // You will have to modify the following code.
        aCar.move();
    }
    
    
    /*
     * Checks to see if this train is at the boundary of the screen
     * returning a true value if the train has reached a border.
     
     * @return  Value indicating whether the train has reached 
     * the boundary of the display area.
     */
    public boolean atBoundary() {
    
        // You will need to modify the following to handle trains
        // of multiple cars.
        switch (myTrack.getDirection()) {
        
        case Track.EW:
            return aCar.getLocation() == trainLength || aCar.getLocation() == TrainSetDriver.frame.rightEdge;
        default:
            return aCar.getLocation() == trainLength || aCar.getLocation() == TrainSetDriver.frame.bottomEdge;
        }
    }
                
}
