Effect.Updater = Class.create();
Object.extend(Object.extend(Effect.Updater.prototype, Effect.Base.prototype), {
	initialize: function(element) {
		this.element = $(element);
		var options = Object.extend ({
			duration: 0.001,
			newContent: ''
		}, arguments[1] || {});
		this.start(options);
	},
	loop: function(timePos) {
		if(timePos >= this.startOn) {
			Element.update(this.element ,this.options.newContent);
			this.cancel();
			return;
		}
	}
});

function fadeout_flash_message() {
	var div_id = 'flash_message';
	var div = $(div_id);
	var duration = 4.0; // length of fade
	var delay = 6.0; // delay until fade
	var sliding_div = false;
	
	// Begin fade
	var fade_flash_message = new Effect.Opacity(div, {
		duration: duration, 
		delay: delay,
		from: 1.0,
		to: 0.0,
		queue: { position: 'end', scope: 'flash_msg', limit: 2 },
		afterFinish: function() {
			if (sliding_div) {
				return;
			}
			sliding_div = true;
			new Effect.SlideUp(div, {
				queue: { position: 'end', scope: 'flash_msg', limit: 1 }
			});
		}
	});

	
	// Make fade stop on mouseover
	fade_flash_message.element.onmouseover = function() {
		if (sliding_div) {
			return;
		}
		fade_flash_message.cancel();

		var queue = Effect.Queues.get('flash_msg');
		queue.each(function(effect) { effect.cancel(); });
		
		new Effect.Appear(div, {
			duration: 0.2,
			queue: { position: 'end', scope: 'flash_msg', limit: 2 }
		});
		
	};

	
	// Make fade resume after delay on mouseout
	fade_flash_message.element.onmouseout = function() {
		new Effect.Opacity(div, {
			duration: duration,
			delay: delay,
			from: 1.0,
			to: 0.0,
			queue: { position: 'end', scope: 'flash_msg', limit: 2 },
			afterFinish: function() {
				if (sliding_div) {
					return;
				}
				sliding_div = true;
				new Effect.SlideUp(div, {
					queue: { position: 'end', scope: 'flash_msg', limit: 1 }
				});
			}
		});
	}
}

function disableEndTimeInputs(checked) {
	if (checked) {
		$('EventTimeEndHour').disable();
		$('EventTimeEndMin').disable();
		$('EventTimeEndMeridian').disable();
	} else {
		$('EventTimeEndHour').enable();
		$('EventTimeEndMin').enable();
		$('EventTimeEndMeridian').enable();
	}
}

function disableEndDateInputs(checked) {
	if (checked) {
		$('ExhibitionEndDateMonth').disable();
		$('ExhibitionEndDateDay').disable();
		$('ExhibitionEndDateYear').disable();
	} else {
		$('ExhibitionEndDateMonth').enable();
		$('ExhibitionEndDateDay').enable();
		$('ExhibitionEndDateYear').enable();
	}
}

var DropDownMenu = Class.create();

DropDownMenu.prototype = {
	initialize: function(menuElement) {
		menuElement.childElements().each(function(node) {
			// if there is a submenu
			var submenu = $A(node.getElementsByTagName("ul")).first();
			if (submenu != null) {
				// make sub-menu invisible
				Element.extend(submenu).setStyle({display: 'none'});
				// toggle the visibility of the submenu
				node.onmouseover = function() {
					//Element.toggle(submenu);
					submenu.show();
				}
				node.onmouseout = function() {
					//Element.toggle(submenu);
					submenu.hide();
				}
			}
		});
	}
};

function showHide(toggle_this_id, child_count, handle_li_id) {
	var handle_li = $(handle_li_id);
	var toggle_this = $(toggle_this_id);
	if (toggle_this) {
		//var timeToTake = .5 * child_count;
		var timeToTake = .3;
		
		var toggleSubmenuHandle_expand = function (handle_li) {
			handle_li.down('img.expand_collapse').src = '/img/icons/menu-collapsed.png';
			handle_li.down('span').title = 'Click to expand';	
		};

		var toggleSubmenuHandle_collapse = function (handle_li) {
			handle_li.down('img.expand_collapse').src = '/img/icons/menu-expanded.png';
			handle_li.down('span').title = 'Click to collapse';
		};
		
		if (toggle_this.visible()) {
			Effect.Shrink(toggle_this_id, {
				duration: timeToTake, 
				direction: 'top-left', 
				queue: {
					position: 'end', 
					scope: 'tree', 
					limit: 1
				},
				beforeStart: toggleSubmenuHandle_expand.bind(this, handle_li)
			});
		} else {
			Effect.Grow(toggle_this_id, {
				duration: timeToTake, 
				direction: 'top-left', 
				queue: {
					position: 'end', 
					scope: 'tree', 
					limit: 1
				},
				beforeStart: toggleSubmenuHandle_collapse.bind(this, handle_li)
			});
		}						
	}
}

