// Session ID
var session_id = '';

// Mode to view cards : view | edit | textedit | flip | flash | print
var mode = 'view';

// Height of cards (heights must also be edited in stylesheet : at entry #bd_ext_flip, #bd_ext_ss {)
var cardHeight = 220;	// use an even integer

// ID of the deck in the DB 
var deck_id = 0;

// Font size of fields and text
var font_size = '14px';

// OPTION BOX
var show_options_anim;	// show anim
var hide_options_anim;	// hide anim

var options_shown = false;

// FLIP MODE
var flip_id = 0;	// ID of card shown on flip screen (0 for none)
var flip_side = flip_current_side = 'f';	// Flip prompt side 
var flip_shuffle_drawn = new Array();	// list of all cards already drawn if in shuffle mode (flip screen)

// FLASH MODE
var hidden_side = ''; // side that is currently hidden ('b': back; 'f': front; '': none)

// EDIT MODE
var current_edit_mode = 'normal';
var current_input = false;	// input user is currently editing. If clicking on an input different than the one currently editing, the text will hightlight
var spinner_src = './images/spinner.gif'; // image to use while image/sound is loading
var current_edit_element = null;

// CARD SELECTION
var display_selected = false; // true if showing only selected cards, false if showing all cards

// Number of cards
var num_cards = 0;

// Array containing all cards
var cards = new Array();

//This keeps track of the last position added to the playlist so we can play back the sound
var sound_counter = 0 

