if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {};
SiteTreeHandlers.parentChanged_url = 'admin/ajaxupdateparent';
SiteTreeHandlers.orderChanged_url = 'admin/ajaxupdatesort';
SiteTreeHandlers.loadPage_url = 'admin/getitem';
SiteTreeHandlers.loadTree_url = 'admin/getsubtree';

_NEW_PAGES = new Array();

/**
 * Add page action
 */
var addpageclass;
addpageclass = Class.create();
addpageclass.applyTo('#addpage');
addpageclass.prototype = {
	originalValues: new Array(),
	initialize: function () {
		Observable.applyTo($(_HANDLER_FORMS[this.id]));
		this.getElementsByTagName('button')[0].onclick = returnFalse;
		$(_HANDLER_FORMS[this.id]).onsubmit = this.form_submit;
		
		// Save the original page types in to this object
		if ($(_HANDLER_FORMS.addpage).elements.PageType) {
			var options = $(_HANDLER_FORMS.addpage).elements.PageType.options;
			for(var i = 0; i < options.length; i++) {
				this.originalValues.push({
					'value': options[i].value,
					'label': options[i].innerHTML
				});
			}
		
			var selectedNode = $('sitetree').firstSelected();
			if(selectedNode) this.showApplicableChildrenPageTypes(selectedNode.hints);
		}
	},
	
	onclick : function() {
			if(treeactions.toggleSelection(this)) {
			var selectedNode = $('sitetree').firstSelected();
			if(selectedNode) {
				while(selectedNode.parentTreeNode && !selectedNode.hints.defaultChild) {
					$('sitetree').changeCurrentTo(selectedNode.parentTreeNode);
					selectedNode = selectedNode.parentTreeNode;
				}
				
				if( selectedNode.hints && selectedNode.hints.defaultChild )
					$(_HANDLER_FORMS.addpage).elements.PageType.value = selectedNode.hints.defaultChild;
			}
						
			this.o1 = $('sitetree').observeMethod('SelectionChanged', this.treeSelectionChanged.bind(this));
			this.o2 = $(_HANDLER_FORMS[this.id]).observeMethod('Close', this.popupClosed.bind(this));

			$(_HANDLER_FORMS[this.id]).elements.PageType.onchange = this.typeDropdown_change;
		}
		return false;
	},
	
	// Reset the page types dropdown to its original state
	resetPageTypeOptions: function() {
		var select = $(_HANDLER_FORMS.addpage).elements.PageType;
		while (select.childNodes.length >= 1) {	select.removeChild(select.firstChild); } 
		for(var i = 0; i < this.originalValues.length; i++) {
			var option = document.createElement('option');
			option.value = this.originalValues[i].value;
			option.innerHTML = this.originalValues[i].label;
			select.appendChild(option);
		}
	},
	
	// Hide the <option> elements in the new page <select> unless
	// they are in the allowChildren array of the selected tree node
	showApplicableChildrenPageTypes: function(hints) {
		this.resetPageTypeOptions();
		if (typeof hints.allowedChildren != 'undefined') {
			var select = $(_HANDLER_FORMS.addpage).elements.PageType;
			
			var toRemove = new Array();
			for(var i = 0; i < select.options.length; i++) {
				var itemFound = false;
				for(var j = 0; j < hints.allowedChildren.length; j++) {
					if (select.options[i].value == hints.allowedChildren[j]) { itemFound = true; break; }
				}
				if (!itemFound) toRemove.push(select.options[i]);
			}
			for(var i = 0; i < toRemove.length; i++) { select.removeChild(toRemove[i]); }
		}
	},
	
	treeSelectionChanged : function(selectedNode) {
		this.showApplicableChildrenPageTypes(selectedNode.hints);
		$(_HANDLER_FORMS.addpage).elements.PageType.value = selectedNode.hints.defaultChild;
	},
	
	popupClosed : function() {
		$('sitetree').stopObserving(this.o1);
		$(_HANDLER_FORMS.addpage).stopObserving(this.o2);
	},
	
	typeDropdown_change : function() {
		// Don't do anything if we're already on an appropriate node
		var sel = $('sitetree').firstSelected();
		if(sel && sel.hints && sel.hints.allowedChildren) {
			var allowed = sel.hints.allowedChildren;
			for(i=0;i<allowed.length;i++) if(allowed[i] == this.value) return;
		}

		if( typeof siteTreeHints == 'undefined' )
			return;

		// Otherwise move to the default parent for that.
		if( siteTreeHints && siteTreeHints[this.value] ) {
			var newNode = $('sitetree').getTreeNodeByIdx(siteTreeHints[this.value].defaultParent);
			if(newNode) $('sitetree').changeCurrentTo(newNode);
		}
	},
	
	form_submit : function() {
		var st = $('sitetree');
		var parentID = st.getIdxOf(st.firstSelected());
		// TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875
		if(parentID && parentID.substr(0,3) == 'new') {
			alert(ss.i18n._t('CMSMAIN.WARNINGSAVEPAGESBEFOREADDING'));
			
		} else if( Element.hasClassName( st.firstSelected(), "nochildren" ) ) {
			alert(ss.i18n._t('CMSMAIN.CANTADDCHILDREN') );
		} else {
			$(_HANDLER_FORMS.addpage).elements.ParentID.value = parentID ? parentID : 0;
		
			if( !_NEW_PAGES[parentID] )
				_NEW_PAGES[parentID] = 1;

			var suffix = _NEW_PAGES[parentID]++;
			Ajax.SubmitForm(_HANDLER_FORMS.addpage, "action_addpage", {
				onSuccess : Ajax.Evaluator,
				onFailure : function(response) { if (response.status == 403) {
					alert('You cannot add that page at that location.');
				}},
				extraData: '&Suffix=' + suffix
			});
		}
		
		return false;
	}
};

