//--------------------------------------------------------------------------------------------------------------
//
// Parameters
// 	oVecWebSess: Vector Web Session object; the root.
// 	objRecordDoc:	the Record HTML document (the form containing the fields).
// 	strFieldID, strFieldCaption: of the TotalTime field, where the total accumulated is stored.
// 	oMqButton:  MqButton object of the Record HTML document (the form containing the fields)
// 	OnRecordChangedFunc: function to call when the record changes. To be moved to CurrentRecord
// 	oWinMgr: at the moment, only the window/object that has the method OpenModalWindow
//
//--------------------------------------------------------------------------------------------------------------
function CMqTimer(oVecWebSess, objRecordDoc, strFieldID, strFieldCaption, oMqButton, funOnRecordChanged, oWinMgr)
{
	var m_lngStartTime=0;
	var m_objTimerTickFunc=null;
	var m_arrRequiredFields=new Array();
	var m_arrEntryFields=new Array();
	var m_oVecWebSess=oVecWebSess;
	var m_objRecordDoc=objRecordDoc;
	var m_strFieldID=strFieldID;
	var m_strFieldCaption=strFieldCaption;
	var m_blnTimerChanged=false;
	var m_objMqButton=oMqButton;
	var m_oTotalTimeFldVal;
	var m_oCurrRec;
	var m_funOnRecordChanged=funOnRecordChanged;
	var m_oWinMgr=oWinMgr;
	
	if (strFieldID){
		if (m_oVecWebSess){
			m_oCurrRec=m_oVecWebSess.RecordMgr().CurrentRecord();
	
			if(m_oCurrRec){
				//Actually a string with the number
				m_oTotalTimeFldVal=m_oCurrRec.FldVals(strFieldID);  
			}
		}
	}
	
	// Dts Field to store the time to add to the timer field
	var m_iAdditionalTimeEntryFld;
	
	var TIMER_BUTTON_BASE_CLASS="StartStopTimer";
	var TIMER_BUTTON_BASE_NAME="StartStopTimer";
	var MAX_ENTRY_LEN=255;
	var FIELDS_DELIM=",";
	
	var SECS_IN_MIN=60;
	var MINS_IN_HOUR=60;
	var HOURS_IN_DAY=24;
	var TIMER_DELIM=":";

	function _GetCurrentTime()
	{
		var today=new Date();
		var lngSecs = today.getSeconds();
		var lngMins = today.getMinutes();
		var lngHrs = today.getHours();

		return (lngSecs + (SECS_IN_MIN * lngMins) + (SECS_IN_MIN * MINS_IN_HOUR * lngHrs));
	}
		
	function _GetMinsDiff(lngStartSecs, lngEndSecs)
	{
		var lngDiff=lngEndSecs - lngStartSecs;
			
		return Math.floor(lngDiff/SECS_IN_MIN);
	}
			
	function ConfigTimer(strRequiredFieldIDs, strEntryFields)
	{
		if(strRequiredFieldIDs!==""){
			m_arrRequiredFields=strRequiredFieldIDs.split(FIELDS_DELIM);
		}
		if(strEntryFields!==""){
			m_arrEntryFields=strEntryFields.split(FIELDS_DELIM);
		}
	}
	
	function _GetTimerButtonName()
	{
		return m_strFieldID + "_" + TIMER_BUTTON_BASE_NAME;
	}
	
	function OpenTimeCalcWindow()
	{
		if(this.IsTimerRunning()){
			g_MqRef.MsgHlpr.DisplayMessage(g_MqRef.MqStr.Format(g_MqRef.RESX['UNABLE_TO_ADD_MANUAL_TIME'], m_strFieldCaption));
		}else{
			if(m_oWinMgr){
				m_oWinMgr.OpenModalWindow("TmplAddToFieldVal.htm?FID=" + m_strFieldID + 
											"&FC=" + g_MqRef.MqStr.MqEncodeURIComponent(m_strFieldCaption), 400, 200, false);
			}
		}
	}
		
	function StartStopTimer()
	{
		if(!this.IsTimerRunning()){
			this.StartTimer();
		}else{
			this.StopTimer(true);
		}
	}
		
	function StartTimer()
	{
		if(m_objRecordDoc){
			m_lngStartTime=_GetCurrentTime();
			this.DoCounter_Tick();
			
			if(m_funOnRecordChanged){
				m_funOnRecordChanged(m_strFieldID);
			}
				
			var objButton=m_objRecordDoc.getElementById(m_objMqButton.GetButtonHTMLName(_GetTimerButtonName()));
			m_objMqButton.Toggle(objButton, TIMER_BUTTON_BASE_CLASS);
		}
	}

	function StopTimer(blnApplyChange)
	{
		if(m_objTimerTickFunc){
			window.clearTimeout(m_objTimerTickFunc);
			m_objTimerTickFunc=null;
					
			if(blnApplyChange){
				var lngMinsPassed = _GetMinsDiff(m_lngStartTime, _GetCurrentTime());
						
				if(lngMinsPassed>0){
					this.AddTimeToTimer(lngMinsPassed);
					
					this.SetFieldsRequired_UI(true);
				}			
			}
			var objButton=m_objRecordDoc.getElementById(m_objMqButton.GetButtonHTMLName(_GetTimerButtonName()));
			m_objMqButton.Toggle(objButton, TIMER_BUTTON_BASE_CLASS);
					
			m_lngStartTime = 0;
					
			this.InitCounterVal();
		}
	}
	
	function AddTimeToTimer(lngMinsToAdd)
	{
		if(m_oTotalTimeFldVal){
			this.FormatTimerVal(false);
			m_oTotalTimeFldVal.SetValue(Number(m_oTotalTimeFldVal.GetValue()) + Number(lngMinsToAdd));

			if (m_iAdditionalTimeEntryFld)
			{
				var oFldVal=m_oCurrRec.FldVals(m_iAdditionalTimeEntryFld);  
				
				if (oFldVal)
				{
					oFldVal.SetValue(Number(oFldVal.GetValue()) + Number(lngMinsToAdd));
				}
			}

			
			this.FormatTimerVal(true);
			
			this.SetTimerHasChanged(true);
		}	
		
	}
	
	function DoCounter_Tick()
	{
		if(m_objRecordDoc){
			var objCounter=m_objRecordDoc.getElementById(m_strFieldID + "_timerCounter");
		
			if(objCounter){
					
				var strTimer;
				
				var lngDiff = _GetCurrentTime() - m_lngStartTime;
				
				var lngHrs = Math.floor(lngDiff / (SECS_IN_MIN * MINS_IN_HOUR));

				var lngMins = Math.floor((lngDiff / (SECS_IN_MIN * MINS_IN_HOUR) - lngHrs) * MINS_IN_HOUR);

				var lngSecs = Math.round((((lngDiff / (SECS_IN_MIN * MINS_IN_HOUR) - lngHrs) * SECS_IN_MIN) - lngMins) * MINS_IN_HOUR);

				strTimer=lngHrs + TIMER_DELIM;

				if(lngMins<10){
					strTimer+='0';
				}			
				strTimer+=lngMins + TIMER_DELIM;

				if(lngSecs<10){
					strTimer+='0';
				}			
				strTimer+=lngSecs;

				objCounter.innerHTML = strTimer;		
				
				m_objTimerTickFunc=window.setTimeout(DoCounter_Tick,1000)
			}
		}
	}
		
		
	function IsTimerRunning()
	{
		return (parseInt(m_lngStartTime)!==0);
	}
		
	function ResetTimer()
	{
		if(this.IsTimerRunning()){	
			this.StopTimer(false);
		}
	}
	function SetFieldsRequired_UI(blnRequired)
	{
		var lngCount;
		var objTD;
		var lngChildCount;
		var objFont;
		
		if(m_objRecordDoc){
			if(m_arrRequiredFields){
				for(lngCount=0; lngCount<m_arrRequiredFields.length;lngCount++){
					objTD=m_objRecordDoc.getElementById("MqFC_" + m_arrRequiredFields[lngCount]);
					if(objTD){
						for(lngChildCount=0; lngChildCount<objTD.childNodes.length; lngChildCount++){
							objFont=objTD.childNodes.item(lngChildCount);
							if(objFont){
								if(objFont.tagName.toLowerCase()==="font"){
									if(blnRequired){
										objFont.className="requiredfield";
									}else{
										objFont.className="normalfield";
									}
								}
							}
						}
					}
				}
			}
		}
	}

	function _GetFieldCaption(lngFieldID)
	{
		var objFont;
		var lngChildCount;
		var strCaption="";
		
		var objTD=m_objRecordDoc.getElementById("MqFC_" + lngFieldID);
		if(objTD){
			for(lngChildCount=0; lngChildCount<objTD.childNodes.length; lngChildCount++){
				objFont=objTD.childNodes.item(lngChildCount);
				if(objFont){
					if(objFont.tagName.toLowerCase()=="font"){
						strCaption = objFont.innerHTML;
						strCaption=g_MqRef.MqStr.StripTrailing(strCaption, ":");
						break;
					}
				}
			}
		}
		return strCaption;
	}

	
	function ValidateRequiredFields()
	{
		var strMsg="";
		var lngFieldID;
		var lngCount;
		var oFldVal;
		
		if(m_arrRequiredFields){
			if(m_oCurrRec){
				for(lngCount=0; lngCount<m_arrRequiredFields.length;lngCount++){
					lngFieldID=m_arrRequiredFields[lngCount];
					
					oFldVal=m_oCurrRec.FldVals(lngFieldID);  
	
					if (oFldVal)
					{
						if(oFldVal.GetValue()==""){
							strMsg+=g_MqRef.MqStr.Format(g_MqRef.RESX['WARNING_MESSAGE_REQUIRED_FIELD'], 
									_GetFieldCaption(lngFieldID)) + "\n\n";
						}
					}
				}
			}
		}
		return strMsg;
	}
	
	function GetTimerHasChanged()
	{
		return m_blnTimerChanged;
	}
	
	function SetTimerHasChanged(blnChanged)
	{
		m_blnTimerChanged=blnChanged;
	}
	
	function InitCounterVal()
	{
		var objCounter=m_objRecordDoc.getElementById(m_strFieldID + "_timerCounter");
		
		if(objCounter){
			objCounter.innerHTML="0:00:00";
		}
	}
	
	function FormatTimerVal(blnForDisplay)
	{
		var lngDays=0;
		var lngHours=0;
		var lngMins=0;
		var lngTotalMins=0;
		var arrTimerVals;
		var strVal="";
		var IDX_DAYS=0;
		var IDX_HOURS=1;
		var IDX_MINS=2;
		

		if(m_oTotalTimeFldVal){
			strVal=m_oTotalTimeFldVal.GetValue();

			if(blnForDisplay){
				//convert mins to display
			
				if(strVal.indexOf(TIMER_DELIM)<=0){
					lngTotalMins=strVal;
					
					if(lngTotalMins==""){
						lngTotalMins=0;
					}	
					lngDays=parseInt(lngTotalMins/(MINS_IN_HOUR*HOURS_IN_DAY));
				
					if(lngDays>0){
						lngTotalMins=(lngTotalMins-(lngDays*MINS_IN_HOUR*HOURS_IN_DAY));
					}
				
					lngHours=parseInt(lngTotalMins/MINS_IN_HOUR);
					if(lngHours>0){
						lngTotalMins=(lngTotalMins-(lngHours*MINS_IN_HOUR));
					}
				
					lngMins=lngTotalMins;
				
					if(lngMins<10){
						lngMins="0"+lngMins;
					}
					if(lngHours<10){
						lngHours="0"+lngHours;
					}
					
					m_oTotalTimeFldVal.SetValue(lngDays+TIMER_DELIM+lngHours+TIMER_DELIM+lngMins);
				}
			}else{

				if(strVal.indexOf(TIMER_DELIM)>0){
					//convert display to mins
					arrTimerVals=strVal.split(TIMER_DELIM);
					if(arrTimerVals.length>=IDX_MINS){
						lngTotalMins = (parseInt(arrTimerVals[IDX_DAYS]) * MINS_IN_HOUR * HOURS_IN_DAY);
						lngTotalMins+=(parseInt(arrTimerVals[IDX_HOURS]) * MINS_IN_HOUR);
						lngTotalMins+=parseInt(arrTimerVals[IDX_MINS]);
						m_oTotalTimeFldVal.SetValue(lngTotalMins);
					}
				}
			}
			
		}
	}
	
	function SetEntryValues()
	{
		var strEntryVal="";
		var lngCount;
		var lngReqFieldID;
		var lngEntryFieldID;
		var oFldVal;
		
		if(m_arrRequiredFields){
			if(m_arrEntryFields){
				if(m_arrEntryFields.length==m_arrRequiredFields.length){
					if(m_oCurrRec){
						for(lngCount=0; lngCount<m_arrEntryFields.length;lngCount++){
							lngReqFieldID=m_arrRequiredFields[lngCount];
							lngEntryFieldID=m_arrEntryFields[lngCount];
							
							oFldVal=m_oCurrRec.FldVals(lngReqFieldID);  
		
							if (oFldVal)
							{
								strEntryVal=oFldVal.GetValue();
	
								strEntryVal = g_MqRef.MqStr.Left(strEntryVal, MAX_ENTRY_LEN);
							}
							
							oFldVal=m_oCurrRec.FldVals(lngEntryFieldID);  
		
							if (oFldVal)
							{
								oFldVal.SetValue(strEntryVal);
	
							}
							
						}
					}
				}
			}			
		}
	}
	
	// To trak each added time per save in a separate field, with history etc.
	function SetAdditionalTimeEntryFld(iAdditionalTimeEntryFld) 
	{
		m_iAdditionalTimeEntryFld=iAdditionalTimeEntryFld;
	}
	

	this.ConfigTimer=ConfigTimer;
	this.OpenTimeCalcWindow=OpenTimeCalcWindow;
	this.StartStopTimer=StartStopTimer;	
	this.IsTimerRunning=IsTimerRunning;
	this.ResetTimer=ResetTimer;
	this.DoCounter_Tick=DoCounter_Tick;
	this.SetFieldsRequired_UI=SetFieldsRequired_UI;
	this.GetTimerHasChanged=GetTimerHasChanged;
	this.SetTimerHasChanged=SetTimerHasChanged;
	this.FormatTimerVal=FormatTimerVal;
	this.InitCounterVal=InitCounterVal;
	this.ValidateRequiredFields=ValidateRequiredFields;
	this.AddTimeToTimer=AddTimeToTimer;
	this.SetEntryValues=SetEntryValues;
	this.SetAdditionalTimeEntryFld=SetAdditionalTimeEntryFld;
	this.StartTimer=StartTimer;
	this.StopTimer=StopTimer;
}