///////////////////////////
// BEGIN CARD SIDE CLASS //
///////////////////////////
var side = function (card, side, sideID) {
	this.sideID = sideID;
	this.side = side;	// which side is this : f for front, b for back
	this.card = card;	// pointer to the card holding this side
	
	this.input = undefined; // text input in edit mode
	this.image = {
		div: get('bd_ext_'+this.side+'i_'+this.card.id), 
		upload: get('bd_ext_upload_div_'+this.side+'i_'+this.card.id), 
		value: get('bd_ext_'+this.side+'i_'+this.card.id) && get('bd_ext_'+this.side+'i_'+this.card.id).firstChild? get('bd_ext_'+this.side+'i_'+this.card.id).firstChild.src : false
	};
	this.sound = {
		div: get('bd_ext_'+this.side+'s_'+this.card.id), 
		upload: get('bd_ext_upload_div_'+this.side+'s_'+this.card.id),
		value : get('bd_ext_'+this.side+'s_'+this.card.id) && get('bd_ext_'+this.side+'s_'+this.card.id).innerHTML != ''? true: false,
		file: get(this.card.id+'_'+this.side+'s_val')? get(this.card.id+'_'+this.side+'s_val').value : '',
		mini : get('bd_sound_mini_'+side+'_'+this.card.id),
		pl_id: 0,
		is_loaded: false
	};
	this.video = false;	// not implemented yet
	
	// Play sound associated to this side
	this.sound_play = function() {
		
		if (!this.sound.value) return false;
		
		if(!this.sound.is_loaded) {
			thisMovie("mpl").addItem({file: this.sound.file});
			this.sound.pl_id = pl_counter++;
			this.sound.is_loaded = true;
		}
	
		thisMovie("mpl").sendEvent('playitem', this.sound.pl_id);	
	}
	this.keydown = function(e) {
		var key;
		var ctrl = false; //Is this a combo with the CTRL key?
	    if(window.event)
	    {
	    	key = window.event.keyCode;     //IE
	    	if(window.event.ctrlKey)
	    	{
	    		ctrl = true;
	    	}
	    }
		else
		{
			key = e.which;     //firefox
			if(e.ctrlKey)
			{
				ctrl = true;
			}
		}
	    if (key == 13 && !ctrl) // on enter
		{          
			this.save()
			this.card.toggle();
			
			//Check if any edit mode boxes are still open
			showE(get('bd_definitions_box'), false);
			showE(get('symbols_box'), false);
			
			return false;
		}
		else if (key == 9)	// on tab
		{
			this.save();
			
			if (this.side == 'f' && current_edit_mode == 'translate') 
			{
				this.card.back.input.value = 'Translating, please wait...';
				xajax_suggestTranslation(this.card.id, this.input.value, get('bd_translate_opts').value);
				this.card.back.input.focus();	// focus back input
			}
			else if (this.side == 'f' && current_edit_mode == 'define') 
			{
				set_current_input(this.card.back.input);
				get('bd_definitions_header').innerHTML = 'Loading Definitions...';
				get('bd_definitions_container').innerHTML = '';
				this.card.back.show_definitions();
				xajax_suggestDefinition(this.card.id, this.input.value);
			}
			else if(this.side == 'f')
			{
				this.card.back.input.focus();	// focus back input
				card_click_input(this.card.back.input, true);
			} 
			else 
			{
				this.card.toggle('close');	// close current card
				if (!this.card.next()) add_card(1);	// if there are no more card, then add a new one
				if (cards[this.card.next()]) cards[this.card.next()].toggle('open');	// open next card
			}
			
			return false;
		}
		else
		{
			/*// text has been changed, so this is not a new input field anymore
			input.setAttribute('newfield', false);*/
			return true;
		}
	}
	this.keyup = function(e) {
		// resize textarea to fit text
		textarea_resize(this.input);
	}
	this.save = function () {
		xajax_updateText(this.sideID, this.input.value, this.card.id); // Pass it side id, the text to change, and the ID of the card it came from
	}
	
	// show the file input field to add the image
	// media can be 'i' for image, 's' for sound, or 'v' for video
	this.add_media = function(media) 
	{
		if (this.card.status == -1) return; // if card has been removed // nb: if card has been hidden, it is ok to proceed, but no change will be seen on screen

		if (!this.card.ext) this.card.ext = this.card.add_extended(); // extend card so that we can add the input field
		this.card.toggle('open');
		
		var id = this.card.id	// just for convenience
		
		// hide all media of the card's side
		showE(this.image.div, false);	// hide image div of selected side
		showE(this.sound.div, false);	// hide sound div of selected side
		showE(this.image.upload, false);	// hide upload div of image (if it exists)
		showE(this.sound.upload, false);	// hide upload div of sound (if it exists)
		
		if (media == 'i') var ext_upload = this.image.upload;
		else if (media == 's') var ext_upload = this.sound.upload;
		// Check if the upload div already exists (if not, create it)
		if (!ext_upload) {
			ext_upload = this.card.ext_content.rows[0].cells[(this.side=='b')? 1 : 0].appendChild(document.createElement('div'));
			ext_upload.id = 'bd_ext_upload_div_'+this.side+media+'_'+id;
		}
		// print out the form (and the iframe to send the media)
		ext_upload.innerHTML = '<form id="upload_form_'+id+'_'+this.side+media+'" action="uploadMedia.php" enctype="multipart/form-data" method="post" target="upload_'+id+'_'+this.side+media+'">'
			+ '<iframe width="0" height = "0" frameborder="0" marginwidth="0" id="upload_'+id+'_'+this.side+media+'" name="upload_'+id+'_'+this.side+media+'"></iframe>'
			+ (media == 's'?
	          '<div class="bd_upload_sound_section">Upload some sound</div>'
	        :'<br><br>')
	        + '<input type="file" id="media" name="media" />'
			+ '<input type="hidden" name="type" value="'+this.side+media+'"/>'
			+ '<input type="hidden" name="card_id" value="'+ id + '"=>'
			+ '<input type="hidden" name="side_id" value="'+ this.sideID
			 +'" />'
			//+ '<input type="submit" name ="addMedia" value="Upload'+(media.charAt(1)=='i'? ' image':(media.charAt(1)=='s'? ' sound':''))+'" onclick="show_spinner('+id+', \''+media+'\');" />'
			+ '<br><a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].show_spinner(\''+media+'\');get(\'upload_form_'+id+'_'+this.side+media+'\').submit();"><b>Upload'+(media == 'i'? ' image':(media == 's'? ' sound':''))+'</b></a>'	
			+ '<br><a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].add_media_cancel(\''+media+'\');">Cancel</a>'
	        + '</form>'
	        + (media == 's'?
	          '<div class="bd_upload_sound_section">Record my own sound</div>'
	        + '<APPLET archive="/recorder/recorder.jar" CODE="recorder.RecorderApplet" WIDTH=250 HEIGHT=50 MAYSCRIPT>'
			+ '<PARAM NAME="type" VALUE="' + this.side+media + '">'
			+ '<PARAM NAME="card_id" VALUE="' + id + '">'
			+ '<PARAM NAME="side_id" VALUE="' + this.sideID + '">'
			+ '<PARAM NAME="session_id" VALUE="' + session_id + '">'
			+ '</APPLET>'
			: '');
		showE(ext_upload, true); // show upload div
		if (media == 'i') this.image.upload = ext_upload;
		else if (media == 's') this.sound.upload = ext_upload;
	}
	// Hide an add media form on user cancel
	this.add_media_cancel = function(media) {
	
		showE(this.image.upload, false);	// hide upload div of image (if it exists)
		showE(this.sound.upload, false);	// hide upload div of sound (if it exists)
		showE(this.image.div, this.image.value != false);	
		showE(this.sound.div, this.sound.value != false);
		// if there are no more medias, then remove the card extension
		if (this.card.front.sound.value == false && this.card.front.image.value == false && this.card.back.sound.value == false && this.card.back.image.value == false && this.card.ext) this.card.remove_extended();
	}
	// Show the spinner (if the card is opened)
	this.show_spinner = function(media)
	{
		// load the spinner instead of the image while waiting for server response
		// Bug in IE : spinner not animated if loaded before the form -> need to use timeout
		var side = this;
		setTimeout(function() {
			if ((media == 'i' && side.image.value == false) || (media == 's' && side.sound.value == false))
				side.media_uploaded(media, spinner_src);
		}, 1);
	}
	// remove media from card
	this.media_remove = function(media)
	{
		xajax_removeMedia(this.card.id, this.sideID, this.side+media);
	}
	// Generate butons on top 
	// side is 'f' (front) or 'b' (back)
	this.update_media = function() {
		var id = this.card.id;

		// update edit buttons
		this.card.mini_table.rows[0].cells[this.side == 'f'? 2:5].lastChild.innerHTML = 
			(this.image.value != false? '<a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].media_remove(\'i\');">Remove image</a>':'<a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].add_media(\'i\')">Add image</a>')
			+ ' | ' + (this.sound.value != false? '<a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].media_remove(\'s\');">Remove sound</a>':'<a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].add_media(\'s\')">Add sound</a>')
			+ ' | <a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'][\''+(this.side == 'f'? 'front':'back')+'\'].show_symbols()">Symbols/Accents</a>'
			+ ' | <a class="bd_edit_button" href="javascript:;" onClick="cards['+id+'].toggle()">Save</a>'
			+ '';
		// update icons (top left)
		this.card.mini_table.rows[0].cells[this.side == 'f'? 1:4].childNodes[0].className = this.image.value != false? 'bd_icon':'bd_icon_hidden';
		this.card.mini_table.rows[0].cells[this.side == 'f'? 1:4].childNodes[1].className = this.sound.value != false? 'bd_icon':'bd_icon_hidden';
	
		// if there are no more medias, then remove the card extension
		if (this.card.front.sound.value == false && this.card.front.image.value == false && this.card.back.sound.value == false && this.card.back.image.value == false && this.card.ext) this.card.remove_extended();
	}
	
	// function to undo changes made to a side
	this.undo = function() {
		// TODO : Add some code here!
	}
	
	this.media_uploaded = function (media, value) {
		card_media_uploaded(this.card.id, this.side+media, value);
	}
		
	this.show_symbols = function()
	{
		offsets = findPos(this.input);

		set_current_input(this.input);
		
		var symbols_box = get('symbols_box');
		
		symbols_box.style.left = offsets[0] + this.input.offsetWidth / 4;
		symbols_box.style.top = offsets[1] + this.input.offsetHeight;

		showE(symbols_box, true);
	}
	
	this.show_definitions = function()
	{
		offsets = findPos(this.input);

		set_current_input(this.input);
		
		var definitions_box = get('bd_definitions_box');
		
		definitions_box.style.left = offsets[0] + this.input.offsetWidth / 4;
		definitions_box.style.top = offsets[1] + this.input.offsetHeight;

		showE(definitions_box, true);
	}
}
// CARD CLASS
var card = function (id, frontID, backID) {
	// html el ID (not the card id in the DB) 
	this.id = id;
	this.front = new side(this, 'f', frontID);	// front side
	this.back = new side(this, 'b', backID);	// back side
	
	if (id != 0) this.prev = cards[id-1];
	
	this.ext = get('bd_ext_'+id);	// extended div of the card, holding medias, hidden by default
	this.ext_content = get('bd_ext_content_'+id);
	this.mini = get('bd_mini_'+id);	// minimized div of the card
	this.mini_table = get('bd_mini_table_'+id);	// table of the minimized div of the card
	this.select = get('bd_select_'+id);
	
	this.status = 0;	//contains status of the card (0: minimized; 1: extended; -1: removed; -2: hidden)
	this.drawn = false; 	// in flip mode, true if card has already been drawn
	this.selected = false;	// whever card is selected or not (if selection checkbox is checked)
	
	this.show_anim = new YAHOO.util.Anim('bd_ext_'+id, { height: {to: cardHeight} },.1); 
		this.show_anim.onComplete.subscribe(function () {cards[id].ext_content.style.visibility = 'visible';});
	
	this.hide_anim = new YAHOO.util.Anim('bd_ext_'+id, { height: { to: 1} }, .1);
		this.hide_anim.onComplete.subscribe(function () {showE(cards[id].ext, false);});

	if (this.ext) this.ext.style.height = 0;
	
	// add click event on select checkbox
	eval('this.select.onclick = function(e) {cards['+this.id+'].toggle_selected(e, this);}');
	
	
	// get next valid card
	this.next = function() {
		var id = this.id;
		while (cards[++id]) {
			if (cards[id] && cards[id].status >= 0) return id;
		}
		return 0;
	}
	// get previous valid card
	this.prev = function() {
		var id = this.id;
		while (cards[--id]) {
			if (cards[id] && cards[id].status >= 0) return id;
		}
		return 0;
	}
	// open/close a card for view (and editing if edit_mode)
	// use force to force the card in 'open' or 'close' states
	this.toggle = function(force) {
		if (this.status == -1 || this.status == -2) return false;

		// display medias of the card if there are any and if not in text-only edit mode
		if (this.ext && (mode != 'textedit')) {
			if (this.status && force != 'open') {
				// hide image to ease animation
				if (this.ext_content) this.ext_content.style.visibility = 'hidden';
				this.hide_anim.animate();
				if (mode != 'edit') this.status = 0;
			} else if (force != 'close') {
				showE(this.ext, true);
				this.show_anim.animate();
				if (mode != 'edit') this.status = 1;
			}
		}
		// if in edit mode
		if (mode == 'edit' || mode == 'text_edit') {
			if (this.status == 0 && force != 'close') 	// open the card
			{
				// front of the card
				this.front.input = document.createElement('div').appendChild(document.createElement('textarea'));
				this.front.input.style.height = 1;
				this.front.input.parentNode.className = 'bd_edit_text';
				this.front.input.value = this.mini_table.rows[0].cells[2].innerHTML;
				this.front.input.style.fontSize = font_size;
				
				this.mini_table.rows[0].cells[2].innerHTML = '';
				this.mini_table.rows[0].cells[2].appendChild(this.front.input.parentNode);
	
				this.front.input.onkeydown = function (e) {return cards[card.id].front.keydown(e)};
				this.front.input.onkeyup = function (e) {return cards[card.id].front.keyup(e)};
				
				this.front.input.onblur = function (e) {return cards[card.id].front.save()};
				
				this.front.input.onclick = function (e) {
					return card_click_input(this);
				}

				this.mini_table.rows[0].cells[2].appendChild(document.createElement('span'));
				this.mini_table.rows[0].cells[2].lastChild.className = 'bd_edit_button';
				// if in multimedia edit, then display add/remove media buttons
				if (mode != 'textedit') this.front.update_media();
				
				// back of the card
				this.back.input = document.createElement('div').appendChild(document.createElement('textarea'));
				this.back.input.style.height = 1;
				this.back.input.parentNode.className = 'bd_edit_text';
				this.back.input.value = this.mini_table.rows[0].cells[5].innerHTML;
				this.back.input.style.fontSize = font_size;
				
				this.mini_table.rows[0].cells[5].innerHTML = '';
				this.mini_table.rows[0].cells[5].appendChild(this.back.input.parentNode);
				
				var card = this;
				this.back.input.onkeydown = function (e) {return cards[card.id].back.keydown(e)};
				this.back.input.onkeyup = function (e) {return cards[card.id].back.keyup(e)};
				
				this.back.input.onblur = function (e) {return cards[card.id].back.save()};
				
				this.back.input.onclick = function (e) {
					return card_click_input(this);
				}

				this.mini_table.rows[0].cells[5].appendChild(document.createElement('span'));
				this.mini_table.rows[0].cells[5].lastChild.className = 'bd_edit_button';
				// if in multimedia edit, then display add/remove media buttons
				if (mode != 'textedit') this.back.update_media();
				
				// disable click
				this.mini_table.rows[0].cells[1].onclick = null;
				this.mini_table.rows[0].cells[2].onclick = null;
				this.mini_table.rows[0].cells[4].onclick = null;
				this.mini_table.rows[0].cells[5].onclick = null;
	
				// remove pointer cursor
				this.mini.className = 'bd_mini_div';
				//cards_edit[id] = 1;
				this.front.input.focus();
				
				// resize textareas
				textarea_resize(this.front.input);
				textarea_resize(this.back.input);
				
				// select text
				card_click_input(this.front.input, true);
				
				this.status = 1;
			}
			// if card was already opened
			else if(force == 'open')
			{
				this.front.input.focus();
				card_click_input(this.front.input);
				
				this.status = 1;
			} 
			// note: in text only edit mode, cards should not be closed
			else if(this.status == 1 && force != 'open' && mode != 'textedit') 
			{
				// Save data here???
				
				this.mini_table.rows[0].cells[2].innerHTML = this.front.input.value;
				this.mini_table.rows[0].cells[5].innerHTML = this.back.input.value;
				//bd_mini.onclick = function () {toggle_card(id)};
				card = this;
				this.mini_table.rows[0].cells[1].onclick = function(e) {cards[card.id].toggle()};
				this.mini_table.rows[0].cells[2].onclick = function(e) {cards[card.id].toggle()};
				this.mini_table.rows[0].cells[4].onclick = function(e) {cards[card.id].toggle()};
				this.mini_table.rows[0].cells[5].onclick = function(e) {cards[card.id].toggle()};
				
				// add pointer cursor
				this.mini.className = 'bd_mini_div_extend';
				
				// update flip mode card if currently showing this card
				if (flip_id == this.id) bd_flip_go(0);
				
				this.status = 0;
			}
		}
		if (this.next()) cards[this.next()].mini.style.backgroundImage = (this.status && this.ext)? 'url(../images/card_thumb/card_thumb_top_first.png)':'url(../images/card_thumb/card_thumb_top.png)';
		else showE(get('bd_last'), !(this.status && this.ext));
	}
	
	// toggle whether card is selected or not
	// called when user click on a select checkbox
	// use force to force 'selected' or 'unselected'
	this.toggle_selected = function(e, el, force) {
		if (this.status == -1) return false;
		
		// if force is used
		if (force == 'selected' || force == 'unselected') this.selected = (force == 'selected');
		// if checkbox clicked is not the one at the side (ex. hidden front view : user click on the checkox of the popup)
		else if (el && this.select) this.selected = el.checked;
		// if toggle but no click on any checkbox
		else if (!el) this.selected = !this.selected;
		// if normal click on checkbox
		else this.selected = this.select.checked;
	
		this.select.checked = this.selected;

		if (this.id == flip_id) {
			get('bd_select_flip').checked = this.selected;
		}
	
		// if in selected display and card unselected, then hide card
		if (display_selected && !this.selected) {
			this.hide(true);
			if (mode == 'flip') bd_flip_go(1);
		}
		return;
	}
	// hide card if 'hide' is true, show otherwise
	this.hide = function(hide) {
		this.toggle('close');	// close card if not already hidden
		showE(this.mini, !hide);
		
		var prev_id = this.prev();
		var next_id = this.next();
		
		// if it is the last card, determine if the footer need to be shown or not (whever previous card is extended or not)
		if (next_id == 0) showE(get('bd_last'), !hide || (prev_id && !cards[prev_id].status));
		// else if hide then set the bg of the next card to match the card to be hidden
		else if (hide && cards[next_id]) cards[next_id].mini.style.backgroundImage = this.mini.style.backgroundImage;
		// background color : white or transparent
		if (!hide) this.mini.style.backgroundImage = (!cards[prev_id] || cards[prev_id].status == 1)? 'url(../images/card_thumb/card_thumb_top_first.png)':'url(../images/card_thumb/card_thumb_top.png)';
		
		this.status = hide? -2:0;
	}
	// Remove card (called on when click on the cross)
	this.remove = function() {
		if (confirm('Are you sure you want to remove this card ?\n\nThis operation may not be undone')) {
			xajax_removeCard(this.id, this.front.sideID);
		}
	}
	
	// Append the 'extended' div
	this.add_extended = function(fi, fs, bi, bs) {
		var id= this.id;
		var div = document.createElement('div');
		div.id = 'bd_ext_'+id;
		div.className = 'bd_ext_div';
		if (this.mini.nextSibling) this.mini.parentNode.insertBefore(div, this.mini.nextSibling);
		else this.mini.parentNode.appendChild(div);
		if (get('bd_ext_'+id)) {
			this.ext = get('bd_ext_'+id);
			this.ext.innerHTML = '<table id="bd_ext_content_'+id+'" cellspacing="0" cellpadding="1" class="bd_ext_table"><tr>'
				+ '<td class="bd_ext_td1"><div id="bd_ext_fi_'+id+'"'+(fi? '':' style="display: none;"')+'>'+(fi? '<img class="bd_image" src="./images/flashcards/'+fi+'">':'')+'</div><div id="bd_ext_fs_'+id+'"'+(fs? '':' style="display: none;"')+'>'+(fs? '<a href="javascript:;" onClick="cards['+id+'].front.sound_play();"><img title="Play sound" border="0" src="./images/card_thumb/card_thumb_play.png"></a>':'')+'</div></td>'
				+ '<td class="bd_ext_td2"><div id="bd_ext_bi_'+id+'"'+(bi? '':' style="display: none;"')+'>'+(bi? '<img class="bd_image" src="./images/flashcards/'+bi+'">':'')+'</div><div id="bd_ext_bs_'+id+'"'+(bs? '':' style="display: none;"')+'>'+(bs? '<a href="javascript:;" onClick="cards['+id+'].back.sound_play();"><img title="Play sound" border="0" src="./images/card_thumb/card_thumb_play.png"></a>':'')+'</div></td>'
				+ '</tr></table>';
			
			this.ext_content = get('bd_ext_content_'+id);
			this.front.image.div =  get('bd_ext_fi_'+id);
			this.front.sound.div =  get('bd_ext_fs_'+id);
			this.back.image.div =  get('bd_ext_bi_'+id);
			this.back.sound.div =  get('bd_ext_bs_'+id);
			
			this.front.image.value = fi != undefined? fi : false;
			this.front.sound.value = fs != undefined? true : false;
			this.front.sound.file = fs != undefined? fs : false;
			showE(this.front.sound.mini, fs != undefined);
			
			this.back.image.value = bi != undefined? bi : false;
			this.back.sound.value = bs != undefined? true : false;
			this.back.sound.file = bs != undefined? bs : false;
			showE(this.back.sound.mini, bs != undefined);
			
			
			this.show_anim = new YAHOO.util.Anim('bd_ext_'+id, { height: {to: cardHeight} },.1); 
				this.show_anim.onComplete.subscribe(function () {cards[id].ext_content.style.visibility = 'visible';});
			
			this.hide_anim = new YAHOO.util.Anim('bd_ext_'+id, { height: { to: 1} }, .1);
				this.hide_anim.onComplete.subscribe(function () {showE(cards[id].ext, false);});
					
			return this.ext;
		}
		return false;
	}
	// Remove the 'extended' div
	this.remove_extended = function() {
		if (!this.ext) return;
		
		if (this.ext_content) this.ext_content.style.visibility = 'hidden';
		// animation don't work since ext is removed immediatly
		//this.toggle('close');
		
		// remove ext
		var bd_ext = get('bd_ext_'+this.id);
		this.ext = false;
		this.ext_content = false;
		this.front.image.div = false;
		this.front.image.upload = false;
		this.back.image.div = false;
		this.back.image.upload = false;
	
		this.front.sound.div = false;
		this.front.sound.upload = false;
		this.back.sound.div = false;
		this.back.sound.upload = false;
	
		bd_ext.parentNode.removeChild(bd_ext);
		// set bg of the next one (design)
		if (this.next()) cards[this.next()].mini.style.backgroundImage = 'url(../images/card_thumb/card_thumb_top.png)';
		else showE(get('bd_last'), this.status[id] == 0);	
	}
	
	// set font size of field and text
	this.set_font_size = function(size) {
		this.mini_table.style.fontSize = size;
		if ((mode == 'edit' || mode == 'textedit') && this.status == 1 && this.front.input && this.back.input) {
			this.front.input.style.fontSize = size;
			textarea_resize(this.front.input);
			this.back.input.style.fontSize = size;
			textarea_resize(this.back.input);
		}
	}
}