/**
 * Search button click action
 */
var searchclass;
searchclass = Class.create();
searchclass.applyTo('#search');
searchclass.prototype = {
	initialize : function() {
		Observable.applyTo($(_HANDLER_FORMS.search));
	},
	onclick : function() {
		if(treeactions.toggleSelection(this)) {
			this.o2 = $(_HANDLER_FORMS[this.id]).observeMethod('Close', this.popupClosed.bind(this));
		}
		return false;
	},
	popupClosed : function() {
		$(_HANDLER_FORMS.search).stopObserving(this.o2);
		batchActionGlobals.unfilterSiteTree();
	}
};

var SiteTreeFilter = Class.create();
SiteTreeFilter.applyTo('#siteTreeFilterList');
SiteTreeFilter.prototype = {
	initialize: function () {
	},
	reapplyIfNeeded: function() {
		if(this.options[this.selectedIndex].value != 'all') this.onchange();
	},
	onchange : function() {
		var value = this.options[this.selectedIndex].value;
		
		if(value != 'all') { 
			$('sitetree').setCustomURL(SiteTreeHandlers.controller_url+'/getfilteredsubtree?filter='+escape(value));
		} else {
			$('sitetree').clearCustomURL();
		}

		// We can't update the tree while it's draggable; it gets b0rked.
		var __makeDraggableAfterUpdate = false;
		if($('sitetree').isDraggable) {
			$('sitetree').stopBeingDraggable();
			__makeDraggableAfterUpdate = true;
		}
	
		var indicator = $('siteTreeFilterActionIndicator');
		indicator.style.display = 'inline';
	
		$('sitetree').reload({
			onSuccess: function() {
				indicator.style.display = 'none';
				if(__makeDraggableAfterUpdate) $('sitetree').makeDraggable();
				batchActionGlobals.refreshSelected();
			},
			onFailure: function(response) {
				errorMessage('Could not update tree', response);
			}
		});
	}
};
/**
 * Control the site tree filter
 */
