;(function($) {



	var

		$                         = jQuery,

		lang                      = jFrame.registry.get('lang'),

		form                      = $('#form-canvas'),

		pageTitle                 = $('#page-title-form-name'),

		canvas                    = $('#canvas > ul'),

		canvasEmpty               = $('#canvas-empty'),

		loadingWidgets            = $('#loading-widgets'),

		formFields                = $('.tab-survey-designers-panel li'),

		fieldTemplate             = $('#field-template'),

		widgetTitles              = $('.form-element .ui-draggable-handle'),

		duplicateButtons          = $('.form-element-duplicate'),

		removeButtons             = $('.form-element-remove'),

		templates                 = $('#form-element-templates > ol > li'),

		emailFeedback             = $('#email-feedback'),

		cancelBtn                 = $('button.cancel'),

		emailFeedbackToContainer  = $('#email-feedback-to-container');

	

	// example field initialization

	form.find('[name*="name"]').exampleField().init({ onBeforeSubmit : false });

	form.find('[name*="description"]').exampleField().init();

	

	// ajax form

	form.ajaxForm({

			dataType : 'json',

			success  : function(json) {

	

				if (json.success) {

		

					if (json.redirect) {

						var newredirect = String(json.redirect);

						newredirect = newredirect.replace(/\&amp;/g,'&');				

						window.location = newredirect;

					

					} else {

						$('#MainMessage').successMessage(json.message);

					}

				} else {

			

					$('#MainMessage').errorMessage(json.message, json.messages);

					

					for (var i in json.errors) {

						var

							tabs     = $('.form-menu'),

							field    = $('[name="' + i + '"]'),

							tabField = tabs.find(field.selector);

						

						// if a field was found in the tabs

						if (tabField.length) {

							tabs.tabs('select', 1);

						}

						

						// if just a field was found, focus it

						if (field.length) {

							field.focus();

						}

						

						// we are only doing this for the first field

						break;

					}

				}

				

				$('.example-field[name*="description"]').removeAttr('disabled');

			}

		});

	

	// toggle the email feedback option depending on the state of the checkbox

	_toggleEmailFeedback();

	

	// initialize the required fields

	$('.form-element').each(function() {

		_toggleRequired(this);

	});

	

	// set default values

	$('#canvas .example-field').each(function() {

		if ($(this).val() == '') {

			$(this).val($(this).attr('title'));

		}

	});

	

	// initialize the tabs

	$('.form-menu').tabs();

	

	// clear the floating problem in firefox

	$('.form-menu').bind('tabsselect', function(event, ui) {

		$('.tab-survey-designers-panel ul').css("top", "0");		

	});	

	

	// detatch and float the left menu when scrolled past the window's bounds

	$('.tab-survey-designers-panel ul').float({

			offsetTop : 20

	});



	

	// add a class to the form fields in the menu so that we 

	// can identify them after they are dragged onto the canvas

	formFields.addClass('__widget_placeholder__');

	

	// initialize the canvas state

	_markEmpty();

	

	

	

	// form feedback email toggling

	emailFeedback.bind('click', _toggleEmailFeedback);

	

	// draggable form elements

	formFields.draggable({

		connectToSortable : canvas.selector,

		helper            : function() {

			var

				src  = $(this).css('background-image').replace(/url\(("|')?([^"]+)("|')?\)/i, '$2'),

				text = $(this).text();

		

			

			return $('#__template__form-element-drag-helper > div').template().parse({

				img  : '<img src="' + src + '" alt="' + text + '" />',

				text : text

			});

		}

	});

	

	// droppable and sortable canvas

	canvas

		.sortable({

			handle      : '.form-element-title',

			placeholder : 'ui-sortable-placeholder',

			axis        : 'y',

			delay       : 100,

			helper      : function(e, ui) {

					return $('#__template__form-element-sort-helper > div').template().parse();

				}

		});

	

	// bind sorting events



	canvas

		.bind('sortstart', function(e, ui) {

			ui.helper.find('p').text(ui.helper.text().replace('#{text}', ui.item.find('[name*="[label]"]:first').val()));

		})

		.bind('sortreceive', function(e, ui) {

			var 

				type   = ui.item.metadata().get('type'),

				action = ui.item.metadata().get('action') || type;

				//el     = _createWidget(type);

			

			// get the new widget's html and replace the placholder with it

			// section=module&action=custom&module=form&moduleController=build&moduleAction=textarea

			_markEmpty();

			

		

			$.getJSON('index.php?Page=Addons&Addon=surveys&Action=Build&ajax=1&widget=' + type, _addWidget);

			

			return;

		})

		.bind('sortover', function(e, ui) {

			_markEmpty();

		})

		.bind('sortdeactivate', function(e, ui) {

			_markEmpty();

		});



	

	// duplicate form elements when duplicate buttons are clicked

	$('.form-element-duplicate').live('click', function() {

		var

			widget = _getParentWidget(this),

			type   = widget.metadata().get('type');

		

		// insert a placeholder to be replaced

		// we have to give it some content or else it will not be displayed (but it's hidden anyways)

		widget.after('<li class="__widget_placeholder__">_</li>');

		

		// load it and replace the placeholder

		$.getJSON('index.php?Page=Addons&Addon=surveys&Action=Build&ajax=1&widget=' + type, _addWidget);

		

		return false;

	});

	

	// remove elements from canvas, live event

	removeButtons

		.bond('click', function() {

			var formElement = $(this).closest('.form-element');

			

			formElement.addClass('form-element-removing');

			

			var con = confirm('Are you sure you want to remove ' + $(this).closest('.form-element').find('.form-element-title :input').val() + '?\n\nThis action cannot be undone.');

			

			if (con) {

				var 

					id = formElement.find('> :hidden:first').val();

				

				formElement.remove();

				

				_markEmpty();

			} else {

				formElement.removeClass('form-element-removing');

			}

			

			return false;

		});

	

	// when the required checkbox is clicked, toggle the required star in the title

	$('[name$="[is_required]"]').bond('click', function() {

		_toggleRequired(_getParentWidget(this));

	});

	

	// minimizing form elements

	$('.form-element-minimize').live('click', function() {

		_minimize(this);

		

		return false;

	});

	

	// maximizing form elements

	$('.form-element-maximize').live('click', function() {

		_maximize(this);

		

		return false;

	});

	

	$('input#form-title').blur(function() {

		$('input[name="form[surveys_header_text]"]').val($('input#form-title').val());

	});

	

	

	// when the cancel button is pressed, confirm, then delete the form

	/*

	cancelBtn.bind('click', function() {

		if (confirm(lang.editFormConfirmCancel)) {

			window.location = 'index.php?section=module&action=custom&module=form&moduleController=admin&moduleAction=index';

		}

	}); */

	

	// uri browser

	// new IWPUrlBrowser($('#show-page-uri-browser'), $('#show-page-uri-browser').prev());

	

	

	/*

	 * Private functions

	 */

	

	/**

	 * @name        _randId

	 * @description If an object is passed, it applies the random id to it, otherwise it just generates one and returns it.

	 * @return      String - The random id that was just created.

	 * @param       obj    - The object to set the random id of, if any.

	 * @param       prefix - A prefix to prepend to the randomly generated id

	 */

	function _randId(obj, prefix) {

		var 

			prefix = prefix || 'id-',

			rand   = prefix + new Date().getTime();

		

		if (obj) {

			$(obj).eq(0).attr('id', rand);

		}

		

		return rand;

	}

	

	/**

	 * @name        _minimize

	 * @description Minimizes the form element container

	 * @return      Object Parent form element

	 * @param       obj The button that was clicked

	 */

	function _minimize(obj) 

	{

		$(obj)

			.removeClass('form-element-minimize')

			.addClass('form-element-maximize');

		

		return _getParentWidget(obj).find('.form-element-content').hide();

	}

	

	/**

	 * @name        _maximize

	 * @description Maximizes the form element container

	 * @return      Object Parent form element

	 * @param       obj The button that was clicked

	 */

	function _maximize(obj) 

	{

		$(obj)

			.removeClass('form-element-maximize')

			.addClass('form-element-minimize');

		

		return _getParentWidget(obj).find('.form-element-content').show();

	}

	

	function _getParentWidget(ofTHis)

	{

		var obj = $(ofTHis);

		

		if (!obj.is('.form-element')) {

			obj = obj.closest('.form-element');

		}

		

		return obj;

	}

	

	/**

	 * If the canvas is empty, it marks the template as empty, if not

	 * then it removes the marker. Returns whether the canvas is empty

	 * or not after marking it.

	 * 

	 * @return Boolean - Whether the canvas is empty or not.

	 */

	function _markEmpty() 

	{

		if (_isEmpty()) {

			canvasEmpty.show();

			

			return true;

		} else {

			canvasEmpty.hide();

			

			return false;

		}

	}

	

	/**

	 * @name        _getNumWidgets

	 * @description Returns the number of form elements on the canvas.

	 * @return      Integer - The length of the number of widgets present on the canvas.

	 */

	function _getNumWidgets() 

	{

		return canvas.find(' > .form-element').length;

	}

	

	/**

	 * @name        _isEmpty

	 * @description Returns whether the canvas is empty or not.

	 * @return      Boolean - Whether the canvas is empty or not.

	 */

	function _isEmpty() 

	{

		return _getNumWidgets() === 0 && canvas.find('.ui-sortable-placeholder').length === 0;

	}

	

	/**

	 * @name        _toggleEmailFeedback

	 * @description Toggles the email feedback option depending on the checkbox state.

	 * @return      Void

	 */

	function _toggleEmailFeedback()

	{

		if (emailFeedback.get(0).checked) {

			emailFeedbackToContainer.show();

		} else {

			emailFeedbackToContainer.hide();

		}

	}

	

	/**

	 * @name        _toggleRequired

	 * @description Toggles the required star depending on the "Requires an answer" checkbox state.

	 * @return      Void

	 */

	function _toggleRequired(widget)

	{

		var 

			widget   = $(widget),

			star     = widget.find('.form-element-required'),

			required = widget.find('[name$="[is_required]"]');

		

		return star[required.is(':checked') ? 'fadeIn' : 'fadeOut'](200);

	}

	

	/**

	 * @name        _createWidget

	 * @description Creates a new form element of type: type, and populates it's fields with

	 *              any fill data if it is passed in.

	 * @return      Object      - Returns the newly created widget.

	 * @param       String type - The type of widget to create.

	 */

	function _createWidget(type, action)

	{

		var 

			action   = action || type,

			randomId = _randId(null, 'form-element-'),

			el       = templates.metadata().filter('type', type);

		

		// if the template isn't saved yet, save it

		if (!$.fn.template.exists('form-element-' + type)) {

			el.template().save('form-element-' + type);

		}

		

		// load the template and parse it

		el = $.fn.template.load('form-element-' + type).template().parse({ randomId : randomId });

		

		// return it

		return el;

	}



	

	var 

	_dataKey = '__tooltip',

	_template = '<div style="border: 1px solid rgb(231, 227, 190); padding: 10px; display: none; z-index: 1000; position: absolute; width: 190px; background-color: rgb(254, 252, 213); color: rgb(0, 0, 0);"><span class="helpTip"><b>#{title}</b></span><br/><img height="5" width="1" alt="" src="images/blank.gif"/><br/><div class="helpTip" style="padding-left: 5px; padding-right: 5px;">#{content}</div></div>';



	// use event delegation so it works with elemets that 

	// haven't been added to the DOM yet

	$('img.tooltip')

		// show the tooltip when moused over

		.live('mouseover', function(e) {

			var t = $(this);

			

			// reference to the objects tooltip if it doesn't exist

			if (!t.data(_dataKey)) {

				var template = $(_template).template().parse({

						title   : t.attr('alt'),

						content : t.attr('title') 

					}).appendTo('body');

				

				t

					.data(_dataKey, template)

					.removeAttr('title');

			}

			

			// show the tooltip

			t.data(_dataKey)

				.css({

					position : 'absolute',

					top      : e.pageY,

					left     : e.pageX

				})

				.fadeIn();

		})

		// close

		.live('mouseout', function(e) {

			$(this).data(_dataKey).fadeOut();

		})

		// when the mose is moved, move the tooltip with it

		.live('mousemove', function(e) {

			var t = $(this);

			

			// Either IE fires the mousemove event before the mouseover event, or the mouseover

			// event doesn't complete before the mousemove event fires. Whichever way, we need

			// to check to make sure the data is stored on the tooltip, otherwise we can't do

			// anything with it and IE will spit the dummy.

			if (!t.data(_dataKey)) {

				return false;

			}

			

			var

				w    = $(window),

				t    = t.data(_dataKey),

				wh   = w.height(),

				ww   = w.width(),

				st   = w.scrollTop(),

				sl   = w.scrollLeft(),

				bh   = $('body').height(),

				oh   = t.outerHeight(),

				ow   = t.outerWidth(),

				top  = e.pageY,

				left = e.pageX + 10;

			

			if (((e.pageY - st) + oh) > wh) {

				top = (wh + st) - oh - 10;

			}

			

			if (((e.pageX - sl) + ow) > ww) {

				left = e.pageX - ow - 10;

			}

			

			t.css({

				top  : top,

				left : left

			});

		});

	

	/**

	 * Adds a widget to the canvas. Expects a JSON object as the only parameter.

	 * The JSON object must have an html property of the html to use for the widget.

	 * 

	 * @param object json

	 * 

	 * @return void

	 */

	function _addWidget(json)

	{

		var html = $(json.html);

		

		// replace the placeholder with the widget

		canvas.find('.__widget_placeholder__').replaceWith(html);

		

		// find the first text box in the newly created element and focus it



		

		// initialize name example fields; 

		// we have to use a setTimeout because the above .select() will cause IE7 to trigger the

		// clearing of the field (example field behavior) even though it is bound after

		setTimeout(function() {

			html.find('[name*="name"]').exampleField().init({ onBeforeSubmit : false });

		}, 100);

		

		html.find(':text:first').select();

		

		// initialize description example fields

		html.find('[name*="description"]').exampleField().init();

		

		_markEmpty();

	}



})(jQuery);