/**
 * JS helper functions for extended applications
 *
 * @package 	DigiCMS v3.x
 * @file		js/extended.js
 * @version		3.0.0
 * @author		Digitalization
 * @email		info@digitalization.nl
 * @link		http://www.digitalization.nl/
 * @copyright	All code copyright 2009,2010 by Digitalization
 */

/***
 * Message div closing functions
 **********************************************************************************************************/

var messages_closing_all = false;

//Close a single message box
function close_message(box) {
	
	//Only run when not running the close all animation
	//This custom animation is much smoother than a blind or slideUp, due to the margin/padding/border dissapearance
	if (!messages_closing_all) {
		$('div#message_' + box).stop(true).fadeTo(700, 0).animate({
			height: 0, border: 0, marginBottom: 0, paddingTop: 0, paddingBottom: 0
		}, { duration: 500 });
	}
}

//Close all of them at once
function close_all_messages(after) {

	//When to close them
	after = after || 5000;
	
	//Prevent individual closings while running this script
	setTimeout(function(){ 
		
		//Don't do this if already doing it
		if (messages_closing_all == true) {
			return;
		}
		
		//Prevent individual closings
		messages_closing_all = true; 
		
		//Fade all boxes
		$('div.message:not(.no_auto_close)').fadeTo(700, 0).hide('blind',{duration: 1000, queue:'messages'})
		
		//Allow individual closings again
		setTimeout(function(){ messages_closing_all = false;},1000);
		
	}, after);
}

/***
 * Datatable added functionality
 **********************************************************************************************************/

// *** Mark all checkboxes
function datatable_mark_all() {
	$('div.datatable').find('input.mark').each(function() {
		$(this).attr('checked', true);
		$(this).parents('div.data_row').addClass('selected');
	});

	mark_all_text = $('div#mark_all_in_db').html();
	$('div#mark_all_in_db').fadeTo(500,1);
}

// *** Mark none
function datatable_mark_none() {
	$('div.datatable').find('input.mark:checked').each(function() {
		$(this).attr('checked', false);
		$(this).parents('div.data_row').removeClass('selected');
	});

	$('div#mark_all_in_db').fadeTo(0,0);
	mark_all_in_db(false);
}

// *** Inverse the selection
function datatable_mark_inverse() {

	$('div.datatable').find('input.mark').each(function() {
		if ($(this).attr('checked')) {
			$(this).attr('checked', false);
			$(this).parents('div.data_row').removeClass('selected');
		}
		else {
			$(this).attr('checked', true);
			$(this).parents('div.data_row').addClass('selected');
		}
	});

	$('div#mark_all_in_db').fadeTo(0,0);
	mark_all_in_db(false);
}

// *** Mark all items in DB
var marked_all_in_db 	= 	false;
var mark_all_text		=	'';

function mark_all_in_db(mark_all, marked_all_text) {

	if (!marked_all_in_db && !mark_all) {
		return;
	}

	//Call with true, sets the ID's, proper text and bool to true
	if (mark_all) {
		marked_all_in_db 	= 	true;
		mark_all_text		=	$('div#mark_all_in_db').html();
		$('div#mark_all_in_db').html(marked_all_text).highlight();
	}

	//Deselect all
	else {
		marked_all_in_db 	= 	false;
		$('div#mark_all_in_db').fadeTo(500,0).pause(500).html(mark_all_text);
	}
}

// *** Get marked ID's
function datatable_get_marked_ids() {

	if (marked_all_in_db) {
		return 'all';
	}

	var ids = new Array();

	$('div.datatable').find('input.mark').each(function() {
		if ($(this).attr('checked')) {
			var id = $(this).attr('name').replace(/mark_/g,'');
			ids[ids.length] = id;
		}
	});

	return ids.join("/");
}

/***
 * AJAX callback function
 **********************************************************************************************************/