var SiteTreeFilterForm = Class.create();
SiteTreeFilterForm.applyTo('form#search_options');
SiteTreeFilterForm.prototype = {
	initialize: function() {
		var self = this;
		Form.getElements(this).each(function(el){
			if (el.type == 'submit') el.onclick = function(){self.clicked = $F(this);};
		});
	},
	onsubmit: function() {
		var filters = $H();
		
		if (this.clicked == 'Clear') {
			Form.getElements(this).each(function(el){
				if (el.type == 'text') el.value = '';
				else if (el.type == 'select-one') el.value = 'All';
			});
			document.getElementsBySelector('.SearchCriteriaContainer', this).each(function(el){
				Element.hide(el);
			});
		}
		else {
			Form.getElements(this).each(function(el){
				if (el.type == 'text') {
					if ($F(el)) filters[el.name] = $F(el);
				}
				else if (el.type == 'select-one') {
					if ($F(el) && $F(el) != 'All') filters[el.name] = $F(el);
				}
			});
		}
		
		if (filters.keys().length) {
			// Set new URL
			$('sitetree').setCustomURL(SiteTreeHandlers.controller_url + '/getfilteredsubtree?filter=CMSSiteTreeFilter_Search', filters);
			
			// Disable checkbox tree controls that currently don't work with search.
			// @todo: Make them work together
			if ($('sitetree').isDraggable) $('sitetree').stopBeingDraggable();
			document.getElementsBySelector('.checkboxAboveTree input[type=checkbox]').each(function(el){
				el.value = false; el.disabled = true;	
			});
		}
		else {
			// Reset URL to default
			$('sitetree').clearCustomURL();
			
			// Enable checkbox tree controls
			document.getElementsBySelector('.checkboxAboveTree input[type=checkbox]').each(function(el){
				el.disabled = false;	
			});
		}
		
		$('SiteTreeSearchButton').className = $('SiteTreeSearchClearButton').className = 'hidden';
		$('searchIndicator').className = 'loading';
		
		$('sitetree').reload({
			onSuccess :  function(response) {
				$('SiteTreeSearchButton').className = $('SiteTreeSearchClearButton').className = 'action';
				$('searchIndicator').className = '';
				statusMessage('Filtered tree','good');
			},
			onFailure : function(response) {
				errorMessage('Could not filter site tree<br />' + response.responseText);
			}
		});
		
		return false;
	}
};

/**
 * Add Criteria Drop-down onchange action which allows more criteria to be shown
 */
var SiteTreeFilterAddCriteria = Class.create();
SiteTreeFilterAddCriteria.applyTo('#SiteTreeFilterAddCriteria');
SiteTreeFilterAddCriteria.prototype = {
	onchange : function() {
		Element.show('Container' + this.value);
		// Element.show('Text' + this.value);
		// Element.show('Input' + this.value);
		this.selectedIndex = 0; //reset selected criteria to prompt 
	}
};

/**
 * Batch Actions button click action
 */
var batchactionsclass = Class.create();
batchactionsclass.applyTo('#batchactions');
batchactionsclass.prototype = {
	
	initialize : function() {
		Observable.applyTo($(_HANDLER_FORMS.batchactions));
	},
	onclick : function() {
		if(treeactions.toggleSelection(this)) {
			this.multiselectTransform();
			this.actionChanged();
		}
		return false;
	},
	
	actionChanged: function() {
		// Show parameters form, if necessary
		var urlSegment = $('choose_batch_action').value.split('/').pop();
		if ($('BatchActionParameters_'+urlSegment)) {
			jQuery('#BatchActionParameters .params').hide();
			jQuery('#BatchActionParameters_'+urlSegment).show();
			jQuery('#BatchActionParameters').show();
		} else {
			jQuery('#BatchActionParameters').hide();
		}
		
		// Don't show actions that have failed from the previous execution
		batchActionGlobals.removeFailures();
		
		batchActionGlobals.refreshSelected();
	},
	
	multiselectTransform : function() {
		batchActionGlobals.o1 = $('sitetree').observeMethod('SelectionChanged', batchActionGlobals.treeSelectionChanged);
		batchActionGlobals.o2 = $(_HANDLER_FORMS.batchactions).observeMethod('Close', batchActionGlobals.popupClosed);
	
		addClass($('sitetree'),'multiselect');
	
		batchActionGlobals.selectedNodes = { };

		var selectedNode = $('sitetree').firstSelected();
		if(selectedNode && selectedNode.className.indexOf('nodelete') == -1) {
			var selIdx = $('sitetree').getIdxOf(selectedNode);
			batchActionGlobals.selectedNodes[selIdx] = true;
			selectedNode.removeNodeClass('current');
			selectedNode.addNodeClass('selected');	
			selectedNode.open();	
			
			// Open all existing children, which might trigger further
			// ajaxExansion calls to ensure all nodes are selectable
			var children = selectedNode.getElementsByTagName('li');
			for(var i=0; i<children.length; i++) {
				children[i].open();
			}
		}
	}
};

