/** Extra angle converter (deg, min, sec to frac)
 *@author dan
 */

$.fn.deg2frac = function ()
{	
	/*
	 * Interface
	 */
	
	var $inputs = this.find('input'),
		$pattern = this.find('.pattern');
	
	$inputs
		.mousedown(setFocused)
		.focus(setFocused)
		.each(setWidth)
		.bind('keyup input', setWidth)
		.change(correct)
		.change(setWidth);
	
	$inputs.filter(':first').addClass('focus');
	
	function setFocused ()
	{
		$inputs.removeClass('focus');
		$(this).addClass('focus');
	}
	
	function setWidth ()
	{
		$(this).css(
			'width', 
			($pattern.text(this.value).width() + 1) + 'px'
		);
		if (!$.browser.msie)
			this.value = this.value; //place text in proper place
	}
	
	
	/*
	 * Conversion
	 */
	
	var $deg = $inputs.filter(':eq(0)'),
		$min = $inputs.filter(':eq(1)'),
		$sec = $inputs.filter(':eq(2)');
	
	var $degs = $inputs.filter(':lt(3)'),
		$frac = $inputs.filter(':eq(3)');
	
	$degs
		.keyup(validateInt)
		.keyup(deg2frac);
		
	$frac
		.keyup(validateFloat)
		.keyup(frac2deg);
	
	var VALID = true;
	
	function deg2frac ()
	{
		if (VALID)
		{
			var frac = $deg.val().int() + $min.val().int() / 60 + $sec.val().int() / 3600;
			frac = Math.floor(frac * 10000) / 10000; //4 digits after comma
			$frac.val(frac.toString().replace('.', ','));
			$frac.each(setWidth);
		}
	}
	
	function frac2deg ()
	{
		if (VALID)
		{
			var frac = parseFloat($frac.val().replace(',','.')),
				deg = Math.floor(frac),
				min = Math.floor((frac - deg) * 60),
				sec = Math.floor((frac - deg - min/60) * 360);
			
			$deg.val(deg);
			$min.val(min);
			$sec.val(sec);
			$degs.each(setWidth);
		}
	}
	
	function check ($target, valid)
	{
		if (!valid)
			$target.addClass('error');
		else
			$target.removeClass('error');
			
		return valid;
	}
	
	function validateInt ()
	{
		VALID = true;
		$degs.each(function () 
		{
			if (!check($(this), (/^[0-9]+$/).test(this.value)) || this.value == '' )
				VALID = false;
		})
	}
	function validateFloat ()
	{
		VALID = check($(this), (/^[0-9]+([,.][0-9]+)?$/).test(this.value) || this.value == '');
	}
	
	function correct ()
	{
		if (this.value == '') this.value = 0;
	}
	
	//Defaults
	$deg.val(57);
	$min.val(17);
	$sec.val(5);
	$frac.val('57,3');
	$inputs.each(setWidth);
	
	return this;
}

String.prototype.int = function () {return parseInt(this)}