$.fn.durationField = function(options){
    var settings = {
        size: 6,
        parseoninit: true,
        onerror: null,
		allowNegatives: false
    };

    if (options) {
        jQuery.extend(settings, options);
    };
	
	var validate = /^\d*([\.:])*\d*$/i
	var validateNegative = /^[-]\d*([\.:])*\d*$/i
	
	return this.each(function() {
		$(this).attr("size", settings["size"]);
		$(this).bind("blur", function(e){
			try
			{
				var val = $(this).val().replace(/\s/g, "");
				
				if(val.length == 0)
				{
					return;
				}
				else
				{
					if(!validate.test(val))
					{
						if((settings["allowNegatives"] == false) || (settings["allowNegatives"] == true && !validateNegative.test(val)))
						{
							return;
						}
					}
				}

				$(this).val(reformatDuration(val));
			}
			catch (e)
			{
				if(settings["onerror"])
				{
					return settings["onerror"](this, e);
				}
			}
			
		});

		$(this).bind("keypress", function(e){
			if(e.keyCode==13) $(e.target).trigger("blur");
		});

		if(settings["parseoninit"]) $(this).trigger("blur");
	});
	
	function reformatDuration(val) {
		var duration = "";
		var isNegative = false;
		
		// Check if the first character is a negative
		if(val.substring(0, 1) == "-") {
			isNegative = true;
			val = val.substring(1, val.length);
		}
		
		// Get the duration based on a decimal
		duration = durationDecimal(val);
		
		// Get the duration based on a semi-colon
		if(duration.length == 0) { duration = durationColon(val); }
		
		// Get the duration based on number alone
		if(duration.length == 0) { duration = durationNumbers(val); }		
		
		// Continue if the value was negative
		if(isNegative) { duration = "-" + duration; }

		// Return the formatted duration
		return duration;
	}
	
	function durationNumbers(val) {
		var validNumbers = /^\d+$/i
		var duration = "";
		
		// Check if only numbers exist
		if(validNumbers.test(val) && val.length > 0) {
			var hours = 0;
			var minutes = 0;
		
			// Continue if only one character was found
			if(val.length == 1) {
				hours = parseInt(val, 10);
			}
			else if (val.length == 2) {
				minutes = parseInt(val, 10);
			}
			else {
				var strHours = "0";
				var strMinutes = "0";

				// Get the hours and minutes, the minutes are always the last two fields
				strHours = val.substring(0, val.length - 2);
				strMinutes = val.substring(val.length - 2);
				
				// Convert the hours and minutes
				hours = parseInt(strHours, 10);
				minutes = parseFloat(strMinutes, 10);
			}
			
			// Build the duration
			duration = buildDuration(hours, minutes);
		}
		
		return duration;
	}
	
	function durationColon(val) {
		var colonPos = val.indexOf(":");
		var duration = "";
	
		// Continue if a colon exists
		if(colonPos >= 0) {
			var beforeColon = "0";
			var afterColon = "0";
			var hours = 0;
			var minutes = 0;

			// Get the data before and after the decimal
			if(colonPos > 0) { beforeColon = val.substring(0, colonPos); }
			if(colonPos < val.length - 1) { afterColon = val.substring(colonPos + 1); }

			// If only one number is found, assume its a tenth
			if(afterColon.length == 1) { afterColon = afterColon + "0"; }
			
			// Convert the hours and minutes
			hours = parseInt(beforeColon, 10);
			minutes = parseFloat(afterColon, 10);
			
			// Build the duration
			duration = buildDuration(hours, minutes);
		}
		
		// Return the duration
		return duration;
	}
	
	function durationDecimal(val) {
		var decimalPos = val.indexOf(".");
		var duration = "";
		
		// Continue if the decimal exists
		if(decimalPos >= 0) {
			var beforeDecimal = "0";
			var afterDecimal = "0";
			var hours = 0;
			var minutes = 0;

			// Get the data before and after the decimal
			if(decimalPos > 0) { beforeDecimal = val.substring(0, decimalPos); }
			if(decimalPos < val.length - 1) { afterDecimal = val.substring(decimalPos + 1); }

			// Convert the hours and minutes
			hours = parseInt(beforeDecimal, 10);
			minutes = Math.round(parseFloat("." + afterDecimal, 10) * 60);
			
			// Build the duration
			duration = buildDuration(hours, minutes);
		}
		
		// Return the duration
		return duration;
	}
	
	function buildDuration(hours, minutes) {
		 var strHours = "";
		 var strMinutes = "";
		 
		// Continue if the minutes is greater than an hour
		if(minutes > 59){
			var tempHours = 0;
			tempHours = Math.floor(minutes / 60);
			minutes = Math.round(minutes - (tempHours * 60));
			hours += tempHours;
		}

		// Get the hours and minutes
		strHours = hours + "";
		strMinutes = minutes + "";
		
		// Add zeros if necessary
		if(strHours.length == 1) { strHours = "0" + strHours; }
		if(strMinutes.length == 1) { strMinutes = "0" + strMinutes; }
		
		// Return the formatted duration
		return strHours + ":" + strMinutes;
	}

};