function toggleFieldset(id) {
	fieldset = $(id);
	internal = fieldset.down('.fieldset_internal');		
	if (internal.visible()) {
		Effect.SlideUp(internal, {
			afterFinish: function() {
				fieldset.addClassName('collapsed');
			},
			duration: 0.5,
			queue: {
				position: 'end',
				scope: 'fieldset_toggle',
				limit: 1
			}
		});
		
	} else {
		Effect.SlideDown(internal, {
			beforeStart: function() {
				fieldset.removeClassName('collapsed');
			},
			duration: 0.5,
			queue: {
				position: 'end',
				scope: 'fieldset_toggle',
				limit: 1
			}
		});
	}
}

function setupCollapsibleFieldsets() {
	$$('fieldset.collapsible').each(function(fieldset) {
		legend = fieldset.down('legend');
		legend.onclick = function() {
			toggleFieldset(fieldset.identify());
		};
		legend.addClassName('fake_link');
		legend.title = 'Clicky clicky.';
		fieldset.down('div').wrap('div'); // Extra div to make animation smoother
		wrapper = fieldset.down('div').wrap('div');
		wrapper.addClassName('fieldset_internal');
		if (fieldset.hasClassName('collapsed')) {
			wrapper.hide();
		}
	});
}

/* Previously, this only positioned the popup once,
 * then had the popup remain in that position. This made
 * the popups move around when the user zoomed the browser in
 * after loading the page. Positioning the popups at every mouseover
 * fixes this.
 */
function mouseoverCalendarDate(day, cell) {
	//$('calendar_help').hide();
	var popup = $('calpopup_' + day);
	Element.extend(cell);
	var offsets = cell.cumulativeOffset();
	
	// Vertical and horizontal distance between
	// the popup and the calendar cell
	var top_margin = 14;
	var left_margin = 4;
	
	var cell_height = 20;
	var popup_width = popup.getWidth();
	
	var left_offset = offsets[0] - left_margin - popup_width;
	var top_offset = offsets[1] + top_margin;
	popup.setStyle({
		top: top_offset + 'px',
		left: left_offset + 'px'
	});
	popup.show();
}

function mouseoutCalendarDate(day) {
	$('calpopup_' + day).hide();
}

window.onload = function() {
	setupCollapsibleFieldsets();
}

function toggleEvent(event_id) {
	var description = $('event_' + event_id + '_description');
	var handle = $('event_' + event_id + '_handle');
	if (! description) {
		alert('Invalid event selected. YOU BROKE THE INTERNET.');
		return;
	}
	if (description.visible()) {
		handle.style.fontStyle = 'normal';
		Effect.SlideUp(description, {
			duration: 0.3,
			afterFinish: function() {
				description.up('tr').hide();
			},
			queue: {
				position: 'end',
				scope: 'event_details',
				limit: 1
			}
		});
	} else {
		description.up('tr').show();
		handle.style.fontStyle = 'italic';
		Effect.SlideDown(description, {
			duration: 0.3,
			queue: {
				position: 'end',
				scope: 'event_details',
				limit: 1
			}
		});
	}
}

function selectTag(tag_id, submenu_header) {
	var avail_tag_li = $(tag_id + '_li');
	if (! avail_tag_li) {
		alert('There was an error selecting a tag (' + tag_id + '_li)');
		return;
	}
	var selected_tag_div = avail_tag_li.down('div').cloneNode(true);
	var selected_tag_li = selected_tag_div.wrap('li', {'id': tag_id + '_li_selected'});
	
	// If it's not provided whether this tag is or is not a submenu header,
	// we'll check and see for ourselves.
	if (typeof submenu_header == 'undefined') {
		submenu_header = ($(tag_id + '_submenu') != undefined);
	}
	
	// For submenu headers
	if (submenu_header) {
		// Hide 'add' button 
		avail_tag_li.down('img.add_remove').hide();
	
		// Remove 'click here to expand' title
		selected_span = selected_tag_li.down('span');
		selected_span.title = '';
		
		// Remove onclick action
		selected_span.onclick = '';
		
		// Change expand/collapse icon into a leaf icon
		selected_tag_li.down('img.expand_collapse').src = '/img/icons/menu-leaf.png';
		
	// For 'tree leaf' tags
	} else {
		// Hide tag in 'available' list 
		avail_tag_li.hide();
	}

	// Enable hidden input
	selected_tag_li.down('input').enable();

	// Change action button from plus to minus
	var icon = selected_tag_li.down('img');
	icon.src = '/img/icons/fugue/icons-shadowless/minus.png';
	icon.onclick = function() {unselectTag(tag_id, submenu_header);};
	icon.title = 'Click to remove';
	icon.style.visibility = '';
	
	// Place tag in 'selected' list
	$('selected_tags').down('ul').insert({bottom: selected_tag_li});
}

