package com.csc.library.timeattendance;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.csc.library.databean.Memployee;
import com.csc.library.databean.Mtime0;
import com.csc.library.session.DbInquiry;
import com.csc.library.session.DbRecord;
import com.csc.library.session.InitialInquiry;
import com.csc.library.session.InitialRecord;
import com.csc.library.timeattendance.DayShift;
import com.csc.library.timeattendance.WorkingShift;
import com.csc.library.timeinterface.TimeResult;
import com.csc.library.utilities.CscCalendar;
import com.csc.library.utilities.MyLog;
import com.csc.library.utilities.UProfile;

public class ViewWorkers implements WorkerObserv {
	protected String date; /* �ѹ���ӧҹ */
	protected String time; /* ����ö�͡ */
	protected String type; /* ��������ѡ�ҹ (�С�ҧ�ѹ D,�С�ҧ�׹ N)*/
	protected String emp = ""; /* �����ʾ�ѡ�ҹ����ա���ٴ�ѵ� ����Ѻ����Ҷ�����ٴ�ѵ����¤��� �����ӧҹ��������� */
	protected String bus; /* ���ö */
	protected String pathway; /* �شŧö */
	protected String waypoint; /* �شŧö */
	
	protected Vector shiftWorkers = new Vector();
	protected Vector otWorkers = new Vector();
	protected HashMap pathIndexs = new HashMap();
	public UProfile upf;
	
	public ViewWorkers(UProfile upf, CscCalendar datetime, String type, String bus){
		this.date = datetime.getYYYYMMDD();
		this.time = Float.toString(datetime.getCSCTime());
		this.type = type;
		this.bus = bus;
		this.upf = upf;
		CreateWorkers();
	}
	
	public ViewWorkers(UProfile upf, String date, String time, String type, String bus){
		this.date = date;
		this.time = time;
		this.type = type;
		this.bus = bus;
		this.upf = upf;
		CreateWorkers();
	}
	
	public Vector getWorkers(){
		return shiftWorkers;
	}
	
	public Vector getOTWorkers(){
		return otWorkers;
	}
	
	public int getWorkerCount(){
		return shiftWorkers.size();
	}
	
	public int getOTWorkerCount(){
		return otWorkers.size();
	}
	
	public HashMap getPathWays() {
		return pathIndexs;
	}
	
	public int getPathWayCount(String path){
		if(pathIndexs.containsKey(path)){
			return (Integer)pathIndexs.get(path);
		}else{
			return 0;
		}
	}
	
