/**
 * Javascript utility functions
 */

/**
 * Add target="_blank" to all links with rel="external"
 * Allows opening links in new window while preserving valid XHTML
 */
var externalLinks = function(el, ev) {
	if (!document.getElementsByTagName) return;
	var anchors = document.getElementsByTagName("a");
	for (var i=0; i<anchors.length; i++) {
		var anchor = anchors[i];
		if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external")
		{
			anchor.target = "_blank";
		}
	}
}
document.observe("dom:loaded", externalLinks);

/**
 * Add class "defaultfocus" to an element to set default focus..
 */
var setDefaultFocus = function(el) {
	var a = $$('.defaultfocus').first();
	if(a) {	a.focus(); }
	switch (window.location.hash.length) {
		case 0:  break;
		case 1:  $$('body')[0].scrollTo(); break;
		default:
			e = $(window.location.hash.substring(1));
			if (e) e.scrollTo();
			break;
	}
}
document.observe("dom:loaded", setDefaultFocus);

/**
 *
 */
var copyTargetHandlers = function (el, ev) {
	$$('textarea.copytarget').each(function(e) {
	e.observe('mouseup', copyTargetFire);
	e.observe('select', copyTargetFire);
	e.observe('keyup', copyTargetFire);
	});
}
var copyTargetFire = function() {
	this.select();
}
document.observe('dom:loaded', copyTargetHandlers);

/**
 * Fill text box with prompt text in sensible way
 */
var configTextBoxPrompt = function(id, message) {
	return function(el, ev) {
		a = $(id);
		if (!a) return;
		if (!a.getValue()) {
			a.setValue(message);
			a.observe('focus', function(b, ev2) {
				if (a.getValue() == message) a.setValue('');
			});
			a.observe('blur', function(b, ev2) {
				if (a.getValue() == '') a.setValue(message);
			});
		}
	}
}

/**
 * Prevent a form being submitted indirecty by pressing [enter] within a textbox etc
 * Requires form.canSubmit set to true - adds hooks to existing submit buttons
 */
var preventIndirectSubmit = function (form) {
	form.canSubmit = false;
	form.select('input[type=submit]').each(function(e) {
		e.observe('click', function() {
			form.canSubmit = true;
		});
	});
	form.insert({top: new Element('input', {'type': 'submit', 'class': 'dummySubmit off'})});
	form.observe('submit', function(e) {
		if (!form.canSubmit) {
			e.stop();
		};
		form.canSubmit = false;
	});
}


/**
 * String.prototype.namespace()
 * http://www.prototypejs.org/api/enumerable/inject
 * http://ajaxian.com/archives/namespaced-made-easy-with-prototype
 *
 * Creates an object namespace chain extended from $object
 * and delimited by the $separator.
 *
 * usage: Namespace.create('string.to.namespace.ify')
 *
 * @param object $object
 * @param string $separator
 * @return void
 */
var Namespace = {
	separator: ".",
	create: function(space) {
		return space.split(Namespace.separator).inject(window, function(parent, child) {
			return parent[child] = parent[child] || {};
		})
	}
};

/**
 * Handler for modal window containing ajax form
 */
