/* 
 * Disk.java (Implements Disk Access Simulation using different data seeking algorithms).
 *
 * Written by : Nitin  Motgi (nmotgi@cs.ucf.edu)
 * 
 *
 * ASSUMPTIONS :
 *
 * 1. Request time is always in seconds.
 * 2. The request will be in the order of arrival time.
 *
 * Portions copyright(c) 2001 to School of Electrical Engineering and 
 * Computer Science, UCF, Orlando.                   
 *                                    
 * Use and distribution of this source code are strictly governed by 
 * terms and conditions set by the authors.
 * 
 * $Id : Disk.java, 04/10/2001. $
 *            
 * Revision History:
 *
 * 1. Created basic structure           Nitin,        v1.0.0  04/12/2001.
 * 2. Added Documentation.              Nitin,        v1.0.1  04/12/2001.
*/

import java.io.*;
import java.util.*;

public class Disk 
{
    static int heads;
	static int tracks;
	static int sectors;
	static int RPM;
	static int seekRate;
	static Vector accesses;
	//read system information and disk access from file
	public static void readFile(String filename)
	{
		RandomAccessFile file;
		try
		{
			file=new RandomAccessFile(filename,"r");
			String fileStr;
			String str;
			int ic;
			try
			{
				int startIndex;
				Access acc;
				//read information of heads,tracks,sectors,RPM,seekRate
				//if it contains no ':', it is of wrong format.
				fileStr=file.readLine();
				for(ic=0;ic<5;ic++)
				{
					while(fileStr.length()==0||fileStr.startsWith("//"))
						fileStr=file.readLine();
					if ((startIndex=fileStr.lastIndexOf(":"))==-1)
					{ 
						System.out.println("Wrong file format!");
						System.exit(1);
					}
					else
					{
						str=fileStr.substring(startIndex+1,fileStr.length()).trim();
						if(ic==0)
							heads=Integer.parseInt(str);
						else
						if(ic==1)
							tracks=Integer.parseInt(str);
						else
						if(ic==2)
							sectors=Integer.parseInt(str);
						else
						if(ic==3)
							RPM=Integer.parseInt(str);
						else
							seekRate=Integer.parseInt(str); 
					}
					fileStr=file.readLine();
				}
				//read all memory access
				fileStr=file.readLine();
				while(fileStr!=null)
				{  
					acc=new Access();
					fileStr=fileStr.trim();
					if (!fileStr.startsWith("//")&&fileStr.length()!=0)
					{
						for(ic=0;ic<3;ic++)
						{
							if ((startIndex=fileStr.indexOf(","))==-1)
							{ 
								System.out.println("Wrong file format!");
								System.exit(1);
							}
							else
							{
								str=fileStr.substring(0,startIndex).trim();
								fileStr=fileStr.substring(startIndex+1);
								if(ic==0)
									acc.track=Integer.parseInt(str);
								else
								if(ic==1)
									acc.sector=Integer.parseInt(str);
								else
									acc.head=Integer.parseInt(str);
							}
						}
						acc.requestTime=Float.parseFloat(fileStr.trim());
						accesses.addElement(acc);
					}
					fileStr=file.readLine();                
				}
			}
			catch(IOException exce)
			{
			}
			
			try
			{
				file.close();
			}
			catch(IOException exce)
			{
				System.out.println("Close file unsuccessful");
			}
		}
		catch(FileNotFoundException exce)
		{
			System.out.println("Error encountered during opening file...");
			System.exit(1);
		}
	}
    //main program
	public  static void main(String args[]) 
	{
		boolean debug=false;
		if (args.length!=1&&args.length!=2)
		{
			System.out.println("Usage:java Disk FileName [Debug]");
			System.exit(0);
		}
		if (args.length==2)
			if(!args[1].equalsIgnoreCase("debug"))
			{
				System.out.println("Usage:java Disk FileName [Debug]");
				System.exit(0);
			}
			else
				debug=true;
		accesses=new Vector();
		readFile(args[0]);
		String prompt="Disk parameters:\n";
		prompt+="Number of Heads: "+heads;
		prompt+="\nNumber of Sectors per Track: "+sectors;
		prompt+="\nNumber of Tracks: "+tracks;
		prompt+="\nRPM: "+RPM;
		prompt+="\nSeek rate: "+seekRate+" track per second\n";
		System.out.println(prompt);

		FCFS fcfs=new FCFS(accesses,heads,tracks,sectors,RPM,seekRate,debug);
		fcfs.simulate();
		SSTF sstf=new SSTF(accesses,heads,tracks,sectors,RPM,seekRate,debug);
		sstf.simulate();
		SCAN scan=new SCAN(accesses,heads,tracks,sectors,RPM,seekRate,debug);
		scan.simulate();
		CSCAN cscan=new CSCAN(accesses,heads,tracks,sectors,RPM,seekRate,debug);
		cscan.simulate();             
		CLOOK clook=new CLOOK(accesses,heads,tracks,sectors,RPM,seekRate,debug);
		clook.simulate();
	}
}


