use crate::integer::Time;

#[derive(Debug)]
pub struct TimedInstruction<I,T>{
	pub time:Time<T>,
	pub instruction:I,
}

pub trait InstructionEmitter{
	type Instruction;
	type TimeInner;
	fn next_instruction(&self,time_limit:Time<Self::TimeInner>)->Option<TimedInstruction<Self::Instruction,Self::TimeInner>>;
}
pub trait InstructionConsumer{
	type Instruction;
	type TimeInner;
	fn process_instruction(&mut self, instruction:TimedInstruction<Self::Instruction,Self::TimeInner>);
}

//PROPER PRIVATE FIELDS!!!
pub struct InstructionCollector<I,T>{
	time:Time<T>,
	instruction:Option<I>,
}
impl<I,T> InstructionCollector<I,T>
	where Time<T>:Copy+PartialOrd,
{
	pub const fn new(time:Time<T>)->Self{
		Self{
			time,
			instruction:None
		}
	}
	#[inline]
	pub const fn time(&self)->Time<T>{
		self.time
	}
	pub fn collect(&mut self,instruction:Option<TimedInstruction<I,T>>){
		match instruction{
			Some(unwrap_instruction)=>{
				if unwrap_instruction.time<self.time {
					self.time=unwrap_instruction.time;
					self.instruction=Some(unwrap_instruction.instruction);
				}
			},
			None=>(),
		}
	}
	pub fn instruction(self)->Option<TimedInstruction<I,T>>{
		//STEAL INSTRUCTION AND DESTROY INSTRUCTIONCOLLECTOR
		match self.instruction{
			Some(instruction)=>Some(TimedInstruction{
				time:self.time,
				instruction
			}),
			None=>None,
		}
	}
}