// batchActionGlobals is needed because calls to observeMethod doesn't seem to preserve instance variables so a Prototype can't be used
batchActionGlobals = {
	selectedNodes: { },
	// count Int - The number of nodes selected
	count: function() {
		return batchActionGlobals.getIds().length;
	},
	// TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875
	newNodes: { },
	treeSelectionChanged : function(selectedNode) {
		var idx = $('sitetree').getIdxOf(selectedNode);
		if(selectedNode.className.indexOf('nodelete') == -1) {
			if(selectedNode.selected) {
				selectedNode.removeNodeClass('selected');
				selectedNode.selected = false;
				batchActionGlobals.selectedNodes[idx] = false;
	
			} else {
				// Open node in order to allow proper selection of children
				if(Element.hasClassName(selectedNode, 'unexpanded')) {
					selectedNode.open();
				}
				
				// Select node
				selectedNode.addNodeClass('selected');
				selectedNode.selected = true;
				batchActionGlobals.selectedNodes[idx] = true;
				
				// Open all existing children, which might trigger further
				// ajaxExansion calls to ensure all nodes are selectable
				var children = selectedNode.getElementsByTagName('li');
				for(var i=0; i<children.length; i++) {
					children[i].open();
				}
			}
		}
		
		return false;
	},
	
	popupClosed : function() {
		removeClass($('sitetree'),'multiselect');

		$('sitetree').stopObserving(batchActionGlobals.o1);
		$(_HANDLER_FORMS.batchactions).stopObserving(batchActionGlobals.o2);

		for(var idx in batchActionGlobals.selectedNodes) {
			if(batchActionGlobals.selectedNodes[idx]) {
				node = $('sitetree').getTreeNodeByIdx(idx);
				if(node) {
					node.removeNodeClass('selected');
					node.selected = false;
				}
			}
		}
		batchActionGlobals.selectedNodes = { };
	},
	
	getIds: function() {
		var csvIDs = new Array();
		var st = $('sitetree');
		batchActionGlobals.newNodes = new Array();
		for(var idx in batchActionGlobals.selectedNodes) {
			if(batchActionGlobals.selectedNodes[idx]) {
				
				// Delete/Publish new nodes? (Leftover from delete code?) TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875
				if( idx.match(/^new-[a-z0-9A-Z\-]+$/) ) {
					batchActionGlobals.newNodes.push( idx );
				} else {
					if(csvIDs.indexOf(idx) == -1) {
						csvIDs.push(idx);
					}
				}
			}
		}
		return csvIDs;
	},
	getCsvIds : function() {
		return (batchActionGlobals.getIds().toString());
	},
	refreshSelected : function(rootNode) {
		var st = $('sitetree');
		
		for(var idx in batchActionGlobals.selectedNodes) {
			st.getTreeNodeByIdx(idx).addNodeClass('selected');
			st.getTreeNodeByIdx(idx).selected = true;
		}

		// Default to refreshing the entire tree
		if(rootNode == null) rootNode = st;

		/// If batch actions is enabled, then enable/disable the appropriate tree fields
		if($('batchactionsforms').style.display != 'none' && $('choose_batch_action').value) {
			// Collect list of visible tree IDs 
			var ids = [];
			jQuery(rootNode).find('li').each(function() {
				var id = parseInt(this.id.replace('record-',''));
				if(id) ids.push(id);
				
				// Disable the nodes while the ajax request is being processed
				this.removeNodeClass('nodelete');
				this.addNodeClass('treeloading');
			});
		
			// Post to the server to ask which pages can have this batch action applied
			var applicablePagesURL = $('choose_batch_action').value + '/applicablepages?csvIDs=' + ids.join(',');
			jQuery.getJSON(applicablePagesURL, function(applicableIDs) {
				var i;
				var applicableIDMap = {};
				for(i=0;i<applicableIDs.length;i++) applicableIDMap[applicableIDs[i]] = true;
			
				// Set a CSS class on each tree node indicating which can be batch-actioned and which can't
				jQuery(rootNode).find('li').each(function() {
					this.removeNodeClass('treeloading');

					var id = parseInt(this.id.replace('record-',''));
					if(id) {
						if(applicableIDMap[id] === true) {
							this.removeNodeClass('nodelete');
						} else {
							// De-select the node if it's non-applicable
							delete batchActionGlobals.selectedNodes[id];

							this.removeNodeClass('selected');
							this.addNodeClass('nodelete');
						}
					}
				});
			});
		}
	},

	/**
	 * Deselect all nodes in the tree
	 */
	deselectAll : function() {
		batchActionGlobals.selectedNodes = {}
		jQuery('#sitetree').find('li').each(function() {
			this.removeNodeClass('selected');
			this.selected = false;
		});
	},

	/**
	 * Remove the indications of failed batch actions
	 */
	removeFailures : function() {
		jQuery('#sitetree').find('li.failed').each(function() {
			this.removeNodeClass('failed');
		});
	},
	
	unfilterSiteTree : function() {
		// Reload the site tree if it has been filtered
		if ($('SiteTreeIsFiltered').value == 1) {
			// Show all items in Site Tree again
			new Ajax.Request( 'admin/SiteTreeAsUL' + '&ajax=1', {
				onSuccess: function( response ) {
					$('sitetree_ul').innerHTML = response.responseText;
					Behaviour.apply($('sitetree_ul'));
					$('SiteTreeIsFiltered').value = 0;
					$('batchactions').multiselectTransform();
					statusMessage(ss.i18n._t('CMSMAIN.SUCCESSUNFILTER'),'good');
				},
				onFailure : function(response) {
					errorMessage(ss.i18n.sprintf(
						ss.i18n._t('CMSMAIN.ERRORUNFILTER'),
						response.responseText
					));
				}
			});
		}
	}
};


