package tvark.old;
import java.io.Serializable;


public class StudTeachSchedule implements Serializable{
	/**
	 * 
	 */ 
	private static final long serialVersionUID = 7759427429188522370L;
	private Teacher[] teachers;
	private Subject[] subjects;
	private Student[] students;
	private Room[] rooms;
	private ScheduleData data;
	private Teacher[][][] TeacherSchedule;
	private Student[][][][] StudentSchedule;
	private Subject[][][] SubjectSchedule;
	private String[][][] GroupSchedule;
	private Room[][][] RoomSchedule;
	private boolean[][][] placeholder;
	private int[][][] StudentCount;
	private int teacher,roomid;
	private int lpd;
	private int classCount =60;
	private int maxPerGroup=30;// va cia galima keisti deliojant tik pogrupiais
	private int[] group;
	private int count;
	
	
	StudTeachSchedule(ScheduleData dataIn, int lpd, int maxClass){
		this.classCount = maxClass;
		this.lpd = lpd;
		this.data =dataIn;
	//	data = new ScheduleData("c:/naujas.xml");
		teachers = data.getTeachers();
		subjects = data.getSubjects();
		students = data.getStudents();
		rooms = data.getRooms();
		//int RoomsNumber = rooms.length;
		TeacherSchedule = new Teacher[5][lpd][classCount];
		StudentSchedule = new Student[5][lpd][classCount][maxPerGroup];
		SubjectSchedule = new Subject[5][lpd][classCount];
		GroupSchedule =new String[5][lpd][classCount];
		RoomSchedule =new Room[5][lpd][classCount];
		StudentCount = new int[5][lpd][classCount];
		placeholder = new boolean[5][lpd][classCount];

		
		
	//	for(int i=0; i<subjects.length;i++)
	//	PlaceSubj(i);
//-----------sita keiciu-------------------		
//		for(int i=0; i<subjects.length;i++)
//			if(subjects[i].getType().equals("but"))PlaceSubj(i);
			
//		for(int i=0; i<subjects.length;i++){
//			if(!subjects[i].getType().equals("but"))PlaceSubj(i);
//		}

//-------------sudėlioja dalykus pagal prioritetus----------------------
		int n=0;
		for(int p=5; p>0;p--)
		{
			for(int i=0; i<subjects.length;i++)
				if(subjects[i].getPriority().equals(Integer.toString(p)))
				{
					PlaceSubj(i,n);	
					n=1;
				}
		}	
//----------------------------------------			
		
		
	//	printSubjectsScreen();
	//	printSubjectsXML();
	//	getGroups();
	//	printGroupsScreen();
	//	printGroupsXML();
	//	printTeachersXML();
	//	printSubjGroupsXML();
		for (int i=0; i<subjects.length;i++)
			if(hoursLeft(subjects[i])!=0)
				System.out.println("Failure on: "+ i +";");
	}
	
	
	public void PlaceSubj(int i, int n)
	{
	//	System.out.println("Dalyko prioritetas kuri dedame  " +p);
			int iterations =0;
			boolean iter=false;
			int parallel=0;
			int day =0;
			int lesson=0;
			int sk=0;
			while(!isSubjOver(subjects[i]))
			{
				iterations++;
				if(iterations>5*lpd*classCount &&  !iter)
				{
					System.out.println(subjects[i].getSubjCode()+" - subject has not enough teachers");
					System.out.println(classCount+" - available Rooms "+ lpd +" - Lessons Per day");
					iter=true;
					iterations =0;
				}
				if (iterations>10*lpd*classCount &&  iter) 
				{
					if (true) {
						throw new RuntimeException("Fatal error");
					}
					System.exit(1);
				}
//-------------------------------------------------------------------------------------
					if(!isBusy(day,lesson,parallel))
					{
					boolean minusFlag =true;
					
					boolean flag1 =CollectStudGroup(subjects[i],day,lesson);
					boolean flag=FindFreeTeacher(subjects[i],day,lesson);
					
					if(!flag)
						flag1=false;
					
					if(!flag1)
						flag=false;		
					
					if(flag &&	flag1 )
					{
						for(int j=0; j< group.length; j++)
							if(group[j]!=-1 && minusFlag)
								StudentSchedule[day][lesson][parallel][j]=students[group[j]];
							else{
								StudentSchedule[day][lesson][parallel][j]=null;
								minusFlag=false;
							}
						setBusy(day,lesson,parallel);
						TeacherSchedule[day][lesson][parallel] = teachers[teacher];
						SubjectSchedule[day][lesson][parallel] = subjects[i];
						RoomSchedule[day][lesson][parallel] = rooms[roomid];
						StudentCount[day][lesson][parallel] = count;
			//			System.out.println(" mokytojas....."+ teachers[teacher].getName()+" n..."+n);
			//			System.out.println(" diena....."+ day + " pamoka....."+lesson+" paralelus...."+parallel);
			//			System.out.println(" tvarkarastyje mokiniu skaicius....."+ subjects[i].getSubjCode());
			//			System.out.println(" tvarkarastyje mokiniu skaicius....."+ count);
					}
					
					if(!flag &&	!flag1)
					{
						if(teacher!=-1)
						{
							unsetTeacher(subjects[i], day, lesson);
							rooms[roomid].unsetBusy(day, lesson);
					//		System.out.println(" atstoma, kad neuzimtas ,..........."+ rooms[roomid].getRoom());
						}
						unsetGroup(subjects[i], day, lesson);
						
						if(!isSubjOver(subjects[i])){
							
							parallel=0;
		
							if(day<4){
								day++;
	//---------------------------------------------------------	
	 if(n==0 && sk==0)
	 {
		 lesson++;
		 sk=1; 
	     //	 System.out.println(" 1 ifas ...........");
	 }
	 else if(n==0 && sk==1)
	 {
		 lesson--; 
		 sk=0; 
		// System.out.println(" 2 ifas ...........");
	 }						  
	//----------------------------------------------------------														  
							}else {
								day=0;						
								if(lesson<lpd-1){
									lesson++;
									sk=1;
								}else
									lesson=0;
							}										
						}
					}
				}else{				
					if(parallel<classCount-1)parallel++;
					
					if(parallel==classCount-1 && !isSubjOver(subjects[i])){
						
						parallel=0;
						if(day<4){
							day++;
	//--------------------------------------------------------	
 if(n==0 && sk==0)
 {
	 lesson++;
	 sk=1; 
     //	 System.out.println(" 1 ifas ...........");
 }
 else if(n==0 && sk==1)
 {
	 lesson--;
	 sk=0; 
     //	 System.out.println(" 2 ifas ...........");
 }							
	//----------------------------------------------------------------					
						}else {
							day=0;
							if(lesson<lpd-1)
								lesson++;
						}	
					}
				}										
			}
		}
	
//-------------------suformuojama mokiniu grupe-------------------------------------------------------	
	public boolean CollectStudGroup(Subject subj, int day, int lesson){
		boolean ret =false;
		count=0;
		int tempCount =0;
		int groupCount=0;
		boolean flag = true;
		boolean testOver= false;
		//boolean flag1 = true;
		String temp =null;
		String[] klasses = new String[30];
		group =new int[30];
		for(int i=0; i<group.length;i++)
			group[i]=-1;
		for (int i =0; i < students.length; i++)
			if(students[i].getHours()[subj.getNr()]>0 &&
				!students[i].isBusy(day, lesson) &&
				count < subj.getMaxStud() &&        //	count < 30 &&
				tempCount < 30)
			{
				ret = true;
				if(count >17 && groupCount <=2 && temp!=null && temp!=students[i].getKlass() || testOver ){
					group[tempCount]=-1;
					tempCount++;
					flag =false;
				}else {
					group[count]=i;
					klasses[count]= students[i].getKlass();
					count++;
					tempCount++;
					students[i].setBusy(day, lesson);
					students[i].getHours()[subj.getNr()]--;
					testOver = isSubjOver(subj);
				}
				if(temp==null){
					temp=students[i].getKlass();
					groupCount=1;
				}
				//flag1= isFullGroup(subj, temp);
				
				if(temp!=null && temp!=students[i].getKlass() && flag){
					temp = students[i].getKlass();
					groupCount++;
				}
			} else if (tempCount<30 && isSubjOver(subj)&& !students[i].isBusy(day, lesson)){
				group[tempCount]=-1;
				tempCount++;
			}
		
		return ret;
	}
	
