package simulator;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Scanner;

/*
 * AttractionReader.java
 * Created on Feb 3, 2005
 *
 */

/**
 *  AttractionReader - This class is responsible for reading in the rides
 *  from file.
 *  @author Ping
 *
 */
public class AttractionReader
{
	// This is used to count the number of attractions in the file,
	// for such uses as iterations in other classes.
    public static int numAttractions;
	
	/**
     * @param fileName
     */
    public AttractionReader()
    {      
    	numAttractions = 0;
    }
    
    /**
     * This function reads in all the attractions from the file specified.
     * 
     * @param fileName The name of the file that contains the rides
     * @return A collection of all the attractions read in.  It will be 
     * empty if the file is empty and contian as many rides as it read in
     * if an error occurs half way.
     */
    public Collection<Attraction> readAttractions(String fileName) throws FileNotFoundException
    {
        DataReader reader = new DataReader(fileName);
        ArrayList<Attraction> attractions = new ArrayList<Attraction>();
        
        Scanner scanner;
        try
        {
            String dataLine = reader.readDataLine();
            // while there are more lines to read
            while(dataLine != null)
            {
                // Read in each ride
                
                // first line is the ride name
                String rideName = dataLine.trim();
                
                // read the entrance location in
                dataLine = reader.readDataLine();
                scanner = new Scanner(dataLine);
                float entranceX = scanner.nextFloat();
                float entranceY = scanner.nextFloat();
                
                // read the exit location in
                dataLine = reader.readDataLine();
                scanner = new Scanner(dataLine);
                float exitX = scanner.nextFloat();
                float exitY = scanner.nextFloat();
                
                // read in the information about the cars
                dataLine = reader.readDataLine();
                scanner = new Scanner(dataLine);
                int numOfCars = scanner.nextInt();
                int maxNumOfCars = scanner.nextInt();
                int carCapacity = scanner.nextInt();
                
                // read in the information about ride type
                dataLine = reader.readDataLine();
                scanner = new Scanner(dataLine);
                String rideType = dataLine.trim();
                
                // read in the information about ride type
                dataLine = reader.readDataLine();
                scanner = new Scanner(dataLine);
                
                int rideTime = scanner.nextInt();
                int loadTime = 0;
                if(rideType.equalsIgnoreCase(CycleRide.ATTRACTION_TYPE) ||
                   rideType.equalsIgnoreCase(IntervalRide.ATTRACTION_TYPE))
                {
                    loadTime = scanner.nextInt();
                }
                
                Attraction ride = attractionFactory(rideName, entranceX, 
                        entranceY, exitX, exitY, numOfCars, maxNumOfCars, 
                        carCapacity, rideType, rideTime, loadTime);
                
                // add the ride to the list of attractions
                attractions.add(ride);
                // add one for this ride to the number of attractions counter
                numAttractions++;
                
                // read in the next line to see if there are more
                // if the file is empty, then the dataLine will be null
                dataLine = reader.readDataLine();
            }
            
        }
        catch(AttractionReadException e)
        {
            System.err.println("Unable to read in attractions from " + fileName);
            e.printStackTrace();
        }
        return attractions;
    }

    /**
     * This function is a factory for the attractions.  It takes in all
     * the necessary information and creates an instance of the appropriate
     * attraction type.
     * 
     * @param rideName
     * @param entranceX
     * @param entranceY
     * @param exitX
     * @param exitY
     * @param numOfCars
     * @param maxNumOfCars
     * @param carCapacity
     * @param rideType
     * @param rideTime
     * @param loadTime
     * @return
     * @throws AttractionReadException
     */
    protected Attraction attractionFactory(String rideName, 
            float entranceX, float entranceY, float exitX, 
            float exitY, int numOfCars, int maxNumOfCars, int carCapacity,
            String rideType, int rideTime, int loadTime) 
        throws AttractionReadException
    {
        // now create the attraction and add it
        Attraction ride = null;
        if(rideType.equalsIgnoreCase(CycleRide.ATTRACTION_TYPE))
        {
            ride = new CycleRide(rideName, 
                    new Location(entranceX, entranceY),
                    new Location(exitX, exitY), numOfCars,
                    maxNumOfCars, carCapacity, rideTime, loadTime);
        }
        else if(rideType.equalsIgnoreCase(IntervalRide.ATTRACTION_TYPE))
        {
            ride = new IntervalRide(rideName, 
                    new Location(entranceX, entranceY),
                    new Location(exitX, exitY), numOfCars,
                    maxNumOfCars, carCapacity, rideTime, loadTime);
        }
        else if(rideType.equalsIgnoreCase(
                ContinuousRide.ATTRACTION_TYPE))
        {
            ride = new ContinuousRide(rideName, 
                    new Location(entranceX, entranceY),
                    new Location(exitX, exitY), numOfCars,
                    maxNumOfCars, carCapacity, rideTime);
        }
        else
        {
            throw new AttractionReadException("Read in unknown attraction type: " +
                    rideType);
        }
        return ride;
    }
}