Behaviour.register({
	'#choose_batch_action' : {
		onchange : function() {
			$('batchactions').actionChanged();
		}
	}
});

/**
 * Publish selected pages action
 */
var publishpage = Class.create();
publishpage.applyTo('#batchactions_options');
publishpage.prototype = {
	onsubmit : function() {
		csvIDs = batchActionGlobals.getCsvIds();
		if(csvIDs) {		
			var optionEl = $('choose_batch_action').options[$('choose_batch_action').selectedIndex];
			var actionText = optionEl.text;
			
			var confirmationURL = $('choose_batch_action').value + '/confirmation?csvIDs=' + csvIDs;
			jQuery.getJSON(confirmationURL, function(data) {
				// If a custom alert has been provided, show that.
				// otherwise, show the default one
				if (data.alert) {
					if (!confirm(data.content)) return false;
				} else {
					if(!confirm("You have " + batchActionGlobals.count() + " pages selected.\n\nDo your really want to " + actionText.toLowerCase() + "?")) {
						return false;
					}
				}
				
				$('batchactions_options').submitform();
			});
		} else {
			alert(ss.i18n._t('CMSMAIN.SELECTONEPAGE'));
		}

		return false;
	},
	
	submitform: function() {
		csvIDs = batchActionGlobals.getCsvIds();

		var optionEl = $('choose_batch_action').options[$('choose_batch_action').selectedIndex];
		var optionParams = eval(optionEl.className);
		var ingText = optionParams.doingText;
			
		this.elements.csvIDs.value = csvIDs;

		// Select form submission URL
		this.action = $('choose_batch_action').value;

		// Loading indicator
		statusMessage(ingText);
		$('batchactions_go').className = 'loading';

		// Don't show actions that have failed from the previous execution
		batchActionGlobals.removeFailures();

		// Submit form
		Ajax.SubmitForm(this, null, {
			onSuccess :  function(response) {
				Ajax.Evaluator(response);
				$('batchactions_go').className = '';
				batchActionGlobals.deselectAll();
			},
			onFailure : function(response) {
				errorMessage('Error ' + ingText, response);
			}
		});
	}
};


