(function($, w) {
	//add a form to the open list
	var addForm = function(data) {
		var id = data.id;
		var title = data.title || '';
		var url = data.url || '';
		var rights = data.rights || '';
		var icons = data.icons || '';
		var load = data.load || '';
		
		//check if this form is already open
		if ($('#frm'+id).length) {
			//hide all forms
			hideForms();
			//show this form
			$('#frm'+id).fadeIn().trigger('formopen');
			$('#tabs a[form="frm'+id+'"]').addClass('on');
		} else {
			//make sure we don't exceed 5 open forms
			if ($('#forms > div').length >= 5) {
				showDialog('You cannot open more than 5 forms at one time. Please close an existing form and try again.', 'notice');
			} else {
				//hide all forms
				hideForms();
				//create the tab link
				$('<a />', { href: 'javascript://', form: 'frm'+id })
					.html(title)
					.css({ zIndex: 0 - $('#tabs a').length })
					.addClass('on')
					.click(function() {
						addForm({id:id});
					})
					.appendTo($('#tabs'));
				
				//create new form container
				var formContainer = $('<div />', { id: 'frm'+id })
					.addClass('formContainer')
					.css({ position: 'relative' })
					.appendTo($('#forms'));
				//load the form into the container
				$.get('/forms/'+data.url+'?d='+(new Date).valueOf(), {id: id, title: title, rights: rights, icons: icons, load: load}, function(data, status, xhr) {
					formContainer.html(data).fadeIn();
					
					//setup masks
					$('#frm'+id+' form').applyMasks();	

					//setup sigs based on screen size	
					if (isMobile) {
						$('#frm'+id+' .pad').attr('width', (($(window).width() < 768)?($(window).width()-20):500) );
						var sig = $('#frm'+id+' .sigPad').signaturePad({drawOnly:true, lineTop: 85, clear: $('#frm'+id+' .sigClear')});
					} else {
						$('#frm'+id+' .sigPad').hide();
					}

					//mark required labels
					$('#frm'+id+' .required').each(function(i, elm) {
						$('label[for="'+$(elm).attr('id')+'"]').addClass('required');
					});
					
					//setup the tabs
					$('#frm'+id+' div.formTabs > ul > li > a')
						.attr('href', 'javascript://')
						.click(function() {
							$('#frm'+id+' div.formTabs > ul > li > a').removeClass('on');	
							$('#frm'+id+' div.formTabs > div').hide();
							$(this).addClass('on');
							$('#'+$(this).attr('tab')).fadeIn();
							
							if ($('#'+$(this).attr('tab')+' table.grid[id]').length) {
								$('#'+$(this).attr('tab')+' table.grid[id]')
									.eq(0)
									.dataTable()
									.fnAdjustColumnSizing();
							}
						})
						.eq(0)
						.click();
						
					//setup auto scroll
					$('#frm'+id).bind('scrolltotabs', function() {
						$('body').animate({
								scrollTop: $('#frm'+id+' div.formTabs').eq(0).offset().top
							}, 'slow');
					});
					//setup auto scroll on any tab form buttons
					$('#frm'+id+' div.formTabs .formBtns input').click(function() {
						$('#frm'+id).trigger('scrolltotabs');
					});
					
					mobileAutocomplete();
				});
			}
		}
	}
	
	var removeForm = function(id) {
		var tab = $('#tabs a[form="frm'+id+'"]');
		var formContainer = $('#forms > div#frm'+id);
		var newFormId = '';
		
		//hide all forms
		hideForms();
		//open previous form, else next form, else home
		if (formContainer.prev('div').length) {
			newFormId = formContainer.prev('div').attr('id');
		} else if (formContainer.next('div').length) {
			newFormId = formContainer.next('div').attr('id');
		}
		if (newFormId != '') {
			//show this form
			$('#'+newFormId).fadeIn();
			$('#tabs a[form="'+newFormId+'"]').addClass('on');
		} else {
			showHome();
		}
		//remove the form
		tab.remove();
		formContainer.remove();		
	}

	var hideForms = function() { 
		$('#forms > div, #homepage').hide();
		$('#tabs a').removeClass('on');
	}
	
	var showHome = function() {
		$('body').animate({scrollTop:0}, 100, function() { 
			$('#faqLink').attr({ 'href': '/reports/reportengine_faq.php', 'target':'_blank' });
			hideForms();						
			$('#homepage').fadeIn();
			w.fadeWidget(w.currentWidget);
			w.setWidgetContainerHeight(true);
		}); 
	}
	
	var showDialog = function(content, status) {
		if (isMobile) {
			alert(content);	
		} else {
			var bgc = '#c60';
			var bdc = '#930';
			if (status == 'error') {
				bgc = '#c33';
				bdc = '#900';				
			} else if (status == 'success') {
				bgc = '#693';
				bdc = '#360';							
			}

			$.modal(content.replace(/(\r\n|\n|\r)/gm,"<br/>"), {
				containerCss: {
					backgroundColor: bgc,
					border: '2px solid '+bdc,
					color: '#fff',
					marginLeft: '-220px'
				},
				position: [200, '50%'],
				minWidth: 400,
				maxWidth: 400,	
				minHeight: 50,
				zIndex: 20000,
				overlayClose: true				
			});	
		}
	}
	
	var gridScroll = function(elmID) {
		this.prevScrollDistance = 0;
		$('#'+elmID+'_wrapper .dataTables_scrollBody')
			.eq(0)
			.swipe({
				fingers: 1,
				triggerOnTouchEnd: true,
				swipeStatus: function(event, phase, direction, distance) {
					//If we are moving before swipe, and we are going L or R in X mode, or U or D in Y mode then drag.
					if( phase=="move" && (direction=="left" || direction=="right") ) {
						var duration=0;
							
						var srcElm = $('#'+elmID+'_wrapper .dataTables_scrollBody').eq(0);
						var curScroll = srcElm.scrollLeft();
						
						if (direction == "left") {
							srcElm.scrollLeft(curScroll + (Math.abs(distance) - this.prevScrollDistance));
							
						} else if (direction == "right") {
							srcElm.scrollLeft(curScroll - (Math.abs(distance) - this.prevScrollDistance));
						}
						this.prevScrollDistance = Math.abs(distance);
					} else if ( phase == "cancel") {
						this.prevScrollDistance = 0;
					} else if ( phase =="end" ) {
						this.prevScrollDistance = 0;
					}

				},
				allowPageScroll: 'vertical',
				threshold: 100
			});
	}
	
	var multiAutoComplete = function(options) {
		$.getJSON(options.source, function(data) {
			$('#'+options.elmId)
				.addClass('multiAutoComplete')
				.attr('source', options.source)
				.data('dataset', data)
				.autocomplete({
					source: function(request, response) {
						response( 	
							$.ui.autocomplete.filter(
								$(this.element).data('dataset'), (request.term).split(/;\s*/).pop()
							) 
						);
					},
					search: function() {
						if ((this.value).split(/;\s*/).pop().length < options.minLength && !$(this).hasClass('searchAll')) {
							return false;
						}
					},
					focus: function() {
						return false;
					},
					select: function() {
						return false;
					}
				});
			if (options.all) {
				new allScroll($('#'+options.elmId+'All'), $('#'+options.elmId));		
			}
		});
	}
	
	var multiAutoCompleteSelect = function(options) {
		$('#'+options.elmId).bind('autocompleteselect', function(event, ui) {
			//if less values then in model, clear
			var terms = (this.value).split(/;\s*/);
			terms.pop();
			terms.push( ui.item.value );

			if (terms.length < options.model.get(options.key2).split(/,\s*/).length) {
				var tmpObj = {};
				tmpObj[options.key1] = '';
				tmpObj[options.key2] = '';
				options.model.set(tmpObj);
			} 
			if (event.type == 'autocompleteselect') {
				var tmpObj = {};
				tmpObj[options.key1] = options.model.get(options.key1) + ((ui.item == null)?'':ui.item.label+'; ');
				tmpObj[options.key2] = options.model.get(options.key2) + ((ui.item == null)?'':((ui.item.pkey)?ui.item.pkey:ui.item.value)+',');
				options.model.set(tmpObj);
			}
		});
	};
	
	var getParamField = function(elmId) {
		return { paramType: $('#'+elmId).attr('paramType'), field: $('#'+elmId).attr('paramField') };
	}
	
	var allScroll = function(btn, elm) {
		$(btn).click(function() {	
			$(elm)			
				.focus()
				.addClass('searchAll')
				.autocomplete('option', 'minLength', 0)
				.autocomplete('search', '')
				.autocomplete('option', 'minLength', 1)
				.removeClass('searchAll');
		});
	}
	
	var disable = function(elm, state) {
		if (state) {
			$(elm).attr('disabled', 'disabled').addClass('disabled');
			$('#'+elm.attr('id')+'All').attr('disabled', 'disabled').addClass('disabled');
		} else {
			$(elm).removeAttr('disabled').removeClass('disabled');
			$('#'+elm.attr('id')+'All').removeAttr('disabled').removeClass('disabled');
		}
	}

	var require = function(elm, state) {
		if (state) {
			$(elm).addClass('required');
			$('label[for="'+$(elm).attr('id')+'"]').addClass('required');
		} else {
			$(elm).removeClass('required');
			$('label[for="'+$(elm).attr('id')+'"]').removeClass('required');
		}
	}
	
	//set global handles for private functions
	window['addForm'] = addForm;
	window['removeForm'] = removeForm;
	window['showHome'] = showHome;
	window['showDialog'] = showDialog;
	window['gridScroll'] = gridScroll;
	window['multiAutoComplete'] = multiAutoComplete;
	window['multiAutoCompleteSelect'] = multiAutoCompleteSelect;
	window['getParamField'] = getParamField;
	window['allScroll'] = allScroll;
	window['disable'] = disable;
	window['require'] = require;
}(jQuery, Widgets));