// If an unlisted tag needs to be placed
function selectUnlistedTag(tag_id, name) {
	tag_li = $('tag_' + tag_id + '_li');
	if (tag_li) {
		selectTag('tag_' + tag_id);
		return;
	}
	
	var ul = $('selected_tags').down('ul');
	
	var li = new Element('li', {
		'id': 'tag_' + tag_id + '_li_selected'
	});
	
	var div = new Element('div', {
		'class': 'single_row'
	});
	
	var button = new Element('img', {
		'class': 'add_remove',
		'onclick': 'unselectTag(' + tag_id + ', false);',
		'title': 'Click to remove',
		'src': '/img/icons/fugue/icons-shadowless/minus.png'
	});
	
	var span = new Element('span', {
		'id': 'tag_' + tag_id + '_span'
	});
	
	var icon = new Element('img', {
		'class': 'leaf',
		'src': '/img/icons/menu-leaf.png'
	});
	
	var input = new Element('input', {
		'type': 'hidden',
		'value': tag_id,
		'name': 'data[Tag][]'
	});
	
	span.update(name);
	span.insert(input);
	div.insert(button);
	div.insert(icon);
	div.insert(span);
	li.insert(div);
	ul.insert(li);
}

function unselectTag(tag_id, submenu_header) {
	var selected_tag_li = $(tag_id + '_li_selected');

	// Remove tag from 'selected' list
	selected_tag_li.remove();

	var avail_tag_li = $(tag_id + '_li');
	
	if (avail_tag_li) {
		
		// For submenu headers
		if (submenu_header) {
			// Show 'add' button in 'available' list
			avail_tag_li.down('img').show();
			
		// For 'tree leaf' tags
		} else {
			// Show tag in 'available' list 
			avail_tag_li.show();
		}
	} else {
		// If the tag is not found in the 'available tags' list,
		// then it was (probably) an unlisted tag that should not
		// appear in that list after being un-selected
	}
}

//Re-disable any hidden inputs that have been mysteriously re-enabled
function disableUnselectedTags() {
	alert('disabling unselected tags');
	$$('#available_tags input').each(function(input) {
		input.disable();
	});
	return true;
}

// For canonical tags, only ID needs to be passed.
// For unlisted / custom tags, both ID and name needs to be passed
function preloadSelectedTag(id, name) {
	span_id = id + '_span';
	handle = $(span_id);

	// If this tag is in the 'available tags' list
	if (handle) {
		selectTag(id);

	// If this is a custom tag
	} else {
		new_li = '<li><div class="single_row"><span id="' + id + '_span" class="selected_tag">' + name + '<input type="hidden" value="' + id + '" name="data[Tag][]" /></span></div></li>';
		$('selected_tags').down('ul').insert({bottom: new_li});
		new Draggable(id + '_span', {revert: true});
	}
}

function addEvent_removeDate(date_iter) {
	$(date_iter).remove();

	// Hide/show remove buttons as appropriate
	// (don't allow the last date to be removed)
	if ($('dates').childElements().length == 1) {
		$$('.delete_date').each(function(button) {
			button.hide();
		});
		$('add_date_note').hide();
	}
}

function selectTagSublist(letter) {
	$$('#tag_sublist_loading ul.tag_sublist').each(function(sublist) {
		sublist.hide();
	});

	if (letter == 'cloud') {
		$('tag_cloud').show();
	} else {
		$('tag_cloud').hide();
		$('tag_sublist_' + letter).show();
	}
}

function setupEventForm() {
	$('select_age_restriction').onchange = function() {
		if (this.selectedIndex == 0) { // (none)
			$('type_age_restriction').hide();
			$('type_age_restriction').value = '';
		} else if (this.selectedIndex == 1) { // (21+)
			$('type_age_restriction').hide();
			$('type_age_restriction').value = '21+';
		} else if (this.selectedIndex == 2) { // (enter manually)
			$('type_age_restriction').show();
			$('type_age_restriction').value = '';
		}
	}

	$('select_cost').onchange = function() {
		$('type_cost').value = '';
		if (this.selectedIndex == 0) { // (free)
			$('type_cost').hide();
			$('cost_footnote').hide();
		} else if (this.selectedIndex == 1) { // ('Spensive)
			$('type_cost').show();
			$('cost_footnote').show();
		}
	}
}

