package ga050426;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;

public class Loader {
	static int numOfSegments=0;
	static int numOfSymbols=0;
	static int numOfRelocations=0;
	static int Ttotal=0;
	static int Dtotal=0;
	static int Btotal=0;
	
	
	
	public static final int EXIT_FAILURE=1;
	public static void load(String arg){
		BufferedReader file = null;
		
		try {      // Trying to open specified file
			file = new BufferedReader(new FileReader(arg));
		} catch (FileNotFoundException e) {
			System.out.println("Error: Specified file not found!");
			System.exit(EXIT_FAILURE);
		} // Open file
		
		
		try{
			String input = null;
			input=file.readLine();
			StringTokenizer st = new StringTokenizer(input);
			String token=st.nextToken();
			if(!token.equals("LINK")){
				System.out.println("Error: LINK not found!");
				System.exit(EXIT_FAILURE);
			}
			else{
				input=file.readLine();
				st = new StringTokenizer(input);
				token=st.nextToken();
				try{
				numOfSegments=Integer.parseInt(token);
				}catch(NumberFormatException nfe){
					System.out.println("Error: Number format exception! Bad input file!!");
					System.exit(EXIT_FAILURE);	
				} 
				token=st.nextToken();
				try{
				numOfSymbols=Integer.parseInt(token);
				token=st.nextToken();
				}catch(NumberFormatException nfe){
					System.out.println("Error: Number format exception! Bad input file!!");
					System.exit(EXIT_FAILURE);	
				}
				try{
				numOfRelocations=Integer.parseInt(token);
				}catch(NumberFormatException nfe){
					System.out.println("Error: Number format exception! Bad input file!!");
					System.exit(EXIT_FAILURE);	
				}
				
				input=file.readLine();//#Segments
				if(numOfSegments!=0){
					String name;
					int beg=0;
					int end=0;
					boolean p;
					for(int i=0;i<numOfSegments;i++){
						input=file.readLine();
						st = new StringTokenizer(input);
						name = st.nextToken();
						try{
						beg = Integer.decode("0x"+st.nextToken());
						end = Integer.decode("0x"+st.nextToken());
						}catch(NumberFormatException nfe){
							System.out.println("Error: Number format exception! Bad input file!!");
							System.exit(EXIT_FAILURE);	
						}
						p = st.nextToken().contains("P");
						Segments.instance.enter(name, beg, end, p);
					}
				}
				input=file.readLine();//#Symbols
				if(numOfSymbols!=0){
					String name="";
					int value=0;
					int segment=0;
					String type="";
					for(int i=0;i<numOfSymbols;i++){
						input=file.readLine();
						st = new StringTokenizer(input);
						name = st.nextToken();
						try{
						value = Integer.decode("0x"+st.nextToken());
						segment = Integer.decode("0x"+st.nextToken());
						}catch(NumberFormatException nfe){
							System.out.println("Error: Number format exception! Bad input file!!");
							System.exit(EXIT_FAILURE);	
						}
						type = st.nextToken();
						Symbols.instance.enter(name, value, segment, type);
					}
				}
				input=file.readLine();//#Relocations
				if(numOfRelocations!=0){
					int loc=0;
					int seg=0;
					int ref=0;
					String type;
					for(int i=0;i<numOfRelocations;i++){
						input=file.readLine();
						st = new StringTokenizer(input);
						try{
						loc = Integer.decode("0x"+st.nextToken());
						seg = Integer.decode("0x"+st.nextToken());
						ref = Integer.decode("0x"+st.nextToken());
						}catch(NumberFormatException nfe){
							System.out.println("Error: Number format exception! Bad input file!!");
							System.exit(EXIT_FAILURE);	
						}
						type = st.nextToken();
						Relocations.instance.enter(loc, seg, ref, type);
					}
				}
				Emulator.initPC = Symbols.instance.getStartValue();
				if(Emulator.initPC<0){
					System.out.println("Can not find start simbol!!");
					System.exit(1);
				}
				input=file.readLine();//#Data
				
				for(int i=0;i<Segments.instance.numOfPSeg();i++){
					input=file.readLine();	
				
					st = new StringTokenizer(input);
					while(st.hasMoreTokens()){
						token=st.nextToken();
						Emulator.mem[Emulator.toWrite++]= BitsManipulator.getByteFromInput(token);							
					}	
				}
	
				System.out.print(Segments.instance.toString());
				System.out.print(Symbols.instance.toString());
				System.out.print(Relocations.instance.toString());
				System.out.println("Ttotal= " + Segments.instance.Ttotal());	
				System.out.println("Dtotal= " + Segments.instance.Dtotal());	
				System.out.println("Btotal= " + Segments.instance.Btotal());	
				
				System.out.println("Loader finished!");
				System.out.println("Memory dump? (y/N)");
				char t = Citaj.Char();
				if(t=='y'||t=='Y')Emulator.memDump();
			}
		} catch (IOException ioe) {
			System.exit(EXIT_FAILURE);


		} finally {
			try {
				file.close();
			} catch (IOException e) {}
		}	
		
		
	}

}