//////////////////////////////////////
// DICTIONARY TRANSLATION FUNCTIONS //

function select_definition(container_id)
{
	if(get(container_id) && current_input)
	{
		replaceInput(current_input, get(container_id).innerHTML); 
		current_input.focus(); 
		showE(get('bd_definitions_box'), false);
	}
}

///////////////////////////////////////


// GENERAL FUNCTIONS
function loadFunc() {
	show_options_anim = new YAHOO.util.Anim('bd_options', { 
	    height: {to: 240}  
	    },.1); 
	hide_options_anim = new YAHOO.util.Anim('bd_options', { 
	    height: { to: 1}  
	    }, .1);
	// add shotcuts (for flip mode)
	shortcut.add("h",function() {if (mode == 'flip') bd_flip_go(-1);},{
		'type':'keydown',
		'disable_in_input':false,
		'propagate':true,
		'target':document
	});
	shortcut.add("j",function() {if (mode == 'flip') bd_flip_go(1);},{
		'type':'keydown',
		'disable_in_input':false,
		'propagate':true,
		'target':document
	});
	shortcut.add("k",function() {if (mode == 'flip') bd_flip_go(0, true);},{
		'type':'keydown',
		'disable_in_input':false,
		'propagate':true,
		'target':document
	});
	shortcut.add("l",function() {if (mode == 'flip') if (cards[flip_id]) cards[flip_id].toggle_selected();},{
		'type':'keydown',
		'disable_in_input':false,
		'propagate':true,
		'target':document
	});

	//Dictionary words
	shortcut.add("1", function() {
	
		if(current_input && get('definition_1') && get('bd_definitions_box').style.display != 'none')
		{
			replaceInput(current_input, get('definition_0').innerHTML); 
			current_input.focus(); 
			showE(get('bd_definitions_box'), false);
		}
	}, {
		'type':'keydown',
		'disable_in_input':true,
		'propagate':false,
		'target':document
	});
	shortcut.add("2", function() {
	
		if(current_input && get('definition_1') && get('bd_definitions_box').style.display != 'none')
		{
			replaceInput(current_input, get('definition_1').innerHTML); 
			current_input.focus(); 
			showE(get('bd_definitions_box'), false);
		}
	}, {
		'type':'keydown',
		'disable_in_input':true,
		'propagate':false,
		'target':document
	});
	shortcut.add("3", function() {
	
		if(current_input && get('definition_2') && get('bd_definitions_box').style.display != 'none')
		{
			replaceInput(current_input, get('definition_2').innerHTML); 
			current_input.focus(); 
			showE(get('bd_definitions_box'), false);
		}
	}, {
		'type':'keydown',
		'disable_in_input':true,
		'propagate':false,
		'target':document
	});
	
	loadPlayer('jw_player');
}
function get(id) {
	return document.getElementById(id);
}
function showE(el, show) {
	if (el && el.style) return el.style.display = (show)? 'block':'none';
}
function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}
function appendToInput(input, text)
{
	input.value = input.value + text;
	textarea_resize(input);	
}
function replaceInput(input, value)
{
	input.value = value;
	textarea_resize(input);	
}