	public void unsetGroup(Subject subj,int day, int lesson)
	{
		for(int i=0; i<group.length; i++ ){
			if(group[i]!=-1)students[group[i]].unsetBusy(day, lesson);
			if(group[i]!=-1)students[group[i]].getHours()[subj.getNr()]++;
		}
	}
	
	public void unsetTeacher(Subject subj, int day, int lesson)
	{
		for (int i=0; i<teachers[teacher].getSubjects().length; i++)
			if (teachers[teacher].getSubjects()[i].getSubjCode().equals(subj.getSubjCode())){
				teachers[teacher].getHours()[i]++;
				teachers[teacher].unsetBusy(day, lesson);
			}
	}
	
	
	public boolean isFullGroup(Subject subj, String group)
	{
		boolean ret = true;
		
		for (int i=0; i<students.length; i++)
			if (students[i].getKlass().equals(group))
				if(students[i].getHours()[subj.getNr()]==0)
					ret = false;
		
		
		return ret;
	}
	
	public boolean isSubjOver(Subject subj)
	{
		boolean ret = true;
		
		for (int i=0; i<students.length; i++){
			int temp=students[i].getHours()[subj.getNr()];
				if(temp>0)
					ret = false;
		}
		return ret;
	}
//----------randamas kabineto indeksas Room klaseje--------
public int RoomId(int room) 
{	
		int ret = -1;
		for(int i=0; i<rooms.length; i++ )
		{
			if (rooms[i].getRoom() == room)
				ret = i;
		}
		return ret;
}
//-----------randa laisva mokytoja------------------------------------	
	public boolean FindFreeTeacher(Subject subj,int  day,int  lesson){
		boolean ret = false; //return value
		teacher=-1;
		roomid =-1;
		
		for (int i=0; i<teachers.length; i++)
			if (!teachers[i].isBusy(day, lesson))
				for(int j=0; j<teachers[i].getSubjects().length; j++)
				{		
					if(teachers[i].getSubjects()[j].getSubjCode().equals(subj.getSubjCode()) &&
							teachers[i].getHours()[j]>0 && !ret){
						for(int z=0; z<teachers[i].getRooms()[j].length; z++)
						{
							int id = RoomId(teachers[i].getRooms()[j][z]);	
											
							if(!rooms[id].isBusy(day,lesson)&& !ret)
							{
								teacher=i;
								roomid=id;
								teachers[i].setBusy(day, lesson);
								rooms[id].setBusy(day, lesson);
								teachers[i].getHours()[j]--;
								ret =true;
								break;
							}
						}	
					}
				}
		//if(!ret) System.out.println(hoursLeft(subj));
		
		return ret;
	}
//--------------------------------------------------	
	public int hoursLeft(Subject subj){
		int ret=0;
		for (int i=0; i<students.length;i++){
			int temp =students[i].getHours()[subj.getNr()];
			if(temp>0)
				ret+=temp;
		}
		
		return ret;
	}

	

	public String[][][] getGroupSchedule() 
	{
		return GroupSchedule;
	}

	public int getLpd() 
	{
		return lpd;
	}

	public int[][][] getStudentCount() 
	{
		return StudentCount;
	}

	public Student[][][][] getStudentSchedule() 
	{
		return StudentSchedule;
	}

	public Subject[][][] getSubjectSchedule() 
	{
		return SubjectSchedule;
	}

	public Teacher[][][] getTeacherSchedule() {
		return TeacherSchedule;
	}
	
	public Room[][][] getRoomSchedule()
	{
		return RoomSchedule;
	}
	
	public boolean isBusy(int day, int lesson, int parallel)
	{
		return placeholder[day][lesson][parallel];
	}
	public void setBusy(int day, int lesson, int parallel)
	{
		placeholder[day][lesson][parallel] =true;
	}

	public int getMaxPerGroup() 
	{
		return maxPerGroup;
	}

	public boolean[][][] getPlaceholder() 
	{
		return placeholder;
	}
}


