var eWorld_TimePicker_CurrentPicker;

function TimePicker_Picker(id, textBoxId, labelId, buttonId, imageId, hiddenId, validateHiddenId, enabledHiddenId, popupDivId,
   format, amDescriptor, pmDescriptor, lowerBoundTime, upperBoundTime, quadrant, offsetX, offsetY, showClearTime,
   clearTimeText, nullableText, width, height, displayUnselectable, militaryTime, minuteInterval,
   numberOfColumns, roundUpMinutes, scrollable, javascriptFunction, autoPostBack, allowArbitraryText, nullable) {
   
   this.Id = id;
   this.TextBoxId = textBoxId;
   this.LabelId = labelId;
   this.ButtonId = buttonId;
   this.ImageId = imageId;
   this.HiddenId = hiddenId;
   this.ValidateHiddenId = validateHiddenId;
   this.EnabledHiddenId = enabledHiddenId;
   this.PopupDivId = popupDivId;
   this.Format = format;
   this.AmDescriptor = amDescriptor;
   this.PmDescriptor = pmDescriptor;
   this.LowerBoundTime = lowerBoundTime;
   this.UpperBoundTime = upperBoundTime;
   this.Quadrant = quadrant;
   this.OffsetX = offsetX;
   this.OffsetY = offsetY;
   this.ShowClearTime = showClearTime;
   this.ClearTimeText = clearTimeText;
   this.NullableText = nullableText;
   this.Width = width;
   this.Height = height;
   this.DisplayUnselectable = displayUnselectable;
   this.MilitaryTime = militaryTime;
   this.MinuteInterval = minuteInterval;
   this.NumberOfColumns = numberOfColumns;
   this.RoundUpMinutes = roundUpMinutes;
   this.Scrollable = scrollable;
   this.JavascriptFunction = javascriptFunction;
   this.AutoPostBack = autoPostBack;
   this.AllowArbitraryText = allowArbitraryText;
   this.Nullable = nullable;
   
   this.ImageClick = null;
   
   this.GetStyle = function() {
      return eWorld_FindItem(eWorld_TimePicker_Styles, this.Id);
   }
   
   this.Setup = function() {
      var div = document.getElementById(this.PopupDivId);
      
      TimePicker_MouseOut();
      eWorld_AddEvent(div, 'mouseout', TimePicker_MouseOut);
      eWorld_AddEvent(div, 'mouseover', TimePicker_MouseOver);
   }
   
   this.Show = function() {
      eWorld_TimePicker_CurrentPicker = this;
      var div = document.getElementById(this.PopupDivId);
      var divIframe = document.getElementById(this.PopupDivId + '_iframe');
      var tb = document.getElementById(this.TextBoxId);
      var img = document.getElementById(this.ImageId);
      var btn = document.getElementById(this.ButtonId);
      if (div.style.display != 'none') {
         this.Hide();
      } else {
         this.DisplayPicker();
         this.Setup();
         
         if (this.Height.length > 0) {
            div.style.height = this.Height;
         }
         if (this.Width.length > 0) {
            div.style.width = this.Width;
         }
         if (this.Scrollable) {
            div.style.overflow = 'auto';
         }
         
         var obj = tb;
         if (obj == null) obj = img;
         if (obj == null) obj = btn;
         var result = eWorld_FindPosition(obj);
         var x = result.x;
         var y = result.y;
         
         div.style.visibility = 'hidden';
         div.style.display = 'block';
         
         switch (this.Quadrant) {
            case 1:
               y += (obj.offsetHeight + 1);
               break;
            case 2:
               x -= (div.offsetWidth - 2);
               break;
            case 3:
               x += (obj.offsetWidth + 1);
               break;
            case 4:
               y -= (div.offsetHeight - 1);
         }
         
         div.style.top = y + this.OffsetY + 'px';
         div.style.left = x + this.OffsetX + 'px';
         
         div.style.visibility = 'visible';
         
         if (divIframe != null) {
            divIframe.width = div.offsetWidth - 4;
            divIframe.height = div.offsetHeight - 4;
            divIframe.style.top = div.style.top;
            divIframe.style.left = div.style.left;
            divIframe.style.display = 'block';
         }
      }
   }
   
   this.DisplayPicker = function() {
      var style = this.GetStyle();
      var hid = document.getElementById(this.HiddenId);
      var i = 1;
      var cont = true;
      var theTime = new Date();
      theTime.setHours(0, 0);
      var enteredTime = this.SplitTime(hid.value, this.RoundUpMinutes);
      var lowerTime = this.SplitTime(this.LowerBoundTime, false);
      var upperTime = this.SplitTime(this.UpperBoundTime, false);
      
      var output = '<table border=0 cellspacing=0px cellpadding=2px>';
      
      var selectableFormat = '<td align=\"right\" {0}><span onclick=\"TimePicker_FindPicker(\'{1}\').SelectTime(\'{2}\')\">{2}</span></td>';
      var unselectableFormat = '<td align=\"right\" {0}><span>{1}</span></td>';
      while (cont) {
         var doIncrement = true;
         var tempOutput = '';
         var selectedTime = this.GetTime(theTime);
         if (theTime.getHours() >= lowerTime.getHours() && theTime.getHours() <= upperTime.getHours()) {
			   if (theTime.getHours() != lowerTime.getHours() && theTime.getHours() != upperTime.getHours()) {
				   if (enteredTime != null && theTime.getHours() == enteredTime.getHours() && theTime.getMinutes() == enteredTime.getMinutes()) {
					   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.SelectedTime, this.Id, selectedTime));
				   } else {
					   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.Time, this.Id, selectedTime));
					}
			   } else {
				   if (theTime.getHours() == lowerTime.getHours() && theTime.getMinutes() >= lowerTime.getMinutes()) {
					   if (enteredTime != null && theTime.getHours() == enteredTime.getHours() && theTime.getMinutes() == enteredTime.getMinutes()) {
						   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.SelectedTime, this.Id, selectedTime));
					   } else {
						   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.Time, this.Id, selectedTime));
						}
				   } else {
					   if (theTime.getHours() == upperTime.getHours() && theTime.getMinutes() <= upperTime.getMinutes()) {
						   if (enteredTime != null && theTime.getHours() == enteredTime.getHours() && theTime.getMinutes() == enteredTime.getMinutes()) {
							   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.SelectedTime, this.Id, selectedTime));
						   } else {
							   tempOutput += eWorld_ReplaceFormat(selectableFormat, new Array(style.Time, this.Id, selectedTime));
							}
					   } else {
						   if (this.DisplayUnselectable) {
							   tempOutput += eWorld_ReplaceFormat(unselectableFormat, new Array(style.DisabledTime, selectedTime));
						   } else {
							   doIncrement = false;
							}
					   }
				   }
			   } 
		   } else {
			   if (this.DisplayUnselectable) {
				   tempOutput = eWorld_ReplaceFormat(unselectableFormat, new Array(style.DisabledTime, selectedTime));
			   } else {
				   doIncrement = false;
				}
		   }
   		
		   if (i == 1 && doIncrement) {
			   output += '<tr>';
			}
   		
		   if (tempOutput.length > 0) {
			   output += tempOutput;
			}
   			
		   if (i == this.NumberOfColumns) {
			   output += '</tr>';
			   i = 0;
		   }
   		
		   if(doIncrement) {
			   i++;
			}
   	
		   var dateInMs = theTime.getTime();
		   dateInMs += this.MinuteInterval * 60 * 1000;
		   theTime.setTime(dateInMs);
		   if (theTime.getHours() == 0 && theTime.getMinutes() == 0) {
			   cont = false;
			}
      }
      
      if (i > 1 && i <= this.NumberOfColumns) {
		   while (i <= this.NumberOfColumns) {
			   output += '<td ' + style.TimeStyle + '></td>';
			   if (i == this.NumberOfColumns) {
				   output += '</tr>';
				}
			   i++;
		   }
	   }
	   
	   if(this.ShowClearTime) {
		   output += eWorld_ReplaceFormat('<tr><td colspan=\"{0}\" align=\"center\" {1}><span onclick=\"javascript:TimePicker_FindPicker(\'{2}\').Clear()\">{3}</span></td></tr>', new Array(this.NumberOfColumns, style.ClearTime, this.Id, this.ClearTimeText));
		}
	   output += '</table>';
	   
	   var div = document.getElementById(this.PopupDivId);
      var divIframe = document.getElementById(this.PopupDivId + '_iframe');
      
      div.innerHTML = output;
      
      if (divIframe != null) {
         divIframe.width = (document.all) ? div.offsetWidth : div.offsetWidth - 4;
         divIframe.height = (document.all) ? div.offsetHeight : div.offsetHeight - 4;
         divIframe.style.top = div.style.top;
         divIframe.style.left = div.style.left;
      }
   }
   
   this.Clear = function() {
      if (this.Nullable) {
         this.VisibleDate = new Date();
         if (document.getElementById(this.TextBoxId) != null) {
            document.getElementById(this.TextBoxId).value = '';
         }
         document.getElementById(this.HiddenId).value = '';
         if (document.getElementById(this.LabelId) != null) {
            document.getElementById(this.LabelId).innerHTML = this.NullableText;
         }
         document.getElementById(this.ValidateHiddenId).value = '';
         this.RaiseClientFunctions();
         this.Hide();
         this.Validate();
      }
   }
   
   this.Validate = function() {
      eWorld_ValidateControl(document.getElementById(this.ValidateHiddenId));
   }
   
   this.SelectTime = function(input) {
      var oldSelectedTime = document.getElementById(this.HiddenId).value;
      var timeHasChanged = (oldSelectedTime != input);
      if (timeHasChanged) {
         if (document.getElementById(this.TextBoxId) != null) {
            document.getElementById(this.TextBoxId).value = input;
         }
         document.getElementById(this.HiddenId).value = input;
         if (document.getElementById(this.LabelId) != null) {
            document.getElementById(this.LabelId).innerHTML = input;
         }
         var date = new Date();
         document.getElementById(this.ValidateHiddenId).value = date.getMonth() + '/' + date.getDay() + '/' + date.getFullYear() + ' ' + input;
         this.RaiseClientFunctions();
         this.Validate();
      }
      this.Hide();
   }
   
   this.Hide = function() {
      var div = document.getElementById(this.PopupDivId);
      var iframe = document.getElementById(this.PopupDivId + '_iframe');
      
      div.style.display = 'none';
      if (iframe != null) {
         iframe.style.display = 'none';
      }
      eWorld_TimePicker_CurrentPicker = null;
      
      this.RemoveEvents();
   }
   
   this.RemoveEvents = function() {
      var div = document.getElementById(this.PopupDivId);
      
      TimePicker_MouseOver();
      eWorld_RemoveEvent(div, 'mouseout', TimePicker_MouseOut);
      eWorld_RemoveEvent(div, 'mouseover', TimePicker_MouseOver);
   }
   
   this.RaiseClientFunctions = function() {
      if (this.JavascriptFunction.length > 0) {
         var value = '';
         var tb = document.getElementById(this.TextBoxId);
         var hid = document.getElementById(this.HiddenId);
         var value = '';
         if (tb != null) {
            value = tb.value;
         } else {
            value = hid.value;
         }
         
         eval(eWorld_ReplaceFormat('{0}("{1}", {2}, "{3}")', new Array(this.JavascriptFunction, value, (value.length == 0), this.Id)));
      }
      if (this.AutoPostBack) {
         __doPostBack(this.Id, '');
      }
   }
   
   this.TextChanged = function() {
      var hid = document.getElementById(this.HiddenId);
      var tb = document.getElementById(this.TextBoxId);
      var valHid = document.getElementById(this.ValidateHiddenId);
      var time = this.SplitTime(tb.value, this.RoundUpMinutes);
      
      if (!this.AllowArbitraryText) {
         if (tb.value == '' && this.Nullable) {
            this.Clear();
            return;
         } else {
            tb.value = this.GetTime(time);
         }
      }
      
      hid.value = tb.value;
      var date = new Date();
      valHid.value = date.getMonth() + '/' + date.getDay() + '/' + date.getFullYear() + ' ' + tb.value;
      
      this.RaiseClientFunctions();
      this.Hide();
      this.Validate();
   }
   
   this.SplitTime = function(inputTime, roundUp) {
	   var curSelTime = inputTime;
	   var theTime = new Date();
	   var h, m;
	   if(curSelTime == '') {
		   return null;
	   } else {
		   switch(this.Format) {
			   case 1:
			   case 6:
				   h = curSelTime.substr(0, curSelTime.indexOf(':'));
				   m = curSelTime.substr((curSelTime.indexOf(':') + 1), 2);
				   if(curSelTime.indexOf(this.PmDescriptor) > -1) {
					   if(parseInt(h) != 12) {
						   h = parseInt(h) + 12;
						}
				   } else {
					   if(parseInt(h) == 12) {
						   h = 0;
						}
				   }
				   break;
			   case 2:
			   case 3:
				   h = curSelTime.substr(0, curSelTime.indexOf(':'));
				   m = curSelTime.substr((curSelTime.indexOf(':') + 1), 2);
				   break;
			   case 4:
			   case 5:
				   var startIndex;
				   if(curSelTime.indexOf(this.AmDescriptor) > -1) {
					   startIndex = this.AmDescriptor.length;
				   } else {
					   startIndex = this.PmDescriptor.length;
					}
				   h = curSelTime.substr(startIndex, curSelTime.indexOf(':'));
				   m = curSelTime.substr((curSelTime.indexOf(':') + 1), 2);
				   break;
			   case 7:
				   h = curSelTime.substr(0, curSelTime.indexOf('.'));
				   m = curSelTime.substr((curSelTime.indexOf(':') + 1), 2);
				   if(curSelTime.indexOf(this.PmDescriptor) > -1) {
					   if(parseInt(h) != 12) {
						   h = parseInt(h) + 12;
						}
				   } else {
					   if(parseInt(h) == 12) {
						   h = 0;
						}
				   }
				   break;
			   case 8:
				   h = curSelTime.substr(0, curSelTime.indexOf(':'));
				   m = curSelTime.substr((curSelTime.indexOf(':') + 1), 2);
				   break;
			   case 9:
				   break;
		   }
		   if(isNaN(parseInt(m))) {
		      m = theTime.getMinutes();
		   }
		   
		   if(roundUp) {
			   while((m % this.MinuteInterval) != 0) {
				   m++;
				}
		   }
			
		   theTime.setHours(h);
		   theTime.setMinutes(m);
		   
		   return theTime;
	   }
   }
   
   this.GetTime = function(input) {
	   var outDate = '';
	   var h, m;
	   h = input.getHours();
	   m = input.getMinutes();
	   var format, hour, minute, descriptor;
	   
	   if (h < 12) {
	      descriptor = this.AmDescriptor;
	   } else {
	      descriptor = this.PmDescriptor;
	   }
	   
	   minute = this.GetNonMilitaryValue(m, false, true);
	   
	   switch(this.Format) {
		   case 1:
		      format = '{0}:{1} {2}';
		      hour = this.GetNonMilitaryValue(h, true, true);
			   break;
		   case 2:
		      format = '{0}:{1}'
			   hour = this.GetMilitaryValue(h, false);
			   break;
		   case 3:
		      format = '{0}:{1}'
			   hour = this.GetMilitaryValue(h, true);
			   break;
		   case 4:
		      format = '{2} {0}:{1}'
			   hour = this.GetNonMilitaryValue(h, true, true);
			   break;
		   case 5:
		      format = '{2} {0}:{1}';
			   hour = this.GetNonMilitaryValue(h, true, false);
			   break;
		   case 6:
		      format = '{0}:{1} {2}'
			   hour = this.GetNonMilitaryValue(h, true, false);
			   break;
		   case 7:
		      format = '{0}.{1}'
			   hour = this.GetMilitaryValue(h, false);
			   break;
		   case 8:
		      format = '{0}.{1}.{2}'
			   hour = this.GetNonMilitaryValue(h, true, false);
			   break;
		   case 9:
		      format = '{0}.{1}'
			   hour = this.GetMilitaryValue(h, true);
			   break;
	   }
	   return eWorld_ReplaceFormat(format, new Array(hour, minute, descriptor));
   }

   this.GetNonMilitaryValue = function(inVal, isHour, pad) {
	   var out = '';
	   if(isHour) {
		   if(inVal > 11) {
			   inVal -= 12;
			}
		   if(inVal < 10 && inVal > 0 && pad) {
			   out += '0';
			}
		   if(inVal == 0) {
			   out += '12';
		   } else {
			   out += inVal;
			}
	   } else {
		   if(inVal < 10 && pad) {
			   out += '0';
			}
		   out += inVal;
	   }
	   return out;
   }

   this.GetMilitaryValue = function(inVal, pad) {
	   var out = '';
	   if(inVal < 10 && pad) {
		   out += '0';
		}
	   out += inVal;
	   return out;
   }
   
   this.Disable = function() {
      var tb = document.getElementById(this.TextBoxId);
      var btn = document.getElementById(this.ButtonId);
      var img = document.getElementById(this.ImageId);
      var hid = document.getElementById(this.EnabledHiddenId);
      
      if (tb != null) {
         tb.disabled = true;
      }
      if (btn != null) {
         btn.disabled = true;
      }
      if (img != null) {
         img.disabled = true;
         img.style.cursor = 'default';
         this.ImageClick = img.onclick;
         img.onclick = null;
      }
      hid.value = 'false';
   }
   
   this.Enable = function() {
      var tb = document.getElementById(this.TextBoxId);
      var btn = document.getElementById(this.ButtonId);
      var img = document.getElementById(this.ImageId);
      var hid = document.getElementById(this.EnabledHiddenId);
      
      if (tb != null) {
         tb.disabled = false;
      }
      if (btn != null) {
         btn.disabled = false;
      }
      if (img != null) {
         img.disabled = false;
         img.style.cursor = 'pointer';
         img.onclick = this.ImageClick;
         this.ImageClick = null;
      }
      hid.value = 'true';
   }
   
   // NOTE: This needs to be placed at the end of the construction so that the method exists
   if (document.getElementById(this.EnabledHiddenId).value == 'false') {
      this.Disable();
   }
}

function TimePicker_Style(id, time, selectedTime, disabledTime, clearTime) {
   this.Id = id;
   this.Time = time;
   this.SelectedTime = selectedTime;
   this.DisabledTime = disabledTime;
   this.ClearTime = clearTime;
}

function TimePicker_FindPicker(id) {
   return eWorld_FindItem(eWorld_TimePicker_Pickers, id);
}

function TimePicker_LostFocus() {
   if (eWorld_TimePicker_CurrentPicker != null) {
      eWorld_TimePicker_CurrentPicker.Hide();
   }
}

function TimePicker_MouseOut() {
   eWorld_AddEvent(document, 'mousedown', TimePicker_LostFocus);
}

function TimePicker_MouseOver() {
   eWorld_RemoveEvent(document, 'mousedown', TimePicker_LostFocus);
}

function TimePicker_InitializeCompatibility() {
   if (typeof(eWorld_UI_TimePickers) != 'undefined') {
      for (var i=0; i<eWorld_UI_TimePickers.length; i++) {
         var element = document.getElementById(eWorld_UI_TimePickers[i]);
         
         eWorld_TimePicker_Pickers[i] = eval(element.timePickers);
         eWorld_TimePicker_Styles[i] = eval(element.timeStyles);
      }
   }
}