/* EVENT LISTENNERS */

// function to resize a textarea to match value
var textarea_resize_current = false;
function textarea_resize(input) {
	// a hidden div is used to calulate textarea height
	var hdiv = get('hidden_div_cal_height');
	if (input != textarea_resize_current) {
		hdiv.style.width = input.offsetWidth;
		textarea_resize_current = input;
	}
	hdiv.innerHTML = input.value.length == 0? 'A':input.value.replace(/  /g," &nbsp;");
	input.style.height = hdiv.offsetHeight;
	return;
}
// called when user click on a text input box (if new card then highlight all text)
function card_click_input(input, force) {
	if (force || current_input != input) {
		current_input = input;
		input.select();
	}
}
// called when symbols/accents is clicked
function set_current_input(input)
{
	current_input = input;	
}

// called to set special edit mode
function toggle_current_edit_mode(new_mode)
{
	if(current_edit_mode != new_mode)
	{
		current_edit_mode = new_mode;
	}
	else
	{
		current_edit_mode = 'normal';
	}
}


/* FUNCTION FOR THE FLASH MODE */

var show_side_id = 0;
var hide_side_timer = false;
function card_over(id) {
	if (hide_side_timer) clearTimeout(hide_side_timer);
	if (id == show_side_id) return;
	card_show_side(id);
}
function card_out(id) {
	if (id != show_side_id) return;
	if (hide_side_timer) clearTimeout(hide_side_timer);
	hide_side_timer = setTimeout(card_hide_side, 400);
}
function card_hide_side() {
	showE(get("bd_show_side"), false);
	show_side_id = 0;
}
function card_show_side(id) {
	var card = cards[id];
	var ss = get('bd_show_side');
	var bd_ext_content_ss = get('bd_ext_content_ss');
	
	if (hidden_side == '' || !card.mini || !ss) return;
	
	// hide it while editing content
	bd_ext_content_ss.style.visibility = 'hidden';
	
	// save id so that it is not generated on each mouse mouve
	show_side_id = id;
	
	if (card.ext) {
		bd_ext_content_ss.rows[0].cells[0].innerHTML = card.ext_content.rows[0].cells[hidden_side=='f'?0:1].innerHTML + card.mini_table.rows[0].cells[hidden_side=='f'?2:5].innerHTML;
		remove_children_id(bd_ext_content_ss);
	} else {
		bd_ext_content_ss.rows[0].cells[0].innerHTML = card.mini_table.rows[0].cells[hidden_side=='f'?2:5].innerHTML+ '<br><br>';
	}
	
	// position it
	ss.style.left = card.mini.offsetLeft  + (hidden_side == 'f'? -20-400 : 400+30) + get('bd_content').offsetLeft;
	
	// adjust vertical position
	if ((card.mini.offsetTop + (cardHeight/2 + 42)) > get('bd_content').offsetHeight) 
		ss.style.top = get('bd_content').offsetTop + get('bd_content').offsetHeight - (cardHeight + 42);
	else if ((card.mini.offsetTop - cardHeight/2 < 0) )
		ss.style.top = get('bd_content').offsetTop;
	else ss.style.top = card.mini.offsetTop + get('bd_content').offsetTop - (card.status != 1? cardHeight/2:0);
	bd_ext_content_ss.style.visibility = 'visible';
	showE(ss, true);
}
// function to recursivly remove all children's ids from an element
function remove_children_id(el) {
	var i = 0;
	while (el.childNodes[i]) {
		if (el.childNodes[i].id) el.childNodes[i].id = '';
		if (el.childNodes[i].childNodes) remove_children_id(el.childNodes[i]);
		i++;
	}
}

