if(window.Node && Node.prototype && !Node.prototype.contains){
  Node.prototype.contains = function (arg){
    return !!(this.compareDocumentPosition(arg) & 16);
  };
}

jQuery.fn.timePicker24 = function(settings) {
  var options = {
    hourRange   : [0,24],
    hourStep    : 1,
		minuteRange : [0,60],
    minuteStep  : 5,
    showMinutes : true,
		secondRange : [0,60],
    secondStep  : 5,
    showSeconds : false,
    separator   : ':',
    clearField  : 'Clear field',
    hours       : 'Hours',
    minutes     : 'Minutes',
    seconds     : 'Seconds'
  };
  jQuery.extend(options, settings || {});

	var selfRef = this;

	jQuery(document).bind('DOMFocusIn mousedown blur', function(e) {
	  e = e || window.event;
    var target = e.target || e.srcElement || false;
    if (!target) { return; }
    if (selfRef.isOpen
       && target != selfRef.picker
       && !selfRef.picker.contains(target)) {
      selfRef.toggleWidget();
    }
	});

	if(typeof(jQuery.hasTimePicker24) == 'undefined') {

	  selfRef.currentInput = null;
		selfRef.isOpen = false;
	  this.span = null;

	  this.maxClickCnt = 1;
	  this.clickCnt = 0;

	  // those are used several times as a shortcut
	  this.refArr = ['hrs','min','sec'];
	  this.refObj = {hrs:0,min:1,sec:2}

		this.addSeparator = function() {
		  jQuery(this.picker).append('<div class="ui-separator"/>');
		}

		this.toggleWidget = function(offset){
		  if(!offset) {
		    jQuery('span', selfRef.jPicker).removeClass('ui-state-active');
		    selfRef.jPicker.hide();
		    selfRef.isOpen = false;
		  }
		  else {
		    for( var item in selfRef.refObj) {
				  if(!selfRef[item]) {
				    continue;
				  }
  				jQuery('span', selfRef[item]).each(function() {
  				  if(this.innerHTML === selfRef.currentInput.valueArr[selfRef.refObj[item]]){
  				    jQuery(this).addClass('ui-state-active');
  				  }
  				})
				}
				selfRef.jPicker.css({top:(offset.top + 21) + 'px',left:offset.left + 'px'});
		    selfRef.jPicker.show('slow');
		    selfRef.isOpen = true;
		  }
		}

		// building the spans
		this.buildSpan = function(cnt, container) {
		  if(typeof(selfRef.refObj[container]) == 'undefined') {
		    return false;
		  }
			this.span = document.createElement('span');
			this.span.innerHTML = cnt < 10 ? '0' + cnt.toString() : cnt;
			this.span.className = 'ui-state-default';
			this[container].appendChild(this.span);
			jQuery(this.span).click(function() {
				selfRef.applyValue(this, selfRef.refObj[container]);
				jQuery('span',this.parentNode).removeClass('ui-state-active');
				jQuery(this).addClass('ui-state-active');
	      selfRef.clickCnt++;
	      if(selfRef.clickCnt == selfRef.maxClickCnt) {
	        selfRef.toggleWidget();
	      }
			})
			.mouseover(function() {
				jQuery(this).addClass('ui-state-hover');
			})
			.mouseout(function() {
				jQuery(this).removeClass('ui-state-hover');
			})
		}

		this.applyValue = function(sender, i) {
			if(selfRef.currentInput) {
				selfRef.currentInput.valueArr[i] = sender.innerHTML;
				if(options.showMinutes && options.showSeconds) {
  				selfRef.currentInput.value = selfRef.currentInput.valueArr[0]
  				                           + options.separator
  				                           + selfRef.currentInput.valueArr[1]
  				                           + options.separator
  				                           + selfRef.currentInput.valueArr[2];
				}
				else if(options.showMinutes) {
  				selfRef.currentInput.value = selfRef.currentInput.valueArr[0]
  				                           + options.separator
  				                           + selfRef.currentInput.valueArr[1];
				}
				else {
  				selfRef.currentInput.value = selfRef.currentInput.valueArr[0];
				}
				if(selfRef.currentInput.valueArr[0] == selfRef.currentInput.valueArr[1] == selfRef.currentInput.valueArr[2] == '00') {
				  selfRef.currentInput.valueArr[2] = '01';
				}
				selfRef.currentInput.orig.value = selfRef.currentInput.valueArr[0]
				                                + ':'
				                                + selfRef.currentInput.valueArr[1]
				                                + ':'
  				                              + selfRef.currentInput.valueArr[2];
			}
		}


		// create timepicker
		this.picker = document.createElement('div');
		document.body.appendChild(this.picker);
		this.jPicker = jQuery(this.picker);
		this.picker.style.zIndex = 10000;
		this.picker.style.display = 'none';

		this.picker.className = 'ui-timepicker24 ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible';
		this.picker.id = 'ui-timepicker24-div';

		// hours

		this.hrs = document.createElement('div');
		if(options.hours) {
		  this.hrsTitle = document.createElement('div');
		  this.hrsTitle.className = 'ui-timepicker24-title';
		  this.hrsTitle.innerHTML = options.hours;
		  this.hrs.appendChild(this.hrsTitle);
		}
		this.hrs.className = 'ui-timepicker24-block';
		this.picker.appendChild(this.hrs);
		for(var i = options.hourRange[0]; i < options.hourRange[1]; i += options.hourStep) {
			this.buildSpan(i, 'hrs');
		}

		if(options.showMinutes) {
		  this.addSeparator();
  		this.min = document.createElement('div');
  		if(options.minutes) {
  		  this.minTitle = document.createElement('div');
  		  this.minTitle.className = 'ui-timepicker24-title';
  		  this.minTitle.innerHTML = options.minutes;
  		  this.min.appendChild(this.minTitle);
  		}
  		this.min.className = 'ui-timepicker24-block';
  		this.picker.appendChild(this.min);
  		for(var i = options.minuteRange[0]; i < options.minuteRange[1]; i += options.minuteStep) {
  			this.buildSpan(i, 'min');
  		}
	    this.maxClickCnt++;
  	}

		if(options.showMinutes && options.showSeconds) {
		  this.addSeparator();
  		this.sec = document.createElement('div');
  		if(options.seconds) {
  		  this.secTitle = document.createElement('div');
  		  this.secTitle.className = 'ui-timepicker24-title';
  		  this.secTitle.innerHTML = options.seconds;
  		  this.sec.appendChild(this.secTitle);
  		}
  		this.sec.className = 'ui-timepicker24-block';
  		this.picker.appendChild(this.sec);
  		for(var i = options.secondRange[0]; i < options.secondRange[1]; i += options.secondStep) {
  			this.buildSpan(i, 'sec');
  		}
	    this.maxClickCnt++;
  	}

  	this.addSeparator();

  	this.jClear = jQuery('<div class="ui-clear-field ui-widget-header">' + options.clearField + '</div>')
  	              .click(function() {
  	                selfRef.currentInput.value = '';
  	                selfRef.currentInput.orig.value = '';
	                  selfRef.toggleWidget();
  	              })
		jQuery(this.picker).append(this.jClear);





		// assign timepicker to input
		return this.each(function() {
			if(this.tagName != 'INPUT') {
				return false;
			}
			this.clone = this.cloneNode(false);
			this.clone.orig = this;
			this.clone.removeAttribute('name');
		  jQuery('label[for=' + this.id + ']').attr('for', this.id + '-clone');
		  this.clone.id = this.id + '-clone';
			this.clone.setAttribute('readonly', true);
			jQuery( this ).css('display','none');
			this.parentNode.appendChild(this.clone);


			var jThis = jQuery(this.clone);

			this.clone.valueArr = this.clone.value && this.clone.value.indexOf(options.separator) > -1
									        ? this.clone.value.split(options.separator)
									        : ['00','00','00'];

			jThis.click(function() {
				selfRef.currentInput = this;
	      selfRef.clickCnt = 0;
	      selfRef.toggleWidget(jQuery(this).offset());
			})
		})

		// avoid multiple calls
		jQuery.hasTimePicker24 = true;
	}
}