var initAjaxModalWindowFunc = function(targetlink, parentform) {
	return function(el) {
		initAjaxModalWindow(targetlink, parentform);
	}
}
var initAjaxModalWindow = function(targetlink, parentform) {

	targetlink = $(targetlink);
	if (!targetlink) return;
	if (parentform) {
		parentform = $(parentform);
		if (!parentform) return;
	}

	var modal = new Control.Modal(targetlink);
	targetlink._lightboxWindow = modal;
	modal.container._lightboxWindow = modal;

	var form_type='';
	if (modal.container.hasClassName('lbform_submit')) {
		form_type='submit';
	} else if (modal.container.hasClassName('lbform_update')) {
		form_type='update';
	}

	var topForm = modal.container.up('form');
	if (topForm) {
		if (form_type=='submit') {
			// automatically redirect internal submission to parentForm
			parentForm = topForm;
		} else if (form_type=='update') {
			// create ghost elements to be updated on OK, and reset on Cancel
			modal.container.select('input[name]:not([type=button]):not([type=submit]):not([type=image])', 'select', 'textarea').each(function(el){
				el.realForm = topForm;
				var newEl = topForm.select('input[type=hidden][name="'+el.name+'"]').first();
				if (!newEl) {
					var newEl = document.createElement('input');
					Element.extend(newEl);
					newEl.type='hidden';
					newEl.name=el.name;
					topForm.insert(newEl);
				}
				el.resetContent = (function(){
					switch (this.type.toLowerCase()) {
						case 'checkbox':
						case 'radio':
							this.checked = (this.value==newEl.value);
							break;
						default:
							this.value = newEl.value;
							break;
					}
				}).bind(el);
				el.saveContent  = (function(){
					var value = this.getValue();
					if (this.validateValue) {
						try {
							// to allow for things like allowed characters, etc
							value = this.validateValue(value);
						} catch (e) {
							// save nothing
							return;
						}
					}
					if (value != undefined || this.type.toLowerCase()=='checkbox') {
						newEl.setAttribute('value', value);
					}
				}).bind(el);
				el.saveContent();
			});
		}
	}

	// ensure target container is a top level element for correct absolute center positioning
	c = modal.container.remove().addClassName('control_window').addClassName('content');
	document.body.insert(c);

	modal.observe('beforeOpen', function() {
		modal.container.select('.formfields').each(function(el) { el.show(); el.setStyle({height: null}); });
		modal.container.select('.control_window_status').each(function(el) { el.hide(); });
		modal.container.select('.control_window_done').each(function(el) { el.hide(); });
		if (parentform) {
			modal.container.select('form').each(function(el) {
				el.observe('submit', function(event) {
					redirectForm(el, parentform);
					//Control.Modal.close();
					event.stop();
				});
			});
			modal.container.select('form input[type=submit]').each(function(el) {
				el.observe('click', function(event) {
					modal.container.select('.formfields').each(function(el) { el.hide(); });
					modal.container.select('.control_window_status').each(function(el) { el.show(); });
					redirectForm(el.up('form'), parentform, el);
					//Control.Modal.close();
					event.stop();
				});
			});
		}

		if (form_type=='update') {
			// refresh all fields from parent form
			modal.container.select('input[name]:not([type=button]):not([type=submit]):not([type=image])', 'select', 'textarea').each(function(eli){
				if (eli.resetContent) {
					eli.resetContent();
				}
			});
		}
	});
	modal.observe('afterOpen', function() {
		var a = modal.container.select('.lbdefaultfocus').first();
		if (a) { a.focus(); }
	});

	$$('.control_window.lbform_update .control_ok').each(function(el) {
		el.observe('click', function(event) {
			var acset = modal.container.select('.AccessSetViewEdit');
			if (acset) {
				acset.each(function(ac){
					// update access set summary if there is one
					var sum=$(ac.identify().replace(/_acEd$/, '')+'_acSum');
					if (sum) {
						sum.update(AccessSetViewEdit.generateAccessSummary(ac));
					}
				});
			}
			modal.container.select('input[name]:not([type=button]):not([type=submit]):not([type=image])', 'select', 'textarea').each(function(eli){
				if (eli.saveContent) {
					eli.saveContent();
				}
			});
			Control.Modal.close();
		});
	});
	$$('.control_window.lbform_update .control_cancel').each(function(el) {
		el.observe('click', function() {
			modal.container.select('input[name]:not([type=button]):not([type=submit]):not([type=image])', 'select', 'textarea').each(function(eli){
				if (eli.resetContent) {
					eli.resetContent();
				}
			});
			Control.Modal.close();
		});
	});
	$$('.control_window_close').each(function(el) {
		el.observe('click', function() { Control.Modal.close(); });
	});
	$$('.control_window').each(function(w) {
		Element.select(w, 'form.spinner').each(function(el) { // use of Element.select(w ..) instead of w.select to prevent exception when w is occasionally undefined in IE7..
			el.observe('submit', function(event) {
				var tmp = el.select('.control_window_status').first();
				if (tmp) tmp.show();
				el.select('.formfields').each(function(fields) {
					fields.hide();
				});
			});
		});
		Element.select(w, 'form.async').each(function(el) { // use of Element.select(w ..) instead of w.select to prevent exception when w is occasionally undefined in IE7..
			el.observe('submit', function(event) {
				var tmp = el.select('.control_window_status').first();
				if (tmp) tmp.removeClassName('error').addClassName('msg').update('Sending...please wait').show();
				el.select('.formfields').each(function(fields) {
					effect = Effect.BlindUp(fields, {duration: 0.2} );
				});
				event.element().request({
					onSuccess: function(transport) {
						if (typeof effect !== 'undefined') effect.cancel();
						el.select('.formfields').each(function(el) { el.hide(); });
						m = transport.responseText;
						if (!m) { m = 'Thanks!'; }
						var tmp = el.select('.control_window_status').first();
						if (tmp) tmp.removeClassName('error').addClassName('msg').update(m).show();
						tmp = el.select('.control_window_done').first()
						if (tmp) tmp.show();
						event.element().reset(); // reset the form in case the user wants to use it again
					},
					onFailure: function(transport) {
						m = transport.responseText;
						if (!m) { m = 'Sorry, an error occurred. Please try again or e-mail us at <a href="mailto:helpdesk@groupspaces.com">helpdesk@groupspaces.com</a>'; }
						var tmp = el.select('.control_window_status').first();
						if (tmp) tmp.removeClassName('msg').addClassName('error').update(m).show();
						if (typeof effect !== 'undefined') effect.cancel();
				    	el.select('.formfields').each(function(el) { el.show(); el.setStyle({height: null}); });
					}
				});

				event.stop();
			});
		});
	});
	return modal;
}

