SDNA.forms  = {};

SDNA.forms.bindFields = function( $dom ){

	$dom.find('.form .field :input')
		.unbind('focus.field')
		.bind('focus.field',
			function(e){
				
				var $field = $j(this).parents('.field').eq(0);
				var $prev = $j().data('focused_field');
				
				if( !$prev || ($prev && $field.get(0) != $prev.get(0)) ){
					$j().data('focused_field', $field);
					$j('.focus').removeClass('focus');
					$field.addClass('focus').parents('.field').addClass('focus');
				}
			}
		)
		.unbind('blur.field')
		.bind('blur.field',
			function( e ){				
				
				var $field = $j(this).parents('.field').eq(0);
				var $prev = $j().data('focused_field');
				
				if( !($prev && $prev.get(0) ==  $field.get(0) || $j(e.currentTarget) )  ){
					$field.removeClass('focus').find('.field').removeClass('focus');
				}
			}
		);

}

SDNA.forms.bindBranching = function( $dom ){

	//find branching checkboxes and radios and bind them
	$dom
		.find('form.form .branching .tree')
		.filter(':checkbox,:radio')
		.unbind('click.branch')
		.bind('click.branch',
			function( e ){
				var $input = $j(this);
				$input
					.parents('.branching')
					.eq(0)
					.find('.branch')
					[ this.checked? 'show' : 'hide']();
			}
		).trigger('click.branch');

}

SDNA.forms.bindSubmit = function( $dom ){
	
	//setup submit feedback
	$dom.find('form.form')
		.unbind('submit.feedback')
		.bind('submit.feedback', 
			function(e){
				SDNA.Event.trigger(
					'form.submitting', 
					{ 
						target: this 
					}
				); 
			}
		)
		.unbind('submitted')
		.bind('submitted', 
			function(e){
				SDNA.Event.trigger(
					'form.submitted', 
					{ 
						target: this 
					}
				);
			} 
		);

}

SDNA.forms.submitting = function( e, data ){
	
	var $form = $j(data.target);
	
	$form.addClass('submitting').find(':submit').addClass('disabled').attr('disabled','disabled');
	
	//Publish a submitting event to all listeners
	SDNA.Event.publish('form.submitting', data );
	
}
SDNA.forms.submitted = function( e, data){

	var $form = $j(data.target);
	
	$form.removeClass('submitting').find(':submit').removeClass('disabled').removeAttr('disabled','disabled');

	//Publish a submited event to all listeners
	SDNA.Event.publish('form.submitted', { target: this } );

}

SDNA.forms.bindAutogrow = function( $dom ){
	
	$j($dom).find("#eventdetails textarea,.status_bar textarea,textarea#commentinput").autogrow();
	
}

SDNA.forms.bindWatermarks = function( $dom ){
	
    var watermarks = $j($dom).find('.watermark');
    if (watermarks.length) {
        watermarks.watermark({mode:'blank'});
    }
	
}

SDNA.forms.bindUserList = function( $dom ){
	
	//setup user choices
	$j($dom).find('li.user_choice').unbind('click.user_choice').bind('click.user_choice',
		function(e){
			var $li 	= $j(this);
			var $check 	= $li.find(':checkbox'); 	

			if( $j(e.originalTarget).is('li') ){
				if( $check.is(':checked')  ){
					$check.removeAttr('checked');
					$li.removeClass('selected');
				} else {
					$check.attr('checked','checked');
					$li.addClass('selected');
				}
				$check.triggerHandler('change');
			} else {
				if( $check.is(':checked')  ){
					$li.addClass('selected');
				} else {
					$li.removeClass('selected');
				}
			}
	});
	
}


//Takes a errors array (filled with json objects) and adds them to the 
//correct fields in $form
SDNA.forms.showErrors =  function( $form, errors ){
	
	//make sure $form is a reference to a jQuery DOM wrapper
	$form = $j($form);
	
	//first, get rid of all previous errors
	$form.find('.field').removeClass('error').find('.error').remove();
	
	//errors should be of the following format:
	// [ { name: 'field_name', message: 'Error message for field name' }, ...]
	
	//Find the fields associated with the errors and add them
	for(var i=0,e; e = errors[i]; ++i){
		
		//reference to the jQuery wrapper for the DOM field
		var $input = $form.find( ':input[name=' + e.name + ']' );
		var $field = $input.parent('.field').eq(0);
		
		//ref the jQuery wraper for the label
		var $errorPlacement = $input.siblings('label').filter('[for=' + $input.attr('id') +']');
		
		if( $errorPlacement.length < 1 ){
			$errorPlacement = $field;
		}	
		
		//add an error class to field
		$field.addClass('error');
		
		//add this error
		$errorPlacement.append( $j('<span class="error" />').text( e.message ) );
		
	}

}