	private void CreateWorkers(){
		try {
			/* ���ҧ�ʴ��ش���-ŧ �ͧ��ѡ�ҹ*/
			DbRecord recMpath = new InitialRecord(upf).getDbRecord("MPATH_GETONPOINT");
			recMpath.setColumn("*");

			/* ���ҧ�ʴ���������´�� */
			DbRecord recTime0 = new InitialRecord(upf).getDbRecord("Mtime0");
			recTime0.setColumn("*");

			/* ���ҧ�ʴ� Job grade*/
			DbRecord recJobGrade = new InitialRecord(upf).getDbRecord("Mjobgrade0");
			recJobGrade.setColumn("*");

			/* ���ҧ�ʴ� Job code */
			DbRecord recJobCode = new InitialRecord(upf).getDbRecord("Mjobcode");
			recJobCode.setColumn("*");
			recJobCode.putChild(recJobGrade);
			
			/* ���ҧ�ʴ� Job code */
			DbRecord recBu1 = new InitialRecord(upf).getDbRecord("Mbu1");
			recBu1.setColumn("*");
			recBu1.putChild(recBu1);

			/* ���ҧ�ʴ� Job code */
			DbRecord recBu2 = new InitialRecord(upf).getDbRecord("Mbu2");
			recBu2.setColumn("*");
			recBu2.putChild(recBu2);

			/* ���ҧ�ʴ� Job code */
			DbRecord recBu3 = new InitialRecord(upf).getDbRecord("Mbu3");
			recBu3.setColumn("*");
			recBu3.putChild(recBu3);
			
			/* ���ҧ�ʴ���������´��ѡ�ҹ */
			DbRecord recEmp = new InitialRecord(upf).getDbRecord("Memployee");
			recEmp.setColumn("*");
			recEmp.putChild(recTime0);
			recEmp.putChild(recMpath);
			recEmp.putChild(recJobCode);
			recEmp.putChild(recBu1);
			recEmp.putChild(recBu2);
			recEmp.putChild(recBu3);

			/* ���ҧ filter ��� type ���������������С�ҧ�׹ (N)��д֧��ѡ�ҹ��駡� D ��� M */
			StringBuffer filter = new StringBuffer();
			if(type.equalsIgnoreCase("N")){
				filter.append("swipedate = '" + date + "' and swipetype = '0' and employeeid in (select employeeid from memployee where ");
				filter.append(" time0 like '%N%' and "); 
				filter.append(" pathway_index in "); 
				filter.append(" (select pathway_index from mpath_getonpoint where pathwayid = '" + bus + "'))");
			}else{ 
				filter.append("swipedate = '").append(date).append("' and swipetype = '0' and employeeid in (select employeeid from memployee where ");
				filter.append(" (time0 like '%D%' or time0 like '%M%') and "); 
				filter.append(" pathway_index in "); 
				filter.append(" (select distinct(pathway_index) from mpath_getonpoint where pathwayid = '").append(bus).append("') )");
			}
			
			/* �֧�������ٴ�ѵ� (੾�з�����ٴ��� swipetype = 1 ��� ���ʡТ�鹵鹴��� D ���� N ������ type ����������) ���͵�ͧ�����੾�о�ѡ�ҹ�����ҷӧҹ��ѹ�����ҹ�� �������ٴ����������� */
			DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry();		
			inq.initMyTable("ttimetemp",filter.toString(), "");
			inq.setColumn("*");
			inq.setOrderBy("employeeid");
			inq.putChild(recEmp);
			inq.refresh();	
			
			while(inq.next()){
				DbRecord mta = (DbRecord)inq.getChild("memployee");
				DbRecord mpath = (DbRecord)inq.getChild("memployee").getChild("Mpath_getonpoint"); 
				Mtime0 mtime0 = (Mtime0)inq.getChild("memployee").getChild("mtime0"); 
				mtime0.setEmpRec((DbRecord)mta);
				
				/* ����੾�о�ѡ�ҹ������ʡз���鹵鹴��� M,D ���� N �������� Type ����Ѻ�����  ��� ����ͧ�� �����礨ҡ  filter ��ҹ������*/
				//if(mtime0.getString("time0id").indexOf("MDN") > -1){ 
					if(!isDuplicateID(inq.getString("employeeid"))){
						/* ��ͧ��������ҧἹ ����������������������ش��÷ӧҹ �֧���¡��੾�� Method ������ */
						WorkingShift wsf = mtime0.genWorkingShift(new CscCalendar(date));
						wsf.setEmployeeid(inq.getString("employeeid"));
						wsf.setEmpTimeCode(mtime0.getString("time0id"));
						wsf.setUProfile(upf);
						wsf.adjust(); 		/* �������ѹ����ա�û�ѺἹ ����ռš�з������������ش��÷ӧҹ������� �� ���� ������¹�� ���ͷ� �繵�	*/
						wsf.createLink(); 	/* ��ҷ��ͷյ�͡� �Т������ҡ�÷ӧҹ����ѵ��ѵ� */

						/* ��������¹�ѹ��ش�һ�ѺἹ����  */
		                ManageAdjustChangeHoliday mac = new ManageAdjustChangeHoliday(this.upf);
		                wsf.adjustChangeHoliday(mac.getAdjustChangeHolidayData(wsf, recEmp), this.upf);
		                
		                /* ��ѺἹ�Ѻ���  */
		                ManageAdjustLeave mal = new ManageAdjustLeave(this.upf);
		                wsf.adjustDocument(mal.getAdjustLeaveData(wsf, recEmp, mtime0), this.upf);
		                
		                /* ��ѺἹ�Ѻ��â��ͷ� */
		                ManageAdjustOT mao = new ManageAdjustOT(this.upf);
		                wsf.adjustDocument(mao.getAdjustOTData(wsf, recEmp, mtime0), this.upf);
						
						addWorkers(mta,mpath,wsf);
					}
				}
			//}
		}catch(Exception e){
			System.out.println("[ERROR:ViewWorkers] Can't create workshift for employeeid : " + emp);
			e.printStackTrace();
		}
	}
	