/* FUNCTIONS FOR CARD SELECTION */

// function to select all / none
function bd_select_all(all) {
	for (i=1; i<= num_cards; i++) {
		cards[i].toggle_selected(undefined, undefined, all? 'selected':'unselected');
	}
}

function bd_toggle_select_card(flip_id) {
	cards[flip_id].toggle_selected();
}


/* AJAX RETURN FUNCTIONS */

// Function to be called on media uploadED
function card_media_uploaded(id, media, value) {

	// empty value means media has not been added to the card, so remove it
	if (value == '') return card_media_removed(id, media);

	// media is given as 'fi' for front image, so separate the two informations : side and type of media
	var side = media.charAt(0) == 'f'? 'front':'back';
	var media = media.charAt(1);
	
	if (!cards[id] || cards[id].status == -1) return; // if card has been removed	// if hidden, it is ok to proceeed
	
	// check that card has extended div
	if (!cards[id].ext) cards[id].add_extended();
	
	if (media == 'i') {
		showE(cards[id][side].image.upload, false);	// hide upload div
		if (!cards[id][side].image.div) return;
		
		if (!cards[id][side].image.div.firstChild) cards[id][side].image.div.appendChild(document.createElement('img'));
		cards[id][side].image.div.firstChild.className = 'bd_image';
		cards[id][side].image.div.firstChild.src = value;
		cards[id][side].image.value = value;
		
	} else if (media == 's') {
		showE(cards[id][side].sound.upload, false);	// hide upload div
		if (!cards[id][side].sound.div) return;
		cards[id][side].sound.value = true;
		
		// see if it is the real sound or just the spinner
		if (value == spinner_src) {
			cards[id][side].sound.div.innerHTML = '<img title="Loading sound" border="0" src="'+spinner_src+'">';
		} else {

			cards[id][side].sound.div.innerHTML = '<a href="javascript:;" onClick="cards['+id+'].'+side+'.sound_play();"><img title="Play sound" border="0" src="./images/card_thumb/card_thumb_play.png"></a>';
			showE(cards[id][side].sound.mini, true);
			cards[id][side].sound.is_loaded = false;
			cards[id][side].sound.file = value;
		}
		
		cards[id][side].sound.is_loaded = false;
	}
	
	// 	show media div (if they exists)
	showE(cards[id][side].image.div, cards[id][side].image.value != false);	
	showE(cards[id][side].sound.div, cards[id][side].sound.value != false);
	
	// update card (update icons, buttons, etc...)
	cards[id][side].update_media();
}
// Function to be called when a media has been removed from a card
function card_media_removed(id, media) {
	// media is given as 'fi' for front image, so separate the two informations : side and type of media
	var side = media.charAt(0) == 'f'? 'front':'back';
	var media = media.charAt(1);
	
	if (!cards[id] || cards[id].status == -1) return; // if card has been removed	// if hidden, it is ok to proceeed
	
	if (media == 'i') {
		showE(cards[id][side].image.upload, false);	// hide upload div
		if (!cards[id][side].image.div) return;
		
		cards[id][side].image.div.innerHTML = '';
		cards[id][side].image.value = false;
		
	} else if (media == 's') {
		showE(cards[id][side].sound.upload, false);	// hide upload div
		if (!cards[id][side].sound.div) return;

		cards[id][side].sound.div.innerHTML = '';
		cards[id][side].sound.value = '';
		cards[id][side].sound.file = '';
		cards[id][side].sound.is_loaded = false;
		showE(cards[id][side].sound.mini, false);
	}
	
	// 	show media div (if they exists)
	showE(cards[id][side].image.div, cards[id][side].image.value != false);	
	showE(cards[id][side].sound.div, cards[id][side].sound.value != false);
	
	// update card (update icons, buttons, etc...)
	cards[id][side].update_media();
}
// function to be called when a card is removed from the database
function card_removed(id) {
	if (!cards[id] || cards[id] == -1) return; // if card has already been removed
	var bd_mini = get('bd_mini_'+id);
	
	var prev_id = cards[id].prev();
	var next_id = cards[id].next();
	
	// remove extension (if exists)
	cards[id].remove_extended();
	
	// if it is the last card, determine if the footer need to be shown or not
	if (next_id == 0) showE(get('bd_last'), prev_id && cards[prev_id].status == 0);
	// else set the bg image of the next card to match the card to be removed
	else if (cards[next_id] && cards[next_id].mini) cards[next_id].mini.style.backgroundImage = cards[id].mini.style.backgroundImage;
	
	// remove card
	cards[id].mini = false;	// remove referent
	cards[id].mini_table = false;
	bd_mini.parentNode.removeChild(bd_mini);

	
	cards[id].status = -1;
}

