package com.csc.library.timeattendance;

import com.csc.library.utilities.MyLog;
import com.csc.library.utilities.CscCalendar;
import com.csc.library.utilities.MyTreeMap;
import com.csc.library.database.StaticConfig;
import com.csc.library.timeattendance.Shift;
import com.csc.library.timeinterface.AdjustTime;
import com.csc.library.timeinterface.SwipeTrans;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

public class DayShift extends MyTreeMap {
	
	CscCalendar shiftDate; //�ѹ���ͧ��
	SwipeTrans swipeData; //�����š���ٴ�ѵâͧ��ѡ�ҹ
	Vector swipeHoliday = new Vector();
	HashMap errorResult;
	
	public DayShift() {
		super();
		this.errorResult = new HashMap();
	}

	public DayShift(CscCalendar d) {
		this.shiftDate = d;
		this.errorResult = new HashMap();
	}

	/*
	 * ��˹���ҡ��ŧ�����������С�
	 * ���͹����㹡�èѺ����÷ӧҹ����
	 */
	public void setSwipeTrans(SwipeTrans trans) {
		this.swipeData = trans;
		Shift s;
		String key;
		for (Iterator IT = this.keySet().iterator(); IT.hasNext();) {
			key = (String) IT.next().toString();
			s = (Shift) this.get(key);
			s.setSwipeTrans(this.swipeData);
		}
	}
	
	public SwipeTrans getSwipeTrans() {
		return this.swipeData;
	}

	/*
	 * �ӡ�èѺ����÷ӧҹ�����º��º
	 * ������ҧ��÷ӧҹ��Т����š���ٴ�ѵ�
	 */
	public void findTime() {
		Shift s;
		String key;
		for (Iterator IT = this.keySet().iterator(); IT.hasNext();) {
			key = (String) IT.next().toString();
			s = (Shift) this.get(key);
			s.setSecondLoop(false);
			s.findTime();
		}
	}
	
	public void findTime(boolean secondLoop) {
		Shift s;
		String key;
		for (Iterator IT = this.keySet().iterator(); IT.hasNext();) {
			key = (String) IT.next().toString();
			s = (Shift) this.get(key);
			s.setSecondLoop(secondLoop);
			s.findTime();
		}
	}
	
	/*
	 * �ӡ�����ҧ���ҡ���ٴ�ѵ�����ѵ���ѵ�
	 * 㹡óշ���աз�������ͧ�ѹ
	 * ��	T 08.00 - 17.00
	 * 			O 17.00 - 19.00
	 * �зӡ�����ҧ�����š���ٴ�ѵ����� 17.00 ���Ѻ����ͧ��
	 */
	 public void genVirtualSwipeForJoinShift() {
		Shift s;
		String key;
		for (Iterator IT = this.keySet().iterator(); IT.hasNext();) {
			key = (String) IT.next().toString();
			s = (Shift) this.get(key);
			s.genVirtualSwipeForJoinShift();
		}
	}

	 /*
	  * ���ҧ�Ţ�Ѵ仢ͧ TR_type ���е�� T, A, O, H, I
	  */
	public String getNextRuningCode(String code) {		
		String result;
		int max = 0;		
		Iterator it = this.keySet().iterator();
		if (this.isEmpty()) {
			max = 0;
		} else {
			while (it.hasNext()) {
				Shift sh = (Shift) this.get((String) it.next());
				String t = sh.getTR_Type();
				if (t.equalsIgnoreCase("")) {
					max = 0;
				} else {
					if (t.substring(0, 1).equalsIgnoreCase(code)) {
						if (Integer.valueOf(t.substring(1, 2)).intValue() >= max) {
							max = Integer.valueOf(t.substring(1, 2)).intValue();
							max++;
						}
					}
				}
			}
		}		
		if (code.length()==1) 
			result = code + max;
		else result = code.substring(0, 1) + max;
		return result;
	}