	private void addWorkers(DbRecord emp, DbRecord mpath, WorkingShift wsf){
		try {
			DayShift dShifttmp = (DayShift) wsf.get(date);    	
	    	dShifttmp.genProcessResult();
	    	HashMap errorDayShiftResult = dShifttmp.getErrorResult();
	    	
			/** 
			 * �����ѹ����ա�����ҧ��������� �ʴ���ҷӧҹ���� ���� ���ͷ�Ẻ��͡�
			 * ����ҡ����˹�觡� �ʴ�����Ҩ���ա�â��� ���ͷ��ͷ�Ẻ����͡� ��ͧ�礨ҡ���ش���������ԡ��ǧ����� �������㹪�ǧ��͹ö�͡������� 
			 **/
	    	int idx = 0;
	    	CscCalendar in = new CscCalendar();
	    	for (Iterator IT1 = dShifttmp.keySet().iterator(); IT1.hasNext();) {			
				String key1 = (String) IT1.next();			
				TimeResult tr = (TimeResult) dShifttmp.get(key1);
				
				if(dShifttmp.size() == 1) { /* ������������ */
					if(tr.getResultEventGroup().equals("T")){ 	/* �繡зӧҹ���� */
						//if(isBusZone(tr.getResult_c_dt_out())){	/* ����㹪�ǧ��͹����ö�͡ */
							addShiftWorkers(createWorker(emp, mpath, tr.getResult_c_dt_in(), tr.getResult_c_dt_out(),false));
						//}
					}else if(tr.getResultEventGroup().equals("OT")){ /* ���ͷ� */
						addOTWorkers(createWorker(emp, mpath, tr.getResult_c_dt_in(), tr.getResult_c_dt_out(),true));
					}
				}else{ /* ��÷ӧҹ��ѹ���١�������� � �� �Ҩ���ͧ�Ҩҡ �բ��Ҫ�ǧ��� ����ҷӧҹ���� ���ͷ��ͷ�����͡� �֧��ͧ����ش���¢ͧ�ѹ�繵�Ǻ͡������ԡ�ҹ */
					idx++; 			/* �ӴѺ�Тͧ�ѹ���  � */
					if(idx == 1) { 	/* ����繡��á�ͧ�ѹ ��੾�������������÷ӧҹ */
						in = new CscCalendar(tr.getResult_c_dt_in().getYYYYMMDDHHMMSS());  
					}else if(idx == dShifttmp.size()){ /* �繡��ӴѺ�ش���¢ͧ�ѹ ���红����Ţͧ��ѡ�ҹ ��������������ӧҹ�ͧ���á �����������ش�ͧ���ش���� */
						if(tr.getResultEventGroup().equals("T")){ 	/* �繡зӧҹ���� */
							//if(isBusZone(tr.getResult_c_dt_out())){	/* ����㹪�ǧ��͹����ö�͡ */
								addShiftWorkers(createWorker(emp, mpath, in, tr.getResult_c_dt_out(),false));
							//}
						}else if(tr.getResultEventGroup().equals("OT") || tr.getResultEventGroup().equals("O")){ /* ���ͷ� */
							addOTWorkers(createWorker(emp, mpath, in, tr.getResult_c_dt_out(),true));
						}
					}
					
				}
	    	}
		}catch(Exception e){
			e.printStackTrace();
		}		
	}
	