/**
 * Delete selected pages action
 */
var deletepage;
deletepage = Class.create();
deletepage.applyTo('#Form_DeleteItemsForm');
deletepage.prototype = {
	onsubmit : function() {
		csvIDs = batchActionGlobals.getCsvIds();
		if(csvIDs || batchActionGlobals.newNodes.length > 0) {
			
			if(confirm(ss.i18n.sprintf(
				ss.i18n._t('CMSMAIN.REALLYDELETEPAGES'),
				batchActionGlobals.count()
			))) {
				this.elements.csvIDs.value = csvIDs;
				
				statusMessage(ss.i18n._t('CMSMAIN.DELETINGPAGES'));
				// TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875	
				for( var idx = 0; idx < batchActionGlobals.newNodes.length; idx++ ) {
					var newNode = $('sitetree').getTreeNodeByIdx( batchActionGlobals.newNodes[idx] );
					
					if( newNode.parentTreeNode )
						newNode.parentTreeNode.removeTreeNode( newNode );
					else
						alert( newNode.id + ' has no parent node');
						
					$('Form_EditForm').reloadIfSetTo(idx);
				}
				
				batchActionGlobals.newNodes = new Array();
				// Put an AJAXY loading icon on the button
				$('Form_DeleteItemsForm_action_deleteitems').className = 'loading';
				Ajax.SubmitForm(this, null, {
					onSuccess : function(response) {
						Ajax.Evaluator(response);
						$('Form_DeleteItemsForm_action_deleteitems').className = '';
						treeactions.closeSelection($('batchactions'));
					},
					onFailure : function(response) {
						errorMessage(ss.i18n._t('CMSMAIN.ERRORDELETINGPAGES'), response);
					}
				});
			}
			
		} else {
			alert(ss.i18n._t('CMSMAIN.SELECTONEPAGE'));
		}

		return false;
	}
};

/**
 * Tree context menu
 */
TreeContextMenu = {
	'Edit this page' : function(treeNode) {
		treeNode.selectTreeNode();
	},
	'Duplicate page and children' : function(treeNode) {
		// First save the page silently (without confirmation) and then duplicate the page.
		autoSave(false, treeNode.duplicatePageWithChildren.bind(treeNode)); 
	},
	'Duplicate just this page' : function(treeNode) {
		// First save the page silently (without confirmation) and then duplicate the page.
		autoSave(false, treeNode.duplicatePage.bind(treeNode)); 
	},
	'Sort sub-pages' : function(treeNode) {
		var children = treeNode.treeNodeHolder().childTreeNodes();
		var sortedChildren = children.sort(function(a, b) {
			var titleA = a.aTag.innerHTML.replace(/<[^>]*>/g,'');
			var titleB = b.aTag.innerHTML.replace(/<[^>]*>/g,'');
			return titleA < titleB ? -1 : (titleA > titleB ? 1 : 0);
		});
		
		var i,child;
		for(i=0;child=sortedChildren[i];i++) {
			treeNode.appendTreeNode(child);
		}
		
		treeNode.onOrderChanged(sortedChildren,treeNode);
	}
};