DabblePageForm = {
	path: '',
	requiredFields: [],
	errorMessage: 'Before you can submit this form, the following fields must be completed:',
	noMatches: 'No matches found.',
	resizeComponents: {
		runOnce: false,
		subtractFooter: false
	},
	navBoxTimer: null,
	form: null,
	submitButtonName: null,
	promoteFixedContainer: function() {
		return;
	},
	toggleNavigation: function() {
		var navigation = $('dabblePageNavigation');
		if (navigation) {
			navigation.style.display = (navigation.style.display == 'block') ? 'none' : 'block';
		}
		return false;
	},
	fixIESelect: function(box) {
		if (DabblePageForm.Browser.name == 'Internet Explorer' && DabblePageForm.Browser.version < 7) {
			box = $(box);
			var iframe = box.down('iframe.dabblePageIE6CoverSelects');
			if (!iframe) {
				iframe = $E('iframe.dabblePageIE6CoverSelects', { src: '/weblatest/blank.html' });
				iframe.setAttribute('scrolling', 'no');
				iframe.setAttribute('frameborder', '0');
				box.insertBefore(iframe, box.firstChild);
			}
			iframe.setStyle({ height: box.offsetHeight + 'px' });
		}
	},
	togglePopMenu: function(id) {
		var box = $(id);
		box.toggle();
		this.fixIESelect(box);
	},
	
	fileUpload: function(node, id) {
		while(node.firstChild) { node.removeChild(node.firstChild) }
		node.appendChild($E('input.file', { type: 'file', name: id }));
	},
	
	requestPage: function(postData, updateID) {
		var viewContent = $('dabbleViewContent');
		var table, busyLoadingBox;
		if (viewContent) {
			table = viewContent.down('table');
			if (!table) return;
			busyLoadingBox = viewContent.insertBefore($E('div.dabblePageBusyLoadingBox', { innerHTML: '<img src="/weblatest/images/spinner.gif" alt="Loading" />' }), viewContent.firstChild);
			var height = parseInt(table.offsetHeight / 2) + 'px';
			var width = table.offsetWidth + 'px';
			busyLoadingBox.setStyle({
				height: height,
				paddingTop: height,
				width: width
			});
		}
		if ($('dabblePageFocusField')) {
			 $('dabblePageFocusField').value = postData.match(/focus=(.*?)&/).last();
		}
		new Ajax.Updater(updateID, document.location.pathname, {
			parameters: postData,
			evalScripts: true,
			method: 'get',
			onComplete: function () {	DabblePageForm.initTableRows();	}
		});
	},

	validate: function(event) {
		var errors = [];
		var resultHTML = '';
		this.errorBox.innerHTML = '';
		Event.stop(event);
		$A(this.form.elements).each(function (element) {
			element = $(element);
			var autocompleteParent = element.up('.dabblePageAutocompleteFieldBox');
			if (autocompleteParent) {
				var hiddenField = $('f' + element.name + '-autocomplete');
				if (hiddenField && hiddenField.value == '' && element.value.indexOf('Search for ') == 0) {
				   element.value = ''; // if the value of the autocomplete box begins with "Search for ", assume it's blank
				}
				if (autocompleteParent.previous('.dabblePageAutocompleteFieldBox') || autocompleteParent.previous('select')) {
					return; // if this is not the first to-many box, don't bother checking for validation
				}
			}
			var parentDiv = element.up('.dabblePageFormItemRequired');
			if (parentDiv == undefined || element.up('.datePickerTable') || (element.nodeName.toLowerCase() == 'input' && element.type != 'text')) {
				return;
			}
			parentDiv.removeClassName('dabblePageFormItemRequiredError');
			if (element.getValue() == '') {
				var label = element.up('.dabblePageFormField').previous('.dabblePageFormLabel').down('label').innerHTML;
				if (label.charAt(label.length - 1) == '*') {
					label = label.slice(0, label.length - 1);
				}
				errors.push(label);
				parentDiv.addClassName('dabblePageFormItemRequiredError');
			}
		});
		if (errors.length > 0) {
			resultHTML = '<p>' + this.errorMessage + '</p><ul class="bulleted">';
			for (var i = 0, j = errors.length; i < j; i++) {
				resultHTML += '<li>' + errors[i] + '</li>';
			}
			resultHTML += '</ul>';
			this.errorBox.update(resultHTML);
			window.location = "#dabblePageErrors";
		} else {
			DabblePageForm.Attachments.startUploads();
			DabblePageForm.Attachments.submitIfFilesFinished(event);
		}
	},
	
	Attachments: {
		debug: false,
		flashPath: 'swf/swfupload62.swf',
		uploadPath: window.location.href,
		parameters: {},
		strings: {
			'allFiles': 'All files...',
			'queued': '%file% Save to upload.',
			'received': '%file% received',
			'uploading': 'Uploading %file%',
			'uploadingFiles': 'Uploading files'
		},
		stringWithFileName: function(string, filename) {
			return this.strings[string].replace(/\%file\%/, '<span class="dabblePageFormFileIcon">' + filename + '</span>');
		},
		counter: 0,
		handlers: {},
		swfsOnPage: {},
		buildUploadStatusBox: function() {
			if (!DabblePageForm.form) return;
			var lightBox = $E('div.dabblePageFormFileUploadStatusBox#dabblePageFormFileUploadStatusBox');
			lightBox.style.display = 'none';
			lightBox.innerHTML = '<div class="dabblePagePopWindow"><div class="dabblePagePopWindowHeader">' +
				DabblePageForm.Attachments.strings['uploadingFiles'] + 
				'</div><div class="dabblePagePopWindowContent"><ul id="dabblePageFormFileUploadStatus"></ul><p><input type="submit" value="Cancel" class="submit button" onclick="DabblePageForm.Attachments.forceSubmit()" /></div></div>';
			DabblePageForm.form.appendChild(lightBox);
			DabblePageForm.fixIESelect(lightBox);
		},
		startUploads: function() {
			var fileHasBeenQueued = false;
			for (container in this.swfsOnPage) {
				if (this.handlers[container].fileIsQueued) {
					this.swfsOnPage[container].startUpload();
					fileHasBeenQueued = true;
				}
			}
			if (fileHasBeenQueued) {
				$('dabblePageFormFileUploadStatusBox').show();
				DabblePageForm.promoteFixedContainer();	
			}
		},
		submitIfFilesFinished: function(event) {
			for (container in this.handlers) {
				if (this.handlers[container].fileIsQueued) {
					if (event) Event.stop(event);
					return false;
				}
			}
			this.forceSubmit();
		},
		forceSubmit: function() {
			if (DabblePageForm.submitButtonName != '') {
				DabblePageForm.form.appendChild($E('input', { type: 'hidden', name: DabblePageForm.submitButtonName, value: DabblePageForm.submitButtonName }));
			}
			DabblePageForm.form.submit();
		},
		add: function(container, callback) {
			if (!DabblePageForm.form) {
				DabblePageForm.form = $('dabblePageForm');
				if (!DabblePageForm.form) return;
			}
			if (!($('dabblePageFormFileStatusBox'))) {
				this.buildUploadStatusBox();
			}
			this.counter++;
			this.handlers[container] = new this.AttachmentHandler(container);
			this.swfsOnPage[container] = new SWFUpload({
				debug: DabblePageForm.Attachments.debug,
				upload_target_url: DabblePageForm.Attachments.uploadPath,
				file_post_name: callback,
				post_params: DabblePageForm.Attachments.parameters,
				ui_container_id: container,
				degraded_container_id: container + 'NoFlash',
				ui_function: this.showUI,
				flash_url: DabblePageForm.Attachments.flashPath,
				file_size_limit: 30720,	// 30 MB
				file_types: '*.*',
				file_types_description: DabblePageForm.Attachments.strings['allFiles'],
				file_upload_limit: '1',
				begin_upload_on_queue: false,
				use_server_data_event: true,
				validate_files: false,
				file_queued_handler: DabblePageForm.Attachments.handlers[container].fileQueued.bind(DabblePageForm.Attachments.handlers[container]),
				file_validation_handler: DabblePageForm.Attachments.handlers[container].fileValidation.bind(DabblePageForm.Attachments.handlers[container]),
				file_progress_handler: DabblePageForm.Attachments.handlers[container].uploadProgress.bind(DabblePageForm.Attachments.handlers[container]),
				file_cancelled_handler: DabblePageForm.Attachments.handlers[container].uploadFileCancelled.bind(DabblePageForm.Attachments.handlers[container]),
				file_complete_handler: DabblePageForm.Attachments.handlers[container].uploadFileComplete.bind(DabblePageForm.Attachments.handlers[container]),
				queue_complete_handler: DabblePageForm.Attachments.handlers[container].queueComplete.bind(DabblePageForm.Attachments.handlers[container]),
				error_handler: DabblePageForm.Attachments.handlers[container].uploadError.bind(DabblePageForm.Attachments.handlers[container])
			});
		},
		AttachmentHandler: function(container) {
			if (!($('dabblePageFormFileUploadStatus'))) return false;
			this.uploadStatus = $('dabblePageFormFileUploadStatus').appendChild($E('li'));
			this.report = function(text) {
				var element = this.statusList.appendChild($E('span'));
				element.className = 'dabblePageFormFileStatusItem';
				if (text) {
					element.innerHTML = '<span class="alignWithButton">' + text + '</span>';
				}
				return element;
			};
			this.container = $(container);
			this.statusBox = $(container + 'Status');
			this.fileID = $(container + 'FileID');
			this.fileIsQueued = false;
			this.browseButton = $(container + 'Browse');
			this.browseButton.observe('click', function() { DabblePageForm.Attachments.swfsOnPage[container].browse(); });
			this.cancelButton = $(container + 'Cancel');
			this.cancelButton.observe('click', function() {
				DabblePageForm.Attachments.swfsOnPage[container].stopUpload();
				DabblePageForm.Attachments.swfsOnPage[container].cancelQueue();
			});
			this.statusList = this.statusBox.appendChild($E('span'));
			this.statusList.className = 'dabblePageFormFileStatusContainer';
			this.fileQueued = function(file) {
				this.fileIsQueued = true;
				this.browseButton.hide();
				this.cancelButton.show();
				this.statusList.innerHTML = '';
				this.report(DabblePageForm.Attachments.stringWithFileName('queued', file.name));
				this.uploadStatus.innerHTML = DabblePageForm.Attachments.stringWithFileName('uploading', file.name) + ' (0%)';
			};
			this.fileValidation = function(file) {};
			this.queueComplete = function(file) {
				this.fileIsQueued = false;
				DabblePageForm.Attachments.submitIfFilesFinished();
			};
			this.uploadProgress = function(file, bytesloaded) {
				this.uploadStatus.innerHTML = DabblePageForm.Attachments.stringWithFileName('uploading', file.name) + ' (' + Math.floor(bytesloaded / file.size * 100) + '%)';
			};
			this.uploadFileComplete = function(file, serverData) {
				this.browseButton.hide();
				this.cancelButton.hide();
				this.uploadStatus.innerHTML = DabblePageForm.Attachments.stringWithFileName('received', file.name);
				this.fileID.value = serverData;
				this.fileQueued = false;
				DabblePageForm.Attachments.submitIfFilesFinished();
			};
			this.uploadFileCancelled = function(file, queuelength) {
				this.statusList.innerHTML = '';
				this.browseButton.show();
				this.cancelButton.hide();
				this.fileQueued = false;
				DabblePageForm.Attachments.submitIfFilesFinished();
			};
			this.uploadError = function(errorCode, file, message) {
				var errorMessage;
				this.statusList.innerHTML = '';
				this.browseButton.show();
				this.cancelButton.hide();
				switch(errorCode) {
					case SWFUpload.ERROR_CODE_QUEUE_LIMIT_EXCEEDED:
						errorMessage = "You have attempted to queue too many files.\n" + (message == 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."));
						break;
					case SWFUpload.ERROR_CODE_MISSING_UPLOAD_TARGET:
						errorMessage = "There was a configuration error.  You will not be able to upload a resume at this time.";
						this.debugMessage("Error Code: No backend file, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT:
						errorMessage = "The file you selected is too big.";
						this.debugMessage("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_ZERO_BYTE_FILE:
						errorMessage = "The file you select is empty.  Please select another file.";
						this.debugMessage("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_UPLOAD_LIMIT_EXCEEDED:
						errorMessage = "You may only upload 1 file.";
						this.debugMessage("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_INVALID_FILETYPE:
						errorMessage = "The file you choose is not an allowed file type.";
						this.debugMessage("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_HTTP_ERROR:
						errorMessage = "Upload error";
						this.debugMessage("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_UPLOAD_FAILED:
						errorMessage = "Upload failed";
						this.debugMessage("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_IO_ERROR:
						errorMessage = "Server (IO) error";
						this.debugMessage("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.ERROR_CODE_SECURITY_ERROR:
						errorMessage = "Security error";
						this.debugMessage("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
						break;
					default:
						errorMessage = "An error occurred during the upload.";
						this.debugMessage("Error Code: " + error_code + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
				}
				this.report('Error: ' + errorMessage);
				this.fileQueued = false;
				DabblePageForm.Attachments.submitIfFilesFinished();
			};
			return this;
		}
	},

	Browser: {
		name: '',
		version: '',
		OS: '',
		versionLocationInString: 8,
		agentString: navigator.userAgent.toLowerCase(),
		browserStrings: {
			'konqueror': "Konqueror",
			'webkit': "Safari",
			'omniweb': "OmniWeb",
			'opera': "Opera",
			'webtv': "WebTV",
			'icab': "iCab",
			'msie': "Internet Explorer",
			'firefox': "Firefox"
		},
		OSStrings: {
			'linux': "Linux",
			'x11': "Unix",
			'mac': "Mac",
			'win': "Windows"
		},
		findOS: function() {
			for (s in this.OSStrings) {
				var index = this.agentString.indexOf(s);
				if (index != -1) {
					this.OS = this.OSStrings[s];
					return;
				}
			}
			this.OS = "An unknown operating system";
			return;
		},
		detect: function() {
			for (s in this.browserStrings) {
				var index = this.agentString.indexOf(s);
				if (index != -1) {
					this.name = this.browserStrings[s];
					this.version = this.agentString.charAt(index + s.length + 1);
					this.findOS();
					return;
				}			
			}
			
			if (this.agentString.indexOf('compatible') == -1) {
				this.name = "Netscape Navigator";
				this.version = this.agentString.charAt(8);
			} else {
				this.name = "An unknown browser";
			}
			
			this.findOS();
			return;
		}
	},

	SearchField: function(field) {
		field = $(field);
		var hiddenField = $E('input#' + 'f' + field.name + '-autocomplete', { type: 'hidden', name: field.name + '-autocomplete' });
		if (field.style.color != 'gray') {
			hiddenField.value = field.value; // if a value is present, put it in the hidden field too
		}
		field.parentNode.insertBefore(hiddenField, field);
		new Form.Element.Observer(field, 0.3, function(element, value) {
			var results = $(element.id + '-searchResults');
			results.hide();	
			if (value == hiddenField.value) return;
			if (value.length > 0) {
			   var field = element.id.slice(1).split("-")[0];
				var request = new Ajax.Request(location.href.match(/^[^?]+/)[0] + '/autocomplete/' + field, {
					parameters: '?filter=' + escape(value),
					method: 'get',
					onSuccess: function(t) {
						function addResultItem(text, value) {
							var listItem = $E('li');
							var link = listItem.appendChild($E('a'));
							value = value.match(/^\s*(.+\S)\s*$/)[1]; // trim leading/trailing spaces
							link.setAttribute('href','javascript:void(0)');
							link.innerHTML = text;
							link.onclick = function() {
								hiddenField.value = element.value = value;
								results.hide();
							};
							list.appendChild(listItem);
						}
						while (results.firstChild) { results.removeChild(results.firstChild) }
						var list = results.appendChild($E('ul'));
						if (t.responseText == '[]') {
						  addResultItem(DabblePageForm.noMatches, '');
						} else {
							var resultItems = eval(t.responseText);
							resultItems.each(function (ea) {
								addResultItem(ea, ea);
							});
						}
						document.getElementsByClassName('dabblePageFieldSearchResults').invoke('hide');
						results.show();
						DabblePageForm.fixIESelect(results);
					}
				});
			}
		});
	},
	
	duplicateField: function(field) {
		field = $(field);
		box = field.up('.dabblePageFormField');
		var newField = field.cloneNode(true);
		var newFieldBox = $E('span');
		var removeButton = $E('input.dabblePageAutocompleteFieldRemoveButton', { type: 'image', src: this.path + 'images/icons/delete.gif' });
		var fieldCount = 1;
		var lastField;
		newFieldBox.className = 'dabblePageAutocompleteFieldBox';
		newFieldBox.appendChild(newField);
// find a unique ID for the new field
// start at 2 and count up until there's no existing field with that number
		do { 
			fieldCount++; 
			lastField = $(field.id + '-' + fieldCount);
		} while (lastField);
		newField.id += '-' + fieldCount;
		removeButton.onclick = function() {
			$(newField.id).up().remove();
			return false;
		};
		newFieldBox.appendChild(removeButton);
		if (newField.nodeName.toLowerCase() == 'input') {
			newField.value = '';
			var results = $E('span.dabblePageFieldSearchResults#' + newField.id + '-searchResults');
			results.hide();
			newFieldBox.appendChild(results);
			box.insertBefore(newFieldBox, $(field.id + '-addAnotherButton'));
			new DabblePageForm.SearchField(newField.id);
			var name = newField.up('.dabblePageFormField').previous('.dabblePageFormLabel').down('label').innerHTML;
			newField.style.color = 'gray';
			newField.value = "Search for " + name;
		} else if (newField.nodeName.toLowerCase() == 'select') {
			newField.selectedIndex = 0;
			box.insertBefore(newFieldBox, $(field.id + '-addAnotherButton'));
			newField.focus();
		}
	},
	
	fixNavBoxSize: function() {
		var rc = DabblePageForm.resizeComponents;
		if (!rc.runOnce) {
			rc.runOnce = true;
			rc.navBox = $('dabblePageNavigation');
			if (!rc.navBox) return;
			rc.searchForm = $('dabblePageSearchForm');
			rc.pageContent = $('dabblePageContent');
			rc.header = rc.navBox.previous();
			if (DabblePageForm.form) {
				rc.footer = rc.pageContent.down('.dabblePageSectionFormActions'); // try finding the footer in the page content
				if (rc.footer) {
					rc.subtractFooter = true; // subtract the footer if it's in the content
				} else {
					rc.footer = DabblePageForm.form.down('.dabblePageSectionFormActions'); // otherwise find it in the form
				}
			}
		} else if (!rc.navBox) {
			return;
		}
		var pageWidth = rc.pageContent.offsetWidth;
		if (pageWidth < 500) return; // on small screens do nothing
		var headerHeight = (rc.header) ? rc.header.offsetHeight : 0;
		var footerHeight = (rc.footer) ? rc.footer.offsetHeight : 0;
		var formHeight, navScrollHeight;
		if (rc.pageContent) {
			formHeight = rc.pageContent.offsetHeight + (rc.searchForm ? rc.searchForm.offsetHeight : 0);
			if (rc.subtractFooter) {
				formHeight -= footerHeight; // if footer is part of PageContent div, subtract it
			}
			rc.navBox.setStyle({
				paddingTop: headerHeight + 'px',
				paddingBottom: footerHeight + 'px',
				height: formHeight + 'px'
			});
			navScrollHeight = rc.navBox.scrollHeight - headerHeight - footerHeight;
			if (formHeight < navScrollHeight) {
				if (rc.subtractFooter) {
					rc.footer.setStyle({ marginTop: (navScrollHeight - formHeight + footerHeight) + 'px' });
				} else {
					rc.pageContent.setStyle({ height: navScrollHeight + 'px' });
				}
			}
		} else { // deprecated code if pageContent div doesn't exist
			formHeight = rc.navBox.up().offsetHeight - headerHeight - footerHeight;
			rc.navBox.setStyle({
				paddingTop: headerHeight + 'px',
				paddingBottom: footerHeight + 'px',
				height: formHeight + 'px'
			});
		}
		this.navBoxTimer = window.setTimeout(DabblePageForm.fixNavBoxSize, 100);
	},
	
	highlightTableRow: function(event) {
		var element = Event.element(event);
		if (element.nodeName.toLowerCase() != 'tr') {
			element = element.up('tr');
		}
		element.addClassName('clickRowHover');
	},
	
	unhighlightTableRow: function(event) {
		var element;
		event = event || window.event;
		element = $(event.target || event.srcElement);
		while (element && element.nodeName.toLowerCase() != 'tr') {
			element = $(element.parentNode);
		}
		if (element) {
			element.removeClassName('clickRowHover');
		}
	},
	
	clickTableRow: function(event) {
		var element = Event.element(event);
		if (element.nodeName.toLowerCase() == 'a' || element.up('a')) {
			return // don't click the row when on an active link
		}
		if (element.nodeName.toLowerCase() != 'tr') {
			element = element.up('tr');
		}
		var entry = $('entry' + element.id);
		if (entry) {
			window.location = entry.href;
		}
	},
	
	initTableRows: function() {
		var tableRows = $$('tr.entryRow');
		tableRows.each(function (row) {
			row.observe('mouseover', DabblePageForm.highlightTableRow);
			row.observe('mouseout', DabblePageForm.unhighlightTableRow);
			row.observe('drag', Event.stop);
			row.observe('click', DabblePageForm.clickTableRow);
		});
	},
	
	scrollLink: function(event) {
		var element = Event.element(event);
		var href = element.href;
		if (href) {
			Event.stop(event);
			DabblePageForm.scrollTo(href);
		}
	},
	
	scrollTo: function(href) {
		var hashIndex = href.indexOf('#');
		if (hashIndex != -1) {
			href = href.substr(hashIndex + 1);
		}
		new Effect.ScrollTo(href, { duration: 0.4 });
	},
	
	init: function() {
		if (!this.form) {
			this.form = $('dabblePageForm');
		}
		if (this.form) {
			this.errorBox = $('dabblePageErrors');
			this.submitButton = $('dabblePageFormSubmit');
			this.form.getElementsBySelector('input[type="submit"]').invoke('observe','click', function(evt) {
				DabblePageForm.submitButtonName = Event.element(evt).name;
			});
			
			this.form.observe('submit',this.validate.bindAsEventListener(this));
			if (this.submitButton) {
				this.submitButton.disabled = false;
			}
	// Find autocomplete fields and add handler
			$$('.dabblePageFieldSearchResults').each(function (resultBox) {
				new DabblePageForm.SearchField(resultBox.id.match(/(f\d+-*\d*)-searchResults/)[1]);
			});
	// Find to-many fields and add a button to clone
			$$('.dabblePageFieldAddAnotherButton').each(function (button) {
				button.observe('click', function() { DabblePageForm.duplicateField(button.id.match(/(f\d+)-addAnotherButton/)[1]); });
			});
			$$('a.inPageLink').each(function (link) {
				link.observe('click', DabblePageForm.scrollLink);
			});
		}
		
		this.initTableRows();
		this.fixNavBoxSize();
// Set nav height to match page height
	}	
};

// Element builder with support for classes and IDs using CSS style selectors
function $E(tag, attributes) {
	var tagComponents = tag.match(/([A-Za-z]+)([\.\#]?.*)/);
	var tagName = tagComponents[1];
	var selectors = tagComponents[2];
	var classes = [];
	var id = '';
	if (selectors) {
		classes = selectors.split('.');
		for (var i = classes.length - 1; i >= 0; i--) {
			var possibleIDs = classes[i].match(/(.*)\#(.+)/);
			if (possibleIDs && possibleIDs.length > 1) {
				id = possibleIDs[2];
				classes[i] = possibleIDs[1];
			}
		}
	}
	var element = $(document.createElement(tagName));
	if (classes.length >= 1) {
		element.className = classes.join(' ');
	}
	if (id) {
		element.id = id;
	}
	for (a in attributes) {
		element[a] = attributes[a];
	}
	return element;
}

DabblePageForm.Browser.detect();

Event.observe(window, 'load', DabblePageForm.init.bindAsEventListener(DabblePageForm));