function MqTimerAdapterExt(objTimer, lngFieldID, strFieldCaption)
{			
	var m_objTimer=objTimer;
	var m_lngFieldID=lngFieldID;
	var m_strFieldCaption=strFieldCaption;
	
	function saveBefore(objExtHdlr)
	{
		if(m_objTimer){
			if(m_objTimer.IsTimerRunning()){
				objExtHdlr.SetCancelProcess(true);
				objExtHdlr.SetErrorMsg(g_MqRef.MqStr.Format(g_MqRef.RESX['MSG_STOP_TIMERS_BEFORE_SAVING'], m_strFieldCaption));
			}else{
				if(m_objTimer.GetTimerHasChanged()){
					var strMsg=m_objTimer.ValidateRequiredFields();
					if(strMsg===""){
						
						//set the entry fields to 255 chars of the required fields
						m_objTimer.SetEntryValues();
						
						//convert the timer value back to minutes
						m_objTimer.FormatTimerVal(false);
					}else{
						objExtHdlr.SetCancelProcess(true);
						objExtHdlr.SetErrorMsg(strMsg);
					}				
				}else{					
					//convert the timer value back to minutes
					m_objTimer.FormatTimerVal(false);
				}
			}
		}
		return objExtHdlr;
	}

	function saveAfter()
	{
		if(m_objTimer){
			m_objTimer.SetFieldsRequired_UI(false);
		}
	}
	
	function cancelAfter()
	{
		if(m_objTimer){
			m_objTimer.ResetTimer();
			m_objTimer.SetFieldsRequired_UI(false);
		}
	}
	
	function OnBeforeLoadRec()
	{
		m_objTimer.SetTimerHasChanged(false);
	}
	
	function OnAfterLoadRec()
	{
		//change format of current time to be in hours:mins format
		m_objTimer.FormatTimerVal(true);
		m_objTimer.InitCounterVal();
	}
	
	this.Name="MqTimerAdapterExt " + m_lngFieldID;
	this.saveBefore=saveBefore;
	this.saveAfter=saveAfter;
	this.cancelAfter=cancelAfter;
	this.OnBeforeLoadRec=OnBeforeLoadRec;
	this.OnAfterLoadRec=OnAfterLoadRec;
	
	WriteConsole("MqRoleAdapter: Initializing the extension " + this.Name);		
}