function ajax_callback(xml) {

	//Initialize vars
	var id		=	0;
	var html	=	'';
	
	//Pre parse the XML to see if there were any errors
	if (xml = pre_parse_xml(xml)) {
		
		//Get the action, jquery, tab text and message(s)
		var action 	= $(xml).find('action').text();
		var jquery 	= $(xml).find('jquery').text();
		var message = $(xml).find('message').text();
		var tab		= $(xml).find('tab').text();

		//Set message(s)
		if (message != '') {
			$('div#messages').html(message);
		}
		
		//Set tab
		if (tab != '') {
			show_tab(tab);
		}

		//Find datatable columns to replace
		$(xml).find('col').each(function() {
			
			//Get the row ID and replacement HTML
			id 		= $(this).find('id').text();
			html 	= $(this).find('html').text();

			//Replace the proper column contents
			$('div#col_' + id).html(html);
		});

		//Find datatable rows to replace
		$(xml).find('row').each(function(){

			//Get the row ID and replacement HTML
			id 		= 	$(this).find('id').text();
			html 	= 	$(this).find('html').text();
			pos		=	$(this).find('position').text();
			
			//Replace the proper row contents if HTML is found
			if (html != '') {
				
				if (pos == 'prepend') {
					$('div.datatable div.body').prepend(html);
					$('div#data_row_' + id).hide();
					$('div#data_row_' + id).show('slow');
				}
				else if (pos == 'append') {
					$('div.datatable div.body').append(html);
					$('div#data_row_' + id).hide();
					$('div#data_row_' + id).show('slow');
				}
				else {
					$('div#data_row_' + id).html(html);
				}
				
				//Fix filler width
				$('div#data_row_' + id).find('div.filler').width(filler_width);
			}

			//No HTML? Means the row should be deleted
			else {
				$('div#data_row_' + id).hide('slow');
			}

			//Fix layout again
			datatables_layout_fix($('div.datatable'));
		});
		
		//Find datatable rows to swap
		$(xml).find('swap').each(function() {
		
			//Find the rows to swap
			var row_1	=	$('div#data_row_' + $(this).find('row_1').text());
			var row_2	=	$('div#data_row_' + $(this).find('row_2').text());
			
			//Determine levels
			var level_1 = row_1.attr('rel');
			var level_2 = row_2.attr('rel');
			
			//Determine positions
			var index_1	= $('div.data_row').index(row_1);
			var index_2	= $('div.data_row').index(row_2);
			
			//Determine direction
			if (index_2 > index_1) {
				var direction = 'down';
			}
			else {
				var direction = 'up';
			}
			
			//Initialize item arrays
			var row_1_and_children = new Array(row_1);
			var row_2_and_children = new Array(row_2);
			
			
			//Get the next item after row 1
			var next_item = row_1.next();
				
			//Get any items that are children (higher level)
			while (next_item.length > 0) {
				
				//Not a data row? We have reached the end of the table
				if (!next_item.hasClass('data_row')) {
					break;
				}
				
				//Determine level of this item
				var next_item_level = next_item.attr('rel');
				
				//Same or smaller than the level of row 1?
				if (next_item_level <= level_1) {
					break;
				}
				
				//Child, add to array
				row_1_and_children.push(next_item);
				
				//Continue to next item
				next_item = next_item.next();
			}
			
			//Get the next item after row 2
			var next_item = row_2.next();
				
			//Get any items that are children (higher level)
			while (next_item.length > 0) {
				
				//Not a data row? We have reached the end of the table
				if (!next_item.hasClass('data_row')) {
					break;
				}
				
				//Determine level of this item
				var next_item_level = next_item.attr('rel');
				
				//Same or smaller than the level of row 2?
				if (next_item_level <= level_2) {
					break;
				}
				
				//Child, add to array
				row_2_and_children.push(next_item);
				
				//Continue to next item
				next_item = next_item.next();
			}
			
			//If the direction is down, it means that row_1 is above row_2, and should be moved to after the last child of row 2
			if (direction == 'down') {
			
				//Get the last child of row 2
				var after_item = row_2_and_children[row_2_and_children.length-1];
			
				//Loop the children of row 1
				for (c = 0; c < row_1_and_children.length; c++) {
					
					//Place the item after the after-item
					after_item.after(row_1_and_children[c]);
					
					//This item becomes the new after-item
					after_item = row_1_and_children[c];
				}
			}
			
			//If the direction is down, it means row_1 is under row_2, and should be moved before the first child of row 2
			else {
			
				//Get the first child of row 2
				var before_item = row_2_and_children[0];
				
				//Move row 1
				before_item.before(row_1_and_children[0]);
				
				//After item
				var after_item = row_1_and_children[0];
				
				//Loop the children of row 1 and place them after row 1
				for (c = 1; c < row_1_and_children.length; c++) {
					
					//Place the item after the after-item
					after_item.after(row_1_and_children[c]);
					
					//This item becomes the new after-item
					after_item = row_1_and_children[c];
				}
			}
		});

		//Evaulate jquery code
		if (jquery) {
			eval(jquery);
		}
	}
}

// *** Pre parse the XML returning from an AJAX call
function pre_parse_xml(xml) {
	
	//Initialize errors counter and string
	var errors 	= 	0;
	var error  	=	'';
	
	//Not a valid XML object?
	if (xml && typeof(xml) != 'object') {
		error = xml;
	}
	
	//Process errors
	else {
		$(xml).find('ajax_error').each(function() {
			if (error != '') {
				error += "<br/></br/><br/>";
			}
			error += $(this).text();
		});
	}
	
	//Was there anything? Toggle the error div and return nothing
	if (error != '') {
		$('div#errors').html($('div#errors').html() + error);
		$('div#errors').toggle(800);
		return '';
	}
	
	//Return the xml
	return xml;
}