SDNA.forms.uploader = {};


SDNA.forms.uploader.fileOpen = function( e, q, file ){

}

SDNA.forms.uploader.fileUploaded = function($input, event, queueID, file, serverResponse, data) {
	
	if (serverResponse && serverResponse.errors) {
		
		Window.pop( serverResponse.errors, {error:true});
		
	} else {
	
		var response =  { target: $input.get(0), event: event, id:queueID, file:file, response: serverResponse , data: data };
		
		SDNA.forms.uploader.enableForm( $input )	
		
		//Publish this uploaded event to all subscribers
		SDNA.Event.publish('uploaded', response);
	}
	
}

SDNA.forms.uploader.disableForm = function( $input ){
	//ref the parent form
	var $form = $input.parents('form').eq(0);
	
	//the form has to pause submission until file upload either complete or canceled
	var $submit = $form.find('.form_actions  :submit');
	
	//disable the submit button
	$submit
		.addClass('disabled')
		.attr('disabled','disabled')
		.data('uploader_submit_text', $submit.text())
		.html( 'Uploading file&hellip;' );
}

SDNA.forms.uploader.enableForm = function( $input ){
	//ref the parent form
	var $form = $input.parents('form').eq(0);
	
	//the form has to pause submission until file upload either complete or canceled
	var $submit = $form.find('.form_actions :submit');
	
	//enable the submit button
	$submit
		.removeClass('disabled')
		.removeAttr('disabled')
		.html( $submit.data('uploader_submit_text') );
			
}

SDNA.forms.uploader.removeFile = function( $file, response  ){

	//remove it from the form
	$file.remove();
	
	//Publish this removed file  event to all subscribers
	SDNA.Event.publish('uploaded_file_removed', response);
}

SDNA.forms.uploader.removeFile.click = function(e){
	
	e.preventDefault();
	
	//find the file
	$file = $j(this).parents('span.file').eq(0);
	
	//reformat the data
	var response = $j.extend( {}, e.data, { target: this, input: e.data.target });
	
	//remove the file
	SDNA.forms.uploader.removeFile( $file, response );
}

SDNA.forms.uploader.addUploadedFile = function( e, response ){
	
	if( response.response ){
		
		var $input = $j(response.target);
		var $form = $input.parents('form').eq(0);
		
		if( $form.length > 0 ){
			
			//rip the extension from the file
			var sExt = response.file.name.replace(/\w+\.([a-z]+)$/i,'$1').toLowerCase(); 
			
			//create a truncated file name
			var sFileName = response.file.name.truncate('15', 'middle');
					
			//create a file in the drawer with a class of the extension of the file
			var $file = $j('<span class="file" />')
								.addClass( sExt )
								.append( $j('<label />').text( sFileName ) );
			
			//create a hidden photo id input to send with the form					
			var $photoId = $j('<input />').attr({
										value: response.response.photoId,
										type:'hidden',
										name:'photo_id'
									});
									
			//next add a remove button to the file span
			var $remove = $j('<a><span>Remove</span></a>')
									.attr({
										'class': 'remove',
										href: '#remove',
										title: 'Remove this file'
									})
									.bind('click.removefile', response, SDNA.forms.uploader.removeFile.click ); 
			
			//add the photo id to the file span						
			$file.append( $photoId ).append( $remove );
			
			//find the file cabinet and the drawer
			var $cabinet = $input.parents('.cabinet').eq(0);
			var $drawer = $cabinet.find('.drawer');
			
			//Create a file drawer in the cabinet if not created
			if( $drawer.length < 1 ){
				$drawer = $j('<div class="drawer" />').prependTo( $cabinet );
			}
			
			//empty the drawer if only one file can be uploaded at a time
			if( SDNA.forms.uploader.options.multi == false ){
				$drawer.empty();
			}
			
			//Finally, add the file to the drawer
			$drawer.append( $file );
			
			//reformat the data
			var response = $j.extend( {}, response, { target: $file.get(0), input: response.target });
			
			//Publish to all subscribers that this file was added
			SDNA.Event.publish('uploaded_file_added', response );
		}
	}
	
}