/* ADD CARD / ADD EXTENSION TO A CARD FUNCTIONS */

/* CAUTION : modifications of to structure of the output html also have to be made in the php file */

// Add a card (called on when click or tab)
// add 'num' cards at the bottom
function add_card(num) {
	if (num > 20) return alert('Please do not add more than 20 cards at a time');
	xajax_addCard(deck_id); //We're only allowing one card to be added for rof
}
// function called from AJAX to add a card on screen after it has been added to the database
function card_added(frontID, backID, front_text, fi, fs, back_text, bi, bs, activated) {
	// cardFID and cardBID need to be provided for card to be fully functional (needed to be added in DB before this function call
	// OR (beter option i think) : if (cardFID = undefined) then add into DB
	num_cards += 1;
	var id = num_cards;
	// if first card, then show header and footer
	showE(get('bd_last'), true);
	showE(get('bd_header'), true);
	
	var mdiv = get('bd_cards');
	// check if the tab need to be extended in order to show pictures
	var extend = (fi || bi || fs || bs);
	
	var div = document.createElement('div');
	div.id = 'bd_mini_'+id;
	div.className = 'bd_mini_div'+(extend? '_extend':'');
	div.onmouseover = function() {
		card_over(id);
	}
	div.onmouseout = function() {
		card_out(id);
	}
	
	mdiv.appendChild(div);
	get('bd_mini_'+id).innerHTML += '<table id="bd_mini_table_'+id+'" cellspacing="0" cellpadding="0" class="bd_mini_table"><tr>'
		+ '<td class="bd_mini_td_select"><input class="bd_select" type="checkbox" id="bd_select_'+id+'"></td>'
		+ '<td class="bd_mini_td1" onClick="cards['+id+'].toggle();"><img title="Card contains an image" class="bd_icon'+(fi? '':'_hidden')+'" src="./images/card_thumb/card_thumb_image.png"><img title="Card contains sound" class="bd_icon'+(fs? '':'_hidden')+'" src="./images/card_thumb/card_thumb_sound.png"></td>'
		+ '<td class="bd_mini_td2" onClick="cards['+id+'].toggle();">'+(front_text? front_text:'')+'</td>'
		+ '<td class="bd_mini_td_sound"><img title="Play sound" id="bd_sound_mini_f_'+id+'" class="bd_sound" style="display: none;" border="0" onclick="cards['+id+'].front.sound_play();" src="./images/card_thumb/card_thumb_play_mini.png"></td>'
		+ '<td class="bd_mini_td3" onClick="cards['+id+'].toggle();"><img title="Card contains an image" class="bd_icon'+(bi? '':'_hidden')+'" src="./images/card_thumb/card_thumb_image.png"><img title="Card contains sound" class="bd_icon'+(bs? '':'_hidden')+'" src="./images/card_thumb/card_thumb_sound.png"></td>'
		+ '<td class="bd_mini_td4" onClick="cards['+id+'].toggle();">'+(back_text? back_text:'')+'</td>'
		+ '<td class="bd_mini_td5"><img title="Play sound" id="bd_sound_mini_b_'+id+'" class="bd_sound" style="display: none;" border="0" onclick="cards['+id+'].back.sound_play();" src="./images/card_thumb/card_thumb_play_mini.png"><img title="Remove this card" id="bd_remove_'+id+'" class="bd_remove"'+((mode == 'edit' || mode == 'textedit')? '':'style="display: none;"')+' onClick="cards['+id+'].remove();" border="0" src="./images/card_thumb/card_thumb_remove.png"></td>'					
		+ '</tr></table>';
	
	cards[id] = new card(id, frontID, backID);
	
	if (id == 1 || cards[id].prev()) cards[id].mini.style.backgroundImage = 'url(../images/card_thumb/card_thumb_top_first.png)';
	
	if (extend) cards[id].add_extended(fi, fs, bi, bs);

	if (mode == 'edit' || mode == 'textedit') cards[id].toggle('open');
	return id;
}


/* FLIP MODE */