	/*
	 * �ӡ�ù���� 2 ��������ѹ
	 */
	public DayShift addShift(DayShift ds1, DayShift ds2) {
		Iterator it = ds2.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) ds2.get(code);
			ds1.put(sh);
		}
		return ds1;
	}

	/*
	 * �ӡ�ùӢ������ ADJTIME0 �ҷӡ�û�Ѻ��ا�����
	 * ���ҡ�÷ӧҹ���Է�����ҧ�����
	 * + ----> ADD SHIFT [UPDTYPE != D --> A, O, H, T]
	 * - ----> SUB SHIFT [UPDTYPE = D]
	 */
	public void adjust(AdjustTime ajTime) {
		adjust(ajTime, ajTime.getDocDate());
	}
	
	/* �� actual date 仴��� */
	public void adjust(AdjustTime ajTime, CscCalendar keydate) {
		//MyLog.debug(this, "DayShift="+this);
		if (!ajTime.getUpdateType().equalsIgnoreCase("D")) { //�ӡ��������
			Shift sh = new Shift(new CscCalendar(ajTime.getDocDate().getTimestamp()));
			sh.setActualDate(keydate.getDDMMYYYY());	// �ѹ���ͧ�з���ŧἹ
			sh.set_c_dt_in(ajTime.get_DT_BG()); //��˹��ѹ��������������Ѻ��
			sh.set_c_dt_out(ajTime.get_DT_EN()); //��˹��ѹ��������ش���Ѻ��
			
			CscCalendar c = new CscCalendar(ajTime.getDocDate().getDDMMYYYY());	/* ���ҧ�е���ѹ���ͧ actual date */
			try {
				c.setCSCTime(ajTime.get_DT_BG().getCSCTime());
			} catch (Exception e) {}
			sh.setShiftDate(c); //��˹��ѹ�������Ѻ��
			
			sh.setTimeCode(ajTime.getTime0()); 			//��˹����ʵ��ҧ��÷ӧҹ���Ѻ��
			sh.setOldTimeCode(ajTime.getOldTime0()); 	//��˹����ʵ��ҧ��÷ӧҹ������Ѻ��
			sh.setEventGroup(ajTime.getEventGroup()); 	//��˹��������ѹ���Ѻ��
			sh.setOldEventGroup(ajTime.getOldEventGroup()); //��˹��������ѹ������Ѻ��
			sh.setTR_Type(ajTime.get_TR_Type());		//��˹��������ѹ���Ѻ��
			sh.setDocType(ajTime.getDocType()); 		//�ӹ��������͡������Ѻ��
			sh.setDocNo(ajTime.getDocNo()); 			//��˹������Ţ�͡������Ѻ��
			sh.setLV_Type(ajTime.get_LV_TY()); 			//��˹���������������Ѻ��
			//sh.setAppStatus(ajTime.getAppStatus()); 	//��˹�ʶҹС��͹��ѵ��͡��� (W ���������ҧ���͹��ѵ� ����繪�ͧ��ҧ�ʴ����͹��ѵ���������)
			sh.set_o_dt_in(ajTime.get_DT_BG()); 
			sh.set_o_dt_out(ajTime.get_DT_EN());
			
			TimeZone tz = ajTime.getTimeWork(); //�֧�ѹ���ҵ�����ҧ��÷ӧҹ�ͧ���͡��
			if(tz!=null){
				sh.set_sh_dt_in(tz.getBeginZone()); //��˹��ѹ����������鹵�����ҧ��÷ӧҹ���Ѻ��
				sh.set_sh_dt_out(tz.getEndZone()); //��˹��ѹ��������ش������ҧ��÷ӧҹ���Ѻ��
			}//end if 			
			if (ajTime.getUpdateType().equalsIgnoreCase("A")) { //������� set ���ҷ�����ŧ�				
				sh.setLv(ajTime.get_LV()); //���ҷ�����
				sh.setDocStatus(ajTime.getDocStatus());	
				sh.setTR_Type("A0");
				try {
					sh.setActualEvent(ajTime.get_TR_Type().substring(0,1)); /* ��˹��������ѹ��ԧ � �ͧ�� */
				}catch(Exception e){
					sh.setActualEvent("T");
				}
			} else if (ajTime.getUpdateType().equalsIgnoreCase("O")||
					ajTime.getUpdateType().equalsIgnoreCase("H")||
					ajTime.getUpdateType().equalsIgnoreCase("I")) { //���ͷ���� set ���ҷ����ͷ�ŧ�	
				if(ajTime.getUpdateType().equalsIgnoreCase("O")) {
					sh.setTR_Type("O0");
				}
				if (!this.isEmpty()) { //����ա� H ���� I ������ OT ���ӡ��ź�з��
					Shift shHoliday = (Shift) this.get((String) this.keySet().iterator().next());
					/* ��ҡз���Ѿഷ�� O ��ͧ�� actual_event ����������ѹ��ش�����ѹ�ӧҹ */
					sh.setAp_ot(ajTime.get_LV()); //���ҷ����ͷ�
					if(shHoliday!=null && shHoliday.getType()=='A'){ /* ���ͷ� �Ѻ���� ��ͧ��Ѻ�����ͷ��͡� ������Ѻ */
						if(sh.get_c_dt_in().beforeEqualsDateTime(shHoliday.get_c_dt_in()) 
								&& sh.get_c_dt_out().afterEqualsDateTime(shHoliday.get_c_dt_out())){
							/* �ͷդ�������ҷ����� �������ͷ�ŧ */
						}else if(sh.get_c_dt_in().afterEqualsDateTime(shHoliday.get_c_dt_in())
								&& sh.get_c_dt_out().beforeEqualsDateTime(shHoliday.get_c_dt_out())){
							/* ���Ҥ�����ͷշ����� �������ͷ�ŧ */
						}else if(sh.get_c_dt_in().beforeDateTime(shHoliday.get_c_dt_in()) 
								&& sh.get_c_dt_out().afterDateTime(shHoliday.get_c_dt_in()) 
								&& sh.get_c_dt_out().beforeEqualsDateTime(shHoliday.get_c_dt_out()) ){
							/* �ͷշѺ���Һҧ��ǹ �������������ش����ҡѺ������������� */
							sh.c_dt_out = new CscCalendar(shHoliday.get_c_dt_in().getTime());
						}else if(sh.get_c_dt_in().afterEqualsDateTime(shHoliday.get_c_dt_in())
								&& sh.get_c_dt_in().beforeDateTime(shHoliday.get_c_dt_out())
								&& sh.get_c_dt_out().afterDateTime(shHoliday.get_c_dt_out())){
							/* ��������ͷ�㹪�ǧ���� ��ͧ��Ѻ����������ͷ� */
							sh.c_dt_in = new CscCalendar(shHoliday.get_c_dt_out().getTime()); 
						}
					}else if (shHoliday!=null && (shHoliday.getType()=='H' || shHoliday.getType()=='I')) {
						sh.setActualEvent(String.valueOf(shHoliday.getType()));
						//sh.setEventGroup(String.valueOf(shHoliday.getType()));	/* ����繡��ͷ� ��ѹ��ش ��Ѻ eventgrp ����������ѹ��ش (H ��ش����, I ��ش�ѡ�ѵġ��)*/
						//sh.setTR_Type(String.valueOf(shHoliday.getTR_Type()));
						sh.setTimeCode(shHoliday.getTimeCode());	// �ó��ͷ��ѹ��ش ��ͧ��Ѻ���ʡ� ���ç�Ѻ�з���ѺἹ������ѹ��ش ���ͧ�ҡ�ռŵ�͡�äӹdz�ͷ������ ��й͡���ҷӧҹ
						sh.set_sh_dt_in(new CscCalendar(shHoliday.get_sh_dt_in().getYYYYMMDDHHMMSS()));
						sh.set_sh_dt_out(new CscCalendar(shHoliday.get_sh_dt_out().getYYYYMMDDHHMMSS()));
						
						this.remove(this.keySet().iterator().next().toString());
					}else if(shHoliday.getActualEvent().equals("H") || shHoliday.getActualEvent().equals("I")){ /* �繡��ͷ���ѹ��ش */
						if(shHoliday.getEventGroup().equals("O")){	/* �С�͹˹����ѹ���ǡѹ���ͷ��ѹ��ش ��ͧ�֧ actual event ��૵���Ѻ���ͷ� */
							sh.setActualEvent(shHoliday.getActualEvent());
						}else{
							sh.setActualEvent(String.valueOf(shHoliday.getType()));	/* ������ѹ��ش������ͷ� ��˹� actual_event ���ѹ��ش�ӡѺ��� */
						}
						if(shHoliday.getType()=='H' || shHoliday.getType()=='I'){	/* ��ͧ�繡��ѹ��ش�֧��ź ����繡��ͷ���ѹ��ش����ͧź */
							this.remove(this.keySet().iterator().next().toString());
						}
					}else{	/* ������ѹ��ش ���繡��ͷ� ��������ͧ ���������ѹ�ӧҹ*/
						sh.setActualEvent("T");
					}
					
					/* ����繡��ͷ� ��ѹ��ش �����ź�����������ѹ��ش�͡ ���������ͷ�ŧ� ���繵�ͧ��˹������� � 㹡��ѹ��ش���Ѻ���ͷմ��� */
					sh.setMidDayStop(shHoliday.midDayStop); //��˹���ǧ���ҡ�þѡ���Ѻ��
					sh.setAdjustTemp(shHoliday.getAdjustTemp());
					//----- ��˹������ŵ�ҧ� ���Ѻ�� ����͡��÷���͡��� -----//
					sh.setWorkarea(shHoliday.getWorkarea()); //��˹�ʶҹ���ӧҹ���Ѻ��
					sh.setSalatype(shHoliday.getSalatype()); //��˹����ʤ�����������Ѻ��
					sh.setOT_type(shHoliday.getOT_type()); //��˹��������ͷ����Ѻ��
					sh.setOT_time0(shHoliday.getOT_time0()); //��˹����ʵ��ҧ��÷ӧҹ�������ͷ����Ѻ��
					//-------------------------------------------------------//
					sh.setHour_s(shHoliday.getHour_s()); //��˹� ��.�ӧҹ����ѹ ���Ѻ��
					sh.setHour_d(shHoliday.getHour_d()); //��˹� ��. �����/�ӧҹ/�ͷ� ���Ѻ��
					sh.setDocStatus(shHoliday.getDocStatus()); //��˹���������âͧ��á�͡�͡��� [4=͹��ѵԨҡ WF, 6=HR ��͡���]
				}else{	/* �������ա������ѹ��� �ʴ�������ѹ��ش ��ж١��� adjust ��Ἱ����������ѹ��ش � TransfertimeProcess */
					sh.setActualEvent("H");
				}
			} else if (ajTime.getUpdateType().equalsIgnoreCase("T") && !ajTime.getDocType().equals("CH") 
					&& !ajTime.getDocType().equals("C")
					/**
				 * Author : Nuiss
				 * Date : 27/03/2553
				 * Logic : ����š�� �� ����ͧ clear property ��ҹ��ҧ��� ����
				 * Site NSTDA Doctype ='E' �����š��
				 */
					&& !ajTime.getDocType().equals("E") &&  !ajTime.getDocType().equals("D") ) {
				//����繡л��� ���������Ҩҡ�������¹�� ���ź��ҷ������ǡѺ�͡��÷��
				
				sh.setOldEventGroup("");
				sh.setDocType("");
				sh.setDocNo("");
				sh.setLV_Type("");
			}else if(ajTime.getUpdateType().equalsIgnoreCase("T")){
				sh.setActualEvent(ajTime.getUpdateType()); /* ��˹��������ѹ��ԧ � �ͧ�� ������ѹ�ӧҹ */
			}
				
			if((sh.getEventGroup().equals("H") && sh.getActualEvent().equals("H")) || (sh.getEventGroup().equals("O"))){
				// ����ͧ��˹���ҫ�� ���ж١�˹��ҡ�괢�ҧ������
			}else{
				sh.setMidDayStop(ajTime.getTimeBreak()); //��˹���ǧ���ҡ�þѡ���Ѻ��
				sh.setAdjustTemp(ajTime.getAdjustTemp());
				//----- ��˹������ŵ�ҧ� ���Ѻ�� ����͡��÷���͡��� -----//
				sh.setWorkarea(ajTime.getWorkarea()); //��˹�ʶҹ���ӧҹ���Ѻ��
				sh.setSalatype(ajTime.getSalatype()); //��˹����ʤ�����������Ѻ��
				sh.setOT_type(ajTime.getOT_type()); //��˹��������ͷ����Ѻ��
				sh.setOT_time0(ajTime.getOT_time0()); //��˹����ʵ��ҧ��÷ӧҹ�������ͷ����Ѻ��
				//-------------------------------------------------------//
				sh.setHour_s(ajTime.getHour_s()); //��˹� ��.�ӧҹ����ѹ ���Ѻ��
				sh.setHour_d(ajTime.get_LV()); //��˹� ��. �����/�ӧҹ/�ͷ� ���Ѻ��
				sh.setDocStatus(ajTime.getDocStatus()); //��˹���������âͧ��á�͡�͡��� [4=͹��ѵԨҡ WF, 6=HR ��͡���]
			}
			
			if (ajTime.getEventGroup().equals("T")) {  //����繡л��� ��������������͡ �ç�Ѻ��ǧ�ѡ ����ͧ�����áѺ�й��				
				TimeZone timeBreak = sh.getMidDayStop();
				if (timeBreak.getBeginZone().equals(sh.get_c_dt_in()) && 
						timeBreak.getEndZone().equals(sh.get_c_dt_out())) {
					//do nothing
				} else {
					this.put(sh);
				}//end if 
			} else {
				if(sh.getTimeCode().equals("")){	/* �ó������ time0id ���������ʢͧ����ѹ��� � ���� */
					copyTimeCodeFromDefault(sh);
				}
				this.put(sh);			
			}
		} else if (ajTime.getUpdateType().equalsIgnoreCase("D")) { //�ӡ��ź��		
			String tmp = ajTime.get_DT_BG().getTimestamp().toString();
			String key = tmp.substring(0,tmp.length()-2);			
			if (this.containsKey(key)) {
				//MyLog.debug(this, "======> REMOVE SHIFT : "+key);
				Shift shTmp = (Shift) this.get(key);				
				if (shTmp.get_c_dt_in().equals(ajTime.get_DT_BG()) && 
						(shTmp.get_c_dt_out().equals(ajTime.get_DT_EN()))) {
					this.remove(key);		
				}			
			} 
		}
	}
	
	/* �ó������ time0id ���������ʢͧ����ѹ��� � ���� */
	private void copyTimeCodeFromDefault(Shift sh){
		try {
			Iterator it = this.keySet().iterator();
			for(;it.hasNext();){
				String key = (String) it.next();
				Shift tmsh = (Shift) this.get(key);
				if(tmsh.getEventGroup().equals("T") || tmsh.getEventGroup().equals("H") || tmsh.getEventGroup().equals("I")){
					if(!tmsh.getTimeCode().equals("")){
						sh.setTimeCode(tmsh.getTimeCode());
						sh.set_sh_dt_in(new CscCalendar(tmsh.get_sh_dt_in().getYYYYMMDDHHMMSS()));
						sh.set_sh_dt_out(new CscCalendar(tmsh.get_sh_dt_out().getYYYYMMDDHHMMSS()));
						break;
					}
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}

	private String getTimeFormat(String str) {
		DecimalFormat df = new DecimalFormat("#0.00");
		String value = df.format(Double.valueOf(str).doubleValue());
		String tmp = value.substring(0, value.indexOf("."));
		if (tmp.length() == 1)
			value = "0" + value;
		return value;
	}

	public String toString() {
		String buff = "";
		Iterator it = this.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			buff = buff + "Key : " + code + " # " + sh.toString() + "\n";
		}
		return buff;
	}

	public void put(Shift sh) {
		super.put(sh.getKey(), sh);
	}

	/*
	 * ���ҧἹ��÷ӧҹ ੾���ѹ����ͧ�ӧҹ
	 */
	public void genWorkingTimeTransaction(MyTreeMap tm) {		
		Iterator it = this.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			if (sh.isWorking()) { //������繡з���ͧ�ӧҹ
				tm.put(sh.getStringTimeIn(), sh.getKey());
				tm.put(sh.getStringTimeOut(), sh.getKey());
			}
		}
	}

	/*
	 * ���ҧἹ��÷ӧҹ�ء�ѹ
	 */
	public void genAllTimeTransaction(MyTreeMap tm) {
		Iterator it = this.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			tm.put(sh.getStringTimeIn(), sh.getKey());
			tm.put(sh.getStringTimeOut(), sh.getKey());
		}
	}

	public void setShiftDate(CscCalendar d) {
		this.shiftDate = d;
	}

	public CscCalendar getShiftDate() {
		return this.shiftDate;
	}
	
	/** �ӡ�ä��ҡ���ٴ�ѵ���ѹ��ش */
	public void findHolidaySwipe() {
		CscCalendar beg, end;
		beg = new CscCalendar(this.shiftDate.getTimestamp());
		end = new CscCalendar(this.shiftDate.getTimestamp());
		
		try {
			beg.setCSCTime((float)00.00);
			end.setCSCTime((float)23.59);
		} catch (Exception e) {
			MyLog.error(this, e);			
		}
		
		Vector vt;
		this.swipeHoliday.clear();
		vt = this.swipeData.getSwipeList(new TimeZone(beg, end));
		this.swipeHoliday = (Vector) vt.clone();
		
		return;
	}
	
	public void genProcessResult() {		
		this.errorResult.clear();
 		if (this.swipeHoliday.size() > 0) {
   			this.errorResult.put("11",this.swipeHoliday);    			  				
   		}
    }

	public HashMap getErrorResult() {
		return this.errorResult;
	}
	
	public void setErrorResult(HashMap hm) {
		this.errorResult = hm;
	}
	
	/*
	 * ������ѹ�ѧ����� ���ѹ����ͧ�ӧҹ�������
	 * ���硨ҡ�������ѹ�ͧ��
	 * �ҡ�� A ���� M ��� return false
	 */
	public boolean isHoliday() {
		boolean result = true;
		String eventGroup = "";
		Iterator it = this.keySet().iterator();
		while (it.hasNext() && result) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			eventGroup = sh.getEventGroup();
			if (sh.isWorking()) result = false;
		}
		
		/*if (this.size()==1 && eventGroup.equals("O")) {
			result = true;
		}*/
		return result;
	}
		
	public Vector getSwipeHoliday() {
		return this.swipeHoliday;
	}
	
	public void setSwipeHoliday(Vector vt) {
		this.swipeHoliday = vt;
	}
	
	/*
	 * �ӡ�ä�������ѹ�˹���ѹ��ش��Ш��ѻ���������ѹ��ش��Шӻ��������
	 * ����� H=�ѹ��ش��Ш��ѻ����, I=�ѹ��ش��Шӻ�, T=�ѹ�ӧҹ����
	 */
	public String getStopDayStatus() { 
		String status = "";
		Iterator it = this.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			if (sh.getEventGroup().equals("H") || sh.getEventGroup().equals("I")) {
				return sh.getEventGroup();
			} else if (sh.getEventGroup().equals("A") || sh.getEventGroup().equals("T")) {
				return "T";
			}
		}
		return status;
	}
	
	/*
	 * �ӡ�� clone ������
	 */
	/*public DayShift cloneData() {
		DayShift ds = new DayShift();
		ds.setErrorResult(this.errorResult);
		ds.setShiftDate(this.shiftDate);
		ds.setSwipeHoliday(this.swipeHoliday);
		ds.setSwipeTrans(this.swipeData);
		ds.setUprofile(this.getUprofile());
		Iterator it = this.keySet().iterator();
		while (it.hasNext()) {
			String code = (String) it.next();
			Shift sh = (Shift) this.get(code);
			ds.put(code, sh.cloneData());
		}
		return ds;
	}*/
	
}