SDNA.forms.uploader.error = function( $input, event, queueID, file, error ){
	
	//Handle file too large error
	if( error.type == "File Size" ){
		
		var reImage    = new RegExp(SDNA.forms.uploader.imageFilesAllowed.join('|') ,'i');
		var sType 		= file.name.match( reImage )? 'image' : 'file';
		var iMaxMb		= (error.info / 1000 / 1000).toFixed(2);
		var iFileMb		= (file.size / 1000 / 1000).toFixed(2);
		var sMessage	= 'You tried to upload <strong class="message">' + file.name + ', which is ' + iFileMb + ' megabytes</strong>. The largest image that you are allowed to upload is <strong class="message">' + iMaxMb + ' megabytes.</strong>';
		var $message	= $j('<h2>That ' + sType + ' is too large</h2><p>' + sMessage + '</p>');
		
		Window.pop( $message ,{alert:true});	
		
	//all other errors defer to a generic handler	
	}else{
	
		Window.pop( error, {error:true});
	
	}

	//cancel this upload
	$input.uploadifyCancel(queueID)
			.uploadifyClearQueue();

	
}

SDNA.forms.uploader.progress = function( $input, event, queueID, file, data ){

	var $queue = $j('#' + $input.attr('id') + queueID );
	var $progress = $queue.find('.percentage');
	var iFrameWidth = 16;
	var iFrames = 16;		
	var iCurrentFrame = Math.floor(iFrames * (data.percentage/100));				
	var iBgX = iCurrentFrame * iFrameWidth * -1;
	
	$progress.css({'background-position': iBgX.toString() + 'px center' });

}


SDNA.forms.uploader.select = function( $input, event, queueID, file, data ){
		
	SDNA.forms.uploader.disableForm( $input );	
	
}


SDNA.forms.uploader.cancel = function( $input, event, queueID, file, data ){

	SDNA.forms.uploader.enableForm( $input );

}

SDNA.forms.uploader.bind = function( $dom ){

	$dom.find(':file').each(
		function( i, o){
						
			var $file 	 = $j(this);
			var $label 	 = $file.parent('label');
			var iQueueId = 'file_queue_' + i;

				//build a queue
				$label.after(
					$j('<div class="queue" />')
						.attr('id', iQueueId)
				);	
				
				//setup the options
				$j.extend( SDNA.forms.uploader.options, {
					queueID: iQueueId,		
					height: $label.height(),
					width: $label.width(),
					onProgress: function( event, queueID, file, data ){
						SDNA.forms.uploader.progress.call(this, $file, event, queueID, file, data );
					},
					onError: function( event, queueID, file, error ){
						SDNA.forms.uploader.error.call(this, $file, event, queueID, file, error );
					},
					onSelect: function( event, queueID, file ){
						SDNA.forms.uploader.select.call(this, $file, event, queueID, file );
					},
					onCancel: function( event, queueID, file ){
						SDNA.forms.uploader.cancel.call(this, $file, event, queueID, file );
					}, 
					onComplete: function(event, queueID, file, sResponse, data){
						var oResponse = eval('(' + sResponse +  ')');
						SDNA.forms.uploader.fileUploaded.call( this, $file, event, queueID, file, oResponse, data);
					}
				});	
				
				if( navigator.userAgent.indexOf("Linux")!=-1 && typeof uploadifyOptions != "undefined"){
					uploadifyOptions.hideButton = false;
					uploadifyOptions.buttonText = "Choose a photo";
				}

			var $flashUpgrade = $j('<div><h2>You need Flash Player to upload</h2><p>Please upgrade Flash player to be able to upload images. <a target="_flash" href="http://get.adobe.com/flashplayer">Upgrade Flash player now</a></p></div>');
			
			if(swfobject.getFlashPlayerVersion().major==9){
				if(swfobject.getFlashPlayerVersion().minor<=0 && swfobject.getFlashPlayerVersion().release<=24){
					$file.click(function(e){
						e.preventDefault();
						Window.pop($flashUpgrade,{alert:true});
					});
				}
			}else if(swfobject.getFlashPlayerVersion().major<9){
				$file.click(function(e){
					e.preventDefault();
					Window.pop($flashUpgrade,{alert:true});
				});
			}
			//enable flash upload	
			$file.uploadify( SDNA.forms.uploader.options );

				
		}
	);		
}

SDNA.forms.uploader.imageFilesAllowed = ['.jpg','.jpeg','.gif','.png'];

SDNA.forms.uploader.options = {
	uploader: 	'/js/uploadify.swf',
	script: 		'/ajax/Upload/Upload.jsn',
	scriptData: {"PHPSESSID" : window.CONFIG.PHPSESSID},
	hideButton:	true,
	auto: 		true,
	multi: 		false,
	cancelImg: 	'/images/icons/progress_cancel_dual.png',
	fileDesc: 	"Image Files",
	fileExt:		'*' + SDNA.forms.uploader.imageFilesAllowed.join(';*'),
	folder: 		'/uploads',
	wmode: 		'transparent',
	sizeLimit:	window.CONFIG.MAX_IMAGE_SIZE * 100 || 2000000 //MAX_IMAGE_SIZE is in KB (we need it in bytes)
};