// function to go to next/prev card OR flip current
function bd_flip_go(advance, flip) {
	if (flip) var side = (flip_current_side == 'f') ? 'b':'f';
	else var side = flip_side;
	
	if (get('bd_flip_shuffle').checked) var id = bd_flip_shuffle(advance);
	else {
		var id = flip_id;
		if (id == 0) id = 1;	// * id must not be 0 for the loop
		while (advance != 0) {
			// increase of 1 or decrease of -1
			id = id + advance/Math.abs(advance);
			if (id < 1) id = num_cards;
			else if (id > num_cards) id = 1;
			// if id = flip_id : we went through all cards, none are valid then keep flip_id
			if (id == flip_id) break;
			// if card is valid
			if (cards[id].status >= 0) advance += -advance/Math.abs(advance)
		}
	}
	// if no valid card found, then clear card
	if (id == 0 || !cards[id] || cards[id].status < 0) {	// see *
		flip_id = 0;
		flip_current_side = flip_side;
		var bd_mini_table_flip = get('bd_mini_table_flip');
		var bd_ext_content_flip = get('bd_ext_content_flip');
		
		bd_ext_content_flip.rows[0].cells[0].innerHTML = '';
		bd_mini_table_flip.rows[0].cells[0].innerHTML = '';
		bd_mini_table_flip.rows[0].cells[1].innerHTML = '';
		bd_mini_table_flip.rows[0].cells[1].innerHTML = '';
		
		// disable select box
		get('bd_select_flip').checked = false;
		get('bd_select_flip').disabled = true;
		
		bd_flip_update_info();
		return;
	}
	flip_id = id;
	flip_current_side = side;
	
	var bd_mini_table_flip = get('bd_mini_table_flip');
	var bd_ext_content_flip = get('bd_ext_content_flip');
	
	if (cards[id].ext) {
		bd_ext_content_flip.rows[0].cells[0].innerHTML = cards[id].ext_content.rows[0].cells[side=='f'?0:1].innerHTML;
	} else {
		bd_ext_content_flip.rows[0].cells[0].innerHTML = '';
	}
	
	bd_ext_content_flip.rows[0].cells[0].innerHTML += cards[id].mini_table.rows[0].cells[side=='f'?2:5].innerHTML+'<br><br>'
	
	//bd_mini_table_flip.rows[0].cells[0].innerHTML = bd_mini_table.rows[0].cells[side=='f'?1:4].innerHTML;
	//bd_mini_table_flip.rows[0].cells[1].innerHTML = bd_mini_table.rows[0].cells[side=='f'?2:5].innerHTML;
	bd_mini_table_flip.rows[0].cells[0].innerHTML = '';
	bd_mini_table_flip.rows[0].cells[1].innerHTML = '';
	
	// remove all ID of copied content (so that it does not interfer
	remove_children_id(bd_mini_table_flip);
	
	// check/uncheck select box
	get('bd_select_flip').disabled = false;
	get('bd_select_flip').checked = cards[id].selected;
	
	bd_flip_update_info();
}

// get id of next/prev card in shuffle
// direction : positive: next or negative: prev
function bd_flip_shuffle(direction) {
	if (direction == 0) return flip_id;
	// if previous
	if (direction < 0 && flip_shuffle_drawn.length > 0) {
		var card = flip_shuffle_drawn[flip_shuffle_drawn.length-1];
		flip_shuffle_drawn.pop();
		return card;
	}
	// otherwise, if next
	
	var num_valid = num_cards;
	// remove from total number of cards those not valid
	for (i = 1; i <= num_cards; i++) {
		if (!cards[i] || cards[i].status < 0) num_valid--;
	}
	// if no valid cards, stop
	if (num_valid < 1) return false;

	// if no undrawn cards, reset
	if (num_valid - flip_shuffle_drawn.length <= 0) {
		flip_shuffle_drawn = new Array();
		for (i = 1; i <= num_cards; i++) {
			if (cards[i]) cards[i].drawn = false;
		}
	}
	
	// remove those already drawn
	num_valid = num_valid - flip_shuffle_drawn.length;

	// draw
	var draw = Math.floor(Math.random()*num_valid);
	var i = 0;
	while (i < num_cards) {
		i++;
		// check valid
		if (!cards[i] || cards[i].status < 0) continue;
		// check not drawn
		if (cards[i].drawn) continue;
		// decrease draw on each valid card until draw = 0
		if (draw > 0) draw--;
		else {
			// add card id to array of drawn cards
			flip_shuffle_drawn.push(i);
			cards[i].drawn = true;
			return i;
		}
	}
	return flip_id;
}
// function to display number of current card and total number of cards
function bd_flip_update_info() {
	var current = 0;
	var total = 0;
	var found = false;
	for (i=1; i<=num_cards; i++) {
		if (!cards[i] || cards[i].status < 0) continue;
		total++;
		if (!found) {
			if (i == flip_id) found = true;
			current++;
		}
	}
	get('bd_flip_total').innerHTML = total==0? 'none':total;
	get('bd_flip_current').innerHTML = current;
	get('bd_flip_side').innerHTML = flip_current_side=='f'? 'Front':'Back';
	get('bd_ext_content_flip').style.height = '100%';
}

// change prompt side
function bd_flip_set_prompt(side) {
	flip_side = side;
	get('bd_flip_prompt_front').className = 'bd_flip_prompt'+(side=='f'? '_selected':'');
	get('bd_flip_prompt_back').className = 'bd_flip_prompt'+(side=='b'? '_selected':'');
}


/* PAGE DISPLAY AND CARD ANIMATION FUNCTION */