function setupExhibitionForm() {
	$('select_cost').onchange = function() {
		$('type_cost').value = '';
		if (this.selectedIndex == 0) { // (free)
			$('type_cost').hide();
			$('cost_footnote').hide();
		} else if (this.selectedIndex == 1) { // ('Spensive)
			$('type_cost').show();
			$('cost_footnote').show();
		}
	}
}

function addEvent_addDate() {
	// Create a copy of the hidden and disabled date selection
	var date_selection = $('date_selection').down().cloneNode(true);
	var dates = $('dates');
	dates.insert({bottom: date_selection});

	// Enable its <select> tags
	var id_of_clone = date_selection.identify();
	$$('#'+id_of_clone+' select').each(function(select_element) {
		select_element.enable();
	});

	// Get the number assigned to this new date (0 if first, 1 if second, nothing fancy here)
	var date_iter = $('date_iter').value;
	
	// Set various values in this div to reflect this value
	date_selection.id = 'date_' + date_iter;
	date_selection.down('span.delete_date').onclick = function() {
		addEvent_removeDate('date_' + date_iter);
	};
	$$('#date_' + date_iter + ' select').each(function(select) {
		select.name = select.name.replace('dateiter', date_iter);
	});
	
	// Advance date_iter
	$('date_iter').value = Number(date_iter) + 1;
	
	// Hide/show remove buttons as appropriate
	// (don't allow the last date to be removed)
	if (dates.childElements().length == 1) {
		$$('.delete_date').each(function(button) {
			button.hide();
		});
		$('add_date_note').hide();
	} else if (dates.childElements().length == 2) {
		$$('.delete_date').each(function(button) {
			button.show();
		});
		$('add_date_note').show();
	}
}

function toggleTaskDeadlineSelect() {
	var deadline_select = $('task_deadline_select');
	var category_select = $('task_category_select');
	if (category_select.getValue() == 21) {
		$$('#task_deadline_select select').each(function(input) {
			input.enable();
		});
		deadline_select.show();
	} else {
		deadline_select.hide();
		$$('#task_deadline_select select').each(function(input) {
			input.disable();
		});
	}
}

function load_front_page_feed_options(type, selected) {
	$('load_feed_selections').update();
	type = (typeof type == 'undefined') ? 'news' : type;
	if (type == 'webcam') {
		new Ajax.Updater('load_front_page_feed', '/feeds/webcams/ajax', {
			asynchronous:true, 
			evalScripts:true, 
			onLoading:function(request) {
				$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/loading2.gif')";
				Effect.Fade('load_front_page_feed', {
					queue: 'end',
					duration: 0.3,
				});
			}, 
			onLoaded:function(request) {
				$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/icons/fugue/icons/arrow-turn-270.png')";
				Effect.Appear('load_front_page_feed', {
					queue: 'end',
					duration: 0.3,
				});
			}, 
			requestHeaders:['X-Update', 'load_feed_selections']
		});
	} else {
		var url = '/feeds/selections/' + type;
		if (typeof selected != 'undefined') {
			url += '/' + selected;
		}
		new Ajax.Updater('load_feed_selections', url, {
			asynchronous:true, 
			evalScripts:true, 
			onLoading:function(request) {
				$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/loading2.gif')"
			}, 
			onLoaded:function(request) {
				$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/icons/fugue/icons/arrow-turn-270.png')"
			}, 
			requestHeaders:['X-Update', 'load_feed_selections']
		});
	}	
}

function load_front_page_feed(feed_id) {
	if (feed_id == 0) {
		var feed_url = '/articles/index';
	} else {
		var feed_url = '/feeds/view/' + feed_id;
	}
	new Ajax.Updater('load_front_page_feed', feed_url, {
		asynchronous:true, 
		evalScripts:true, 
		onLoading:function(request) {
			$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/loading2.gif')";
			Effect.Fade('load_front_page_feed', {
				queue: 'end',
				duration: 0.3,
			});
		}, 
		onLoaded:function(request) {
			$('front_page_feed_loading_indicator').style.backgroundImage = "url('/img/icons/fugue/icons/arrow-turn-270.png')";
			Effect.Appear('load_front_page_feed', {
				queue: 'end',
				duration: 0.3,
			});
		}, 
		requestHeaders:['X-Update', 'load_front_page_feed']
	});
}