package cs372.lab1.student;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import cs372.lab1.driver.*;

public class PRIORITY1 implements IScheduler {
	
	private List ready_q = new ArrayList();
	private Integer current_pid = null;
	private HashMap all_pcb = new HashMap();
   private ICPU current_CPU = null;

	/* (non-Javadoc)
	 * @see IScheduler#getPCB(java.lang.Integer)
	 */
	public PCB getPCB(Integer pid) {
		// TODO Auto-generated method stub
      return (PCB)all_pcb.get( pid );
	}

	/* (non-Javadoc)
	 * @see IScheduler#processStarted(PCB)
	 */
	public void processStarted(PCB pcb) {
		pcb.setQuantum( Integer.MAX_VALUE );
		ready_q.add( pcb.getPID() );
		all_pcb.put( pcb.getPID(), pcb );

		int p = pcb.getPriority();

		if ( current_pid != null && p < ((PCB)all_pcb.get( current_pid )).getPriority() )
			current_CPU.setPreemptRequest();
	}

	/* (non-Javadoc)
	 * @see IScheduler#quantumExpired(java.lang.Integer, ICPU, int)
	 */
	public void quantumExpired(Integer pid, ICPU cpu, int ticks_given) {
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see IScheduler#schedule(ICPU)
	 */
	public Integer schedule(ICPU cpu) {
		if (ready_q.size() == 0) {
			current_pid = null;
			return null;
		}
		
		int lowest = Integer.MAX_VALUE;
		int index = 0;
		int val = 0;
		
		for ( int x = 0; x < ready_q.size(); x++ ) {
			val = ((PCB)all_pcb.get( (Integer)ready_q.get( x ) )).getPriority();
			if ( val < lowest) {
				lowest = val; 
				index = x;
			}
		}
		
		current_pid = (Integer)ready_q.remove( index );
		
		current_CPU = cpu;

		return current_pid;
	}
		

	/* (non-Javadoc)
	 * @see IScheduler#getCurrentPID()
	 */
	public Integer getCurrentPID() {
		return current_pid;
	}

	/* (non-Javadoc)
	 * @see IScheduler#processExited(java.lang.Integer)
	 */
	public void processExited(Integer pid) {
		all_pcb.remove( pid );
		current_pid = null;
	}

	/* (non-Javadoc)
	 * @see IScheduler#processBlocked(java.lang.Integer, ICPU, int)
	 */
	public void processBlocked(Integer pid, ICPU cpu, int burst_given) {
		current_pid = null;
	}

	/* (non-Javadoc)
	 * @see IScheduler#unblocked(java.lang.Integer)
	 */
	public void unblocked(Integer pid) {
		ready_q.add( pid );
		int p = ((PCB)all_pcb.get( pid )).getPriority();

		if ( current_pid != null && p < ((PCB)all_pcb.get( current_pid )).getPriority() )
			current_CPU.setPreemptRequest();
	}

	/* (non-Javadoc)
	 * @see IScheduler#quantumInterrupted(java.lang.Integer, CPU, int)
	 */
	public void quantumInterrupted(Integer pid, CPU cpu, int ticks_given) {
		ready_q.add( current_pid );
		current_pid = null;
	}

}