// Deck details show/hide
function bd_toggle_options(ele) {
	if (!get('bd_options') || !ele) return;
	if (options_shown) hide_options_anim.animate();
	else show_options_anim.animate();
	ele.innerHTML = options_shown? "Show Deck Information":"Hide Deck Information";
	//if (get('bd_options_button')) get('bd_options_button').src = options_shown? './images/arrowright.gif':'./images/arrowdown.gif';
	options_shown = !options_shown;
}
// Set font size for the card text
function bd_set_size(size) {
	font_size = size;
	get('hidden_div_cal_height').style.fontSize = size;
	for(i=1; i <= num_cards; i++) {
		cards[i].set_font_size(size);
	}
	get('bd_mini_table_flip').style.fontSize = size;
	get('bd_ext_content_flip').rows[0].cells[0].style.fontSize = size;
	get('bd_ext_content_ss').style.fontSize = size;
	
}
// set the different edit/view mode
function bd_set_mode(new_mode) {
	// perform required changes on switch mode
	
	if ((new_mode == 'view' || new_mode == 'flip') && (mode == 'edit' || mode == 'textedit')) {
		bd_display_selected(false);
		get('bd_showing').style.visibility = 'visible';
	}

	switch (new_mode) {
		case 'edit':
			bd_toggle_all('close');
			if(!options_shown) show_options_anim.animate();
			get('bd_options_button').innerHTML = "Hide Deck Information";
			options_shown = true;
			get('edit_tab').oSrc = 'images/FCF_TopNav_Edit_on.jpg';
			get('learn_tab').oSrc = 'images/FCF_TopNav_Learn.jpg';
			MM_swapImage('learn_tab','','images/FCF_TopNav_Learn.jpg',0);
			showE(get('bd_modes_view'), false);
			showE(get('bd_modes_edit'), true);
			
			//Subtabs on the topnav
			topnav_EditMode();
			
			//Show special edit box
			showE(get('bd_special_edit_box'), true);
			
			break;
		case 'view':
			bd_toggle_all('close');
			get('learn_tab').oSrc = 'images/FCF_TopNav_Learn_on.jpg';

			//alert(edit_tab);
			if(get('edit_tab')) {
				get('edit_tab').oSrc = 'images/FCF_TopNav_Edit.jpg';
				MM_swapImage('edit_tab','','images/FCF_TopNav_Edit.jpg',0);
				//Subtabs on the topnav
				topnav_LearnMode();
			}
			showE(get('bd_modes_view'), true);
			showE(get('bd_modes_edit'), false);			
			break;
		case 'textedit': 
			bd_toggle_all('close');
			bd_toggle_all('open'); 
			break;
		case 'flip':
			if (flip_id == 0 || !cards[flip_id] || cards[flip_id].status < 0) bd_flip_go(1);
			else bd_flip_update_info();
			break;
		case 'flash':
			bd_hide_side('b');
			break;
	}
	MM_swapImgRestore();
	showE(get('bd_list'), new_mode != 'flip');
	showE(get('bd_flip'), new_mode == 'flip');
	
	if (new_mode != 'flip') { 
		// perfom action on each card (in list mode)
		for (i = 1; i <= num_cards; i++) {
			if (!cards[i]) continue;
			// show remove button if in edit mode
			showE(get('bd_remove_'+i), new_mode == 'edit' || new_mode == 'textedit');
			// set cursor to pointer on all bd_mini if in edit mode or on all extandable if in view mode
			cards[i].mini.className = 'bd_mini_div'+((new_mode == 'edit') || (new_mode != 'edit' && new_mode != 'textedit' && cards[i].ext)? '_extend':'');
		}
	}
	
	// if in edit mode, user cannot select only some cards... so hide everything relative to selection
	if (new_mode == 'edit' || new_mode == 'textedit') {
		// show all cards
		bd_display_selected(false);
		showE(get('bd_select_div_selected'), false);
		showE(get('bd_select_div_all'), false);
		get('bd_showing').style.visibility = 'hidden';
		get('bd_tr_save_details').style.display = '';
	}
	else
	{
		showE(get('bd_tr_save_details'), false);
		showE(get('bd_special_edit_box'), false);
	}
	
	// Make deck options editable
	var i = 0;
	while(get("bd_o"+i)) {
		// put input content into cell
		if (new_mode != 'edit' && new_mode != 'textedit') get("bd_o"+i).innerHTML = get("bd_o"+i+"_edit").firstChild.value;
		else get("bd_o"+i+"_edit").firstChild.value = get("bd_o"+i).innerHTML;
		showE(get("bd_o"+i), new_mode != 'edit' && new_mode != 'textedit');
		showE(get("bd_o"+i+"_edit"), new_mode == 'edit' || new_mode == 'textedit');
		i++;
	}
	//Make Tags editable:
	//showE(get('tags_view'), !edit_mode);
	//showE(get('tags_edit'), edit_mode);
	
	// show add card button at bottom if in edit mode
	showE(get('bd_add'), new_mode == 'edit' || new_mode == 'textedit');
	
	
	// buttons to show.hide from back should be available only in flash mode
	if (new_mode == 'flash') {
		showE(get('bd_front_show_button'), hidden_side == 'f');
		showE(get('bd_back_show_button'), hidden_side == 'b');

	} else {
		bd_hide_side('');
		showE(get('bd_front_show_button'), false);
		showE(get('bd_back_show_button'), false);
	}
	
	// change directions
	get('direction2_edit').style.display = (new_mode == 'edit' || new_mode == 'textedit')? 'inline' : 'none';
	get('direction2_view').style.display = new_mode == 'view'? 'inline' : 'none';
	get('direction2_flip').style.display = new_mode == 'flip'? 'inline' : 'none';
	get('direction2_flash').style.display = new_mode == 'flash'? 'inline' : 'none';	
	
	// Hide symbols box on change
	showE(get('symbols_box'), false);	

	
	mode = new_mode;
	
}
// Open/close all cards
function bd_toggle_all(state) {
	for (i=1; i <= num_cards; i++) {
		if (cards[i]) cards[i].toggle(state);
	}
}
// hide front ('f') or back ('b') or none ('') of all cards
function bd_hide_side(side) {
	if (mode == 'edit' || mode == 'textedit') side = '';
	hidden_side = side;
	get('bd_content').style.width = side == ''? 775 : (side=='f'? 375:400);
	get('bd_content').style.left = side == 'f'? 400 : 0;
	get('bd_cards').style.left = side == 'f'? -400 : 0;
	get('bd_last').style.left = side == 'f'? -375 : 25;

	//get('bd_front_show_button').className = (mode != 'edit' && mode != 'textedit' && hidden_side == 'f')? 'bd_hide_side_selected':'bd_hide_side';
	//get('bd_back_show_button').className = (mode != 'edit' && mode != 'textedit' && hidden_side == 'b')? 'bd_hide_side_selected':'bd_hide_side';

	showE(get('bd_front_show_button'), (mode != 'edit' && mode != 'textedit' && hidden_side == 'f'));
	showE(get('bd_back_show_button'), (mode != 'edit' && mode != 'textedit' && hidden_side == 'b'));
}

// function to show/hide a direction span
function show_hide_direction(dir, el_id) {
	if (!get(dir)) return;
	var shown = get(dir).style.display == 'inline';
	xajax_setShowHide(shown);
	get(el_id).innerHTML = shown? 'Show Directions':'Hide Directions';
	get(dir).style.display = shown? 'none':'inline';
}
// show only selected/all cards
function bd_display_selected(selected) {
	display_selected = selected;
	
	get('bd_showing').innerHTML = selected? 'Showing only selected':'Showing all cards';
	showE(get('bd_select_div_selected'), selected);
	showE(get('bd_select_div_all'), !selected);
	
	get('bd_flip_display_selected_tip').style.display = !selected? 'none':'inline';
	get('bd_flip_display_all_tip').style.display = selected? 'none':'inline';
	get('bd_flip_display_selected').style.display = !selected? 'none':'inline';
	get('bd_flip_display_all').style.display = selected? 'none':'inline';
	
	for (i=1; i<=num_cards; i++) {
		// hide cards not selected (and not removed)
		if (get('bd_select_'+i)) cards[i].hide(selected && !get('bd_select_'+i).checked);
	}
	
	if (mode == 'flip') bd_flip_update_info();
}

function bd_print()
{
	window.open("print_deck.php?deckID=" + deck_id,null,"height=600,width=750,status=no,toolbar=no,menubar=no,location=no,scrollbars=yes");
}

function editTags(deck_id, el, e) {
	
	var key;

    if(window.event)
    	key = window.event.keyCode;     //IE
	else
		key = e.which; //Firefox
		
    if (key == 13)
	{          
		el.disabled = true;
		xajax_addTags(deck_id, el.value, el.id);
		return false;
	}
	else
		return true;
}
function emptyStar(star)
{
	var i = 1;
	while(i <= star)
	{
		//document.getElementById("star_"+ i).innerHTML = "<img src='images/star_empty.jpg' onmouseover='fullStar("+ i +")'>"
		document.getElementById("star_"+ i +"_img" ).src = "images/star_empty.jpg";
		i++;
	}
}
function fullStar(star)
{
	var i = 1;
	while(i <= star)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_full.jpg";
		i++;
	}
	while(i <= 5)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_empty.jpg";
		i++;
	}
}
function redStar(star)
{
	var i = 1;
	while(i <= star)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_red.jpg";
		i++;
	}
}
function resetRedStar(rating)
{
	var i = 1;
	while(i <= rating)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_red.jpg";
		i++;
	}
	while(i <= 5)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_empty.jpg";
		i++;
	}
}
function resetFullStar(rating)
{
	var i = 1;
	while(i <= rating)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_full.jpg";
		i++;
	}
	while(i <= 5)
	{
		document.getElementById("star_"+ i +"_img" ).src = "images/star_empty.jpg";
		i++;
	}
}
function enableEl(el) {
	get(el).disabled = false;
}