SDNA.forms.bindAutocomplete = function( $area ) {
	var $fields = $area.find('input[type=text].loc_autocomplete');
	
	$fields.autocomplete("/ajax/Search/AutoCompleteLocation.htm", {
		minChars: 2,
		selectFirst: false
	});

	$fields.unbind('result').bind('result', function(event, data, formatted) {
		if (data && data[1])
			$j(this).val(data[1]);
	});	
}

SDNA.forms.domChanged = function(e, response ){
	
	if( response.target ){
		
		var $target = $j(response.target);		
		SDNA.forms.bind( $target );
		
	}
}

SDNA.forms.createDatePickerMenu = function( trigger, startDate, endDate ){

	//ref the jquery trigger
	var $trigger = $j(trigger);
	
	//create the menu to hold the calendar
	var menu = new Menu( trigger );
	
	var $year  = $trigger.closest('.field').eq(0).find('select[name$=Year]').eq(0);  
	var $month = $trigger.closest('.field').eq(0).find('select[name$=Month]').eq(0);  
	var $day   = $trigger.closest('.field').eq(0).find('select[name$=Day]').eq(0);

	var selectedDate = new Date();
	selectedDate.setFullYear($year.val(),$month.val()-1,$day.val());
	
		
	//init the datepicker
	var $datePicker = $j('<div>')
		.click(function(e){e.stopPropagation();})
		.addClass('datepicker')
		.datepicker(
			{  
				dateFormat: 	'yy-mm-dd',
				minDate: 		startDate,
				maxDate: 		endDate,
				defaultDate: 	selectedDate,
				onSelect: 		function(date,datepicker) {
					var values = date.split('-');
					//this needs to be generic somehow.
					$trigger.closest('.field').find('select[name$=Year]').eq(0).val(values[0]);  
					$trigger.closest('.field').find('select[name$=Month]').eq(0).val(values[1]);  
					$trigger.closest('.field').find('select[name$=Day]').eq(0).val(values[2]);
					
					//close the menu
					menu.close();
				}
			}
		);
		
	//bind change functions to the year, month and day
	function updateDatepicker(){
		var selectedDate = new Date();
		selectedDate.setFullYear($year.val(),$month.val()-1,$day.val());
		
		menu.$options.find('.datepicker').datepicker( 'setDate', selectedDate );
	}	
	$year.change( updateDatepicker );
	$month.change( updateDatepicker );	
	$day.change( updateDatepicker );			
	
	//now add the datepicker as an option to the menu
	menu.addOptions( $datePicker );
	
	//last, return the menu
	return menu;
	
}

SDNA.forms.bindCalendar = function( $area ) {
	
	$j($area || document)
		.find('button.date')
		.live('click.datepicker', 
		function(e){
			
			//keep this link from functioning
			if(e){
				e.preventDefault();
				e.stopPropagation();
			}
			
			//get a ref to this button
			var $trigger = $j(this);	
			
			//get the menu
			var mCalendar = Menu.getMenuFor( this );
			
			if( !mCalendar ){
				if( $trigger.hasClass('birthdate') ){			
					mCalendar = SDNA.forms.createDatePickerMenu( this, '-105Y','-7Y');
				}else{
					mCalendar = SDNA.forms.createDatePickerMenu( this, 0,'+7Y');
				}
			}
						
			//toggle open/closes the menu
			mCalendar.toggle();
			
			return false;	
		}
	);
		
}

SDNA.forms.bind = function( $dom ){
	
	var $dom = $j($dom) || $j(document);
	
	SDNA.forms.bindFields( $dom );
	SDNA.forms.bindWatermarks( $dom );
	SDNA.forms.bindAutogrow( $dom );
	SDNA.forms.bindSubmit( $dom );
	SDNA.forms.bindUserList( $dom );
	SDNA.forms.bindBranching( $dom );
	SDNA.forms.uploader.bind( $dom );
	//Disabled until UI is complete SDNA.forms.bindAutocomplete( $dom );
	
}

//Calendars are live bound, so they don't need to be called
SDNA.forms.bindCalendar();

SDNA.Event.subscribe('tab_loaded', 	SDNA.forms.domChanged );
SDNA.Event.subscribe('uploaded', 	SDNA.forms.uploader.addUploadedFile );