	/* �������ԡ�ҹ㹪�ǧ��͹ö�͡������� */
	private boolean isBusZone(CscCalendar csEndShift){
		boolean result = false;
		try {
			if(csEndShift.afterEqualsDateTime(getBusZoneIN()) && csEndShift.beforeEqualsDateTime(getBusZoneOUT()))
				result = true; 
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return result;
	}
	
	/* �ӹdz�����Ҫ�ǧ���ҡ�͹ö�͡ 㹡óչ���˹��繤�Ҥ���� ��� 2 ��. */
	private CscCalendar getBusZoneIN(){
		final float MAX = 3.0f; /* ��� ��. �����ź�Ѻ���ҷ��ö�͡ ������������������� �ͧ��ǧ���ҷ�边ѡ�ҹ����ԡ�ҹ �������ö �� ö�͡ 17.00 �ѡ�͡ 2 ��. �� 15.00 ���Щ��鹨���੾�о�ѡ�ҹ������ԡ�ҹ㹪�ǧ 15.00 - 17.00 */
		CscCalendar busZoneIN = new CscCalendar();
		try {
			busZoneIN.setCalendar(date);
			if(type.equalsIgnoreCase("N")){ busZoneIN.incDate(); } /* ����繡С�ҧ�׹ ����ö�͡��������ѧ���§�׹ �������Ңͧ�ѹ���� �֧��ͧ�ǡ�ѹ���� */
			busZoneIN.setCSCTime(Float.parseFloat(time));
			busZoneIN.decTime(MAX);
		}catch(NumberFormatException e){
			System.out.println("[ERROR:ViewWorkers.getBusZoneIN] time is not number");
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		return busZoneIN;
	}
	
	/* �ӹdz������ö�͡ */
	private CscCalendar getBusZoneOUT(){
		CscCalendar busZoneOUT = new CscCalendar();
		try {
			busZoneOUT.setCalendar(date);
			if(type.equalsIgnoreCase("N")){ busZoneOUT.incDate(); } /* ����繡С�ҧ�׹ ����ö�͡��������ѧ���§�׹ �������Ңͧ�ѹ���� �֧��ͧ�ǡ�ѹ���� */
			busZoneOUT.setCSCTime(Float.parseFloat(time));
		}catch(NumberFormatException e){
			System.out.println("[ERROR:ViewWorkers.getBusZoneOUT] time is not number");
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		return busZoneOUT;
	}

	/* ���ͻਡ�쾹ѡ�ҹ���ӧҹ�л��������ͷ�� Vector */
	private void addShiftWorkers(Workers worker){
		shiftWorkers.add(worker);
	}

	/* ���ͻਡ�쾹ѡ�ҹ�����ͷ�ŧ� Vector */
	private void addOTWorkers(Workers worker){
		otWorkers.add(worker);
	}

	/* ���ҧ�ͻਡ�쾹ѡ�ҹ ������������´ ���� ���͹��ʡ�� ������ҹ ��ԡ�ҹ ʶҹз��ͷ� */
	private Workers createWorker(DbRecord emp, DbRecord mpath, CscCalendar in, CscCalendar out, boolean ot){
		Workers worker = new Workers();
		try {
			DbRecord recJobGrade = (DbRecord)emp.getChild("mjobcode").getChild("mjobgrade0");
			DbRecord recBu1 = (DbRecord)emp.getChild("mbu1");
			DbRecord recBu2 = (DbRecord)emp.getChild("mbu2");
			DbRecord recBu3 = (DbRecord)emp.getChild("mbu3");
			
			worker.setId(emp.getString("employeeid"));
			worker.setFullname(emp.getString("fullname"));
			worker.setPathway(emp.getString("pathway_index"));
			worker.setWayPoint(mpath.getString("getonpointid"));
			worker.setJobGrade(recJobGrade.getString("jobgradeid"));
			worker.setJobGradeThai(recJobGrade.getString("tdesc"));
			worker.setBu1(recBu1.getString("bu1id"));
			worker.setBu1Thai(recBu1.getString("tdesc"));
			worker.setBu2(recBu2.getString("bu2id"));
			worker.setBu2Thai(recBu2.getString("tdesc"));
			worker.setBu3(recBu3.getString("bu3id"));
			worker.setBu3Thai(recBu3.getString("tdesc"));
			worker.setStart(in);
			worker.setFinish(out);
			worker.setIsWorkingOT(ot);
			
			countWayPath(worker); /* ��ʶԵԨش���ŧö */
		}catch(Exception e){
			System.out.println("[ERROR:CreateWorker] Can't create worker emp or wsf is null ");
			e.printStackTrace();
		}
		return worker;
	}

	/* ��Ǩ�ͺ������ʾ�ѡ�ҹ��ӡѺ�����Ūش��͹˹�ҹ��������� ���к�ҧ�����ٴ�ѵ�����ҡ����˹�觤��� */
	private boolean isDuplicateID(String emp){
		boolean result = false;
		try {
			if(this.emp.equalsIgnoreCase(emp)){ 
				result = true; 
			}else{
				this.emp = emp;
			}
		}catch(Exception e){
			e.printStackTrace();
			return result;
		}
		return result;
	}
	
	/* �Ѻ�ӹǹ�ش���ŧ���Шش����ա�褹 */
	private void countWayPath(ManageWorkers worker){
		int initValue = 1;
		if(pathIndexs.containsKey(worker.getPathway())){
			int count = (Integer)pathIndexs.get(worker.getPathway());
			pathIndexs.put(worker.getPathway(), count++);
		}else{
			pathIndexs.put(worker.getPathway(), initValue);
		}
	}

}