document.observe("dom:loaded", function(){
	$$('a[rel~="lightbox"]').each(function(el){
		initAjaxModalWindow(el);
	});
});

var FormWatch = Class.create();
FormWatch.prototype = {
	allowSubmit: false,

	initialize : function(form) {
		this.submitted = false;
		this.form = $(form);
		this.form.watcher = this;

		this.warning = "Your changes haven't been saved yet.\n** If you continue you will lose your changes **";

		if (this.form.hasClassName('forceDirty')) {
			this.formcontents = '_dirty';
		} else {
			this.formcontents = $(form).serialize();
		}

		Event.observe(this.form, 'submit', this.setAllowSubmit.bindAsEventListener(this));
		Event.observe(window, 'beforeunload', this.unloadHandler.bindAsEventListener(this));
	},

	unloadHandler: function(e) {
		if ((this.checkDirty() || this.checkFCKDirty()) && !this.allowSubmit) {
			e.returnValue = this.warning;
			return this.warning;
		}
	},

	checkDirty: function() {
		var newcontents = this.form.serialize();
		return newcontents != this.formcontents;
	},

	checkFCKDirty: function() {
		if (window.FCKeditorAPI)
		{
			for (fckeditorName in window.FCKeditorAPI.Instances)
			{
				if (FCKeditorAPI.GetInstance(fckeditorName).IsDirty())
				{
					return true;
				}
			}
		}
	},

	setAllowSubmit: function (e) {
		this.allowSubmit = true;
		new PeriodicalExecuter(this.resetAllowSubmit.bind(this), 2);
	},

	resetAllowSubmit: function (pe) {
		this.allowSubmit = false;
	    pe.stop();
	}
}

document.observe('dom:loaded', function(){
	$$('form.warnDirty').each(function(el){
		new FormWatch(el);
	});
});

function redirectForm(sourceForm, targetForm, submitter) {
	// sourceForm is where we want to take all of the elements from
	// targetForm is where they get added to, and is then submitted
	// submitter is the submit button that was clicked in sourceForm
	if (submitter) {
		targetForm.insert(new Element('input', {type: 'hidden', name: submitter.name, value: submitter.getValue()}));
		submitter.remove();
	}
	sourceForm.getElements().each(function(el) {
		targetForm.insert(el.hide().remove());
	});
	if (targetForm.watcher) {
		// force skip warning message
		targetForm.watcher.allowSubmit=true;
	}
	targetForm.submit();
}

document.observe('dom:loaded', function() {
	$$('form.require_fb_session').each(function(f) {
		if (!f) return;
		Event.observe(f, 'submit', function(e) {
			if (FB && FB.Connect) {
				var status = FB.Connect.get_status();
				if (status && status.result !== FB.ConnectState.connected) {
					FB.Connect.requireSession(function() {
						setTimeout(function () {
							f.submit()
						}, 3000);
					});
					Event.stop(e);
					return false;
				}
			}
		});
	});
});
