var Iamota = {

	go: function(url_str, url_pre) {
		if (!url_pre) url_pre = '/members';
		window.location.href = url_pre+'/?'+url_str;
	},
	
	timeout: function() {
		Iamota.go('timeout=1');
		return false;
	},
	
	// from: http://jehiah.cz/archive/firing-javascript-events-properly
	fireEvent: function(element, event) {
		if (document.createEventObject) {
			// dispatch for IE
			var evt = document.createEventObject();
			return element.fireEvent('on'+event, evt);
		} else {
			// dispatch for others
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent(event, true, true); // event type, bubbling, cancelable
			return !element.dispatchEvent(evt);
		}
	},
	
	get: function(id, post_string) {
		new Ajax.Updater(id, '/ws/members/?do=service', {
			method: 'post',
			postBody: post_string,
			evalScripts: true,
			on403: function() {
				// Forbidden access (bad request, or session timed out)
				Iamota.timeout();
			},
			onSuccess: function() {
				// If a loader was in place, remove it
				$(id).removeClassName('loader');
				$(id).addClassName('ajax_body');
			},
			onComplete: function() {
				// Fire observed events
				document.fire('iamota:getComplete');
				document.fire('iamota:splitResize');
			}
		});
	},
	
	grab: function(container_id, path, action, params) {
		// Insert Content
		Iamota.get(container_id, 'program=_iamota'
		  +'&path='+path
		  +'&action='+action
		  +'&uniqID='+Iamota.uniqID()  // helps avoid caching
		  +'&'+params.toQueryString() 	
		);
	},
	
	insertRow: {
		// Called to insert a new toggle-able row below the current row
		do_insertion: function(node_id, path, action, params) {
			var new_node_id = node_id+'_'+action;
			if (!$(new_node_id+'_content')) {
				// Add Row
				new Insertion.After(node_id, this.build_node(node_id, new_node_id));
				
				// Insert Content
				Iamota.grab(new_node_id+'_content', path, action, params);
			}
			else {
				// Toggle display of the row
				$(new_node_id).toggle();
			}
		
		},
	
		// Constructs the row HTML
		build_node: function(node_id, new_node_id) {
			var colspan = 0;
			$(node_id).childElements().each(function(e) {
				colspan += e.colSpan;
			 });
			var return_str = ''
			  + '<tr id="' + new_node_id + '">'
			    + '<td colspan="'+colspan+'" class="insertted_row">'
			      + '<div id="' + new_node_id + '_content"><div class="loader"></div></div>'
			    + '</td>'
			  + '</tr>';
			return return_str;
		}
	},
	
	iframeResize: function(aIfr) {
		var ifr = $(aIfr);
		var ifr_height = 85; // Default to 85
		if (ifr) {
			ifr.setStyle({ display:'block' });
			if (!window.opera && ifr.contentDocument && ifr.contentDocument.body.offsetHeight) ifr_height = ifr.contentDocument.body.offsetHeight;
			else if (ifr.contentDocument && ifr.contentDocument.documentElement && ifr.contentDocument.documentElement.offsetHeight) ifr_height = ifr.contentDocument.documentElement.offsetHeight;
			else if (ifr.Document && ifr.Document.body.scrollHeight) ifr_height = ifr.Document.body.scrollHeight;
		}
		//ifr.setStyle({height: ifr_height+'px'});
		new Effect.Morph(ifr,{style:{height:ifr_height+'px'}});
		ifr.stopObserving('load', function() { Iamota.iframeResize(ifr.id) });
		ifr.observe('load', function() { Iamota.iframeResize(ifr.id) });
	},
	
	message: function(message) {
		$('message').update(message);
		$('message_box').show();
		new Effect.Highlight('message_box', { duration:5 });
	},
		
	run: function(post_string) {
		new Ajax.Request('/ws/members/?do=service', {
			method: 'post',
			postBody: post_string,
			on403: function() {
				Iamota.timeout();
			},
			onSuccess: function(transport) {
				// Eval all scripts
				transport.responseText.evalScripts();
			}
		});
	},
	
	showImage: function(aElement, media) {
		var element = $(aElement);
		var post_body = 'm='+escape(media);

		new PeriodicalExecuter(function(pe) {
			new Ajax.Request('/ws/members/media/?do=prepare', {
				method: 'post',
				postBody: post_body,
				onSuccess: function(transport) {
					pe.stop();
					var picImg = new Image;
					picImg.onload = function() {
						element.update('<img src="'+picImg.src+'" border="0" />');
						// must wait for browser to render image before calling the update function
					}
					picImg.src = '/ws/members/media/?do=display&f='+transport.responseText;
				},
				on404: function(transport) {
					// still loading, do nothing
				},
				onFailure: function(transport) {
					pe.stop();
					element.update('<div style="text-align:center;">Error loading media.</div>');
				}
			});
		}, 1000);
	},
	
	update: function(id, post_string, freq, delay) {
		if (freq === undefined) { freq = 3; }
		if (delay === undefined) { delay = 1.5; }
		new Ajax.PassivePeriodicalUpdater(id,'/ws/members/?do=service', {
			method: 'post',
			postBody: post_string,
			frequency: freq,
			decay: delay,
			on403: function() {
				// Forbidden access (bad request, or session timed out)
				Iamota.timeout();
			},
			onComplete: function() {
				// Fire observed events
				document.fire('iamota:splitResize');
			}
			// Handle onFailure!
		});
	},
	
	Calendar: {
		
		calendars: new Hash(), // Empty hash to hold calendars
		
		redraw: function(id) {
			var cal = Iamota.Calendar.calendars.get(id);
			if (cal) {
				// Calendar exists in buffer, display it
				Iamota.Calendar.show(cal[0], cal[1], cal[2], cal[3], cal[4], cal[5]);
			}
		},
		
		remove: function(id, path, program, alert_id) {
			if (confirm('Are you sure you wish to delete this message? This cannot be undone!')) {
				new Ajax.Request('/ws/members/?do=service', {
					method: 'post',
					postBody: 'path='+escape(path)+'&program='+escape(program)+'&action=delete&alert='+escape(alert_id),
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onSuccess: function(transport) {
						Iamota.message('Message deleted successfully.');
						
						// Call the panelCalendar function to re-render the calendar
						Iamota.Calendar.redraw(id);
					},
					onFailure: function(transport) {
						alert('FAILURE!\n'+transport.responseText.stripTags());
					}
				});
			}
		},
		
		show: function(id, path, program, year, month, day) {
			if (day != null) {
				// Day view
				new Ajax.Updater(id, '/ws/members/?do=panelcalendarday', {
					method: 'post',
					postBody: 'id='+escape(id)+'&path='+escape(path)+'&program='+escape(program)+'&year='+escape(year)+'&month='+escape(month)+'&day='+escape(day),
					evalScripts: true,
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onComplete: function() {
						Iamota.Calendar.calendars.set(id, [id, path, program, year, month, day]);
					}
				});
			} else {
				// Month view
				new Ajax.Updater(id, '/ws/members/?do=panelcalendarmonth', {
					method: 'post',
					postBody: 'id='+escape(id)+'&path='+escape(path)+'&program='+escape(program)+'&year='+escape(year)+'&month='+escape(month),
					evalScripts: true,
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onComplete: function() {
						Iamota.Calendar.calendars.set(id, [id, path, program, year, month, day]);	
					}
				});
			}
			return false;
		}
		
	},
	
	Catalog: {
		
		select: function(element, services) { // services is an array
			// First clear all UL.catalog LI's from having the 'current' class
			$$('UL.catalog LI.current').each(function(elem) {
				elem.removeClassName('current');
			});
			
			var found_first = false;
			$$('DIV.catalog_service').each(function(elem) {
				elem.removeClassName('first');
				if (services.indexOf(elem.id.sub('catalog_', '')) > -1) {
					if (!found_first) {
						elem.addClassName('first');
						found_first = true;
					}
					elem.show();
				} else elem.hide();
			});
			$(element.parentNode).addClassName('current'); // need to use $() because IE is dumb

			// Fire event
			document.fire('iamota:splitResize');
		}
		
	},
	
	Form: {
		
		/* Adrian original version before multiple country & multiple shortcode support
		checkKeyword: function(id, key) {
			var id = $(id);
			new Ajax.Request('/ws/members/?do=keywordcheck', {
				method: 'post',
				postBody: 'keyword='+escape(key),
				onSuccess: function(transport) {
					var response = transport.responseText.toLowerCase().strip();
					if (response == 'yes') {
						id.update('UNAVAILABLE');
						id.setStyle({ color: '#FF0000' });
					} else {
						id.update('AVAILABLE');
						id.setStyle({ color: '#00FF00' });
					}
				},
				onFailure: function() {
					id.update('AVAILABLE');
					id.setStyle({ color: '#00FF00' });
				}
			});
		},
		*/
		checkKeyword: function(id, key) {
			var element = $(id);
			new Ajax.Request('/ws/members/?do=keywordcheck', {
				method: 'post',
				postBody: 'keyword='+escape(key),
				onSuccess: function(transport) {
					var response = transport.responseText.strip();
					if (response == 'AVAILABLE') {
						element.update(response);
						element.setStyle({ color: '#00FF00' });
					} else {
						element.update(response);
						element.setStyle({ color: '#FF0000' });
					}
				},
				onFailure: function() {
					element.update('AVAILABLE');
					element.setStyle({ color: '#00FF00' });
				}
			});
		},
		
		clearError: function(element) {
			// Error DIV's have the id element.name+'_error'
			element = $(element);
			if ($(element.id+'_error')) $(element.id+'_error').remove();
		},
		
		clearErrorEvent: function(event) {
			// Calls clearError via an event
			Iamota.Form.clearError(event.element());
		},
		
		message: function(element, msg) {
			element = $(element);
			if (element) {
				element.update(msg);
				element.show();
				new Effect.Highlight(element, { duration:3 });
			}
		},
		
		post: function(path, program, form_id, postElement) {
			var options = Object.extend({
				calendar: null
			}, arguments[3] || { });
			
			var serialized = $(form_id).serialize();
			$(form_id).disable();
			var form_message = $('formmsg_'+form_id);
			new Ajax.Request('/ws/members/?do=service', {
				method: 'post',
				postBody: 'path='+escape(path)+'&program='+escape(program)+'&'+serialized,
				on403: function() {
					// Forbidden access (bad request, or session timed out)
					Iamota.timeout();
				},
				on430: function(transport) {
					$(form_id).enable();
					Iamota.Form.message(form_message, Prototype.Browser.Opera ? transport.statusText : transport.responseText);
				},
				onSuccess: function(transport) {
					$(form_id).enable();
					if (form_message) form_message.hide();
					// First eval all scripts within script tags in the responseText
					transport.responseText.evalScripts();
					// Then see if there is any non-script content left to display in a box, if so, display it
					var msg = transport.responseText.stripScripts();
					if (postElement === undefined) { postElement = ''; }
					if (postElement.length > 0) { $(postElement).innerHTML = msg; }
					else if (msg.length) { Iamota.Form.message(form_message, msg); } 
					
					if (options.calendar) Iamota.Calendar.redraw(options.calendar);
				},
				onFailure: function(transport) {
					$(form_id).enable();
					Iamota.Form.message(form_message,  Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
				}
			});
		},
		
		showInfo: function(id) {
			$$('div.info_split').each(function(s) {
				s.hide();
			});
			$(id).show();
			return false; // So doesn't 'follow' the link (if accessed through a href)
		},
		
		toggleRadioHiders: function(element) {
			element = $(element);
			if (element.type != 'radio') return;
			
			var radio_hiders = $$('input[type=radio][name='+element.name+']');
			radio_hiders.each(function(elem) {
				if ($('radiohider_'+elem.id)) $('radiohider_'+elem.id).hide();
			});
			if ($('radiohider_'+element.id)) $('radiohider_'+element.id).show();
		},
		
		postWizard: function(path, form_id) {
			var serialized = $(form_id).serialize();
			$(form_id).disable();
			
			var form_message = $('formmsg_'+form_id);
			new Ajax.Request('/ws/members/?do=service', {
				method: 'post',
				postBody: 'path='+escape(path)+'&'+serialized,
				on403: function() {
					// Forbidden access (bad request, or session timed out)
					Iamota.timeout();
				},
				on430: function(transport) {
					$(form_id).enable();
					if (form_message) {
						if (!Prototype.Browser.Opera) form_message.innerHTML = transport.responseText;
						else form_message.innerHTML = transport.statusText;
						form_message.show();
						new Effect.Highlight(form_message, { duration:5 });
					}
				},
				onSuccess: function(transport) {
					$(form_id).enable();
					if (form_message) form_message.hide();
					// First eval all scripts within script tags in the responseText
					transport.responseText.evalScripts();
					// Then see if there is any non-script content left to display in a box, if so, display it
					var msg = transport.responseText.stripScripts();
					if (msg.length) Iamota.message(msg);
				},
				onFailure: function(transport) {
					$(form_id).enable();
					if (form_message) {
						if (!Prototype.Browser.Opera) form_message.innerHTML = transport.responseText.stripTags();
						else form_message.innerHTML = transport.statusText.stripTags();
					}
				}
			});
		}
		
	},
	
	History: {
		
		remove: function(path, program, alert_id) {
			if (confirm('Are you sure you wish to delete this message? This cannot be undone!')) {
				new Ajax.Request('/ws/members/?do=service', {
					method: 'post',
					postBody: 'path='+escape(path)+'&program='+escape(program)+'&action=delete&alert='+escape(alert_id),
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onSuccess: function(transport) {
						Iamota.message('Message deleted successfully.');
					},
					onFailure: function(transport) {
						alert('FAILURE!\n'+transport.responseText.stripTags());
					}
				});
			}
		}
		
	},
	
	Panel: {
		
		addToSummary: function(prod, tab, sub, pan, sol, prog) {
			new Ajax.Request('/ws/members/?do=addpaneltosummary', {
				method: 'post',
				postBody: 'prod='+escape(prod)+'&tab='+escape(tab)+'&sub='+escape(sub)+'&pan='+escape(pan)+'&sol='+escape(sol)+'&prog='+escape(prog),
				on403: function() {
					Iamota.timeout();
				},
				onSuccess: function() {
					Iamota.message('Panel successfully added to the <a href="/members/?prod=iamota&tab=accountsummary">summary screen</a>!');
				},
				onFailure: function(transport) {
					Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
				}
			});
		},
		
		order: function(prod, tab, sub, sol, prog, side) {
			new Ajax.Request('/ws/members/?do=orderpanels', {
				method: 'post',
				postBody: 'prod='+escape(prod)+'&tab='+escape(tab)+'&sub='+escape(sub)+'&sol='+escape(sol)+'&prog='+escape(prog)+'&side='+escape(side)
				  +'&'+Sortable.serialize('subpage_'+side),
				onFailure: function(transport) {
					Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
				}
			});
		},
		
		remove: function(element, prod, tab, sub, pan, sol, prog) {
			if (confirm('Click OK if you\'re sure you want to remove this panel.')) {
				element = $(element);
				new Ajax.Request('/ws/members/?do=removepanel', {
					method: 'post',
					postBody: 'prod='+escape(prod)+'&tab='+escape(tab)+'&sub='+escape(sub)+'&pan='+escape(pan)+'&sol='+escape(sol)+'&prog='+escape(prog),
					on403: function() {
						Iamota.timeout();
					},
					onSuccess: function() {
						element.remove();
						Iamota.message('The panel has been successfully removed. If you wish to show it again, please go to the <a href="/members/?prod=iamota&tab=settings&sub=managelayout">manage layout</a> page.');
					},
					onFailure: function(transport) {
						Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
					}
				});
			}
		},
		
		removeFromSummary: function(element, prod, tab, sub, pan, sol, prog) {
			if (confirm('Click OK if you\'re sure you want to remove this panel from your summary page.')) {
				element = $(element);
				new Ajax.Request('/ws/members/?do=removepanelfromsummary', {
					method: 'post',
					postBody: 'prod='+escape(prod)+'&tab='+escape(tab)+'&sub='+escape(sub)+'&pan='+escape(pan)+'&sol='+escape(sol)+'&prog='+escape(prog),
					on403: function() {
						Iamota.timeout();
					},
					onSuccess: function() {
						element.remove();
					},
					onFailure: function(transport) {
						Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
					}
				});
			}
		},
		
		selectTab: function(panel_id, tab_id) {
			var clicked_button = $('button_'+panel_id+'_'+tab_id);
			var clicked_paneltab = $('paneltab_'+panel_id+'_'+tab_id);
			
			if (clicked_button.hasClassName('tab_selected') && clicked_paneltab.visible()) {
				clicked_button.removeClassName('tab_selected');
				clicked_paneltab.hide();
			} else {
				var panel = $('panel_'+panel_id);
				
				// First set the class of the selected tab button to be 'selected'
				var elems = panel.select('div.tab_button');

				elems.each(function(el) {
					el.removeClassName('tab_selected');
				});
				clicked_button.addClassName('tab_selected');
				
				// Hide the open tab(s) content
				var elems = panel.select('div.tab_content');
				elems.each(function(el) {
					el.hide();
				});
				clicked_paneltab.show();
			}
		},
		
		setSortable: function(prod, tab, sub, sol, prog) {
			Sortable.create('subpage_left', {
				tag: 'div',
				handle: 'title',
				constraint: '',
				containment: ['subpage_left', 'subpage_right'],
				dropOnEmpty: true,
				starteffect: Prototype.emptyFunction,
				endeffect: Prototype.emptyFunction,
				onUpdate: function() {
					Iamota.Panel.order(prod, tab, sub, sol, prog, 'left');
				}
			});
			
			Sortable.create('subpage_right', {
				tag: 'div',
				handle: 'title',
				constraint: '',
				containment: ['subpage_left', 'subpage_right'],
				dropOnEmpty: true,
				starteffect: Prototype.emptyFunction,
				endeffect: Prototype.emptyFunction,
				onUpdate: function() {
					Iamota.Panel.order(prod, tab, sub, sol, prog, 'right');
				}
			});
		},
		
		toggle: function(element, id, prod, tab, sub, pan, sol, prog) {
			element = $(element); id = $(id);
			Element.toggle(id);
			if (id.visible()) {
				element.removeClassName('panelbutton_max');
				element.addClassName('panelbutton_min');
			} else {
				element.removeClassName('panelbutton_min');
				element.addClassName('panelbutton_max');
			}
			new Ajax.Request('/ws/members/?do=togglepanel', {
				method: 'post',
				postBody: 'prod='+escape(prod)+'&tab='+escape(tab)+'&sub='+escape(sub)+'&pan='+escape(pan)+'&sol='+escape(sol)+'&prog='+escape(prog)+'&is_collapsed='+!$(id).visible(),
				on403: function() {
					// Forbidden access (bad request, or session timed out)
					Iamota.timeout();
				},
				onFailure: function(transport) {
					Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
				}
			});
			return false;
		}

	},
	
	SplitSubpage: {
		
		observe: function() {
			document.observe('iamota:splitResize', Iamota.SplitSubpage.resize);
		},
		
		resize: function() {
			$('subpage_right').setStyle({ height: '' });
			var max_height = Math.max($('group').getHeight() - 70, $('subpage_left').getHeight(), $('subpage_right').getHeight(), 150);
			$('subpage_right').setStyle({ height: max_height+'px' });
		}
		
	},
	
	Tab: {
	
		remove: function(prod, tab) {
			new Ajax.Request('/ws/members/?do=removetab', {
				method: 'post',
				postBody: 'prod='+escape(prod)+'&tab='+escape(tab),
				on403: function() {
					Iamota.timeout();
				},
				onSuccess: function() {
					// 'Refresh' the screen
					Iamota.go('prod='+prod);
				},
				onFailure: function(transport) {
					Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
				}
			});
		}
		
	},
	
	Vote: {
	
		remove: function(path, program, element, vote_id, removeAction, updateAction) {
			if (confirm('Are you sure you wish to delete this voting campaign? This cannot be undone!')) {
				new Ajax.Request('/ws/members/?do=service', {
					method: 'post',
					postBody: 'path='+escape(path)+'&program='+escape(program)+'&action='+removeAction+'&vote_id='+escape(vote_id),
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onSuccess: function(transport) {
						Iamota.message('Vote deleted successfully.');
						new Ajax.Updater(element, '/ws/members/?do=service', {
							method: 'post',
							postBody: 'path='+escape(path)+'&program='+escape(program)+'&action='+updateAction,
							evalScripts: true,
							on403: function() {
								// Forbidden access (bad request, or session timed out)
								Iamota.timeout();
							}
						});
					},
					onFailure: function(transport) {
						Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
					}
				});
			}
		}
	
	},
	
	Venue: {
	
		remove: function(path, program, element, venue_id, removeAction, updateAction) {
			if (confirm('Are you sure you wish to delete this text to screen venue? This cannot be undone!')) {
				new Ajax.Request('/ws/members/?do=service', {
					method: 'post',
					postBody: 'path='+escape(path)+'&program='+escape(program)+'&action='+removeAction+'&venue_id='+escape(venue_id),
					on403: function() {
						// Forbidden access (bad request, or session timed out)
						Iamota.timeout();
					},
					onSuccess: function(transport) {
						Iamota.message('Venue deleted successfully.');
						new Ajax.Updater(element, '/ws/members/?do=service', {
							method: 'post',
							postBody: 'path='+escape(path)+'&program='+escape(program)+'&action='+updateAction,
							evalScripts: true,
							on403: function() {
								// Forbidden access (bad request, or session timed out)
								Iamota.timeout();
							}
						});
					},
					onFailure: function(transport) {
						Iamota.message(Prototype.Browser.Opera ? transport.statusText.stripTags() : transport.responseText.stripTags());
					}
				});
			}
		}
	
	},
	
	Resizable: {
		/* Tracking Variables */
		startY: 0,
		startHeight: 0,
		resizeBarObj: null,
		resizeObj: null,
		performResizeFn: null,
		stopResizeFn: null,
			
		/* Starts Tracking the Resizing */
		startResize: function(event) {
			// Save starting conditions
			this.resizeBarObj = Event.element(event);
			this.resizeObj = $(this.resizeBarObj.id.replace('_bar', ''));	//get the object being resized
			this.startY = Event.pointerY(event);							//get the Y-axis location of the cursor
			this.startHeight = parseInt(this.resizeObj.style.height.replace(Array('em','ex','px','%','in','cm','mm','pt','pc'), ''));
 
			// Start watching for resize release
			Event.observe(document, 'mousemove', this.performResizeFn);
			Event.observe(document, 'mouseup', this.stopResizeFn);
		},
		
		/* Resize Box while Mouse Down */
		performResize: function(event) {
			// Calculate new height
			newY = Event.pointerY(event);					//get new mouse position
			pxMove = parseInt(newY-this.startY);			//calculate movement in pixels
			newHeight = parseInt(this.startHeight+pxMove);	//determine new height
			newHeight = (newHeight<3?3:newHeight);			//conditional to set minimum height to 3

			// Adjust height
			this.resizeObj.style.height = newHeight+'px';	//set the new height of the div

			Event.stop(event);
		},
		
		/* Stops Tracking the Resizing */
		stopResize: function(event) {
			// Stop watching for resize release
			Event.stopObserving(document, 'mousemove', this.performResizeFn);
			Event.stopObserving(document, 'mouseup', this.stopResizeFn);
			
			// Reset tracking
			this.resizeObj = null;
			this.resizeBarObj = null;
			this.startY = 0;
			this.startHeight = 0;
			
			Event.stop(event);
		},
		
		/* Maximize the Box */
		maximize: function(event) {
			resizeBarObj = Event.element(event);
			resizeObj = $(resizeBarObj.id.replace('_bar', ''));	//get the object being resized
			resizeBarObj.remove();								//disable future resizing
			resizeObj.style.height = 'auto';					//maximize the display
			resizeObj.removeClassName('resizableBox');
			resizeObj.addClassName('maximizedBox');
		},
		
		/* Register Event Listeners */
		registerEvents: function() {
			// Prepare Listeners for movement and release
			this.performResizeFn = this.performResize.bindAsEventListener(this);
			this.stopResizeFn = this.stopResize.bindAsEventListener(this);

			startResizeFn = this.startResize.bindAsEventListener(this);
			maximizeFn = this.maximize.bindAsEventListener(this);

			// Attach resizable listeners to all elements with a class = 'resizableDivBar' 
			$$('.resizable').each(function(resizableElem) {
				var uniqID = Iamota.uniqID();
				var resizableBarElem = new Element('div', { 'class' : 'resizableBar', 'id' : uniqID+'_resizable_bar'});
				resizableElem.id = uniqID + '_resizable';
				resizableElem.insert({ after: resizableBarElem });
				resizableElem.removeClassName('resizable');	
				resizableElem.addClassName('resizableBox');	
				
				// Add observers to the resizable bar
				Event.observe(resizableBarElem, 'mousedown', startResizeFn, true);
				Event.observe(resizableBarElem, 'dblclick', maximizeFn, true);	
			});
		}
		
	},
	
	Pagination: Class.create({
		/* Member Variables */
		uniqID: null,
		contentPath: null,
		containerTarget: null,
		contentTarget: null,
		
		currentPage: null,
		maxPages: null,
		maxDisplayPages: null,
		containerObj: null,
		filters: null,
		
		/* Constructor */
		initialize: function(uniqID, contentPath, maxPages, currentPage, maxDisplayPages) {
			this.uniqID = uniqID;
			this.contentPath = contentPath;
			this.containerTarget = uniqID;
			this.contentTarget = uniqID+'_content';
			this.maxPages = maxPages;
			this.currentPage = (currentPage===undefined?1:currentPage);
			this.maxDisplayPages = (maxDisplayPages===undefined?10:maxDisplayPages);
			this.containerObj = new Element('div', { 'class' : 'pageNav' });
			this.filters = new Hash();
			
			this.draw();
		},
		
		draw: function() {
			// Abort if there is only 1 page
			if (this.maxPages <= 1) return;
			
			// Jump to Page Input
			if (this.maxPages > this.maxDisplayPages) {
				var navJumpTo = new Element('span', { 'class' : 'pageNavJump' }).update('Go to page:');
				
				var navJumpInput = new Element('input', { 'class' : 'pageNavInput', 
											           'type'  : 'text' });
				navJumpTo.insert({ bottom: navJumpInput });
				
				var navJumpButton = new Element('span', { 'class' : 'pageNavButton' }).update('Go');
				Event.observe(navJumpButton, 'click', this.selectPageJumpEvent.bindAsEventListener(this, navJumpInput));
				navJumpTo.insert({ bottom: navJumpButton });
				
				this.containerObj.insert({ bottom: navJumpTo });
			}
			
			// First Page
			var navFirst = new Element('span', { 'class' : 'pageNavButton' }).update('&lt;&lt;');
			Event.observe(navFirst, 'click', this.selectPageEvent.bindAsEventListener(this, 1));
			this.containerObj.insert({ bottom: navFirst });
			
			// Previous Page
			var navPrev = new Element('span', { 'class' : 'pageNavButton' }).update('&lt; Prev');
			Event.observe(navPrev, 'click', this.jumpEvent.bindAsEventListener(this, -1));
			this.containerObj.insert({ bottom: navPrev });
			
			// Page Specific Navigation
			if (this.maxPages <= this.maxDisplayPages) {
				// Display Page Selectors
				for  (var currPage=1;currPage <= this.maxPages;currPage++) {
					var navPage = new Element('span', { 'class' : 'pageNavButton' }).update(currPage);
					Event.observe(navPage, 'click', this.selectPageEvent.bindAsEventListener(this, currPage));
					this.containerObj.insert({ bottom: navPage });
				}
			} else {
				// Page Display Label
				var navPage = new Element('span', { 'class' : 'pageNavDisplay' });
				this.containerObj.insert({ bottom: navPage });
				this.containerObj.fire('iamota:Pagination:pageChange');
			}			
			
			// Next Page
			var navNext = new Element('span', { 'class' : 'pageNavButton' }).update('Next &gt;');
			Event.observe(navNext, 'click', this.jumpEvent.bindAsEventListener(this, +1));
			this.containerObj.insert({ bottom: navNext });
			
			// Last Page
			var navLast = new Element('span', { 'class' : 'pageNavButton' }).update('&gt;&gt;');
			Event.observe(navLast, 'click', this.selectPageEvent.bindAsEventListener(this, this.maxPages));
			this.containerObj.insert({ bottom: navLast });
		
			// Add the Navigation
			Event.observe(this.containerObj, 'iamota:Pagination:pageChange', this.updatePageDisplay.bindAsEventListener(this));
			$(this.containerTarget).insert({ before: this.containerObj });
			this.containerObj.fire('iamota:Pagination:pageChange');
		},
				
		/* Change to the requested page */
		selectPage: function(page) {
			// Enforce Page Boundaries
			page = (page<1?1:page);
			page = (page>this.maxPages?this.maxPages:page);

			// Use AJAX to change the page
			$(this.contentTarget).update('<br /><div class="loader"></div>');
			Iamota.get(this.contentTarget, 'program=_iamota'
											+'&path='+this.contentPath
											+'&action=refresh'
											+'&uniqID='+this.uniqID
											+'&page='+page
											+'&totalPages='+this.maxPages
											+'&'+this.filters.toQueryString()
										);				
		
			// Update the current Page Counter
			this.currentPage = page;

			// Update the Nav Display
			this.containerObj.fire('iamota:Pagination:pageChange');
		},
		
		// Update the number of pages
		setMaxPages: function(maxPages) {
			// Update the max pages
			this.maxPages = maxPages;
			
			// Ensure the page your viewing exists
			this.currentPage = Math.min(this.currentPage, maxPages);
			
			// Update the Nav Display
			this.updatePageDisplay();
		},
		
		// Move the page by the requested amount (negative numbers allowed)		
		jumpPages: function(amount) {
			this.selectPage(parseInt(this.currentPage) + parseInt(this.amount));
		},
		
		// Select a page, from a mouse event
		selectPageEvent: function(e, page) {
			this.selectPage(parseInt(page));
		},
		
		// Select a page, from a mouse event
		selectPageJumpEvent: function(e, jumpTargetElement) {
			this.selectPage(parseInt(jumpTargetElement.value));
		},		
		
		// Jump pages, from a mouse event
		jumpEvent: function(e, amount) {
			this.selectPage(parseInt(this.currentPage) + parseInt(amount));
		},
		
		// Update the Page Display
		updateFilters: function(filters) {
			this.filters = filters;
		},
		
		// Update the Page Display
		updatePageDisplay: function(e) {
			// Update the Page Display
			this.containerObj.select('.pageNavDisplay').each(function(elem) {
					elem.update('Page <strong>'+this.currentPage+'</strong> of <strong>'+this.maxPages+'</strong>');
				}, this);
			
			// Highlight the button for the selected page
			this.containerObj.select('.pageNavButton').each(function(elem) {
					if (elem.innerHTML == this.currentPage) {
						elem.addClassName('selected');
					}
					else {
						elem.removeClassName('selected');
					}
				}, this);			
		}
	}),	
	
	QueryViewer: Class.create({
		/* Member Variables */
		uniqID: null,
		contentPath: null,
		containerTarget: null,
		filterContainer: null,
		contentTarget: null,
		filters: null,
		pagination: null,

		/* Constructor */
		initialize: function(uniqID, contentPath, filters) {
			this.uniqID = uniqID;
			this.contentPath = contentPath;
			this.containerTarget = uniqID;
			this.contentTarget = uniqID + '_content';

			this.filters = filters;
			this.filterContainer = new Element('div', { 'id' : this.uniqID + '_filters', 'class' : 'filters' });
			$(this.containerTarget).insert({ before: this.filterContainer });
			
			this.loadDisplay();
		},
		
		loadDisplay: function() {
			$(this.containerTarget).addClassName('loader');
			Iamota.get(this.containerTarget, 'program=_iamota'
											+'&path='+this.contentPath
											+'&action=load'
											+'&uniqID='+this.uniqID
											+'&page=1'
											+'&'+this.filters.toQueryString()
										);	
		},
		
		refreshDisplay: function() {
			$(this.contentTarget).update('<br /><div class="loader"></div>');
			Iamota.get(this.contentTarget, 'program=_iamota'
											+'&path='+this.contentPath
											+'&action=refresh'
											+'&uniqID='+this.uniqID
											+((this.pagination != null)?'&page='+this.pagination.currentPage:'')
											+((this.pagination != null)?'&totalPages='+this.pagination.maxPages:'')
											+'&'+this.filters.toQueryString()
										);
		},
		
		/* ----------------------------------------------------------------------------------
		Filter: Paging 
		---------------------------------------------------------------------------------- */		
		enablePagination: function(maxPages, currentPage, maxDisplayPages) {
			// Create a Pagination Element
			this.pagination = new Iamota.Pagination(this.uniqID, 
			  this.contentPath,
			  maxPages,
			  currentPage,
			  maxDisplayPages);

			this.pagination.updateFilters(this.filters);
		},
		
		/* ----------------------------------------------------------------------------------
		Filter: Results-Per-Page 
		---------------------------------------------------------------------------------- */	
		updateResultsPerPage: function(resultsPerPage) {
			// Save Filter Settings
			this.filters.set('f_m', resultsPerPage);
			
			// Update Pagination
			this.pagination.updateFilters(this.filters);
			this.pagination.selectPage(1);
		},
		
		/* ----------------------------------------------------------------------------------
		Filter: Results-Per-Page 
		---------------------------------------------------------------------------------- */	
		updateMaxPages: function(maxPages) {
			// Save Filter Settings
			this.pagination.currentPage = 1;
			this.pagination.setMaxPages(maxPages);
		},
		
		/* ----------------------------------------------------------------------------------
		Filter: Searching 
		---------------------------------------------------------------------------------- */
		enableSearch: function(columnList) {
			// Create a Search Element
			searchObj = new Element('div', { 'id' : this.uniqID + '_search',
									         'class' : 'search' });
			
			// Add Search Link
			var searchLink = new Element('span', { 'id' : this.uniqID + '_search_link',
										           'class': 'search_link' }).update('Search');
			Event.observe(searchLink, 'click', this.toggleSearch.bindAsEventListener(this));
			searchObj.insert({ bottom: searchLink });
			
			var searchBox = new Element('div', { 'id' : this.uniqID + '_search_box',
										         'class' : 'search_box' }).update('<strong>Search:</strong><br />');
			searchBox.hide();
			searchObj.insert({ bottom: searchBox });
			
			var searchForm = new Element('form', { 'id' : this.uniqID + '_search_form' });
			searchBox.insert({ bottom: searchForm });
			
			var searchText = new Element('input', { 'id' : this.uniqID + '_search_text', 'type' : 'text' });
			searchForm.insert({ bottom: searchText });
			
			var searchIn = new Element('span').update(' in ');
			searchForm.insert({ bottom: searchIn });
			
			var searchColumns = new Element('select', { 'id' : this.uniqID + '_search_col' });
			searchForm.insert({ bottom: searchColumns });
			
			var searchComlumArray = columnList.split(',');
			searchComlumArray.each(function(elem) {
				var aSearchColumn = new Element('option').update(elem.toString().toLowerCase());
				searchColumns.insert({ bottom: aSearchColumn });
			});
			
			var searchNav = new Element('div');
			searchNav.setStyle({
						  margin: '2px',
						  textAlign: 'right'
						});
			searchForm.insert({ bottom: searchNav });
			
			var searchSubmit = new Element('input', { 'type' : 'button', 'value' : 'Search' });
			Event.observe(searchSubmit, 'click', this.performSearch.bindAsEventListener(this));
			searchNav.insert({ bottom: searchSubmit });
			
			var searchCancel = new Element('input', { 'type' : 'button', 'value' : 'Cancel' });
			Event.observe(searchCancel, 'click', this.toggleSearch.bindAsEventListener(this));
			searchNav.insert({ bottom: searchCancel });

			$(this.filterContainer).insert({ before: searchObj });
		},
		
		toggleSearch: function() {
			element = $(this.uniqID + '_search_link');
			var elemPos = Position.positionedOffset(element); 
			$(this.uniqID+'_search_box').setStyle({ top: elemPos[1]+15+'px', left: elemPos[0]+15+'px' }); 
			$(this.uniqID+'_search_box').toggle(); 
		},

		performSearch: function() { 
			var form = $(this.uniqID + '_search_form');
			if ($F(form[this.uniqID + '_search_text']).length == 0) { 
				alert('You must provide a term to search for.'); 
				return; 
			} else {
				// Save Filter Settings
				this.filters.set('f_sc', $F(form[this.uniqID + '_search_col']));
				this.filters.set('f_ss', $F(form[this.uniqID + '_search_text']));
				
				// Update Pagination
				this.pagination.updateFilters(this.filters);
				this.pagination.selectPage(1);
				
				// Hide the Search Box
				$(this.uniqID+'_search_box').toggle(); 
			}
		},
		
		/* ----------------------------------------------------------------------------------
		Filter: Date Range Filters 
		---------------------------------------------------------------------------------- */
		enableDateRange: function(dateColumn) {
			// Remember the data column to filter
			this.dateColumn = dateColumn;
			
			// Create a Date Filter Element
			dateObj = new Element('div', { 'id' : this.uniqID + '_date_filter',
									         'class' : 'dateFilter' }).update('<span title="' + dateColumn + '">Date:</span>');
			
			// Add a Date Filter Form
			var dateForm = new Element('form', { 'id' : this.uniqID + '_date_form' });
			dateObj.insert({ bottom: dateForm });
			
			// Add Date Filter Input
			var dateFilter = new Element('select', { 'id' : this.uniqID + '_date',
										            'class': 'filterInput'});
			
			// Add Date Filter Options
			// The update() and selected = true was required for IE8 to work
			var option;
			option = new Option('Today', 'Today', false);
			option.update('Today');
			dateFilter.appendChild(option);
			
			option = new Option('24 hours', '24 hours', false);
			option.update('Last 24 Hours');
			dateFilter.appendChild(option);
			
			option = new Option('Yesterday', 'Yesterday', false);
			option.update('Yesterday');
			dateFilter.appendChild(option);

			option = new Option('Week', 'Week', false);
			option.update('Last 7 Days');
			dateFilter.appendChild(option);

			option = new Option('Month', 'Month', false);
			option.update('This Month');
			dateFilter.appendChild(option);
			
			option = new Option('30 days', '30 days', false);
			option.update('Last 30 Days');
			dateFilter.appendChild(option);
		
			option = new Option('All', 'All', true);
			option.update('All Time');
			option.selected = true;
			dateFilter.appendChild(option);			

			Event.observe(dateFilter, 'change', this.performDateFilter.bindAsEventListener(this));
			dateForm.insert({ bottom: dateFilter });

			$(this.filterContainer).insert({ before: dateObj });
		},
		
		performDateFilter: function() { 
			var form = $(this.uniqID + '_date_form');
			if ($F(form[this.uniqID + '_date']).length == 0) { 
				alert('No date filter value selected'); 
				return; 
			} else {
				// Save Filter Settings
				this.filters.set('f_dc', this.dateColumn);
				this.filters.set('f_dv', $F(form[this.uniqID + '_date']));
				
				// Update Pagination
				this.pagination.updateFilters(this.filters);
				this.pagination.selectPage(1);
			}
		}		
		
	 }),
	
	uniqID: function() {
		var newDate = new Date;
		return newDate.getTime();
	}
}


Event.observe(window, 'load', function() {
	// Switch the noscript tag out
	$('page').show();
	$('noscript').remove();
	
	// Get all form elements and add the onfocus listener to remove any error events
	$$('INPUT', 'SELECT', 'TEXTAREA').each(function(elem) {
		Event.observe(elem, 'blur', Iamota.Form.clearErrorEvent);
	});
	
	// Update any date fields to today's date
	$$('input.textdatefield').each(function(elem) {
		var montharray=new Array("January","February","March","April","May","June",
                            "July","August","September","October","November","December")
		var d = new Date();
		var curr_day = d.getDate();
		var curr_month = d.getMonth();
		var curr_year = d.getFullYear();
		elem.value = montharray[curr_month] + " " + curr_day + ", " + curr_year;
	});

	// Register Resizable Events
	document.observe('iamota:getComplete', Iamota.Resizable.registerEvents.bindAsEventListener(Iamota.Resizable));
	
	// Fire any window events
	document.fire('iamota:splitResize');
});