//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
/* Pokemon core data and functions */

//--------------------------------------------------------------------------------
// software version

var version = '2.7.5';

//--------------------------------------------------------------------------------
// configuration global variables found in config.js

//--------------------------------------------------------------------------------
// code for determining the type of browser - found in autosuggest.js
// is_msie7, is_msie, is_firefox, is_safari, is_opera - true/false variables

//--------------------------------------------------------------------------------
// unique id counter - incremented each time a new row is added

var id_count = 0;

//--------------------------------------------------------------------------------
// checkbox counters - inc/dec each time checkboxes are clicked

var ck_count = {'pokemon':0, 'trainer':0, 'energy':0};

//--------------------------------------------------------------------------------
// data entry cell and node child numbers

var cell_num_ck    = 0;
var cell_num_qty   = 1;
var cell_num_name  = 2;
var cell_num_info  = 3;
var cell_num_card  = 3;
var cell_num_img   = 3;
var cell_num_note  = 3;
var child_num_ck   = 0;
var child_num_qty  = 0;
var child_num_name = 0;
var child_num_info = 0;
var child_num_card = 1;
var child_num_img  = 2;
var child_num_note = 3;

//--------------------------------------------------------------------------------
// pre-load the rarity images

var R_image = new Image();  R_image.src = rarity_images_loc + 'R.gif';
var U_image = new Image();  U_image.src = rarity_images_loc + 'U.gif';
var C_image = new Image();  C_image.src = rarity_images_loc + 'C.gif';

//--------------------------------------------------------------------------------
// initialize the events and pre-load the event images

var aa_events = [
	{'pic':'No_Event.png' , 'name':''                     , 'img':null},
	{'pic':'BR_Autumn.png', 'name':'Battle Roads - Autumn', 'img':null},
	{'pic':'BR_Spring.png', 'name':'Battle Roads - Spring', 'img':null},
	{'pic':'City.png'     , 'name':'City Championship'    , 'img':null},
	{'pic':'State.png'    , 'name':'State Championship'   , 'img':null},
	{'pic':'Regional.png' , 'name':'Regional Championship', 'img':null},
	{'pic':'National.png' , 'name':'National Championship', 'img':null},
	{'pic':'World.png'    , 'name':'World Championship'   , 'img':null},
	{'pic':'OP_POP.png'   , 'name':'Other Premier Event'  , 'img':null}];

for (i=0;  i<aa_events.length;  i++) {
	aa_events[i].img = new Image();
	aa_events[i].img.src = event_images_loc + aa_events.pic;
} //for

//--------------------------------------------------------------------------------
// pre-load the set symbol images (this is done in data.js)

//--------------------------------------------------------------------------------
// trim functions

function  trim(str) { return str.replace(/^\s+|\s+$/g,""); }
function ltrim(str) { return str.replace(/^\s+/,""); }
function rtrim(str) { return str.replace(/\s+$/,""); }

//--------------------------------------------------------------------------------
// provide a sort function to sort cards by name, then by order of declaration

function sort_cards (a, b) {

	if      (a[0]          < b[0])          return -1;
	else if (a[0]          > b[0])          return  1;
	else if (a[a.length-1] < b[b.length-1]) return -1;
	else if (a[a.length-1] > b[b.length-1]) return  1;
	else                                    return  0;

} //function

//--------------------------------------------------------------------------------
// combine the sets into one array for each type
// sort the cards (sort by card name, then by modified first - misc/newest first - ordered in data.js)

var ALL_cards_list = {'pokemon':[], 'trainer':[], 'energy':[]};

for (var type in ALL_cards_list) {

	for (var i=0;  i<ALL_sets_list.length;  i++)

		ALL_cards_list[type] = ALL_cards_list[type].concat (ALL_sets_list[i][type]);

	// add a sequence number to keep the arrays sorted by order of declaration (after sorted by name)
	for (var i=0;  i<ALL_cards_list[type].length;  i++)

		ALL_cards_list[type][i].push(i);

	ALL_cards_list[type].sort(sort_cards);

} //for

//--------------------------------------------------------------------------------
// create the suggestion lists (include one with only the most recent trainer/energy cards)
// assumption - the list is sorted for recent-only option

var aaSugg = {'pokemon':[], 'trainer':[], 'energy':[]};

var aaSugg_RecentOnly = {'pokemon':[], 'trainer':[], 'energy':[]};

for (var type in aaSugg)

	for (var i=0;  i<ALL_cards_list[type].length;  i++) {

		aaSugg[type].push (sugg_item (ALL_cards_list[type][i]));

		// include all pokemon in "recent-only"
		// only include latest versions (first in list) of trainer/energy cards
		if ((type == 'pokemon') || (i==0) || (ALL_cards_list[type][i][0] != ALL_cards_list[type][i-1][0]))
			aaSugg_RecentOnly[type].push (sugg_item (ALL_cards_list[type][i]));

	} //for

//--------------------------------------------------------------------------------
// create the actual array items for the suggestion

function sugg_item (card_data) {
var card   = card_data[0];  //index also used in "recent-only" array construction
var num    = card_data[1];
var size   = card_data[2];
var rarity = card_data[3];
var set    = card_data[4];
var info   = card_data[5];
var note   = card_data[6];  //index also used in "recent-only" array construction
var order  = card_data[7];

	var font = 'font-size:10px; font-style:italic;';
	var sugg = card + (note || '');
	var sCardFill = card;

	var sCardDisplay = '<div style="text-align:left; font-size:12px">' + card + '</div>';

	var sNumSet = '<div style="text-align:right; ' + font + '">' + num + ((size=='') ? '' : '/') + size + '</div>';

	var sRarityShow = sRarityHide = '<div style="text-align:center;">';
	var sSymbolShow = sSymbolHide = '<div style="text-align:center;">';
	if (rarity != '')  sRarityShow += '<img src="' + rarity_images_loc + rarity + '.gif" style="width:12px;height:12px;" /></div>';
	else               sRarityShow += '&nbsp;</div>';
	sSymbolShow += '<img src="' + card_images_loc + set + '/set_symbol.gif" style="width:29px;height:29px;" /></div>';
	sRarityHide += '&nbsp;</div>';
	sSymbolHide += set + '</div>';

	// pad numbers with leading zeros
	if      (num < 10)   num = '00' + num;
	else if (num < 100)  num = '0'  + num;
	else;

	var sImgShow = sImgHide = '<div style="text-align:center;">';
	var sImgSrc = card_images_loc + set + '/' + num + '.jpg';

	sImgShow += '<img src="' + sImgSrc + '" style="width:50px;height:70px;"/></div>';
	sImgHide += '<!--src="' + sImgSrc + '"--></div>';

	var sInfo = info;
	var sNote = note;
	var sCard = sCardFill + '\t' + sInfo;

	//add more search-able text to the "match" field

	sCardMatch = sCardFill + '\t' + sInfo;

	return (new Array (sCardMatch, sCardFill, sCardDisplay, sNumSet,
		sRarityShow, sRarityHide, sSymbolShow, sSymbolHide, sImgShow, sImgHide, sInfo, sNote, sCard, sImgSrc));

} //function

//--------------------------------------------------------------------------------
// create the auto-suggest objects

var objSugg = {
	'pokemon': new clsAutoSuggestControl ('pokemon', aaSugg.pokemon),
	'trainer': new clsAutoSuggestControl ('trainer', aaSugg.trainer),
	'energy' : new clsAutoSuggestControl ('energy' , aaSugg.energy )
} //objSugg array

//--------------------------------------------------------------------------------
// change the auto-suggest object after changes to auto-suggest options

function change_sugg () {

	for (type in objSugg)
	with (objSugg[type]) {
		objHiddenItems[4] = !decklist_options.suggestions.show_set_images;   //show rarity symbol
		objHiddenItems[5] =  decklist_options.suggestions.show_set_images;   //hide rarity symbol
		objHiddenItems[6] = !decklist_options.suggestions.show_set_images;   //show set symbol
		objHiddenItems[7] =  decklist_options.suggestions.show_set_images;   //hide set symbol
		objHiddenItems[8] = !decklist_options.suggestions.show_card_images;  //show card image
		objHiddenItems[9] =  decklist_options.suggestions.show_card_images;  //hide card image
		iMinRowHeight       = (decklist_options.suggestions.show_card_images ? 80 : (decklist_options.suggestions.show_set_images ? 40 : 20));
		iMaxNumDisplayItems = (decklist_options.suggestions.show_card_images ?  4 : (decklist_options.suggestions.show_set_images ?  8 : 12));
		iMaxNumSuggestionItems = Math.min (16, 2*iMaxNumDisplayItems);
		iMinNumCharacters = decklist_options.suggestions.min_num_chars;
		bMatchStartOnly   = decklist_options.suggestions.match_start_only;
		objAllItems       = (decklist_options.suggestions.most_recent_only ? aaSugg_RecentOnly[type] : aaSugg[type]);
	} //with

	// include/exclude basic energy cards from all sets - always include the "misc" basic energy cards
	with (objSugg['energy']) {
		for (var i=0;  i<objAllItems.length;  i++)
			if ((objAllItems[i][0].search(' - Basic') >= 0) && (objAllItems[i][10] != ''))
				objExcludeItems[i] = !decklist_options.suggestions.include_basic_energy;
	} //with

} //function

//--------------------------------------------------------------------------------
// initialize the auto-suggest object (once during body.onload)

var objSugg_loaded = false;

function init_sugg () {

	if (objSugg_loaded)  return;
	objSugg_loaded = true;

	objSugg['pokemon'].highlightColor = 'Pink';
	objSugg['trainer'].highlightColor = 'LightGreen';
	objSugg['energy' ].highlightColor = 'PowderBlue';
	for (type in objSugg)
	with (objSugg[type]) {
		objHiddenItems[0]  = true;  //sugg match text
		objHiddenItems[1]  = true;  //sugg fill  text
		objHiddenItems[10] = true;  //info
		objHiddenItems[11] = true;  //note
		objHiddenItems[12] = true;  //complete card name/info
		objHiddenItems[13] = true;  //img src
		iSuggestionMatchIndex   = 0;
		iSuggestionFillIndex    = 1;
		iSuggestionDisplayIndex = 2;
		iWidenDropDown = (is_firefox ? 66 : 68);
		bWidenScrollbar = false;
		createDropDown();  // do this last after all the settings
	} //with

	// initialize according to the initial options
	change_sugg();

} //function

//--------------------------------------------------------------------------------
// connect the textbox/info to the auto-suggest control

function connect (objText, sType, ID) {

	var objNote = document.getElementById (ID + '_card_note');
	var objInfo = document.getElementById (ID + '_info');
	var objCard = document.getElementById (ID + '_card_hidden');
	var objImg  = document.getElementById (ID + '_card_img');

	objSugg[sType].connect (objText,
		[objInfo, 'value', 10, '', false],
		[objNote, 'value', 11, '', false],
		[objCard, 'value', 12, '', false],
		[objImg,  'value', 13, '', false]);

} //function

//--------------------------------------------------------------------------------
// input box style

var input_style = 'display:inline; font-family:verdana,arial,helvetica; font-size:12px;';

// tighten up the entry boxes
input_style += (is_msie7 ? ' margin:-1px 0px -1px 0px;' : ' margin:0px;');

//--------------------------------------------------------------------------------
// create the checkbox html

function ck_html (id) {

	return ('<input type="checkbox" id="' + id + '_ck" tabindex="-1"' +
		' onclick="click_ck_count(this)" />');

} //function

//--------------------------------------------------------------------------------
// create the qty input text box

function qty_input_html (id) {

	return ('<input type="text" style="' + input_style + ' width:40px;"' +
		' id="' + id + '_qty" value="" onchange="update_totals()" />');

} //function

//--------------------------------------------------------------------------------
// create the name input text box

function name_input_html (id, type) {

	return ('<input type="text" style="' + input_style + ' width:' + iWidth_name + 'px;"' +
		' id="' + id + '" value=""' +
		' onfocus="connect(this,\'' + type + '\',\'' + id + '\')" />');

} //function

//--------------------------------------------------------------------------------
// create the input text box for additional card display info

function info_html (id) {

	return ('<input type="text" style="' + input_style + ' width:72px;"' +
		' id="' + id + '_info" value="" />' +
		'<input type="hidden" id="' + id + '_card_hidden" value="" />' +
		'<input type="hidden" id="' + id + '_card_img" value="" />' +
		'<input type="hidden" id="' + id + '_card_note" value="" />');

} //function

//--------------------------------------------------------------------------------
// update the add/delete buttons depending on the given table id

function update_buttons (table) {

	// update all the buttons if no table was entered
	if (!table) {
		update_buttons ('pokemon');
		update_buttons ('trainer');
		update_buttons ('energy');
		return;
	} //if

	// get the checkbox count for the given table
	var count = ck_count[table];

	// get the button objects
	var obj_add_button = document.getElementById (table + '_add_row');
	var obj_del_button = document.getElementById (table + '_del_row');

	// update the button object labels
	obj_add_button.value = ((count==0) ? 'Add New Row'     : 'Insert Row');
	obj_del_button.value = ((count==0) ? 'Delete Last Row' : 'Delete ' + count + ' Checked Row' + (count>1?'s':''));

} //function

//--------------------------------------------------------------------------------
// update the checkbox count when clicked

function click_ck_count (obj_ck) {

	// determine the table from the obj id
	var table = '';
	if      (obj_ck.id.search('pokemon')>=0)  table = 'pokemon'
	else if (obj_ck.id.search('trainer')>=0)  table = 'trainer'
	else if (obj_ck.id.search('energy') >=0)  table = 'energy'
	else                                      table = '';

	// increment or decrement the count
	if (obj_ck.checked)  ck_count[table]++;
	else                 ck_count[table]--;

	// update the appropriate add/delete buttons
	update_buttons (table);

} //function

//--------------------------------------------------------------------------------
// dynamically add a row to the give line of the given table

function add_row_at (row, table) {

	// get the table object
	var obj_table = document.getElementById (table + '_table');

	// create a new row object
	var obj_newRow = obj_table.insertRow (row+1);

	// create the object ID for the new row
	var id = table + (++id_count);

	// insert the checkbox cell
	var obj_ck = obj_newRow.insertCell(-1);
	obj_ck.innerHTML = ck_html (id);

	// insert the QTY cell
	var obj_qty = obj_newRow.insertCell(-1);
	obj_qty.innerHTML = qty_input_html (id);

	// insert the NAME cell and suggestion widget
	var obj_name = obj_newRow.insertCell(-1);
	obj_name.innerHTML = name_input_html (id, table);

	// insert the INFO cell
	var obj_info = obj_newRow.insertCell(-1);
	obj_info.innerHTML = info_html (id);

} // function

//--------------------------------------------------------------------------------
// dynamically add a row to the end of the given table

function add_row (table) {

	// get the table object
	var obj_table = document.getElementById (table + '_table');

	// insert a row at the first checked box
	var ck_flag = false;
	for (var i=1; i<obj_table.rows.length-2; i++) {
		var obj_ck = obj_table.rows[i+1].cells[cell_num_ck].childNodes[child_num_ck];
		if (obj_ck.checked) {
			ck_flag = true;
			add_row_at (i, table);
			break;
		} //if
	} //for

	// create a new row object
	if (!ck_flag)  add_row_at (obj_table.rows.length-2, table);

	// update the buttons
	update_buttons(table);

	// activate the DELETE ROW button
	var obj_del_button = document.getElementById (table + '_del_row');
	obj_del_button.disabled = false;

//	// deactivate the ADD ROW button if needed
//	if (obj_table.rows.length > 32)
//	{
//		var obj_add_button = document.getElementById (table + '_add_row');
//		obj_add_button.disabled = true;
//	} //if

} // function

//--------------------------------------------------------------------------------
// dynamically delete the given row in the given table

function del_row_at (row, table) {

	// get the table object
	var obj_table = document.getElementById (table + '_table');

	// delete the given row
	obj_table.deleteRow(row+1);

} // function

//--------------------------------------------------------------------------------
// dynamically delete a row at the end of the given table or checked rows

function del_row (table) {

	// get the table object
	var obj_table = document.getElementById (table + '_table');

	// delete all the rows that are checked, starting at the bottom
	var ck_flag = false;
	for (var i=obj_table.rows.length-3; i>0; i--) {
		var obj_ck = obj_table.rows[i+1].cells[cell_num_ck].childNodes[child_num_ck];
		if (obj_ck.checked) {
			ck_flag = true;
			del_row_at (i, table);
			ck_count[table]--;
		} //if
	} //for

	// delete the last row
	if (!ck_flag)  del_row_at (obj_table.rows.length-3, table);

	// update the totals and buttons
	update_totals();
	update_buttons(table);

//	// activate the ADD ROW and INSERT ROW buttons
//	var obj_add_button = document.getElementById (table + '_add_row');
//	obj_add_button.disabled = false;

	// deactivate the DELETE ROW button if needed
	if (obj_table.rows.length < 4)
	{
		var obj_del_button = document.getElementById (table + '_del_row');
		obj_del_button.disabled = true;
	} //if

} // function

//--------------------------------------------------------------------------------
// get the total for the given table and update the display

function get_total(table) {

	// get the applicable total and table objects
	var obj_total      = document.getElementById(table + '_total');
	var obj_total_left = document.getElementById(table + '_total_left');
	var obj_table      = document.getElementById(table + '_table');

	// start with a null qty object
	var obj_qty = null;

	// initialize the total and qty
	var total = 0, qty = 0;

	// get the qty objects and add up the total
	for (var i=1; i<obj_table.rows.length-2; i++) {
		obj_qty = obj_table.rows[i+1].cells[cell_num_qty].childNodes[child_num_qty];
		qty = parseInt(obj_qty.value);
		total += (isNaN(qty) ? 0 : qty);
	} //for

	// update the total object display value
	obj_total.innerHTML      = (total==0 ? '' : total);
	obj_total_left.innerHTML = (total==0 ? '' : total);

	// return the total for this table
	return (total);

} //function

//--------------------------------------------------------------------------------
// update the checkbox counts

function update_ck_counters() {

	for (table in ck_count) {

		// get the applicable table object
		var obj_table = document.getElementById(table + '_table');

		// initialize the ck total
		ck_count[table] = 0;

		// get the ck objects and add up the ck count
		for (var i=1; i<obj_table.rows.length-2; i++) {
			obj_ck = obj_table.rows[i+1].cells[cell_num_ck].childNodes[child_num_ck];
			if (obj_ck.checked)  ck_count[table]++;
		} //for

	} //for

} //function

//--------------------------------------------------------------------------------
// update the totals

function update_totals() {

	// get the grand total object
	var obj_total = document.getElementById('deck_total');

	// add up the total for all tables
	var total = get_total('pokemon') + get_total('trainer') + get_total('energy');

	// update the grand total object display value
	obj_total.innerHTML = (total==0 ? '' : total);

} //function

//--------------------------------------------------------------------------------
// update the event logo

function update_logo (obj_event_name) {

	var obj_event_logo = document.getElementById('event_logo');

	if (obj_event_name == null)
		obj_event_name = document.getElementById('event_name');

	obj_event_logo.src = event_images_loc + obj_event_name.value;

} //function

//--------------------------------------------------------------------------------
// update the favorite pokemon picture
// if objDex is passed in, a list selection occured

function update_fav_poke (objDex) {

	var obj_fav_poke_pic = document.getElementById ('fav_poke_pic');

	with (decklists[deck_num-1].data.fav_poke) {

		//update the dex if blank to sugimori (backward compatible to v2.0)
		if (!dex || (dex == 'sugimori'))  dex = 'default_sugimori';

		// clear the pic label
		var img_label = document.getElementById('fav_poke_pic_label');
		img_label.innerHTML = '';

		// if no dex object, get the pic from the decklists array,
		if (!objDex) {

			if (dex == 'default_sugimori')
				obj_fav_poke_pic.src = pokemon_images_loc + (img ? img : '000.png');
			else
				obj_fav_poke_pic.src = img;

			// try to set the index
			var dex_list = document.getElementById('dex_' + decklist_options.fav_poke.pokedex);
			dex_list.selectedIndex = -1;
			dex_list.value = img;

			// if index not set (not in list), add text to img
			if ((dex_list.selectedIndex == -1) && name)
				img_label.innerHTML = '<br />' + (pokedex[dex] ? pokedex[dex].name : dex) + ':&nbsp; ' + name + '<br />';

		} //if

		// selection occured, get the pic from the selection value
		else {

			if (objDex.selectedIndex == 0) {
				objDex = document.getElementById('dex_default_sugimori');
				objDex.selectedIndex = 0;
			} //if

			if (objDex.id == 'dex_default_sugimori')
				obj_fav_poke_pic.src = pokemon_images_loc + (objDex.value ? objDex.value : '000.png');
			else
				obj_fav_poke_pic.src = objDex.value;

			// update the decklists array
			name = objDex.options[objDex.selectedIndex].text;
			dex  = objDex.id.replace(/dex_/, '');
			img  = (objDex.value ? objDex.value : '000.png');

		} //else

	} //with

} //function

//--------------------------------------------------------------------------------
// check the date and update the age division

function check_birthdate (obj_birthdateString) {

	var obj_birthdate = new Date();
	obj_birthdate.setTime (Date.parse (obj_birthdateString.value));
	var birthyear = obj_birthdate.getFullYear();
	var obj_age_division = document.getElementById("age_division");

	if      (birthyear >= JR_yr                     )  obj_age_division.value = 'junior'
	else if (birthyear >= SR_yr && birthyear < JR_yr)  obj_age_division.value = 'senior'
	else if (                      birthyear < SR_yr)  obj_age_division.value = 'master'
	else                                               obj_age_division.value = ''

} //function

//--------------------------------------------------------------------------------
// update the deck counter display

function update_deck_counter () {

	var obj_deck_counter = document.getElementById('deck_counter');

	obj_deck_counter.innerHTML = deck_num + '&nbsp;/&nbsp;' + decklists.length;

	var obj_deck_list_select = document.getElementById('deck_list_select');

	obj_deck_list_select.selectedIndex = deck_num-1;

} //function

//--------------------------------------------------------------------------------
// update the deck list select after any changes

function update_deck_list_select () {

	var deck_name = document.getElementById('deck_name').value;

	var obj_deck_list_select = document.getElementById('deck_list_select');

	with (obj_deck_list_select)  options[selectedIndex].text = get_jump_text (deck_name);

} //function

//--------------------------------------------------------------------------------
// update the form (run this initially at body.onload)

if (window.addEventListener)
	window.addEventListener('load', update_form, false)
else if (window.attachEvent)
	window.attachEvent('onload', update_form)
else {}

function update_form () {

	init_sugg();
	update_totals();
	update_logo();
	update_fav_poke();
	update_ck_counters();
	update_buttons();
	update_deck_counter();
	update_deck_list_select();

	// re-sync the options
	set_options();
	get_options();

	// show/hide unowns
	var div  = document.getElementById('div_unowns');
	if (decklist_options.other.show_unowns)  uStr (document.getElementById('player_name').value, div.id);
	div.style.display = (decklist_options.other.show_unowns ? 'block' : 'none');

} //function

//--------------------------------------------------------------------------------
// set up the resize handler to reposition the "get" button
// needed if the form is centered or right-aligned

if (window.addEventListener)
	window.addEventListener('resize', resize_handler, false)
else if (window.attachEvent)
	window.attachEvent('onresize', resize_handler)
else {}

var cancel_resize = (is_msie ? true : false);
function resize_handler() {

	// IE bug - cancel resize first time through
	if (cancel_resize)  { cancel_resize = false;  return; }

	for (type in objSugg) {

		if (objSugg[type].objDropDown.style.visibility == 'visible')  objSugg[type].hideDropDown();
		if (objSugg[type].objGet     .style.visibility == 'visible')  objSugg[type].repositionGetButton();

	} //for

} //function

//--------------------------------------------------------------------------------
// reset the form

function reset_form () {

	if (!confirm ('Clear the current deck list?')) return;

	// force-reset the fav_poke
	with (decklists[deck_num-1].data.fav_poke)  name = dex = img = '';

	document.getElementById('pokemon_deck_list_form').reset();
	update_form();

} //function

//--------------------------------------------------------------------------------
// submit the form

function submit_form () {

	// do nothing - for Safari compatibility

} //function

//--------------------------------------------------------------------------------
// return the text to display on the deck list jump list

function get_jump_text (desc) {

	return (desc ? desc : '(no deck name)');

} //function

//--------------------------------------------------------------------------------
// escape any special chars for output to "" string

function toStr (str) {

	return (str.replace(/\\/g,'\\\\').replace(/"/g,'\\"'));

} //function

//--------------------------------------------------------------------------------
// escape any special chars for output to XML

function toXml (str) {

	return (str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'));

} //function

//--------------------------------------------------------------------------------
// move the given decklist up (closer to first) in the list

function moveUp_deck (num) {

	// don't do anything if at start of list
	if (num == 1)  return;

	// update the current decklist data first
	update_decklist();

	// move down the deck, then update the deck number
	decklists.splice (num-2, 2, decklists[num-1], decklists[num-2]);
	deck_num--;

	// update the deck list select item text
	var obj_deck_list_select = document.getElementById('deck_list_select');
	obj_deck_list_select.options[deck_num].text = get_jump_text (decklists[deck_num].cards.deck_name);

	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

} //function

//--------------------------------------------------------------------------------
// move the given decklist down (closer to last) in the list

function moveDown_deck (num) {

	// don't do anything if at end of list)
	if (num > decklists.length-1)  return;

	// update the current decklist data first
	update_decklist();

	// move up the deck, then update the deck number
	decklists.splice (num-1, 2, decklists[num], decklists[num-1]);
	deck_num++;

	// update the deck list select item text
	var obj_deck_list_select = document.getElementById('deck_list_select');
	obj_deck_list_select.options[deck_num-2].text = get_jump_text (decklists[deck_num-2].cards.deck_name);

	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

} //function

//--------------------------------------------------------------------------------
// get the given deck number and display it

function get_deck (num, is_vdb) {

	// don't do anything if this is the same deck
	var new_deck_num = Math.min (decklists.length, Math.max (1, num));
	if (new_deck_num == deck_num)  return;

	// update the current decklist data first
	if (!is_vdb)  update_decklist();

	// get the new deck
	deck_num = new_deck_num;

	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

} //function

//--------------------------------------------------------------------------------
// copy the current deck to a new deck and display it

function copy_deck (is_vdb) {

	if (is_vdb)  { if (!confirm ('Copy the current deck?'))  return false; }
	else         { if (!confirm ('Copy the current deck list?'))  return; }

	// update the current decklist data first
	if (!is_vdb)  update_decklist();

	// copy the current deck
	push_blank_deck (decklists);
	copy_decks (decklists[deck_num-1], decklists[decklists.length-1]);
	deck_num = decklists.length;

	// add a new item to the deck list select
	var obj_deck_list_select = document.getElementById('deck_list_select');
	var obj_option = document.createElement('option');
	obj_option.text = get_jump_text (decklists[deck_num-1].cards.deck_name);
	try       { obj_deck_list_select.add (obj_option, null); }  // standards compliant
	catch(ex) { obj_deck_list_select.add (obj_option);       }  // IE only
	
	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

	if (is_vdb)  return true;  else  return;

} //function

//--------------------------------------------------------------------------------
// add a new deck and display it

function add_deck (is_vdb) {

	if (is_vdb)  { if (!confirm ('Add a new deck?'))  return false; }
	else         { if (!confirm ('Add a new blank deck list?'))  return; }

	// update the current decklist data first
	if (!is_vdb)  update_decklist();

	// add the new deck
	deck_num = (is_vdb
		? push_blank_deck (decklists)
		: push_new_deck (decklists));

	// add a new item to the deck list select
	var obj_deck_list_select = document.getElementById('deck_list_select');
	var obj_option = document.createElement('option');
	obj_option.text = get_jump_text (decklists[deck_num-1].cards.deck_name);
	try       { obj_deck_list_select.add (obj_option, null); }  // standards compliant
	catch(ex) { obj_deck_list_select.add (obj_option);       }  // IE only

	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

	if (is_vdb)  return true;  else  return;

} //function

//--------------------------------------------------------------------------------
// delete the given deck number and display the next deck

function del_deck (num, is_vdb) {

	if (is_vdb)  { if (!confirm ('Delete the current deck?')) return false; }
	else         { if (!confirm ('Delete the current deck list?')) return; }

	// delete the current deck item from the deck list select
	var obj_deck_list_select = document.getElementById('deck_list_select');
	with (obj_deck_list_select)
		if (length > 1)  remove (selectedIndex);
		else             options[selectedIndex].text = get_jump_text();

	// delete the current deck
	decklists.splice (deck_num-1, 1);
	deck_num = Math.min (decklists.length, deck_num);
	if (deck_num == 0)  deck_num = push_new_deck (decklists);

	// update the display
	document.getElementById('pokemon_deck_list_form').reset();
	update_displayed_decklist();
	update_form();

	if (is_vdb)  return true;  else  return;

} //function

//--------------------------------------------------------------------------------
// update the displayed decklist data with the cards of the given type

function update_displayed_decklist_cards (type) {

	// get the table data for the given type
	var obj_table = document.getElementById(type + '_table');

	// add/delete a number of rows as needed
	var num_rows = decklists[deck_num-1].cards[type].length - (obj_table.rows.length-3);

	if      (num_rows > 0)  for (var i=0;  i<num_rows;     i++)  add_row (type);
	else if (num_rows < 0)  for (var i=0;  i<(-num_rows);  i++)  del_row (type);
	else {}

	// get the right column data and update the decklist data
	for (var i=1;  i<obj_table.rows.length-2;  i++) {

		// get the card data objects
		var qty  = obj_table.rows[i+1].cells[cell_num_qty ].childNodes[child_num_qty];
		var name = obj_table.rows[i+1].cells[cell_num_name].childNodes[child_num_name];
		var info = obj_table.rows[i+1].cells[cell_num_info].childNodes[child_num_info];
		var card = obj_table.rows[i+1].cells[cell_num_card].childNodes[child_num_card];
		var img  = obj_table.rows[i+1].cells[cell_num_img ].childNodes[child_num_img];
		var note = obj_table.rows[i+1].cells[cell_num_note].childNodes[child_num_note];

		// update the displayed card data - add the card image loc prefix on the card img
		qty.value  = decklists[deck_num-1].cards[type][i-1].qty;
		name.value = decklists[deck_num-1].cards[type][i-1].name;
		info.value = decklists[deck_num-1].cards[type][i-1].info;
		card.value = decklists[deck_num-1].cards[type][i-1].card;
		img.value  = card_images_loc + decklists[deck_num-1].cards[type][i-1].img;
		note.value = decklists[deck_num-1].cards[type][i-1].note;

	} //for

} //function

//--------------------------------------------------------------------------------
// update the displayed decklist with the current deck_num
// fav poke update done in update_fav_poke

function update_displayed_decklist() {

	// get the left column data objects
	var event = document.getElementById('event_name');
	var name  = document.getElementById('player_name');
	var id    = document.getElementById('pop_id');
	var dob   = document.getElementById('dob');
	var div   = document.getElementById('age_division');

	// update the displayed decklist data
	event.value = decklists[deck_num-1].data.event.img;
	name.value  = decklists[deck_num-1].data.player.name;
	id.value    = decklists[deck_num-1].data.player.id;
	dob.value   = decklists[deck_num-1].data.player.dob;
	div.value   = decklists[deck_num-1].data.player.div.toLowerCase();

	// force update the drop down controls
	event.selectedIndex = Math.max (0, event.selectedIndex);
	div.selectedIndex   = Math.max (0, div.selectedIndex);

	// get the right column data and update the displayed decklist data
	var deck_name = document.getElementById('deck_name');
	deck_name.value = decklists[deck_num-1].cards.deck_name;
	update_displayed_decklist_cards ('pokemon');
	update_displayed_decklist_cards ('trainer');
	update_displayed_decklist_cards ('energy');

} //function

//--------------------------------------------------------------------------------
// update the decklist data with the displayed cards of the given type

function update_decklist_cards (type) {

	// get the table data for the given type
	var obj_table = document.getElementById(type + '_table');

	// clear out the cards
	decklists[deck_num-1].cards[type].splice (0, decklists[deck_num-1].cards[type].length);

	// get the right column data and update the decklist data
	for (var i=1;  i<obj_table.rows.length-2;  i++) {

		// get the card data objects - strip the card image loc prefix off the card img
		var qty  = obj_table.rows[i+1].cells[cell_num_qty ].childNodes[child_num_qty ].value;
		var name = obj_table.rows[i+1].cells[cell_num_name].childNodes[child_num_name].value;
		var info = obj_table.rows[i+1].cells[cell_num_info].childNodes[child_num_info].value;
		var card = obj_table.rows[i+1].cells[cell_num_card].childNodes[child_num_card].value;
		var img  = obj_table.rows[i+1].cells[cell_num_img ].childNodes[child_num_img ].value.substring(card_images_loc.length);
		var note = obj_table.rows[i+1].cells[cell_num_note].childNodes[child_num_note].value;

		// update the decklist data
		decklists[deck_num-1].cards[type].push (
			{"qty":qty, "name":name, "info":info, "card":card, "img":img, "note":note});

	} //for

} //function

//--------------------------------------------------------------------------------
// update the decklist with the data from the displayed decklist
// fav poke update done in update_fav_poke

function update_decklist() {

	// get the left column data objects
	var event = document.getElementById('event_name');
	var name  = document.getElementById('player_name');
	var id    = document.getElementById('pop_id');
	var dob   = document.getElementById('dob');
	var div   = document.getElementById('age_division');

	// force update the dropdown lists
	event.selectedIndex = Math.max (0, event.selectedIndex);
	div.selectedIndex   = Math.max (0, div.selectedIndex);

	// update the decklist data
	decklists[deck_num-1].data.event.name    = event.options[event.selectedIndex].text;
	decklists[deck_num-1].data.event.img     = event.value;
	decklists[deck_num-1].data.player.name   = name.value;
	decklists[deck_num-1].data.player.id     = id.value;
	decklists[deck_num-1].data.player.dob    = dob.value;
	decklists[deck_num-1].data.player.div    = div.options[div.selectedIndex].text;

	// get the right column data and update the decklist data
	var deck_name = document.getElementById('deck_name');
	decklists[deck_num-1].cards.deck_name = deck_name.value;
	update_decklist_cards ('pokemon');
	update_decklist_cards ('trainer');
	update_decklist_cards ('energy');

	// update the deck list select
	var obj_deck_list_select = document.getElementById('deck_list_select');
	with (obj_deck_list_select)  options[deck_num-1].text = get_jump_text (deck_name.value);

} //function

//--------------------------------------------------------------------------------
// build the js data for the given cards

function save_cards_js (cards) {

	// start the js data
	var js = '';

	// get the card data
	for (var i=0;  i<cards.length;  i++) {

		// start the card
		js += '\n      {';

		// fill card data
		js += '"qty":"'  + toStr (cards[i].qty)  + '", ';
		js += '"name":"' + toStr (cards[i].name) + '", ';
		js += '"info":"' + toStr (cards[i].info) + '", ';
		js += '"card":"' + toStr (cards[i].card) + '", ';
		js += '"img":"'  + toStr (cards[i].img)  + '", ';
		js += '"note":"' + toStr (cards[i].note) + '"';

		// end the card
		js += ((i==cards.length-1) ? '}' : '},');

	} //for

	// always save at least 1 blank card
	if (cards.length == 0)
		js += '\n      {"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}';

	return (js);

} //function

//--------------------------------------------------------------------------------
// pop up a window to save the deck in an HTML file

function save_deck() {

	// build and display the save message
	var help = '';
	help += 'A window will now pop up that contains the html/data code from current deck list.\n\n' +
		'Depending on how many deck lists there are, this might take a while.\n\n' +
		'To save this code, follow the instructions at the top of the html/data code.\n\n' +
		'To re-load the code, browse to where you saved the file, then open it with your browser.';
	if (!confirm (help))  return;

	// open the window and show the HTML
	var obj_window = window.open ('about:blank','_blank',
		'top=10, left=10, height=640, width=800, resizable=yes, scrollbars=yes, ' +
		'location=no, titlebar=yes, toolbar=yes, menubar=yes');
	obj_window.document.open('text/html');

	// write and flush the html string buffer
	function write_html() {
		obj_window.document.writeln('<pre>'+toXml(html)+'</pre>');
		html = '';
	} //function

	// build the "save" instructions
	var help_html =
		'<!--\n' +
		'**********************************************************************\n' +
		'\n' +
		'To save this html/data code, do the following steps:\n' +
		'\n' +
		'1. Select all the text in this window (CTRL-A).\n' +
		'2. Copy the selected html/data code (CTRL-C). \n' +
		'3. Open a text editor such as Notepad.\n' +
		'4. Paste the html/data code into the editor (CTRL-V).\n' +
		'5. From inside the text editor, click File, Save As...\n' +
		'6. Change the "Save as type" to "All Files".\n' +
		'7. Enter a "File name" and end the file name with extension ".html".\n' +
		'8. Browse to where you want to save the file, then click "Save".\n' +
		'\n' +
		'**********************************************************************\n' +
		'-->\n';

	// create the base href html
	var base_html = '<base id="pokemon_base" href="' + document.getElementById('pokemon_base').href + '" />\n';
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// PokeBeach hack - can't find correct base dynamically
	if (is_pokebeach)
		base_html = '<base id="pokemon_base" href="http://www.pokebeach.com/content/tcg/deck-list/" />\n';
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

	// create the javascript code that prompts for deck list software location
	base_html += '<script language="javascript">\n' +
		'  var obj_base = document.getElementById("pokemon_base");\n' +
		'  obj_base.href = prompt ("Base location of deck list software: ", obj_base.href);\n' + 
		'</script>\n';

	// create the javascrip externals html
	var js_html =
		'<script type="text/javascript" src="config.js"></script>\n' +
		'<script type="text/javascript" src="data.js"></script>\n' +
		'<script type="text/javascript" src="pokedex.js"></script>\n' +
		'<script type="text/javascript" src="autosuggest.js"></script>\n' +
		'<script type="text/javascript" src="core.js"></script>\n' +
		'<script type="text/javascript" src="vdb.js"></script>\n';

	// start the HTML document
	var html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' +
			' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' +
		'<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">\n';

	// add in the "save" instructions
	html += help_html;

	// create the HTML head
	html += '<head>\n' +
		'<title>myDecks</title>\n' + base_html +
		'<p id="splash" style="position:absolute; top:20px; left:20px; font-size:20px;">loading...</p>\n' +
		js_html + '</head>\n' +
		'<body style="font-family:verdana,arial,helvetica;">\n' +
		'<script language="javascript">\n';
	write_html();;

	// update the current decklist being edited
	update_decklist();

	// start the js data
	html += 'var my_decklists = [\n';
	write_html();

	// save all the decks
	for (var i=0;  i<decklists.length;  i++) {

		// start the deck
		html += '{ // start decklist ' + (i+1) + '\n';

		// create the left column js data
		html += '  "data":\n' +
			'  {\n' +
			'    "event":{\n'    +
			'      "name":"'     + toStr (decklists[i].data.event.name) + '",\n' +
			'      "img":"'      + toStr (decklists[i].data.event.img)  + '"},\n' +
			'    "fav_poke":{\n' +
			'      "name":"'     + toStr (decklists[i].data.fav_poke.name) + '",\n' +
			'      "dex":"'      + toStr (decklists[i].data.fav_poke.dex)  + '",\n' +
			'      "img":"'      + toStr (decklists[i].data.fav_poke.img)  + '"},\n' +
			'    "player":{\n'   +
			'      "name":"'     + toStr (decklists[i].data.player.name) + '",\n' +
			'      "id":"'       + toStr (decklists[i].data.player.id)   + '",\n' +
			'      "dob":"'      + toStr (decklists[i].data.player.dob)  + '",\n' +
			'      "div":"'      + toStr (decklists[i].data.player.div)  + '"}\n' +
			'  },\n';

		// create the right column js data
		html += '  "cards":\n' +
			'  {\n' +
			'    "deck_name":"' + toStr       (decklists[i].cards.deck_name) + '",\n' +
			'    "pokemon":[' + save_cards_js (decklists[i].cards.pokemon)   + '],\n' +
			'    "trainer":[' + save_cards_js (decklists[i].cards.trainer)   + '],\n' +
			'    "energy":['  + save_cards_js (decklists[i].cards.energy)    + ']\n'  +
			'  }\n';

		// end the deck and create divider if needed
		html += '} // end decklist ' + (i+1) + '\n';
		write_html();
		html += ((i==decklists.length-1) ? '' : ', // decklist divider\n');
		write_html();

	} //for

	// end the js data
	html += '];\n';
	write_html();

	// create the call to generate the decklist
	html += 'create_multi_deck_entry (my_decklists);\n';
	write_html();

	// start the options
	html += 'var my_options = {\n';

	// create the options
	html += '  "suggestions":{\n'         +
		'    "min_num_chars":'        + decklist_options.suggestions.min_num_chars        + ',\n' +
		'    "match_start_only":'     + decklist_options.suggestions.match_start_only     + ',\n' +
		'    "most_recent_only":'     + decklist_options.suggestions.most_recent_only     + ',\n' +
		'    "show_card_images":'     + decklist_options.suggestions.show_card_images     + ',\n' +
		'    "show_set_images":'      + decklist_options.suggestions.show_set_images      + ',\n' +
		'    "include_basic_energy":' + decklist_options.suggestions.include_basic_energy + '},\n';
	html += '  "text_view":{\n'    +
		'    "show_set_info":' + decklist_options.text_view.show_set_info + '},\n';
	html += '  "cards_view":{\n' +
		'    "fan_cards":"'  + toStr (decklist_options.cards_view.fan_cards) + '",\n' +
		'    "fan_size":'    +        decklist_options.cards_view.fan_size   + ',\n' +
		'    "fan_dir":'     +        decklist_options.cards_view.fan_dir    + '},\n';
	html += '  "print_preview":{\n'      +
		'    "show_decklist_check":' + decklist_options.print_preview.show_decklist_check + ',\n' +
		'    "merge_duplicates":'    + decklist_options.print_preview.merge_duplicates    + ',\n' +
		'    "POP_style":'           + decklist_options.print_preview.POP_style           + ',\n' +
		'    "show_set_legend":'     + decklist_options.print_preview.show_set_legend     + ',\n' +
		'    "include_old_legend":'  + decklist_options.print_preview.include_old_legend  + '},\n';
	html += '  "fav_poke":{\n'    +
		'    "pokedex":"'     + toStr (decklist_options.fav_poke.pokedex    ) + '",\n' +
		'    "my_pic_src":"'  + toStr (decklist_options.fav_poke.my_pic_src ) + '",\n' +
		'    "my_pic_name":"' + toStr (decklist_options.fav_poke.my_pic_name) + '"},\n';
	html += '  "other":{\n'      +
		'    "show_unowns":' +        decklist_options.other.show_unowns  + ',\n' +
		'    "mouse_pet":"'  + toStr (decklist_options.other.mouse_pet  ) + '"}\n';

	// end the options data
	html += '}; //my_options\n';
	write_html();

	// create the call to load the options
	html += 'load_options (my_options);\n';
	write_html();

	// close the HTML
	html += 'document.getElementById(\'splash\').style.display = \'none\';\n' +
		'</script>\n' +
		'</body></html>\n';
	write_html();

	// close the window
	obj_window.document.title = 'myDecks';
	obj_window.document.close();
	obj_window.focus();

} //function

//--------------------------------------------------------------------------------
// fanout the given image and return a table container

function fanOut (sSrc, iNum, iWidth, iHeight, iFanX, iFanY, iBorder, sAddStyle) {

	// exit if there are no images
	if (iNum <= 0)  return '';

	var sHtml = '';

	// different display style for IE
	var sDisplay = (is_msie ? ' display:inline;' : ' display:inline-table;');

	// set the table container attribute
	// add 1 pixel width to print correctly in IE
	var iTableWidth  = iWidth  + Math.abs(iFanX) * (iNum-1) + 2*iBorder + 1;
	var iTableHeight = iHeight + Math.abs(iFanY) * (iNum-1) + 2*iBorder;
	var sDimension   = ' width:' + iTableWidth + 'px; height:' + iTableHeight + 'px;';
	var sPosition    = ' padding:5px; vertical-align:' + (iFanY <= 0 ? 'top;' : 'bottom;');
	var sBorder      = ' border:1px solid #CCCCCC"';
	var sStyle       = ' style="' + sDisplay + sPosition + sBorder + '"';

	// start the table container
	sHtml += '<table cellspacing="0" cellpadding="0"' + sStyle + '><tr><td style="' + sDimension + '">';

	// same settings for all images
	sBorder    = ' border:' + iBorder + 'px solid black;';
	sDimension = ' width:' + iWidth + 'px; height:' + iHeight + 'px;';
	sDisplay   = ' display:inline;';

	// first image only settings
	var iLeft   = (iFanX < 0 ? -iFanX * (iNum-1) : 0);
	var iBottom = (iFanY > 0 ?  iFanY * (iNum-1) : 0);
	var sMargin = ' margin:0px 0px ' + iBottom + 'px ' + iLeft + 'px;';
	sStyle      = ' style="' + sDisplay + sDimension + sMargin + sBorder + sAddStyle + '"';
	var sImage  = '<img src="' + sSrc + '"' + sStyle  + ' />';
	sHtml      += sImage;

	// multiple images settings
	for (var i=1;  i<iNum;  i++) {

		iLeft   = (iFanX < 0 && is_msie7 ? i : 1) * iFanX - iWidth - 2*iBorder;
		iBottom = (iFanY > 0 ? iNum-1-i : -i) * iFanY;
		sMargin = ' margin:0px 0px ' + iBottom + 'px ' + iLeft + 'px;';
		sStyle  = ' style="' + sDisplay + sDimension + sMargin + sBorder + sAddStyle + '"';
		sImage  = '<img src="' + sSrc + '"' + sStyle  + ' />';
		sHtml  += sImage;

	} //for

	// end the table container
	sHtml += '</td></tr></table>';

	return sHtml;

} //function

//--------------------------------------------------------------------------------
// build the html to show the given type of cards

function cards_html (type) {

	var html = '';

	// set the color and title based on the card type
	var color = '';
	var title = '';
	switch (type) {
		case 'pokemon':  title = 'Pokemon';                    color = 'red';    break;
		case 'trainer':  title = 'Trainer/Supporter/Stadium';  color = 'green';  break;
		case 'energy' :  title = 'Energy';                     color = 'blue';   break;
		default:;
	} //switch

	// start the card list HTML
	html += '<div style="width:100%; border:2px solid ' + color + '; font-family:verdana,arial,helvetica; white-space:normal; margin-top:20px;">';
	html += '<div style="text-align:center; font-size:16px; font-weight:bold; color:white; background-color:' + color +
		'; border:2px solid ' + color + ';">' + title + '</div>';

	// get the table data
	var obj_table = document.getElementById(type + '_table');

	// flag to see if cards were displayed
	var cards_present = false;

	// get the card img data
	for (var i=1;  i<obj_table.rows.length-2;  i++) {

		var qty  = obj_table.rows[i+1].cells[cell_num_qty ].childNodes[child_num_qty ].value;
		var name = obj_table.rows[i+1].cells[cell_num_name].childNodes[child_num_name].value;
		var info = obj_table.rows[i+1].cells[cell_num_info].childNodes[child_num_info].value;
		var img  = obj_table.rows[i+1].cells[cell_num_img ].childNodes[child_num_img ].value;

		// don't show cards for blank lines
		var entry = qty + name + info;
		if (entry.replace(/ /gi,'') == '') continue;

		// show the card times the qty, show back of card if img not specified
		qty = parseInt(qty);
		var is_none = (isNaN(qty) || qty < 1);
		if (is_none)  qty = 1;  // always show at least 1
		if (img == '')  img = card_images_loc + 'back/001.jpg';

		// add the base location to the image path
		img = base_loc + img;

		// initialize the fan sizes / direction
		var fanX = fanY = 0;  // none

		// set the fan-out sizes
		with (decklist_options.cards_view)
		if (fan_cards == 'none') {}
		else if (fan_cards == 'fan_horizontal')
			fanX = fan_size * fan_dir;
		else if (fan_cards == 'fan_vertical')
			fanY = fan_size * fan_dir;
		else if (fan_cards == 'fan_vertical_if')
			if (qty>4)  fanX = fan_size * fan_dir;  else  fanY = fan_size * fan_dir;
		else if (fan_cards == 'fan_diagonal')
			fanX = fanY = fan_size * fan_dir;
		else if (fan_cards == 'fan_diagonal_if')
			if (qty>4)  fanX = fan_size * fan_dir;  else  fanX = fanY = fan_size * fan_dir;
		else if (fan_cards == 'fan_diagonal_up')
			{fanX =  fan_size * fan_dir; fanY = -fan_size * fan_dir;}
		else if (fan_cards == 'fan_diagonal_up_if')
			if (qty>4)  fanX = fan_size * fan_dir;  else  {fanX = fan_size * fan_dir; fanY = -fan_size * fan_dir;}
		else if (fan_cards == 'side_by_side')
			fanX = 53 * fan_dir;
		else if (fan_cards == 'side_by_side_if')
			if (qty>4)  fanX = fan_size * fan_dir;  else  fanX = 53 * fan_dir;
		else {}

		// fan out the cards - make transparent if no/bad qty was given
		html += fanOut (img, qty, 50,70, fanX,fanY, 1, (is_none ? ' opacity:0.5;filter:alpha(opacity=50);' : ''));

		// determine if there were cards
		if (qty>0)  cards_present = true;

	} //for

	// include spacer if there were no cards
	if (!cards_present)  html += '&nbsp;';

	// end the pokemon list
	html += '</div>';

	return (html);

} //function

//--------------------------------------------------------------------------------
// show the cards in the deck

function view_cards_html() {

	var html = '';

	// create the deck name html
	var deck_name = document.getElementById('deck_name').value;
	if (trim(deck_name) != '')
		html += '<div style="text-align:center; font-family:verdana,arial,helvetica; ' +
			'font-size:16px; font-weight:bold;">' + deck_name + '</div>';

	// get all the cards
	html += cards_html ('pokemon');
	html += cards_html ('trainer');
	html += cards_html ('energy');

	return ('<div style="padding:20px;">' + html + '</div>');

} //function

function view_cards() {

	show_window_drag ('view_cards', view_cards_html());

} //function

function view_cards_print() {

	if (is_firefox || is_opera)
		if (!confirm ('The cards might not print exactly as they appear.\n\n' +
			'See the "Known Issues" section of the Help Information for any possible solutions.\n\n' +
			'Print anyway?'))
			return;

	var html = '';

	// open the window and show the HTML
	var obj_window = window.open ('about:blank','_blank',
		'top=10, left=10, height=640, width=800, resizable=yes, scrollbars=yes, ' +
		'location=no, titlebar=yes, toolbar=yes, menubar=yes');
	obj_window.document.open('text/html');

	// start the HTML document
	var html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' +
			' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' +
		'<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">\n';

	// create the HTML head
	html += '<head>\n' +
		'<title>SteveP\'s Pokemon Deck List Program - View Cards</title>\n' +
		'</head>\n<body>\n' +
		'<div style="padding:20px;">' + view_cards_html() + '</div>';

	// close the HTML
	html += '\n</body>\n</html>\n';

	obj_window.document.writeln (html);

	// close the window
	obj_window.document.title = 'SteveP\'s Pokemon Deck List Program - View Cards';
	obj_window.document.close();
	obj_window.focus();

	// print the window
	obj_window.print();

} //function

//--------------------------------------------------------------------------------
// build the html to show the given type of cards in text format

function cards_text_html (type) {

	var html = '';

	// set the color and title based on the card type
	var color = '';
	var title = '';
	switch (type) {
		case 'pokemon':  title = 'Pokemon';                    color = 'red';    break;
		case 'trainer':  title = 'Trainer/Supporter/Stadium';  color = 'green';  break;
		case 'energy' :  title = 'Energy';                     color = 'blue';   break;
		default:;
	} //switch

	// start the card list HTML
	html += '<br /><div style="font-size:12px;">' +
		'<b><span style="color:' + color + ';">' + title + '</span></b><br />';

	// get the table data
	var obj_table = document.getElementById(type + '_table');

	// get the card text data
	for (var i=1;  i<obj_table.rows.length-2;  i++) {

		var qty  = obj_table.rows[i+1].cells[cell_num_qty ].childNodes[child_num_qty ].value;
		var name = obj_table.rows[i+1].cells[cell_num_name].childNodes[child_num_name].value;
		var info = obj_table.rows[i+1].cells[cell_num_info].childNodes[child_num_info].value;

		// don't show card text for blank lines
		var entry = qty + name + info;
		if (entry.replace(/ /gi,'') == '') continue;

		html += (qty ? qty + ' x ' : '') + name;
		if ((decklist_options.text_view.show_set_info) && (info != ''))  html += ' - ' + info;
		html += '<br />';

	} //for

	// end the pokemon list
	html += '</div>';

	return (html);

} //function

//--------------------------------------------------------------------------------
// view the cards in the deck in text format

function view_text_html() {

	var html = '';

	// get the player name
	var obj_name = document.getElementById('player_name');
	if (obj_name.value != '')  html += obj_name.value + '<br /><br />';

	// get the deck name
	var deck_name = document.getElementById('deck_name').value;
	if (trim(deck_name) != '')  html += deck_name + '<br />';

	// get all the cards
	html += cards_text_html ('pokemon');
	html += cards_text_html ('trainer');
	html += cards_text_html ('energy');

	return ('<div style="padding:20px;">' + html + '</div>');

} //function

function view_text() {

	show_window_drag ('view_text', view_text_html());

} //function

//--------------------------------------------------------------------------------
// view the errors in the deck list

// generate the errors html - *** MAKE SURE THIS MATCHES view_decklist_html() ***

function view_errors_html() {

	var decklist_errors = '';

	// get the player data
	var logo  = document.getElementById('event_logo');
	var name  = document.getElementById('player_name');
	var id    = document.getElementById('pop_id');
	var dob   = document.getElementById('dob');
	var age   = document.getElementById('age_division');

	// check for player errors
	if (name.value == '')  decklist_errors += '<li>Missing Player Name.</li>';
	if (id.value == '')    decklist_errors += '<li>Missing POP ID.</li>';
	if (dob.value == '')   decklist_errors += '<li>Missing Date of Birth.</li>';
	if (age.value == '')   decklist_errors += '<li>Missing Age Division.</li>';

	// check for mismatching birthdate and age division
	var obj_birthdate = new Date();
	obj_birthdate.setTime (Date.parse (dob.value));
	var birthyear = obj_birthdate.getFullYear();
	if (((birthyear >= JR_yr                     ) && (age.value != "junior")) ||
	    ((birthyear >= SR_yr && birthyear < JR_yr) && (age.value != "senior")) ||
	    ((                      birthyear < SR_yr) && (age.value != "master")))
		decklist_errors += '<li>Mismatching birthdate and age division.</li>';

	// get the card totals
	var total_pokemon = document.getElementById('pokemon_total').innerHTML;
	var total_trainer = document.getElementById('trainer_total').innerHTML;
	var total_energy  = document.getElementById('energy_total').innerHTML;
	var total_deck    = document.getElementById('deck_total').innerHTML;

	// check for card total errors
	if (isNaN (parseInt(total_pokemon)))  decklist_errors += '<li>Too few Pokemon.  Deck must have at least 1 Pokemon.</li>';
	if (isNaN (parseInt(total_deck)))     decklist_errors += '<li>Too few cards.  Deck must have exactly 60 cards.</li>';
	else if (parseInt(total_deck) < 60)   decklist_errors += '<li>Too few cards.  Deck must have exactly 60 cards.</li>';
	else if (parseInt(total_deck) > 60)   decklist_errors += '<li>Too many cards.  Deck must have exactly 60 cards.</li>';
	else;

	// copy/merge the cards to a new card array
	var cards_pokemon = merge_dups ('pokemon');
	var cards_trainer = merge_dups ('trainer');
	var cards_energy  = merge_dups ('energy');

	// check for card errors
	decklist_errors += check_cardlist ('pokemon', cards_pokemon);
	decklist_errors += check_cardlist ('trainer', cards_trainer);
	decklist_errors += check_cardlist ('energy',  cards_energy);

	// list the card totals/errors
	if (decklist_errors == '')  decklist_errors = '<li>&radic; OK</li>';

	// get the deck name
	var deck_name = trim (document.getElementById('deck_name').value);
	if (deck_name != '')  deck_name = '<span style="font-size:14px;">' + deck_name + '<br /><br /></span>';

	// show the card totals at the top of the decklist checklist
	decklist_errors = '<li>' +
		'Total:&nbsp;<b>'   + ((total_deck    == '') ? '0' : total_deck)    + '</b>' +
		'; Pokemon:&nbsp;'  + ((total_pokemon == '') ? '0' : total_pokemon) +
		', Trainer:&nbsp;'  + ((total_trainer == '') ? '0' : total_trainer) +
		', Energy:&nbsp;'   + ((total_energy  == '') ? '0' : total_energy)  + '</li>' + decklist_errors;
	var html = '<div style="font-family:verdana,arial,helvetica; font-size:10px; text-align:left;">' + deck_name +
		'<span style="font-size:12px"><b><u>Deck List Check:</u></b></span>' +
		'<ul style="list-style-type:circle; margin:10; padding:5;">' + decklist_errors + '</ul>' +
		'</div>';

	return ('<div style="padding:20px;">' + html + '</div>');

} //function

function view_errors() {

	show_window_drag ('view_errors', view_errors_html());

} //function

//--------------------------------------------------------------------------------
// build the xml data for the given cards

function cards_xml (cards) {

	// start the xml
	var xml = '\n';

	// get the card data
	for (var i=0;  i<cards.length;  i++) {

		// fill card data
		xml +=
			'\t\t\t<qty>'  + toXml (cards[i].qty)  + '</qty>\n'  +
			'\t\t\t<name>' + toXml (cards[i].name) + '</name>\n' +
			'\t\t\t<info>' + toXml (cards[i].info) + '</info>\n' +
			'\t\t\t<card>' + toXml (cards[i].card) + '</card>\n' +
			'\t\t\t<img>'  + toXml (cards[i].img)  + '</img>\n'  +
			'\t\t\t<note>' + toXml (cards[i].note) + '</note>\n\n';

	} //for

	// always write at least 1 blank card
	if (cards.length == 0)
		xml += '\t\t\t<qty/><name/><info/><card/><img/>\n\n';

	return (xml);

} //function

//--------------------------------------------------------------------------------
// view the deck list data in XML format

function xml_view() {

	// build and display the save message
	var help = '';
	help += 'A window will now pop up that contains the XML data from current deck list.\n\n' +
		'Depending on how many deck lists there are, this might take a while.\n\n' +
		'Cut-n-paste this XML data as needed.';
	if (!confirm (help))  return;

	// update the current displayed decklist data
	update_decklist();

	// open the window and show the HTML
	var obj_window = window.open ('about:blank','_blank',
		'top=10, left=10, height=640, width=800, resizable=yes, scrollbars=yes, ' +
		'location=no, titlebar=yes, toolbar=yes, menubar=yes');
	obj_window.document.open('text/html');

	// start the XML document and root node
	var xml =
		'<?xml version="1.0" encoding="ISO-8859-1"?>\n' +
		'<decklists>\n';
	obj_window.document.writeln('<pre>'+toXml(xml)+'</pre>');  xml = '';

	// get all the decks
	for (var i=0;  i<decklists.length;  i++) {

		// start the deck
		xml += '<deck num="' + (i+1) + '">\n';

		// create the left column xml data
		xml +=
			'\t<data>\n' +
			'\t\t<event>\n'     +
			'\t\t\t<name>'      + toXml (decklists[i].data.event.name)    + '</name>\n' +
			'\t\t\t<img>'       + toXml (decklists[i].data.event.img)     + '</img>\n' +
			'\t\t</event>\n'    +
			'\t\t<fav_poke>\n'  +
			'\t\t\t<name>'      + toXml (decklists[i].data.fav_poke.name) + '</name>\n' +
			'\t\t\t<dex>'       + toXml (decklists[i].data.fav_poke.dex)  + '</dex>\n' +
			'\t\t\t<img>'       + toXml (decklists[i].data.fav_poke.img)  + '</img>\n' +
			'\t\t</fav_poke>\n' +
			'\t\t<player>\n'    + 
			'\t\t\t<name>'      + toXml (decklists[i].data.player.name)   + '</name>\n' +
			'\t\t\t<id>'        + toXml (decklists[i].data.player.id)     + '</id>\n' +
			'\t\t\t<dob>'       + toXml (decklists[i].data.player.dob)    + '</dob>\n' +
			'\t\t\t<div>'       + toXml (decklists[i].data.player.div)    + '</div>\n' +
			'\t\t</player>\n'   +
			'\t</data>\n';

		// create the right column xml data
		xml +=
			'\t<cards>\n' +
			'\t\t<deck_name>' + toXml     (decklists[i].cards.deck_name) + '</deck_name>\n' +
			'\t\t<pokemon>\n' + cards_xml (decklists[i].cards.pokemon)   + '\t\t</pokemon>\n' +
			'\t\t<trainer>\n' + cards_xml (decklists[i].cards.trainer)   + '\t\t</trainer>\n' +
			'\t\t<energy>\n'  + cards_xml (decklists[i].cards.energy)    + '\t\t</energy>\n'  +
			'\t</cards>\n';

		// end the deck
		xml += '</deck>\n';

		// write out the deck xml
		obj_window.document.writeln('<pre>'+toXml(xml)+'</pre>');  xml = '';

	} //for

	// close the XML
	xml += '</decklists>\n';
	obj_window.document.writeln('<pre>'+toXml(xml)+'</pre>');  xml = '';

	// close the window
	obj_window.document.title = 'myXML';
	obj_window.document.close();
	obj_window.focus();

} //function

//--------------------------------------------------------------------------------
// compare card names in order to determine rule-of-4 errors

function same_names (type, name1, name2) {

	// remove blanks
	name1 = (name1.replace (/ /g, '')).toUpperCase();
	name2 = (name2.replace (/ /g, '')).toUpperCase();

	switch (type) {

		case 'pokemon':

			// remove level x text
			name1 = name1.replace (/LV.X/g, '');
			name2 = name2.replace (/LV.X/g, '');

		case 'trainer':
		case 'energy':

		default:;

	} //switch

	return (name1 == name2);

} //function

//--------------------------------------------------------------------------------
// open the print preview window for the current window (IE specific)

function printpr() {

	var OLECMDID = 7;
	// OLECMDID values:
	// 6 - print
	// 7 - print preview
	// 1 - open window
	// 4 - Save As

	var PROMPT = 1; // 2 DONTPROMPTUSER 
	var WebBrowser = '<OBJECT ID="WebBrowser1" WIDTH=0 HEIGHT=0 CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
	document.body.insertAdjacentHTML('beforeEnd', WebBrowser); 
	WebBrowser1.ExecWB(OLECMDID, PROMPT);
	WebBrowser1.outerHTML = "";

} //function

//--------------------------------------------------------------------------------
// strip Basic/Special text on the energy card name

function strip_energy_type (card) {

	return (card.replace(/ - basic/gi, '').replace(/ - special/gi, ''));

} //function

//--------------------------------------------------------------------------------
// check the given card list for errors

function check_cardlist (type, cards) {

	var decklist_errors = '';

	// check for card errors (different rules for basic energy)
	for (var i=0;  i<cards.length;  i++) {

		var qty1  = cards[i].qty;
		var name1 = cards[i].name;
		var info1 = cards[i].info;
		var note1 = cards[i].note;

		var is_arceus = ((type == 'pokemon') && (name1.search(/arceus/gi) >= 0));
		var is_basic  = ((type == 'energy')  && (name1.search(/basic/gi)  >= 0));
		var ignore_4  = is_arceus || is_basic;

		// check for incomplete entry
		var entry = qty1 + name1 + info1;
		if (entry.replace(/ /gi,'') == '') continue;
		if (qty1.replace(/ /gi,'') == '') {
			decklist_errors += '<li>Missing ' + type + ' quantity. <b>line&nbsp;#' + (i+1) + '</b></li>';
			continue;
		} //if
		if (name1.replace(/ /gi,'') == '' || (!is_basic && info1.replace(/ /gi,'') == '')) {
			decklist_errors += '<li>Incomplete ' + type + ' entry. <b>line&nbsp;#' + (i+1) + '</b></li>';
			continue;
		} //if

		// check for possible unknown cards caused by altering the suggestions
		var card1 = cards[i].card;
		if (card1.replace(/ /gi,'').toUpperCase() != (name1+'\t'+info1).replace(/ /gi,'').toUpperCase()) {
			decklist_errors += '<li>Card possibly not allowed in modified format. <b>' +
				name1 + ': ' + info1 + '</b></li>';
			continue;
		} //if

		// check for notes
		if (note1.replace (/ /gi,'') != '') {
			decklist_errors += '<li>Note: ' + note1 + ' <b>' + name1 + ': ' + info1 + '</b></li>';
		} //if

		// check for quantity errors
		var qty = parseInt(qty1);
		if      (isNaN(qty))              decklist_errors += '<li>Invalid quantity (not a number). <b>' + name1 + '</b></li>';
		else if (qty < 1)                 decklist_errors += '<li>Invalid quantity (too few). <b>'      + name1 + '</b></li>';
		else if ((qty > 4) && !ignore_4)  decklist_errors += '<li>Rule-of-4 violation. <b>'             + name1 + '</b></li>';
		else if (i==cards.length-1)  continue; // don't do any more checking the last time thru
		else {
			for (var j=i+1;  j<cards.length;  j++) {

				var qty2  = cards[j].qty;
				var name2 = cards[j].name;
				var info2 = cards[j].info;

				// check for duplicates
				if (same_names (type, name1, name2)) {
					var qty2 = parseInt(qty2);
					if (!isNaN(qty2))  qty += qty2;
					if (info1.replace(/ /gi,'') == info2.replace(/ /gi,''))
						decklist_errors += '<li>Duplicate ' + type + ' entry. <b>' + name1 + '</b></li>';
				} //if

			} //for j

			if ((qty > 4) && !ignore_4)  decklist_errors += '<li>Rule-of-4 violation. <b>' + name1 + '</b></li>';

		} //else

	} //for i
	return (decklist_errors);

} //function

//--------------------------------------------------------------------------------
// merge duplicate cards into one item and return the merged array

function merge_dups (type) {

	// get the table data
	var obj_table = document.getElementById (type + '_table');

	// initialize the pre-merge array
	var cards1 = new Array();

	// get the table content objects
	for (var i=1;  i<obj_table.rows.length-2;  i++) {

		var qty  = obj_table.rows[i+1].cells[cell_num_qty ].childNodes[child_num_qty ].value;
		var name = obj_table.rows[i+1].cells[cell_num_name].childNodes[child_num_name].value;
		var info = obj_table.rows[i+1].cells[cell_num_info].childNodes[child_num_info].value;
		var card = obj_table.rows[i+1].cells[cell_num_card].childNodes[child_num_card].value;
		var img  = obj_table.rows[i+1].cells[cell_num_img ].childNodes[child_num_img ].value;
		var note = obj_table.rows[i+1].cells[cell_num_note].childNodes[child_num_note].value;

		cards1.push ({"qty":qty, "name":name, "info":info, "card":card, "img":img, "note":note});

	} //for

	// end here if the merge option is turned off
	if (!decklist_options.print_preview.merge_duplicates)  return cards1;

	// merge duplicates, top-down, check set-#s for pokemon
	for (var i=0;  i<cards1.length-1;  i++) {
		
		// don't check blank lines, bad quanties, notes, and duplicates
		if (cards1[i].card == 'duplicate')  continue;
		if (isNaN (parseInt (cards1[i].qty)))  continue
		if ((cards1[i].qty + cards1[i].name + cards1[i].info).replace(/ /gi,'') == '')  continue;
		if (cards1[i].note.replace(/ /gi,'') != '')  continue;

	for (var j=i+1;  j<cards1.length;  j++) {

		// don't check blank lines, bad quanties, notes, and duplicates
		if (cards1[j].card == 'duplicate')  continue
		if (isNaN (parseInt (cards1[j].qty)))  continue
		if ((cards1[j].qty + cards1[j].name + cards1[j].info).replace(/ /gi,'') == '')  continue;
		if (cards1[j].note.replace(/ /gi,'') != '')  continue;

		// names have to match first
		if (!same_names (type, cards1[i].name, cards1[j].name))  continue;

		// if names match, check set-# for pokemon
		if ((type == 'pokemon') && (cards1[i].info.replace(/ /gi,'') != cards1[j].info.replace(/ /gi,'')))  continue;

		//merge j-card into i-card
		cards1[i].qty = '' + (parseInt(cards1[i].qty) + parseInt(cards1[j].qty));
		cards1[j].qty  = '';
		cards1[j].name = '';
		cards1[j].info = '';
		cards1[j].card = 'duplicate';

	} //for - inner
	} //for - outer

	// initialize the post-merge array
	var cards2 = new Array();

	// copy cards1 to cards2 without the duplicate-tagged rows caused by the merge
	for (var i=0;  i<cards1.length;  i++)
		with (cards1[i])
			if (card != 'duplicate')
				cards2.push ({"qty":qty, "name":name, "info":info, "card":card, "img":img, "note":note});

	return cards2;

} //function

//--------------------------------------------------------------------------------
// create the given card list html

function cardlist_html (type, cards, bPrintFlag) {

	var html = '';

	// set the color and title based on the card type
	var title = '';
	var color = '';
	var cols  = 1;
	switch (type) {
		case 'pokemon':  title = 'Pokemon';                    color = 'red';    cols = 4;  break;
		case 'trainer':  title = 'Trainer/Supporter/Stadium';  color = 'green';  cols = 2;  break;
		case 'energy' :  title = 'Energy';                     color = 'blue';   cols = 4;  break;
		default:;
	} //switch

	// safari needs "-" instead of "/"
	if (is_safari && type=='trainer')  title = 'Trainer-Supporter-Stadium';

	// start the table
	html += '<div><table cellspacing="0" cellpadding="0" style="width:100%;"><tr><td style="width:100%;">' +
		'<table cellspacing="0" cellpadding="1" style="width:350px; font-size:12px; border-collapse:collapse; border:' +
		(decklist_options.print_preview.POP_style ? '1px solid black;' : '2px solid ' + color + ';') + '">';

	// add the title if not POP style
	if (!decklist_options.print_preview.POP_style)
		html += '<tr valign="center" style="font-size:16px; font-weight:bold; color:black;">' +
			'<td align="center" colspan="' + cols + '">' + title + '</td></tr>';

	// start the heading row
	html += '<tr valign="center" style="font-size:11px; font-weight:bold; ' +
		(decklist_options.print_preview.POP_style ? 'background-color:' + color + '; color:white;' : 'color:black;') + '">';

	// end the card list HTML (different for each type)
	if (type == 'pokemon')
		html += '<td align="center" style="width:10%;">QTY</td>' +
			'<td align="left" style="width:60%;">&nbsp;&nbsp;NAME</td>' +
			'<td align="center" style="width:15%; font-size:8px;">SET</td>' +
			'<td align="center" style="width:15%; font-size:8px;">COLL.#</td>';

	else if (type == 'trainer')
		html += '<td align="center" style="width:10%;">QTY</td>' +
			'<td align="left" style="width:90%;">&nbsp;&nbsp;NAME</td>';

	else if (type == 'energy')
		html += '<td align="center" style="width:10%;">QTY</td>' +
			'<td align="left" style="width:60%;">&nbsp;&nbsp;NAME</td>' +
			'<td align="center" style="width:15%; font-size:8px;">BASIC</td>' +
			'<td align="center" style="width:15%; font-size:8px;">SPECIAL</td>';

	else {}

	// end the heading row
	html += '</tr>';

	// table cell style
	var style = 'border:1px solid black;';

	// return the table content objects (different for pokemon and energy), strip any energy type
	function cardtype_html (type, qty, name, info) {

		if (type == 'pokemon') {
			var card_info = info.split('-');
			var card_set = (card_info[0] ? card_info[0] : '');
			var card_num = (card_info[1] ? card_info[1] : '');
			return '<tr>' +
				'<td align="center" style="' + style + '">' + qty  + '</td>' +
				'<td align="left" style="'   + style + '">&nbsp;' + name + '</td>' +
				'<td align="center" style="' + style + '">&nbsp;' + card_set + '</td>' +
				'<td align="center" style="' + style + '">&nbsp;' + card_num + '</td>' +
				'</tr>';
		} // if
		else if (type == 'trainer')
			return '<tr>' +
				'<td align="center" style="' + style + '">' + qty  + '</td>' +
				'<td align="left" style="'   + style + '">&nbsp;' + name + '</td>' +
				'</tr>';
		else if (type == 'energy')
			return '<tr>' +
				'<td align="center" style="' + style + '">' + qty  + '</td>' +
				'<td align="left" style="'   + style + '">&nbsp;' + strip_energy_type(name) + '</td>' +
				'<td align="center" style="' + style + '">' + (name.search(/basic/i)   >= 0 ? '&radic;' : '&nbsp;') + '</td>' +
				'<td align="center" style="' + style + '">' + (name.search(/special/i) >= 0 ? '&radic;' : '&nbsp;') + '</td>' +
				'</tr>';
		else
			return '';
	} // function

	// build the table content objects
	for (var i=0; i<cards.length; i++)
		html += cardtype_html (type, cards[i].qty, cards[i].name, cards[i].info);

	// POP deck list style
	if (decklist_options.print_preview.POP_style) {

		// add buffer rows if needed (so the right index tab fits)
		var num_rows = {"pokemon":6, "trainer":11, "energy":6};
		for (var i=cards.length; i<num_rows[type]; i++)
			html += cardtype_html (type, '','','');

		// insert the right-side tab
		html += '</table></td><td align="left" style="vertical-align:bottom;">' +
			'<img src="'+ base_loc + tab_images_loc + type + '.png"' +
			(is_safari && bPrintFlag ? ' style="margin-bottom:-3px;"' : '') + ' /></td></tr>';

	} //if

	else
		html += '</table></td></tr>';

	// close the table/div
	html += '</table></div>';

	return (html);

} // function

//--------------------------------------------------------------------------------
// return the detailed description for the give age division

function age_division_desc (age_division) {

	switch (age_division) {

		case 'junior':
			return ' Junior Division (born in ' + (JR_yr) + ' or later)';

		case 'senior':
			return ' Senior Division (born in ' + (SR_yr) + ', ' + (SR_yr+1) + ', ' + (SR_yr+2) + ', or ' + (SR_yr+3) + ')';

		case 'master':
			return ' Masters Division (born in ' + (SR_yr-1) + ' or earlier)';

		default:;

	} // switch

} // function

//--------------------------------------------------------------------------------
// make the set symbol legend HTML

function make_legend() {

	var html = '';
	var num_cols = 8;
	var partial = 0;

	var show_old = false;

	function make_legend_sets (sets) {

		for (var i=0;  i<sets.length;  i++) {

			if (i%num_cols == 0)  html += '<tr>';

			html += '<td style="border:1px solid gray; text-align:center; width:24px;">' +
				'<img src="images/cards/' + sets[i][0] + '/set_symbol.gif"' +
				' alt="' + sets[i][2] + '" style="width:20px; height:20px;" /><br>' + sets[i][1] + '</td>';

			if (i%num_cols == (num_cols-1))  html += '</tr>';

		} //for
		partial = sets.length % num_cols;
		if (partial)
			html += '<td colspan="' + (num_cols-partial) + '"' +
				' style="border:1px solid gray; text-align:center; width:24px;"></td></tr>';

	} //function

	html += '<table cellpadding="2" cellspacing="0"' +
		' style="font-family:verdana,arial,helvetica; font-size:8px; border-collapse:collapse; border:1px solid gray;">';

	html += '<tr><th colspan="' + num_cols + '" style="font-size:12px;">Set Symbols Legend</th></tr>';
	make_legend_sets (sets_mod);

	if (decklist_options.print_preview.include_old_legend) {
		html += '<tr><th colspan="' + num_cols + '" style="height:2px;"></th></tr>';
		make_legend_sets (sets_old);
	} //

	html += '</table>';

	return (html);

} //function

//--------------------------------------------------------------------------------
// view, print or print preview the decklist

function view_decklist_html (bPrintFlag) {

	var decklist_errors = '';

	var html = '';

	// start the decklist HTML
	html += '<table align="center" style="width:680px; border-style:solid; border-width:1px; border-color:black; ' +
		'font-family:verdana,arial,helvetica;">';

	// start the left column
	html += '<tr><td id="left_column" valign="top" align="center" style="width:45%; padding:10px">';

	// get the event/player data
	var logo  = document.getElementById('event_logo');
	var name  = document.getElementById('player_name');
	var id    = document.getElementById('pop_id');
	var dob   = document.getElementById('dob');
	var age   = document.getElementById('age_division');

	// check for event/player errors
	if (name.value == '')  decklist_errors += '<li>Missing Player Name.</li>';
	if (id.value == '')    decklist_errors += '<li>Missing POP ID.</li>';
	if (dob.value == '')   decklist_errors += '<li>Missing Date of Birth.</li>';
	if (age.value == '')   decklist_errors += '<li>Missing Age Division.</li>';

	// check for mismatching birthdate and age division
	var obj_birthdate = new Date();
	obj_birthdate.setTime (Date.parse (dob.value));
	var birthyear = obj_birthdate.getFullYear();
	if (((birthyear >= JR_yr                     ) && (age.value != "junior")) ||
	    ((birthyear >= SR_yr && birthyear < JR_yr) && (age.value != "senior")) ||
	    ((                      birthyear < SR_yr) && (age.value != "master")))
		decklist_errors += '<li>Mismatching birthdate and age division.</li>';

	// create the event logo
	html += '<img src="' + logo.src + '" /><br /><br /><br />';

	// create the unown Pokemon div
	if (decklist_options.other.show_unowns)
		html += '<div style="width:100%; text-align:left;">' + document.getElementById('div_unowns').innerHTML + '</div>';

	// create the event/player HTML
	if (decklist_options.print_preview.POP_style) {
		var html_1 = '<table style="width:100%; font-size:10px;"><tr align="left"><td style="width:1%; font-weight:bold; letter-spacing:-1px; white-space:nowrap;">';
		var html_2 = '<td style="font-size:14px; border-bottom:1px solid black;">&nbsp;';
		var html_3 = '</td></tr><tr align="left"><td style="letter-spacing:-1px; white-space:nowrap;">';
		var html_4 = '</td></tr></table>';
		html += html_1 + 'Player Name:</td>'              + html_2 + name.value + html_4 +
			html_1 + 'POP ID:</td>'                   + html_2 + id.value   + html_4 +
			html_1 + 'Date of Birth (MM/DD/YY):</td>' + html_2 + dob.value  + html_4 +
			html_1 + 'Age Division (check one):</td>' +
				html_3 + (age.value == 'junior' ? '\u2612' : '\u2610') + age_division_desc ('junior') +
				html_3 + (age.value == 'senior' ? '\u2612' : '\u2610') + age_division_desc ('senior') +
				html_3 + (age.value == 'master' ? '\u2612' : '\u2610') + age_division_desc ('master') + html_4;
	} // if
	else {
		var html_1 = '<tr align="left" valign="top"><td style="width:1%; font-weight:bold; white-space:nowrap;">';
		var html_2 = '</td></tr>';
		html += '<table style="width:100%; font-size:10px;">' +
			html_1 + 'Name:</td><td style="font-size:14px;">'      + name.value + html_2 +
			html_1 + 'POP ID:</td><td style="font-size:14px;">'    + id.value   + html_2 +
			html_1 + 'Birthdate:</td><td style="font-size:14px;">' + dob.value  + html_2 +
			html_1 + 'Division:</td><td style="font-size:14px;">'  + age.options[age.selectedIndex].text + html_2 +
			'</table>';
	} // else

	// show the favorite pokemon
	var pic = document.getElementById('fav_poke_pic');
	html += '<br /><img src="' + pic.src + '" />';

	// get the card totals
	var total_pokemon = document.getElementById('pokemon_total').innerHTML;
	var total_trainer = document.getElementById('trainer_total').innerHTML;
	var total_energy  = document.getElementById('energy_total').innerHTML;
	var total_deck    = document.getElementById('deck_total').innerHTML;

	// check for card total errors
	if (isNaN (parseInt(total_pokemon)))  decklist_errors += '<li>Too few Pokemon.  Deck must have at least 1 Pokemon.</li>';
	if (isNaN (parseInt(total_deck)))     decklist_errors += '<li>Too few cards.  Deck must have exactly 60 cards.</li>';
	else if (parseInt(total_deck) < 60)   decklist_errors += '<li>Too few cards.  Deck must have exactly 60 cards.</li>';
	else if (parseInt(total_deck) > 60)   decklist_errors += '<li>Too many cards.  Deck must have exactly 60 cards.</li>';
	else;

	// copy/merge the cards to a new card array
	var cards_pokemon = merge_dups ('pokemon');
	var cards_trainer = merge_dups ('trainer');
	var cards_energy  = merge_dups ('energy');

	// check for card errors
	decklist_errors += check_cardlist ('pokemon', cards_pokemon);
	decklist_errors += check_cardlist ('trainer', cards_trainer);
	decklist_errors += check_cardlist ('energy',  cards_energy);

	// query whether to show the decklist check if there are errors
	var show_check = decklist_options.print_preview.show_decklist_check;
	if (!show_check && decklist_errors)
		show_check = confirm (
			'Your deck list contains errors/issues.\n\n' +
			'Show the Deck List Check listing?\n\n  OK = yes\n  Cancel = no');

	// show the decklist check if desired
	if (show_check) {

		// list the card totals/errors
		if (decklist_errors == '')  decklist_errors = '<li>&radic; OK</li>';

		// show the card totals at the top of the decklist checklist
		decklist_errors = '<li>' +
			'Total:&nbsp;<b>'   + ((total_deck    == '') ? '0' : total_deck)    + '</b>' +
			'; Pokemon:&nbsp;'  + ((total_pokemon == '') ? '0' : total_pokemon) +
			', Trainer:&nbsp;'  + ((total_trainer == '') ? '0' : total_trainer) +
			', Energy:&nbsp;'   + ((total_energy  == '') ? '0' : total_energy)  + '</li>' + decklist_errors;
		html += '<div style="font-family:verdana,arial,helvetica; font-size:10px; text-align:left;"><br /><br /><br />' +
			'<span style="font-size:12px"><b><u>Deck List Check:</u></b></span>' +
			'<ul style="list-style-type:circle; margin:10; padding:5;">' + decklist_errors + '</ul>' +
			'</div>';

	} //if

	// show the set symbol legend
	if (decklist_options.print_preview.show_set_legend)
		html += '<br />' + make_legend (false);

	// start the right column
	html += '</td><td id="right_column" align="center" valign="top" style="width:55%; padding:10px">';

	// get the deck name
	var deck_name = document.getElementById('deck_name').value;

	// create the card list title
	if (decklist_options.print_preview.POP_style)
		html += '<div style="text-align:left;">' +
			'<img src="' + base_loc + tab_images_loc + 'deck.png" style="width:350px;' +
				(is_safari ? ' margin-bottom:-3px;' : '') + '" />' +
			'<table cellspacing="0" style="font-size:12px; border:2px solid orange; width:350px;">' +
			'<tr><td align="center">' + (trim(deck_name)=='' ? '&nbsp;' : deck_name) + '</td></tr>' +
			'</table></div><br />';
	else
		html += '<div style="text-align:left;">' +
			'<table cellspacing="0" style="font-size:12px; border:2px solid orange; width:100%;">' +
			'<tr style="font-size:16px; font-weight:bold; color:black;">' +
				'<td align="center">Deck Registration Sheet</td></tr>' +
			'<tr><td align="center">' + (trim(deck_name)=='' ? '&nbsp;' : deck_name) + '</td></tr>' +
			'</table></div><br />';

	// get all the cards
	html += cardlist_html ('pokemon', cards_pokemon, bPrintFlag) + '<br />';
	html += cardlist_html ('trainer', cards_trainer, bPrintFlag) + '<br />';
	html += cardlist_html ('energy',  cards_energy , bPrintFlag) + '<br />';

	// start the administrative notes HTML
	if (decklist_options.print_preview.POP_style)
		html += '<div  style="text-align:left;">' +
			'<table cellspacing="0" style="font-size:12px; border:1px solid black; width:350px;">' +
			'<tr valign="center" style="font-size:8px; font-weight:bold; color:black; background-color:#CCCCCC;">' +
				'<td style="border-bottom:1px solid black;">&nbsp;ADMINISTRATIVE USE ONLY</td></tr>';
	else
		html += '<div  style="text-align:left;">' +
			'<table cellspacing="0" style="font-size:12px; border:2px solid gray; width:100%;">' +
			'<tr valign="center" style="font-size:8px; font-weight:bold; color:black;">' +
				'<td>&nbsp;ADMINISTRATIVE USE ONLY</td></tr>';

	// display the notes
	var admin_notes = (document.getElementById('notes').value).replace(/  /g,'&nbsp; ');
	var admin_notes_lines = admin_notes.split(/\n/g);
	html += '<tr><td>';
	for (var i=0;  i<admin_notes_lines.length-1;  i++)  html += admin_notes_lines[i] + '<br />';
	for (var i=admin_notes_lines.length;  i<2;    i++)  html += '&nbsp;<br />';
	html += '&nbsp;</td></tr>';

	// close the table
	html += '</table></div>';

	// close the right column and decklist table
	html += '</td></tr>';
	html += '</table>';

	return html;

} //function

function view_decklist() {

	show_window_drag ('view_decklist', view_decklist_html());

} //function

function view_decklist_print (bPrint) {

	var decklist_errors = '';

	// start the HTML document
	var html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' +
			' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' +
		'<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">';

	// create the HTML head
	html += '<head><title>' + document.title + ' - Print Deck List</title></head><body>';

	// get the decklist html
	html += view_decklist_html(true);

	// insert the footnote
	html += footnote_html;

	// close the HTML and include the print dialog object
	html += '</body></html>';

	// open, load, then close the window
	var obj_window = window.open ('about:blank','_blank',
		'top=10, left=10, height=640, width=800, resizable=yes, scrollbars=yes, ' +
		'location=no, titlebar=yes, toolbar=yes, menubar=yes');
	obj_window.document.open('text/html');
	obj_window.document.write(html);
	obj_window.document.close();
	obj_window.focus();

	// print the window
	if (bPrint)  obj_window.print();

} //function

//--------------------------------------------------------------------------------
// default options for the deck list program

var decklist_options = {

	"suggestions" :{
		"min_num_chars"        : 2,
		"match_start_only"     : true,
		"most_recent_only"     : false,
		"show_card_images"     : true,
		"show_set_images"      : true,
		"include_basic_energy" : false},

	"text_view":{
		"show_set_info" : false},

	"cards_view":{
		"fan_cards" : "fan_vertical_if",
		"fan_size"  : 10,
		"fan_dir"   : -1},

	"print_preview":{
		"show_decklist_check" : true,
		"merge_duplicates"    : false,
		"POP_style"           : true,
		"show_set_legend"     : true,
		"include_old_legend"  : false},

	"fav_poke":{
		"pokedex"     : "default_sugimori",
		"my_pic_src"  : "",
		"my_pic_name" : ""},

	"other":{
		"show_unowns" : false,
		"mouse_pet"   : "none"}

} //deck_list_options

//--------------------------------------------------------------------------------
// load the saved deck list options

function load_options (new_options) {

	if (typeof new_options.suggestions != "undefined")
	with (new_options.suggestions) {
		if (typeof min_num_chars        != "undefined")  decklist_options.suggestions.min_num_chars        = min_num_chars;
		if (typeof match_start_only     != "undefined")  decklist_options.suggestions.match_start_only     = match_start_only;
		if (typeof most_recent_only     != "undefined")  decklist_options.suggestions.most_recent_only     = most_recent_only;
		if (typeof show_card_images     != "undefined")  decklist_options.suggestions.show_card_images     = show_card_images;
		if (typeof show_set_images      != "undefined")  decklist_options.suggestions.show_set_images      = show_set_images;
		if (typeof include_basic_energy != "undefined")  decklist_options.suggestions.include_basic_energy = include_basic_energy;
	} //with

	if (typeof new_options.text_view != "undefined")
	with (new_options.text_view) {
		if (typeof show_set_info != "undefined")  decklist_options.text_view.show_set_info = show_set_info;
	} //with

	if (typeof new_options.cards_view != "undefined")
	with (new_options.cards_view) {
		if (typeof fan_cards != "undefined")  decklist_options.cards_view.fan_cards = fan_cards;
		if (typeof fan_size  != "undefined")  decklist_options.cards_view.fan_size  = fan_size;
		if (typeof fan_dir   != "undefined")  decklist_options.cards_view.fan_dir   = fan_dir;
	} //with

	if (typeof new_options.print_preview != "undefined")
	with (new_options.print_preview) {
		if (typeof show_decklist_check != "undefined")  decklist_options.print_preview.show_decklist_check = show_decklist_check
		if (typeof merge_duplicates    != "undefined")  decklist_options.print_preview.merge_duplicates    = merge_duplicates;
		if (typeof POP_style           != "undefined")  decklist_options.print_preview.POP_style           = POP_style;
		if (typeof show_set_legend     != "undefined")  decklist_options.print_preview.show_set_legend     = show_set_legend;
		if (typeof include_old_legend  != "undefined")  decklist_options.print_preview.include_old_legend  = include_old_legend;
	} //with

	if (typeof new_options.fav_poke != "undefined")
	with (new_options.fav_poke) {
		if (typeof pokedex     != "undefined")  decklist_options.fav_poke.pokedex     = pokedex;
		if (typeof my_pic_src  != "undefined")  decklist_options.fav_poke.my_pic_src  = my_pic_src;
		if (typeof my_pic_name != "undefined")  decklist_options.fav_poke.my_pic_name = my_pic_name;
	} //with

	if (typeof new_options.other != "undefined")
	with (new_options.other) {
		if (typeof show_unowns != "undefined")  decklist_options.other.show_unowns = show_unowns;
		if (typeof mouse_pet   != "undefined")  decklist_options.other.mouse_pet   = mouse_pet;
	} //with

} //function

//--------------------------------------------------------------------------------
// show the options dialog div

var options_drag = null;

function options_drag_start (e, win) {

	window_drag_index = window_drag_index + 2;
	win.style.zIndex = window_drag_index;

	// set focus to the window
	var element = document.getElementById('options_drag_x');
	element.focus();
	if (is_msie)  win.focus();  else  ;

} //function

function show_options (id, window_id) {

	hide_all_options_windows();

	// open a particular options window
	if (id)  show_options_window(id);

	var options_div = document.getElementById('decklist_options');

	// position and show the options div
	if (window_id)  options_div.style.left = (parseInt(document.getElementById(window_id).style.left) + 5) + 'px';
	else            options_div.style.left = (vdb_getLeft(document.getElementById('pokemon_deck_list_table')) + (is_msie7 ? 266 : 256)) + 'px';

	if (window_id)  options_div.style.top = (parseInt(document.getElementById(window_id).style.top) + (is_msie7 ? 64 : is_msie ? 66 : is_safari ? 68 : 62)) + 'px';
	else            options_div.style.top = (vdb_getTop(document.getElementById('pokemon_deck_list_table')) + (is_msie7 ? 75 : is_msie ? 61 : is_safari ? 62 : 59)) + 'px';

	window_drag_index = window_drag_index + 2;
	options_div.style.zIndex  = window_drag_index;
	options_div.style.display = 'inline';

	// dispose the old drag object 
	if (options_drag)  options_drag.Dispose();

	// create the new drag object
	var drag_handle = document.getElementById ('options_drag_handle');
	options_drag = new dragObject (options_div, drag_handle,
		new Position(0,0), null,  //position
		options_drag_start, null, null);  //drag event handlers

	// set focus to the window
	var element = document.getElementById('options_drag_x');
	element.focus();
	if (is_msie)  options_div.focus();  else  ;

} //function

//--------------------------------------------------------------------------------
// hide the options dialog div

function hide_options() {

	var options_div = document.getElementById('decklist_options');

	options_div.style.display = 'none';

} //function

//--------------------------------------------------------------------------------
// get the options from the div

function get_options (enable_my_pic, hide_flag) {

	if (hide_flag)  hide_options();

	with (decklist_options) {

		suggestions.min_num_chars         = document.getElementById('min_num_chars').value;
		suggestions.match_start_only      = document.getElementById('match_start_only').checked;
		suggestions.most_recent_only      = document.getElementById('most_recent_only').checked;
		suggestions.show_card_images      = document.getElementById('show_card_images').checked;
		suggestions.show_set_images       = document.getElementById('show_set_images').checked;
		suggestions.include_basic_energy  = document.getElementById('include_basic_energy').checked;
		text_view.show_set_info           = document.getElementById('show_set_info').checked;
		cards_view.fan_cards              = document.getElementById('fan_cards').value;
		cards_view.fan_size               = document.getElementById('fan_size').value;
		cards_view.fan_dir                = document.getElementById('fan_dir').checked ? 1 : -1;
		print_preview.show_decklist_check = document.getElementById('show_decklist_check').checked;
		print_preview.merge_duplicates    = document.getElementById('merge_duplicates').checked;
		print_preview.POP_style           = document.getElementById('POP_style').checked;
		print_preview.show_set_legend     = document.getElementById('show_set_legend').checked;
		print_preview.include_old_legend  = document.getElementById('include_old_legend').checked;
		fav_poke.pokedex                  = document.getElementById('fav_poke_dex').value;
		fav_poke.my_pic_src               = document.getElementById('fav_poke_my_pic_src').value;
		fav_poke.my_pic_name              = document.getElementById('fav_poke_my_pic_name').value;
		other.show_unowns                 = document.getElementById('show_unowns').checked;
		other.mouse_pet                   = document.getElementById('mouse_pet').value;

		// set the new auto-suggestions options (in VDB too)
		change_sugg();
		vdb_change_sugg();

		set_pet();
		if (other.mouse_pet == 'none')  hide_pet();
		else                            show_pet();

		// show/hide unowns
		var div  = document.getElementById('div_unowns');
		if (other.show_unowns)  uStr (document.getElementById('player_name').value, div.id);
		div.style.display = (other.show_unowns ? 'block' : 'none');

		// switch the fav poke lists if needed
		activate_fav_poke_list();

		// set my_pic favorite pokemon
		if (enable_my_pic) {
			fav_poke.my_pic_src  = trim (fav_poke.my_pic_src);
			fav_poke.my_pic_name = trim (fav_poke.my_pic_name);
			if (fav_poke.my_pic_src)
				with (decklists[deck_num-1].data.fav_poke) {
					document.getElementById('fav_poke_pic').src = fav_poke.my_pic_src;
					name = fav_poke.my_pic_name;
					dex  = 'My Pic';
					img  = fav_poke.my_pic_src;
					update_fav_poke();
				} //with
		} //if

		// refresh the view windows if needed
		if (document.getElementById('window_drag_view_decklist').style.display != 'none')
			document.getElementById('window_drag_body_view_decklist').innerHTML = view_decklist_html(false);
		if (document.getElementById('window_drag_view_errors').style.display != 'none')
			document.getElementById('window_drag_body_view_errors').innerHTML = view_errors_html();
		if (document.getElementById('window_drag_view_cards').style.display != 'none')
			document.getElementById('window_drag_body_view_cards').innerHTML = view_cards_html();
		if (document.getElementById('window_drag_view_text').style.display != 'none')
			document.getElementById('window_drag_body_view_text').innerHTML = view_text_html();

	} //with

} //function

//--------------------------------------------------------------------------------
// set the options in the div

function set_options(hide_flag) {

	with (decklist_options) {

		document.getElementById('min_num_chars').value          = suggestions.min_num_chars;
		document.getElementById('match_start_only').checked     = suggestions.match_start_only;
		document.getElementById('most_recent_only').checked     = suggestions.most_recent_only;
		document.getElementById('show_card_images').checked     = suggestions.show_card_images;
		document.getElementById('show_set_images').checked      = suggestions.show_set_images;
		document.getElementById('include_basic_energy').checked = suggestions.include_basic_energy;
		document.getElementById('show_set_info').checked        = text_view.show_set_info;
		document.getElementById('fan_cards').value              = cards_view.fan_cards;
		document.getElementById('fan_size').value               = cards_view.fan_size;
		document.getElementById('fan_dir').checked              = cards_view.fan_dir == 1;
		document.getElementById('show_decklist_check').checked  = print_preview.show_decklist_check;
		document.getElementById('merge_duplicates').checked     = print_preview.merge_duplicates;
		document.getElementById('POP_style').checked            = print_preview.POP_style;
		document.getElementById('show_set_legend').checked      = print_preview.show_set_legend;
		document.getElementById('include_old_legend').checked   = print_preview.include_old_legend;
		document.getElementById('fav_poke_dex').value           = fav_poke.pokedex;
		document.getElementById('fav_poke_my_pic_src').value    = fav_poke.my_pic_src;
		document.getElementById('fav_poke_my_pic_name').value   = fav_poke.my_pic_name;
		document.getElementById('show_unowns').checked          = other.show_unowns;
		document.getElementById('mouse_pet').value              = other.mouse_pet;

	} //with

	if (hide_flag)  hide_options();

} //function

//--------------------------------------------------------------------------------
// show the given options window

function show_options_window (id) {

	document.getElementById ('opt_div_' + id).style.display = 'inline';
	document.getElementById ('opt_a_'   + id).innerHTML = '\u25B2';
	document.getElementById ('opt_tr_'  + id).style.fontWeight = 'bold';

} //function

//--------------------------------------------------------------------------------
// hide the given options window

function hide_options_window (id) {

	document.getElementById ('opt_div_' + id).style.display = 'none';
	document.getElementById ('opt_a_'   + id).innerHTML = '\u25BC';
	document.getElementById ('opt_tr_'  + id).style.fontWeight = 'normal';

} //function

//--------------------------------------------------------------------------------
// toggle the given options window

function toggle_options_window (id) {

	if (document.getElementById ('opt_div_' + id).style.display == 'none')
		show_options_window (id);
	else
		hide_options_window (id);

} //function

//--------------------------------------------------------------------------------
// show all the options window

function show_all_options_windows() {

	show_options_window ('opt_view_decklist');
	show_options_window ('opt_view_cards');
	show_options_window ('opt_view_text');
	show_options_window ('opt_fav_poke');
	show_options_window ('opt_auto_sugg');
	show_options_window ('opt_other');

} //function

//--------------------------------------------------------------------------------
// hide all the options window

function hide_all_options_windows() {

	hide_options_window ('opt_view_decklist');
	hide_options_window ('opt_view_cards');
	hide_options_window ('opt_view_text');
	hide_options_window ('opt_fav_poke');
	hide_options_window ('opt_auto_sugg');
	hide_options_window ('opt_other');

} //function

//--------------------------------------------------------------------------------
// create the options window html
function options_window (title, id, options) {

	var html = '';

	// set different width for IE table
	var sWidth = (is_msie ? (parseInt(document.getElementById('decklist_options').style.width)-6)+'px' : '100%');

	// start the window table
	html += '<table cellspacing="0" cellpadding="3" style="width:' + sWidth + '; font-size:12px; border:1px solid black; margin-top:3px;">';

	// create the window top
	html +=
		'<tr id="opt_tr_' + id + '" style="background-color:#FFFFCC; font-weight:normal;"><td>' +
			'<a id="opt_a_' + id + '" href="javascript:toggle_options_window(\'' + id + '\')"' +
			' style="text-decoration:none; color:blue; border:1px solid transparent;"' +
			' onmouseover="this.style.borderColor=\'black\'" onmouseout="this.style.borderColor=\'transparent\'">' +
			'\u25BC</a>&nbsp;' +
			title + '</td></tr>';

	// start the window body
	html += '<tr><td style="padding:0px; background-color:white; border-top:1px solid #CCCCCC;">' +
		'<div id="opt_div_' + id + '" style="display:none;">';

	for (var i=0;  i<options.length;  i++)
		html += '<span style="display:block; padding:3px;">' + options[i] + '</span>';

	// close the window body/table
	html += '</div></td></tr></table>';

	return (html);

} //function

//--------------------------------------------------------------------------------
// initial the options div

function init_options() {

	// get the options div and decklist objects
	var options_div = document.getElementById ('decklist_options');
	var objDecklist = document.getElementById ('pokemon_deck_list_table');

	// initialize the div styles
	with (options_div.style) {

		display  = 'none';
		iBorder  = 4;
		border   = iBorder + 'px ridge gray';
		position = 'absolute';
		width    = '396px';

		backgroundColor = 'white';

	} //with

	var html = '';

	// start the div inner html by creating title and the upper-right close button
	html +=
		'<table cellspacing="0" cellpadding="5" style="width:100%; border-bottom:1px solid #CCCCCC; font-size:14px; background-color:yellow;"><tr>' +
		'<th id="options_drag_handle" align="left" style="width:99%;" onmouseover="this.style.cursor=\'move\'" onmouseout="this.style.cursor=\'default\'">' +
			(winpic_html ? winpic_html : '<img src="' + vdb_images_loc + 'pokeball.gif" />') + ' Options</th>' +
		'<td align="right"><input type="button" value="X" id="options_drag_x" onclick="javascript:set_options(true);"' +
			' style="background-color:red; color:white; width:30px; font-family:verdana,arial,helvetica; font-size:10px; font-weight:bold; text-align:center;" /></td>' +
		'</tr></table>';

	// create the button attributes
	var btn_attr =
		' style="background-color:lightblue; font-family:verdana,arial,helvetica; font-size:10px; margin:0px 3px 0px 3px;"';

	// create the Expand, Collapse, OK, Cancel, Apply buttons
	html +=
		'<table cellspacing="0" cellpadding="5" style="width:100%; border-bottom:1px solid gray; font-size:10px; background-color:#FFFFCC;"><tr>' +
		'<td align="left">' +
			'<input type="button" value="Expand" onclick="javascript:show_all_options_windows();"' + btn_attr + ' />' +
			'<input type="button" value="Collapse" onclick="javascript:hide_all_options_windows();"' + btn_attr + ' />' +
		'</td>' +
		'<td align="right">' +
			'<input type="button" value="OK" onclick="javascript:get_options(true, true);"' + btn_attr + ' />' +
			'<input type="button" value="Cancel" onclick="javascript:set_options(true);"' + btn_attr + ' />' +
			'<input type="button" value="Apply" onclick="javascript:get_options(true, false);"' + btn_attr + ' />' +
		'</td>' +
		'</tr></table>';

	// start the div for all the options windows
	html += '<div style="padding:0px 3px 3px 3px;' + (is_msie ? ' width:100%;' : '') + '">';

	// create the view -> deck list options window
	html += options_window ('View - Deck List', 'opt_view_decklist',
		[
		'<input type="checkbox" id="show_decklist_check" style="margin-left:10px" ' +
			(decklist_options.print_preview.show_decklist_check ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the Deck List Check listing',
		'<input type="checkbox" id="merge_duplicates" style="margin-left:10px" ' +
			(decklist_options.print_preview.merge_duplicates ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Merge duplicate cards into one line',
		'<input type="checkbox" id="POP_style" style="margin-left:10px" ' +
			(decklist_options.print_preview.POP_style ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Mimic the POP deck list styling',
		'<input type="checkbox" id="show_set_legend" style="margin-left:10px" ' +
			(decklist_options.print_preview.show_set_legend ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the set symbols legend',
		'<input type="checkbox" id="include_old_legend" style="margin-left:50px" ' +
			(decklist_options.print_preview.include_old_legend ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Include old sets'
		]);

	// create the code when the fan default button is clicked
	var fan_default_code = 'javascript:document.getElementById(\'fan_cards\').value=\'fan_vertical_if\';' +
		'document.getElementById(\'fan_size\').value=\'10\';document.getElementById(\'fan_dir\').checked=false;';

	// create the view -> cards options window
	html += options_window ('View - Cards', 'opt_view_cards',
		[
		'<select id="fan_cards" style="margin-left:10px;">' +
			'<option value="none">(none)</option>' +
			'<option value="fan_horizontal">Fan horizontal</option>' +
			'<option value="fan_vertical">Fan vertical</option>' +
			'<option value="fan_vertical_if" selected="selected">Fan vertical, horizontal if > 4</option>' +
			'<option value="fan_diagonal">Fan diagonal</option>' +
			'<option value="fan_diagonal_if">Fan diagonal, horizontal if > 4</option>' +
			'<option value="fan_diagonal_up">Fan diagonal up</option>' +
			'<option value="fan_diagonal_up_if">Fan diagonal up, horizontal if > 4</option>' +
			'<option value="side_by_side">Side-by-side</option>' +
			'<option value="side_by_side_if">Side-by-side, fan if > 4</option>' +
			'</select>' +
			'&nbsp; Fan cards',
		'<select id="fan_size" style="margin-left:10px;">' +
			'<option value="2">Very small</option>' +
			'<option value="5">Small</option>' +
			'<option value="10" selected="selected">Medium</option>' +
			'<option value="15">Large</option>' +
			'<option value="25">Very large</option>' +
			'</select>' +
			'&nbsp; Fan size',
		'<input type="checkbox" id="fan_dir" style="margin-left:10px;" ' +
			(decklist_options.cards_view.fan_dir==1 ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Reverse fan direction',
		'<input type="button" id="fan_default" value="Default" style="margin-left:20px;" onclick="' + fan_default_code + '" />'
		]);

	// create the view -> text options window
	html += options_window ('View - Text', 'opt_view_text',
		[
		'<input type="checkbox" id="show_set_info" style="margin-left:10px" ' +
			(decklist_options.text_view.show_set_info ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the set and card number information'
		]);

	// create the favorite pokemon options window
	var options_html = '';
	for (type in pokedex)
		options_html +=
			'<option value="' + type + (type=='default_sugimori' ? '" selected="selected">' : '">') +
			pokedex[type].name +
			'</option>';
	html += options_window ('Favorite Pokemon', 'opt_fav_poke',
		[
		'<select id="fav_poke_dex" style="margin-left:10px">' + options_html + '</select>' +
			'&nbsp; Pokedex',
		'<input type="text" id="fav_poke_my_pic_src" style="margin-left:10px; width:250px;" \>&nbsp; My Pic URL',
		'<input type="text" id="fav_poke_my_pic_name" style="margin-left:10px; width:250px;" \>&nbsp; My Pic Name'
		]);

	// create the suggestions options window
	html += options_window ('Auto-Suggestion', 'opt_auto_sugg',
		[
		'<input type="checkbox" id="most_recent_only" style="margin-left:10px" ' +
			(decklist_options.suggestions.most_recent_only ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Most recent trainer/energy versions only',
		'<input type="checkbox" id="match_start_only" style="margin-left:10px" ' +
			(decklist_options.suggestions.match_start_only ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Match only the beginning of the card name',
		'<select id="min_num_chars" style="margin-left:10px">' +
			'<option value="1">1</option>' +
			'<option value="2" selected="selected">2</option>' +
			'<option value="3">3</option>' +
			'</select>' +
			'&nbsp; Minimum characters to show suggestions',
		'<input type="checkbox" id="show_card_images" style="margin-left:10px" ' +
			(decklist_options.suggestions.show_card_images ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the card thumbnail images',
		'<input type="checkbox" id="show_set_images" style="margin-left:10px" ' +
			(decklist_options.suggestions.show_set_images ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the card rarity and set symbols',
		'<input type="checkbox" id="include_basic_energy" style="margin-left:10px" ' +
			(decklist_options.suggestions.include_basic_energy ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Include the basic energy cards from all sets'
		]);

	// create the other options window
	html += options_window ('Other Options', 'opt_other',
		[
		'<input type="checkbox" id="show_unowns" style="margin-left:10px" ' +
			(decklist_options.other.show_unowns ? 'checked="checked"' : '') + ' />' +
			'&nbsp;Show the player name using Unown Pokemon',
		'<select id="mouse_pet" style="margin-left:10px">' +
			'<option value="none" selected="selected">(none)</option>' +
			'<option value="025">Pikachu</option>' +
			'<option value="185">Sudowoodo</option>' +
			'<option value="282">Gardevoir</option>' +
			'<option value="492">Shaymin</option>' +
			'</select>' +
			'&nbsp; Mouse Pet'
		]);

	// end the div for all the options windows
	html += '</div>';

	// create the hacker div
	html +=
		'<div id="hack_fav_poke" style="position:absolute; left:2px; top:2px; width:20px; height:20px;"' +
			' ondblclick="javascript:if(this.style.backgroundImage!=\'none\')hacker()"' +
			' onmouseover="javascript:if(Math.random()<0.1)this.style.backgroundImage=\'url(' + catchme_images_loc + '025.gif)\';this.style.cursor=\'help\';"' +
			' onmouseout="javascript:this.style.backgroundImage=\'none\';this.style.cursor=\'default\';">' +
			'</div>';

	options_div.innerHTML = html;

} //function

//--------------------------------------------------------------------------------
// hacks

function hacker() {

	var code = prompt ('Pika! (Caught me!)  Name your prize.', '');

	if (!code)  return;

	switch (code.replace(/ /g,'').toLowerCase()) {

		case 'favoritepokemon':

			var hack_img = prompt ('Favorite Pokemon Picture (full URL including http://):', '');
			if (hack_img)
				with (decklists[deck_num-1].data.fav_poke) {
					name = prompt ('Give your secret image a name:', 'Secret');
					document.getElementById('fav_poke_pic').src = hack_img;
					dex  = 'Secret';
					img  = hack_img;
					update_fav_poke();
				} //with
			break;

		default:

			alert ('Sorry! I have nothing for you.');

	} //switch

} //function

//--------------------------------------------------------------------------------
// convert the given string to unown images and put into div with given ID
function uStr (str, ID) {

	var path = unown_images_loc;
	var div  = '<div style="display:inline; white-space:nowrap; font-size:10px;">';
	var span = '<span style="vertical-align:middle;">';

	str = str.toLowerCase();
	var uHtml = div;

	for (var i=0;  i<str.length;  i++) {

		var ltr = str.charAt(i);
		uHtml += span;

		if      (ltr >= 'a' &&
		         ltr <= 'z')  uHtml += '<img src="' + path + ltr + '.gif" style="margin:1px;" />';
		else if (ltr == '!')  uHtml += '<img src="' + path +     'ep.gif" style="margin:1px;" />';
		else if (ltr == '?')  uHtml += '<img src="' + path +     'qm.gif" style="margin:1px;" />';
		else if (ltr == ' ')  uHtml += '&nbsp;&nbsp;&nbsp;</div> ' + div;
		else                  uHtml += ltr;

		uHtml += '</span>';

	} //for

	uHtml += '</div>';

	document.getElementById(ID).innerHTML = uHtml;

} //function

//--------------------------------------------------------------------------------
/*
Simple Image Trail script- By JavaScriptKit.com
Visit http://www.javascriptkit.com for this script and more
This notice must stay intact
*/

// image path, plus width and height
var mouse_pet = {"up_img":"", "dn_img":"", "width":80, "height":80};
set_pet();

// image x,y offsets from cursor position in pixels. Enter 0,0 for no offset
var offset_from_mouse = [2, -10];

// duration in seconds image should remain visible. 0 for always.
var display_duration = 0;

// create the image div
if (document.getElementById || document.all)
	document.write (
		'<div id="div_pet" style="position:absolute; visibility:hidden; left:0px; top:0px; width:1px; height:1px">' +
		'<img id="img_pet" src="' + mouse_pet.up_img +
			'" width="' + mouse_pet.width + 'px" height="' + mouse_pet.height + 'px" style="border:0px;" />' +
		'</div>');

show_pet();

if (display_duration > 0)
	setTimeout ("hide_pet()", display_duration * 1000)

function set_pet () {
	if (decklist_options.other.mouse_pet == 'none')  return;
	mouse_pet.up_img = cursor_images_loc + decklist_options.other.mouse_pet + '-up.png';
	mouse_pet.dn_img = cursor_images_loc + decklist_options.other.mouse_pet + '-dn.png';
	document.getElementById('img_pet').src = mouse_pet.up_img;
} //function

function true_body() {
	return (!window.opera && document.compatMode && document.compatMode != "BackCompat")
		? document.documentElement
		: document.body;
} //function

function mouse_follow (e) {

	var xcoord = offset_from_mouse[0];
	var ycoord = offset_from_mouse[1];

	var body = true_body();
	var pet  = get_pet_obj().style;

	if (typeof e != "undefined") {
		xcoord += e.pageX;
		ycoord += e.pageY;
	} //if
	else if (typeof window.event !="undefined") {
		xcoord += body.scrollLeft + event.clientX;
		ycoord += body.scrollTop  + event.clientY;
	} //else if

	var doc_width  = document.all
		? body.scrollLeft + body.clientWidth
		: pageXOffset + window.innerWidth-15;
	var doc_height = document.all
		? Math.max (body.scrollHeight, true_body().clientHeight)
		: Math.max (document.body.offsetHeight, window.innerHeight);

	if (xcoord + mouse_pet.width + 3 > doc_width || ycoord + mouse_pet.height > doc_height)
		pet.display = "none";
	else 
		pet.display = "";

	pet.left   = xcoord + "px";
	pet.top    = ycoord + "px";
	pet.zIndex = 9999;

} //function

function mouse_down()  {
	document.getElementById ('img_pet').src = mouse_pet.dn_img;
	setTimeout ("document.getElementById ('img_pet').src = mouse_pet.up_img;", 500);
} //function - event handler
//function mouse_down()  { document.getElementById ('img_pet').src = mouse_pet.dn_img; }
//function mouse_up  ()  { document.getElementById ('img_pet').src = mouse_pet.up_img; }

function get_pet_obj() {
	if (document.getElementById)
		return document.getElementById ("div_pet");
	else if (document.all)
		return document.all.div_pet;
} //function

function show_pet() {
	if (decklist_options.other.mouse_pet == 'none')  return;
	get_pet_obj().style.visibility = "visible";
	document.onmousemove = mouse_follow;
	document.onmousedown = mouse_down;
//	document.onmouseup   = mouse_up;
} //function

function hide_pet() {
	get_pet_obj().style.visibility = "hidden";
	document.onmousemove = "";
	document.onmousedown = "";
	document.onmouseup   = "";
} //function

//--------------------------------------------------------------------------------
// show the help info

function help_info() {

	// open the window
	var obj_window = window.open (base_loc + 'help.htm','_blank',
		'top=10, left=10, height=640, width=800, resizable=yes, scrollbars=yes, ' +
		'location=no, titlebar=yes, toolbar=yes, menubar=yes');
	obj_window.focus();
	var obj_top_div = obj_window.document.getElementById ('top_div_html');
	if (obj_top_div)  obj_top_div.style.display = 'none';

} //function

//--------------------------------------------------------------------------------
// show the help about splash

function help_about() {

	var html =
		'SteveP\'s Pokemon Deck List Completion Program\n\n' +
		'Version ' + version + '\n\n' +
		'Developed by Steve Perucca\n\n\n\n' +
		'Display HELP information?';
	
	if (confirm (html))  help_info();

} //function

//--------------------------------------------------------------------------------
// create the menus

// create the menu styles
var css =
'<style type="text/css">' +

'.horizontalcssmenu ul{' +
'margin: 0;' +
'padding: 0;' +
'list-style-type: none;' +
'}' +

'/*Top level list items*/' +
'.horizontalcssmenu ul li{' +
'position: relative;' +
'display: inline;' +
'float: left;' +
'}' +

'/*Top level menu link items style*/' +
'.horizontalcssmenu ul li a{' +
'display: block;' +
'width: 80px;' +
'padding: 2px 8px;' +
'border: 1px solid #202020;' +
'border-left-width: 0;' +
'text-decoration: none;' +
'background: url(' + menu_images_loc + 'menubg.gif) center center repeat-x;' +
'color: black;' +
'font: bold 13px Tahoma;' +
'text-align:left;' +
'white-space: nowrap;' +
'}' +
	
'/*Sub level menu*/' +
'.horizontalcssmenu ul li ul{' +
'margin-left: -1px;' +
'top: 0;' +
'border-top: 1px solid #202020;' +
'position: absolute;' +
'display: block;' +
'visibility: hidden;' +
'z-index: 98;' +
'}' +

'/*Sub level menu list items*/' +
'.horizontalcssmenu ul li ul li{' +
'display: inline;' +
'float: none;' +
'}' +

'/* Sub level menu links style */' +
'.horizontalcssmenu ul li ul li a{' +
'width: 120px;' +
'font-weight: normal;' +
'padding: 2px 5px;' +
'background: #e3f1bd;' +
'border-width: 0 1px 1px 1px;' +
'white-space: nowrap;' +
'}' +

'.horizontalcssmenu ul li a:hover{' +
'background: url(' + menu_images_loc + 'menubgover.gif) center center repeat-x;' +
'}' +

'.horizontalcssmenu ul li ul li a:hover{' +
'background: #cde686;' +
'}' +

'.horizontalcssmenu .arrowdiv{' +
'position: absolute;' +
'right: 0;' +
'background: transparent url(' + menu_images_loc + 'menuarrow.gif) no-repeat center left;' +
'}' +

'* html p#iepara{ /*For a paragraph (if any) that immediately follows menu, add 1em top spacing between the two in IE*/' +
'padding-top: 1em;' +
'}' +
	
'/* Holly Hack for IE \*/' +
'* html .horizontalcssmenu ul li { float: left; height: 1%; }' +
'* html .horizontalcssmenu ul li a { height: 1%; }' +
'/* End */' +

'</style>';

// load the menu styles
document.write (css);

var cssmenuids = ["main_css_menu"];  //Enter id(s) of CSS Horizontal UL menus, separated by commas
var csssubmenuoffset = -1;      //Offset of submenus from main menu. Default is 0 pixels.
//Safari for MAC fix
if (is_safari && BrowserDetect.OS == 'Mac') csssubmenuoffset = -3;

// create the menu - must be visible when running this
function createcssmenu2() {

	for (var i=0;  i<cssmenuids.length;  i++) {
	var ultags = document.getElementById(cssmenuids[i]).getElementsByTagName("ul")
	for (var t=0;  t<ultags.length;  t++) {
		ultags[t].style.top = ultags[t].parentNode.offsetHeight+csssubmenuoffset + "px";
		var spanref = document.createElement("span");
		spanref.className = "arrowdiv";
		spanref.innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;";
		ultags[t].parentNode.getElementsByTagName("a")[0].appendChild(spanref);

		ultags[t].parentNode.onmouseover = function() {
			this.style.zIndex=window_drag_index+1;
			this.getElementsByTagName("ul")[0].style.visibility = "visible";
			this.getElementsByTagName("ul")[0].style.zIndex = 0;
		} //function - event
		ultags[t].parentNode.onmouseout = function() {
			this.style.zIndex=0;
			this.getElementsByTagName("ul")[0].style.visibility = "hidden";
			this.getElementsByTagName("ul")[0].style.zIndex = window_drag_index+1;
		} //function - event

	} //for - inner
	} //for - outer

} //function

// load the menu in body-onload
if (window.addEventListener)
	window.addEventListener("load", createcssmenu2, false)
else if (window.attachEvent)
	window.attachEvent("onload", createcssmenu2)
else {}

// do nothing top menu items
function do_nothing() {};

// hide the given menu item (mimic onmouseout)
function hide_menu_item (menu_id, ul_num) {

	var item = document.getElementById(menu_id).getElementsByTagName("ul")[ul_num].parentNode;
	item.style.zIndex = 0;
	item.getElementsByTagName("ul")[0].style.visibility = "hidden";
	item.getElementsByTagName("ul")[0].style.zIndex = 98;

} //function

// create the menu
function create_css_menu () {

	document.write (
	'<table id="cssmenu_table" align="center" style="border-collapse:collapse; padding:0px;"><tr>' +
	'<td><div class="horizontalcssmenu">' +
		'<ul id="main_css_menu">' +
		'<li style="border-left: 1px solid #202020;"><a href="javascript:do_nothing();" tabindex="-1">File</a>' +
			'<ul>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',0);save_deck();">Save</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',0);view_decklist_print(true);">Print</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',0);view_decklist_print(false);">Print Preview</a></li>' +
			'</ul>' +
		'</li>' +
		'<li><a href="javascript:do_nothing();" tabindex="-1">Edit</a>' +
			'<ul>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',1);reset_form();">Clear</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',1);add_deck();">Add</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',1);copy_deck();">Copy</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',1);del_deck(deck_num);">Delete</a></li>' +
			'<li><a href="javascript:moveUp_deck(deck_num);">Move &uarr;</a></li>' +
			'<li><a href="javascript:moveDown_deck(deck_num);">Move &darr;</a></li>' +
			'</ul>' +
		'</li>' +
		'<li><a href="javascript:do_nothing();" tabindex="-1">View</a>' +
			'<ul>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);view_decklist();">Deck List</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);view_errors();">Errors</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);view_cards();">Cards</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);view_text();">Text</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);xml_view();">XML</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);rollup_expand_all();">Expand</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',2);rollup_collapse_all();">Collapse</a></li>' +
			'</ul>' +
		'</li>' +
		'<li><a href="javascript:do_nothing();" tabindex="-1">Tools</a>' +
			'<ul>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',3);show_options();">Options</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',3);show_vdb();">Visual Deck Builder</a></li>' +
			'</ul>' +
		'</li>' +
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
(is_pokebeach ? '' :
		'<li><a href="javascript:do_nothing()" tabindex="-1">Sites</a>' +
			'<ul>' +
			'<li><a target="_blank" href="http://www.pokemon.com/us/organized-play/">Pokemon OP</a></li>' +
			'<li><a target="_blank" href="http://www.pokebeach.com">PokeBeach</a></li>' +
			'<li><a target="_blank" href="http://www.pokegym.net">PokeGym</a></li>' +
			'<li><a target="_blank" href="http://www.serebii.net">Serebii</a></li>' +
			'</ul>' +
		'</li>' +
'') +
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
		'<li><a href="javascript:do_nothing()" tabindex="-1">Help</a>' +
			'<ul>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',(is_pokebeach?4:5));help_info();">Information</a></li>' +
			'<li><a href="javascript:hide_menu_item(\'main_css_menu\',(is_pokebeach?4:5));help_about();">About</a></li>' +
			'</ul>' +
		'</li>' +
		'</ul>' +
	'</div></td>' +
	'</tr></table>');

} //function

//--------------------------------------------------------------------------------
// create the navigation buttons

// pre-fetch menu images
var img_first_over = new Image();  img_first_over.src = menu_images_loc + 'first-over.gif';
var img_first_down = new Image();  img_first_down.src = menu_images_loc + 'first-down.gif';
var img_prev_over  = new Image();  img_prev_over.src  = menu_images_loc + 'prev-over.gif';
var img_prev_down  = new Image();  img_prev_down.src  = menu_images_loc + 'prev-down.gif';
var img_next_over  = new Image();  img_next_over.src  = menu_images_loc + 'next-over.gif';
var img_next_down  = new Image();  img_next_down.src  = menu_images_loc + 'next-down.gif';
var img_last_over  = new Image();  img_last_over.src  = menu_images_loc + 'last-over.gif';
var img_last_down  = new Image();  img_last_down.src  = menu_images_loc + 'last-down.gif';

function create_menu () {

	// create the menu div
	document.write ('<div id="menu_div" style="text-align:center; font-size:12px; padding:5px; background-color:#FFFFCC;">');

	// create the menu text/links
	create_css_menu();

	// put the options div here and initialize it *** moved to body-level outside form ***
	init_options();

	// create the nav image for mouse hovering over the navigation pics
	function create_nav (type, jump) {

		return ('&nbsp;<a id="nav_' + type + '" tabindex="-1" style="border:0px" href="javascript:get_deck(' + jump + ')">' +
			'<img src="' + menu_images_loc + type + '-norm.gif" style="border:0px"' +
			' onmouseover="javascript:this.src=\'' + menu_images_loc + type + '-over.gif\'"' +
			' onmousedown="javascript:this.src=\'' + menu_images_loc + type + '-down.gif\'"' +
			' onmouseup  ="javascript:this.src=\'' + menu_images_loc + type + '-over.gif\'"' +
			' onmouseout ="javascript:this.src=\'' + menu_images_loc + type + '-norm.gif\'" /></a>&nbsp;');

	} //function

	// start the decklist navigation
	document.write ('<table align="center" cellspacing="0" cellpadding="0" style="font-size:12px; margin-top:5px; width:90%;"><tr>');

	// create the decklist position counter
	document.write (
		'<td align="left" style="white-space:nowrap; width:20%;">' +
			'Deck&nbsp;<span id="deck_counter">' + deck_num + '&nbsp;/&nbsp;' + decklists.length + '</span></td>');

	// create the decklist navigation
	document.write ('<td align="center" style="white-space:nowrap; width:20%;"><span id="nav_buttons">' +
		create_nav ('first', '1') +
		create_nav ('prev',  'deck_num-1') +
		create_nav ('next',  'deck_num+1') +
		create_nav ('last',  'decklists.length') +
		'</span></td>');

	// create the decklist navigation direct jumps
	document.write (
		'<td align="right" style="width:60%;"><select id="deck_list_select" style="width:400px;"' +
			' onchange="get_deck(this.selectedIndex+1)"' +
			' onkeydown="if (event.keyCode == 13) {event.keyCode = 9}">');
	for (var i=0;  i<decklists.length;  i++)
		document.write ('<option value="">' + get_jump_text (decklists[i].cards.deck_name) + '</option>');
	document.write ('</select></td>');

	// close the navigation
	document.write ('</tr></table>');

	// close the menu div
	document.write ('</div>');

} //function

//--------------------------------------------------------------------------------
// drag control code (copied from internet)
// used in VDB also

function hookEvent(element, eventName, callback)
{
  if(typeof(element) == "string")
    element = document.getElementById(element);
  if(element == null)
    return;
  if(element.addEventListener)
  {
    element.addEventListener(eventName, callback, false);
  }
  else if(element.attachEvent)
    element.attachEvent("on" + eventName, callback);
}

function unhookEvent(element, eventName, callback)
{
  if(typeof(element) == "string")
    element = document.getElementById(element);
  if(element == null)
    return;
  if(element.removeEventListener)
    element.removeEventListener(eventName, callback, false);
  else if(element.detachEvent)
    element.detachEvent("on" + eventName, callback);
}

function cancelEvent(e)
{
  e = e ? e : window.event;
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
}

function Position(x, y)
{
  this.X = x;
  this.Y = y;
  
  this.Add = function(val)
  {
    var newPos = new Position(this.X, this.Y);
    if(val != null)
    {
      if(!isNaN(val.X))
        newPos.X += val.X;
      if(!isNaN(val.Y))
        newPos.Y += val.Y
    }
    return newPos;
  }
  
  this.Subtract = function(val)
  {
    var newPos = new Position(this.X, this.Y);
    if(val != null)
    {
      if(!isNaN(val.X))
        newPos.X -= val.X;
      if(!isNaN(val.Y))
        newPos.Y -= val.Y
    }
    return newPos;
  }
  
  this.Min = function(val)
  {
    var newPos = new Position(this.X, this.Y)
    if(val == null)
      return newPos;
    
    if(!isNaN(val.X) && this.X > val.X)
      newPos.X = val.X;
    if(!isNaN(val.Y) && this.Y > val.Y)
      newPos.Y = val.Y;
    
    return newPos;  
  }
  
  this.Max = function(val)
  {
    var newPos = new Position(this.X, this.Y)
    if(val == null)
      return newPos;
    
    if(!isNaN(val.X) && this.X < val.X)
      newPos.X = val.X;
    if(!isNaN(val.Y) && this.Y < val.Y)
      newPos.Y = val.Y;
    
    return newPos;  
  }  
  
  this.Bound = function(lower, upper)
  {
    var newPos = this.Max(lower);
    return newPos.Min(upper);
  }
  
  this.Check = function()
  {
    var newPos = new Position(this.X, this.Y);
    if(isNaN(newPos.X))
      newPos.X = 0;
    if(isNaN(newPos.Y))
      newPos.Y = 0;
    return newPos;
  }
  
  this.Apply = function(element)
  {
    if(typeof(element) == "string")
      element = document.getElementById(element);
    if(element == null)
      return;
    if(!isNaN(this.X))
      element.style.left = this.X + 'px';
    if(!isNaN(this.Y))
      element.style.top = this.Y + 'px';  
  }
}

function absoluteCursorPostion(eventObj)
{
  eventObj = eventObj ? eventObj : window.event;
  
  if(isNaN(window.scrollX))
    return new Position(eventObj.clientX + document.documentElement.scrollLeft + document.body.scrollLeft, 
      eventObj.clientY + document.documentElement.scrollTop + document.body.scrollTop);
  else
    return new Position(eventObj.clientX + window.scrollX, eventObj.clientY + window.scrollY);
}

function dragObject(element, attachElement, lowerBound, upperBound, startCallback, moveCallback, endCallback, attachLater)
{
  if(typeof(element) == "string")
    element = document.getElementById(element);
  if(element == null)
      return;
  
  this.element = element;

  if(lowerBound != null && upperBound != null)
  {
    var temp = lowerBound.Min(upperBound);
    upperBound = lowerBound.Max(upperBound);
    lowerBound = temp;
  }

  var cursorStartPos = null;
  var elementStartPos = null;
  var dragging = false;
  var listening = false;
  var disposed = false;
  
  function dragStart(eventObj)
  { 
    if(dragging || !listening || disposed) return;
    dragging = true;
    
    if(startCallback != null)
      startCallback(eventObj, element);
    
    cursorStartPos = absoluteCursorPostion(eventObj);
    
    elementStartPos = new Position(parseInt(element.style.left), parseInt(element.style.top));
   
    elementStartPos = elementStartPos.Check();
    
    hookEvent(document, "mousemove", dragGo);
    hookEvent(document, "mouseup", dragStopHook);
    
    return cancelEvent(eventObj);
  }
  
  function dragGo(eventObj)
  {
    if(!dragging || disposed) return;
    
    var newPos = absoluteCursorPostion(eventObj);
    newPos = newPos.Add(elementStartPos).Subtract(cursorStartPos);
    newPos = newPos.Bound(lowerBound, upperBound)
    newPos.Apply(element);
    if(moveCallback != null)
      moveCallback(newPos, element);
        
    return cancelEvent(eventObj); 
  }
  
  function dragStopHook(eventObj)
  {
    dragStop();
    return cancelEvent(eventObj);
  }
  
  function dragStop()
  {
    if(!dragging || disposed) return;
    unhookEvent(document, "mousemove", dragGo);
    unhookEvent(document, "mouseup", dragStopHook);
    cursorStartPos = null;
    elementStartPos = null;
    if(endCallback != null)
      endCallback(element);
    dragging = false;
  }
  
  this.Dispose = function()
  {
    if(disposed) return;
    this.StopListening(true);
    element = null;
    attachElement = null
    lowerBound = null;
    upperBound = null;
    startCallback = null;
    moveCallback = null
    endCallback = null;
    disposed = true;
  }
  
  this.StartListening = function()
  {
    if(listening || disposed) return;
    listening = true;
    hookEvent(attachElement, "mousedown", dragStart);
  }
  
  this.StopListening = function(stopCurrentDragging)
  {
    if(!listening || disposed) return;
    unhookEvent(attachElement, "mousedown", dragStart);
    listening = false;
    
    if(stopCurrentDragging && dragging)
      dragStop();
  }
  
  this.IsDragging = function(){ return dragging; }
  this.IsListening = function() { return listening; }
  this.IsDisposed = function() { return disposed; }
  
  if(typeof(attachElement) == "string")
    attachElement = document.getElementById(attachElement);
  if(attachElement == null)
    attachElement = element;
    
  if(!attachLater)
    this.StartListening();
}

//--------------------------------------------------------------------------------
// initialize the window drag objects

var window_drag = new Array();

window_drag["view_decklist"] = null;
window_drag["view_errors"  ] = null;
window_drag["view_cards"   ] = null;
window_drag["view_text"    ] = null;

//--------------------------------------------------------------------------------
// create the window drag divs

function create_window_drag_all() {

	// set the button styling
	button_style = ' style="' +
		' background-color:lightblue;' +
		' font-family:verdana,arial,helvetica;' +
		' font-size:10px;' +
		' margin:0px 3px 0px 3px;"';

	// create the print button html
	function button_print (id) {
		return '<input type="button" value="Print"' + button_style +
			' onclick="javascript:' + id + '_print(true);" />';
	} //function

	// create the options button html
	function button_options (id) {
		return '<input type="button" value="Options" id="button_opt_' + id + '"' + button_style +
			' onclick="javascript:show_options(\'opt_' + id + '\',\'window_drag_' + id + '\');" />';
	} //function

	// create the refresh button html
	function button_refresh (id) {
		return '<input type="button" value="Refresh"' + button_style +
			' onclick="javascript:document.getElementById(\'window_drag_body_' + id + '\').innerHTML=' + id + '_html();" />';
	} //function

	//create the buttons
	var buttons = new Array();
	buttons['view_decklist'] = button_print   ('view_decklist') + button_options ('view_decklist') + button_refresh ('view_decklist');
	buttons['view_errors'  ] =                                                                       button_refresh ('view_errors'  );
	buttons['view_cards'   ] = button_print   ('view_cards'   ) + button_options ('view_cards'   ) + button_refresh ('view_cards'   );
	buttons['view_text'    ] =                                    button_options ('view_text'    ) + button_refresh ('view_text'    );

	// create each "view" drag window
	create_window_drag ('view_decklist', 'Deck List', 696, buttons['view_decklist']);
	create_window_drag ('view_errors'  , 'Errors'   , 400, buttons['view_errors'  ]);
	create_window_drag ('view_cards'   , 'Cards'    , 708, buttons['view_cards'   ], '', [(58 + 6*65) + 'px', (58 + 10*65) + 'px']);
	create_window_drag ('view_text'    , 'Text'     , 400, buttons['view_text'    ]);

} //function

//--------------------------------------------------------------------------------
// create the window drag divs

function create_window_drag (id, title, width, buttons, body_html, shrink_sizes) {

	var html = '';

	var shrink_button = '';
	if (shrink_sizes) {

		var shrink_code = 'javascript:' +
			'if(this.value==\'<\')' +
				'{this.value=\'>\';document.getElementById(\'window_drag_' + id + '\').style.width=\'' + shrink_sizes[0] + '\';}' +
			'else' +
				'{this.value=\'<\';document.getElementById(\'window_drag_' + id + '\').style.width=\'' + shrink_sizes[1] + '\';}';

		shrink_button = '<input type="button" value="<" onclick="' + shrink_code + '"' +
			' style="background-color:gold; color:gray; width:30px; font-family:verdana,arial,helvetica; font-size:10px; font-weight:bold; text-align:center;" />';

	} //if

	// create the window, title, and drag handle
	html += '<div id="window_drag_' + id + '" style="display:none; position:absolute; background-color:white; width:' + width + 'px;">' +
		'<table align="center" cellpadding="5" cellspacing="0"' +
			' style="font-size:14px; font-family:verdana,arial,helvetica; border:4px ridge gray;">' +
		'<tr style="background:yellow;">' +
			'<td id="window_drag_handle_' + id + '" style="width:' + (width-(shrink_sizes?88:58)) + 'px; border-bottom:1px solid #CCCCCC;"' +
				' onmouseover="this.style.cursor=\'move\'" onmouseout="this.style.cursor=\'default\'">' +
				(winpic_html ? winpic_html : '<img src="' + vdb_images_loc + 'pokeball.gif" />') + ' <b>' + title + '</b></td>' +
			'<td align="right" style="border-bottom:1px solid #CCCCCC; white-space:nowrap;">' + shrink_button +
				'<input type="button" value="X" id="window_drag_x_' + id + '" onclick="javascript:hide_window_drag(\'' + id + '\');"' +
				' style="background-color:red; color:white; width:30px; font-family:verdana,arial,helvetica; font-size:10px; font-weight:bold; text-align:center;" /></td>' +
		'</tr>';

	// create the button bar if needed
	if (buttons)
		html += '<tr style="background-color:#FFFFCC;"><td colspan="2" style="border-bottom:1px solid gray;">' + buttons + '</td></tr>';

	// create the window body (set background to white in case main width is too short; otherwise, it's transparent)
	html += '<tr><td colspan="2" style="background-color:white;"><div id="window_drag_body_' + id + '">';
//	html += '<tr><td colspan="2"><div id="window_drag_body_' + id + '">';

	if (body_html)  html += body_html;
	html += '</div></td></tr>';

	// end the window drag table/div
	html += '</table></div>';

	document.write (html);

	// dispose the old drag object 
	if (window_drag[id])  window_drag[id].Dispose();

	// create the new drag object
	var div_window  = document.getElementById ('window_drag_'        + id);
	var drag_handle = document.getElementById ('window_drag_handle_' + id);
	window_drag[id] = new dragObject (div_window, drag_handle,
		new Position(0,0), null,  //position
		window_drag_start, window_drag_go, window_drag_stop);  //drag event handlers

} //function

//--------------------------------------------------------------------------------
// hide the window drag divs

function hide_window_drag (id) {

	document.getElementById('window_drag_' + id).style.display='none';

	// hide the auto-suggest if needed
	var id_parts = id.split('_');
	if (id_parts[0]=='vdb' && id_parts[1]=='add')
		for (type in vdb_objSugg)
			with (vdb_objSugg[type]) {
				hideDropDown(true);
				bHideGetOnBlur = true;
			} //with

} //function

//--------------------------------------------------------------------------------
// hide the all window drag divs

function hide_window_drag_all () {

	hide_window_drag ('view_decklist');
	hide_window_drag ('view_errors');
	hide_window_drag ('view_cards');
	hide_window_drag ('view_text');

} //function

//--------------------------------------------------------------------------------
// build/show the window drag divs

function show_window_drag (id, body_html) {

	var html = '';

	var id_parts = id.split('_');
	var is_vdb = (id_parts[0] == 'vdb');

	// set the "body" html of the window if needed
	if (body_html)  document.getElementById ('window_drag_body_' + id).innerHTML = body_html;

	// position and show the window
	var div_window = document.getElementById ('window_drag_' + id);

	if (is_vdb)  div_window.style.left = (vdb_getLeft(document.getElementById('vdb_main')) + (is_msie7 ? 11 : is_msie ? 1 : 3)) + 'px';
	else         div_window.style.left = (vdb_getLeft(document.getElementById('pokemon_deck_list_table')) + (is_msie7 ? 13 : 3)) + 'px';

	if (is_vdb)  div_window.style.top = (vdb_getTop(document.getElementById('vdb_main')) + (is_msie7 ? 73 : is_msie ? 59 : is_safari ? 62 : 59)) + 'px';
	else         div_window.style.top = (vdb_getTop(document.getElementById('pokemon_deck_list_table')) + (is_msie7 ? 75 : is_msie ? 61 : is_safari ? 62 : 59)) + 'px';

	window_drag_index = window_drag_index + 2;
	div_window.style.zIndex  = window_drag_index;
	div_window.style.display = 'inline';

	// change any other zIndexes needed
	if (is_vdb && (id_parts[1] == 'add'))
		for (type in vdb_objSugg)
			with (vdb_objSugg[type]) {
				objGet.style.zIndex = window_drag_index;
				objDropDown.style.zIndex =
				objHit.style.zIndex =
				objMore.style.zIndex =
				objAll.style.zIndex =
					window_drag_index + 1;
				bHideGetOnBlur = false;
				placeGetButton();
			} //with

	// set focus to the window
	var element = document.getElementById('window_drag_x_' + id);
	element.focus();

} //function

//--------------------------------------------------------------------------------
// window drag handlers

var window_drag_index = 1000;

function window_drag_start (e, obj_window) {

	window_drag_index = window_drag_index + 2;
	obj_window.style.zIndex = window_drag_index;

	// hide the auto-suggest if needed and adjust the z-indexes
	var id_parts = obj_window.id.split('_');
	if (id_parts[2]=='vdb' && id_parts[3]=='add')
		for (type in vdb_objSugg)
			with (vdb_objSugg[type]) {
				hideDropDown (true);
				objDropDown.style.zIndex =
				objHit.style.zIndex =
				objMore.style.zIndex =
				objAll.style.zIndex =
					window_drag_index + 1;
				objGet.style.zIndex = window_drag_index;
			} //with

	// set focus to the window
	var id = obj_window.id.replace ('window_drag_', '');
	var element = document.getElementById('window_drag_x_' + id);
	element.focus();

} //function

function window_drag_go (e, obj_window) {

} //function

function window_drag_stop (obj_window) {

	var id_parts = obj_window.id.split('_');
	if (id_parts[2]=='vdb' && id_parts[3]=='add')
		for (type in vdb_objSugg)
			vdb_objSugg[type].placeGetButton();

} //function

//--------------------------------------------------------------------------------
// show the visual deck build
function show_vdb () {

	if (typeof vdb_show == 'undefined')
		alert ('Visual Deck Builder is not available.');
	else {
		hide_window_drag_all();
		hide_options();
		set_options();
		vdb_show ('pokemon_deck_list_div');
	} //if

} //function

//------------------------------------------------------------------------------
// rollup button variables

var rollup_button_up = '\u25B2';
var rollup_button_dn = '\u25BC';

//------------------------------------------------------------------------------
// create the rollup window html

function rollup_html (id, header, footer, body,
	style_main, style_button, style_header, style_footer, style_body) {

	// initialize the parameters if not entered by caller
	style_main   = style_main   ? style_main   : '';
	style_button = style_button ? style_button : '';
	style_header = style_header ? style_header : '';
	style_footer = style_footer ? style_footer : '';
	style_body   = style_body   ? style_body   : '';

	var html  = '';

	var style_default = 
		'padding:3px;' +
		'font-size:14px;' +
		'font-weight:bold;' +
		'background-color:#FFFFCC;' +
		'white-space:nowrap;';

	// start the rollup window
	style_main = ' style="' +
		'border:1px solid black;' +
		style_main + '"';
	html += '<div id="rollup_' + id + '"' + style_main + '>';

	// start the rollup header
	style_header = ' style="' +
		style_default +
		'border-bottom:1px solid #CCCCCC;' +
		style_header + '"';
	html += '<div id="rollup_header_' + id + '"' + style_header + '>';

	// create the rollup button
	style_button = ' style="' +
		'text-decoration:none;' +
		'color:blue;' +
		'border:1px solid transparent;' +
		style_button + '"';
	html += '<a id="rollup_button_' + id + '"' + '"' + style_button +
		' href="javascript:rollup_toggle(\'' + id + '\')"' + 
		' onmouseover="this.style.borderColor=\'black\'"' +
		' onmouseout="this.style.borderColor=\'transparent\'">' +
		rollup_button_up + '</a>';

	// close the rollup header
	html += '&nbsp;&nbsp;' + header + '</div>';

	// create the rollup body
	style_body = ' style="' +
		'background-color:white;' +
		'padding:3px;' +
		style_body + '"';
	html += '<div id="rollup_body_' + id + '"' + style_body + '>' + body + '</div>';

	// start the rollup footer if specified
	if (footer) {
		style_footer = ' style="' +
			style_default +
			'border-top:1px solid #CCCCCC;' +
			style_footer + '"';
		html += '<div id="rollup_footer_' + id + '"' + style_footer + '>' + footer + '</div>';
	} //if

	// close the rollup window
	html += '</div>';

	return (html);

} //function

//------------------------------------------------------------------------------
// expand the given rollup window

function rollup_expand (id) {

	document.getElementById ('rollup_body_'   + id).style.display = 'block';
	document.getElementById ('rollup_button_' + id).innerHTML = rollup_button_up;

} //function

//------------------------------------------------------------------------------
// collapse the given rollup window

function rollup_collapse (id) {

	document.getElementById ('rollup_body_'   + id).style.display = 'none';
	document.getElementById ('rollup_button_' + id).innerHTML = rollup_button_dn;

} //function

//------------------------------------------------------------------------------
// toggle the given rollup window

function rollup_toggle (id) {

	if (document.getElementById ('rollup_body_' + id).style.display == 'none')
		rollup_expand (id);
	else
		rollup_collapse (id);

} //function

//--------------------------------------------------------------------------------
// expand all the rollup windows

function rollup_expand_all() {

	rollup_expand ('event');
	rollup_expand ('player');
	rollup_expand ('fav_poke');

	rollup_expand ('title');
	rollup_expand ('pokemon');
	rollup_expand ('trainer');
	rollup_expand ('energy');
	rollup_expand ('note');

} //function

//--------------------------------------------------------------------------------
// collapse all the rollup windows

function rollup_collapse_all() {

	rollup_collapse ('event');
	rollup_collapse ('player');
	rollup_collapse ('fav_poke');

	rollup_collapse ('title');
	rollup_collapse ('pokemon');
	rollup_collapse ('trainer');
	rollup_collapse ('energy');
	rollup_collapse ('note');

} //function

//--------------------------------------------------------------------------------
// create the event entry html

function create_event_entry () {

	var html = '';

	html += '<div id="event_div" style="text-align:center;">' +
		'<img id="event_logo" src="' + event_images_loc + aa_events[0].pic + '" />' +
		'<br /><br />' +
		'<select id="event_name" style="width:100%;"' +
			' onchange="update_logo(this)">';

	for (i=0;  i<aa_events.length;  i++)
		html += '<option value="' + aa_events[i].pic + '">' + aa_events[i].name + '</option>';

	html +='</select>' +
		'</div>';

	document.write (rollup_html ('event', 'Event Name', '', html));

} //function

//--------------------------------------------------------------------------------
// create the player info entry html

function create_player_entry () {

	var html = '';

	html +=
		'<div id="player_div" style="font-size:10px; font-weight:bold">' +
		'<br />' +
		'Name:<br /><input type="text" id="player_name" style="width:97%;" value=""' +
			' onchange="if (decklist_options.other.show_unowns) uStr (this.value, \'div_unowns\')" />' +
			'<div id="div_unowns" style="display:none;"></div>' +
		'<br /><br />' +
		'POP ID:<br /><input type="text" id="pop_id" style="width:97%;" value="" />' +
		'<br /><br />' +
		'Date of Birth (MM/DD/YYYY):<br /><input type="text" id="dob" style="width:97%;" value=""' +
			' onchange="check_birthdate(this)" />' +
		'<br /><br />' +
		'Age Division:<br />' +
			'<select id="age_division" style="width:100%;">' +
				'<option value=""></option>' +
				'<option value="junior">Junior</option>' +
				'<option value="senior">Senior</option>' +
				'<option value="master">Master</option>' +
			'</select>' +
		'</div>';

	document.write (rollup_html ('player', 'Player Information', '', html));

} //function

//--------------------------------------------------------------------------------
// create favorite pokemon entry html

function create_fav_poke_entry () {

	var html = '';

	// start the favorite pokemon entry div
	html +=
		'<div id="fav_poke_div" style="text-align:center; font-size:10px; display:block;">';

	// create the default pokemon image
	html +=
		'<img id=fav_poke_pic src="' + pokemon_images_loc + '000.png" /><br />' +
		'<span id="fav_poke_pic_label" style="font-size:10px;"></span><br />';

	// create the event code for mouse hovering over the menu text/links
	var hover_code =
		' onmouseover="this.style.textDecoration=\'underline\'"' +
		' onmouseout ="this.style.textDecoration=\'none\'"';

	// create all the pokedex combo select
	for (var type in pokedex) {

		html += '<div id="div_' + type + '" style="display:none; font-weight:bold;">';
		if (type == 'default_sugimori')
			html += pokedex[type].name;
		else
			html +=
				'<a tabindex="-1" style="text-decoration:none"' + hover_code +
				' target="_blank" href="' + pokedex[type].url + '"><span style="white-space:nowrap">' + pokedex[type].name + '</span></a>';
		html +=
			'<br /><select id="dex_' + type + '" style="width:100%;"' +
				' onchange="update_fav_poke(this)">' +
				'<option value=""></option>';

		// concat in smaller chunks for better performance, especially in IE
		var html_options = '';
		for (var i=0;  i<pokedex[type].dex.length;  i++) {
			if (i % 20 == 0)  { html += html_options; html_options = ''; }
			var img  = pokedex[type].dex[i][0];
			var name = pokedex[type].dex[i][1];
			html_options += '<option value="' + img + '">' + name + '</option>';
		} //for
		html += html_options + '</select></div>';

	} //for

	// close the favorite pokemon entry div
	html += '</div>';

	document.write (rollup_html ('fav_poke', 'Favorite Pokemon', '', html));

	// activate the fav poke list
	activate_fav_poke_list();

} //function

//--------------------------------------------------------------------------------
// activate the fav poke list

function activate_fav_poke_list() {

	// hide the old list

	for (var type in pokedex)
		document.getElementById('div_' + type).style.display = 'none';

	// show the new list
	var new_div = document.getElementById('div_' + decklist_options.fav_poke.pokedex);
	new_div.style.display = 'block';
	update_fav_poke();

} //function

//--------------------------------------------------------------------------------
// create the totals summary

function create_totals_summary () {

	// start the totals div/table
	document.write (
		'<div id="totals_div">' +
		'<table id="totals_table" align="center" style="font-size:12px; border:1px solid black; background-color:#FFFF66;">');

	// create the totals area
	document.write (
		'<tr style="color:red;"><td>Pokemon:&nbsp;&nbsp;</td><td align="right"><span id="pokemon_total_left"></span></td></tr>' +
		'<tr style="color:green;"><td>Trainer/Supp/Stad:&nbsp;&nbsp;</td><td align="right"><span id="trainer_total_left"></span></td></tr>' +
		'<tr style="color:blue;"><td>Energy:&nbsp;&nbsp;</td><td align="right"><span id="energy_total_left"></span></td></tr>' +
		'<tr><td colspan="2"><hr /></td></tr>' +
		'<tr style="font-weight:bold; color:black;"><td>Total Cards:&nbsp;&nbsp;</td><td align="right"><span id="deck_total"></span></td></tr>');

	// close the totals div/table
	document.write ('</table></div>');

} //function


//--------------------------------------------------------------------------------
// create the deck title and deck name html

function create_deck_entry () {

	var html = '';

	// start the title/name div/table
	html += '<div id="title_div" style="text-align:center;">';

	// create the title banner and deck name entry
	html += '<input type="text" id="deck_name" value="" style="width:98%;"' +
		' onchange="update_deck_list_select()"' +
		' onkeydown="if (event.keyCode == 13) event.keyCode = 9" />';

	// close the deck title/name div/table
	html += '</div>';

	document.write (rollup_html ('title', 'Deck Registration Sheet', '', html,
		'border-color:orange; color:white;', 'color:white;',
		'border-color:orange; background-color:orange;'));

} //function

//--------------------------------------------------------------------------------
// create the card entry html of the given card type

function create_card_entry (type, num_rows) {

	var html = '';

	// set the color and title based on the card type
	var color = '';
	var title = '';
	switch (type) {
		case 'pokemon':  title = "Pokemon";                    color = "red";    break;
		case 'trainer':  title = "Trainer/Supporter/Stadium";  color = "green";  break;
		case 'energy' :  title = "Energy";                     color = "blue";   break;
		default:;
	} //switch

	// create the div and table headings
	html +=
		'<div id="' + type + '_div">' +
		'<table id="' + type + '_table" cellpadding="1" cellspacing="0" style="width:100%; background-color:white;">';
	html += '<tr style="display:none;"><td colspan="4"></td></tr>';  // needed until add/del row is updated
	html +=
		'<tr valign="center" style="font-size:11px; font-weight:bold; color:white; background-color:' + color + ';">' +
		'<td></td>' +
		'<td align="center" style="width:40px;">QTY</td>' +
		'<td style="width:99%;">&nbsp;&nbsp;NAME</td>' +
		'<td align="center" style="width:60px;">SET-#</td></tr>';

	// create the card entry rows
	for (var i=1; i<=num_rows; i++) {

		// create the row html
		var id = type + (++id_count);
		html += '<tr><td>' +
			ck_html (id) + '</td><td>' +
			qty_input_html (id) + '</td><td >' +
			name_input_html (id, type) + '</td><td>' +
			info_html (id) + '</td></tr>';

	} //for

	// create the card total html and add/delete buttons
	html +=
		'<tr align="center" style="font-size:16px; font-weight:bold; color:white; background-color:' + color + '">' +
		'<td></td><td><span id="' + type + '_total"></span></td><td colspan="2">' +
		'<input type="button" id="' + type + '_add_row" tabindex="-1" value="Add New Row"' +
			' onclick="add_row(\'' + type + '\')" />' +
		'&nbsp;&nbsp;' +
		'<input type="button" id="' + type + '_del_row" tabindex="-1" value="Delete Last Row"' +
			' onclick="del_row(\'' + type + '\')" />' +
		'</td></tr>';

	// close the table/div
	html += '</table></div>';

	document.write (rollup_html (type, title, '', html,
		'border-color:' + color + '; color:white;', 'color:white;',
		'border-color:' + color + '; background-color:' + color + ';',
		'', 'padding:0px;'));

} //function

//--------------------------------------------------------------------------------
// create the note entry html for admin use only

function create_note_entry (num_rows) {

	var html = '';

	// create the notes div/table
	html += '<div id="notes_div" style="text-align:center;">';

	// create the admin notes
	html +=
		'<textarea id="notes" rows=' + num_rows + ' style="width:98%;"></textarea>';

	// close the notes div/table
	html += '</div>';

	document.write (rollup_html ('note', 'Administrative Use Only', '', html,
		'border-color:gray; color:white;', 'color:white;',
		'border-color:gray; background-color:gray;'));

	rollup_collapse ('note');

} //function

//--------------------------------------------------------------------------------
// create the main title bar

function create_title_bar() {

	function print() {
		return (
		'<input type="button" value="Print" id="button_print" onclick="javascript:view_decklist_print(true);"' +
		' style="background-color:lightblue; font-family:verdana,arial,helvetica; font-size:10px; margin-right:20px;" />');
	} //function

	function button (type) {
		return (
		'<input type="button" value="' + (type=='left' ? '<' : '>') + '" id="button_align_' + type + '" onclick="javascript:re_align_form(this);"' +
		' style="background-color:gold; color:gray; width:30px; font-family:verdana,arial,helvetica; font-size:10px; font-weight:bold;" />');
	} //function

	document.write (
		'<table cellspacing="0" cellpadding="5" style="width:100%; background-color:yellow; font-weight:bold; font-size:14px;"><tr>' +
			'<td style="width:100%; white-space:nowrap;">' +
			(winpic_html ? winpic_html : '<img src="' + vdb_images_loc + 'pokeball.gif" />') + ' SteveP\'s Deck List Program</td>' +
			'<td style="white-space:nowrap;">' + print() + button ('left') + button ('right') + '</td>' +
		'</tr></table>');

} //function

//--------------------------------------------------------------------------------
// re-align the form according to the align button that was pushed (in title bar)

function re_align_form (objButton) {

	var objTable = document.getElementById ('pokemon_deck_list_table');

	if (objButton.id == 'button_align_left')
		if (objTable.align == 'center')
			objTable.align = 'left';
		else if (objTable.align == 'right')
			objTable.align = 'center';
		else {}
	else
		if (objTable.align == 'center')
			objTable.align = 'right';
		else if (objTable.align == 'left')
			objTable.align = 'center';
		else {}

} //function

//--------------------------------------------------------------------------------
// create the entire decklist html from the given player-supplied data

// used to set the card input textbox width
// main width * right width - other widths (padding, margins, etc).
var iWidth_name = 800 * 0.65 - 181 + (is_msie7 ? 1 : is_msie ? 3 : is_firefox ? 9 : is_safari ? 4 : is_opera ? 7 : 0);

function create_decklist_entry (data, cards) {

	// backward compability (v1.2) - update the decklists data
	if (data && cards)  copy_decklists ([{"data":data, "cards":cards}], decklists);

	// insert the options div at the body-level
	document.write ('<div id="decklist_options" style="display:none"></div>');

	// insert the "view" divs here at the body-level
	create_window_drag_all();

	// start the form and decklist table
	document.write (
		'<div id="pokemon_deck_list_div">' +
		'<form id="pokemon_deck_list_form" action="javascript:submit_form()">' +
		'<table id="pokemon_deck_list_table" align="center" cellspacing="0" cellpadding="0"' +
		' style="width:800px; border:2px solid black; background-color:white;">');

	'<td><input type="button" value="<" id="button_align_left"' +
		' style="background-color:gold; color:gray; width:30px; font-family:verdana,arial,helvetica; font-size:10px; font-weight:bold; margin-right:5px;"' +
		' onclick="javascript:re_align_form(this);" /></td>' +

	// create the title bar
	document.write ('<tr><td colspan="2" style="border-bottom:1px solid #CCCCCC;">');
	create_title_bar() +
	document.write ('</td></tr>');

	// create the top menu row
	document.write ('<tr><td colspan="2" style="border-bottom:1px solid gray;">');
	create_menu();
	document.write ('</td></tr>');

	// start the decklist row and left column
	document.write ('<tr><td valign="top" style="width:35%; padding:16px;">');

	// create all the left column displays
	create_event_entry();     document.write ('<br \>');
	create_player_entry();    document.write ('<br \>');
	create_fav_poke_entry();  document.write ('<br \>');
	create_totals_summary();  document.write ('<br \>');

	// close the left column
	document.write ('</td>');

	// start the right column
	document.write ('<td valign="top" style="width:65%; padding:16px 16px 16px 0px;">');

	// create all the right column displays
	create_deck_entry ();                                                       document.write ('<br \>');
	create_card_entry ('pokemon', decklists[deck_num-1].cards.pokemon.length);  document.write ('<br \>');
	create_card_entry ('trainer', decklists[deck_num-1].cards.trainer.length);  document.write ('<br \>');
	create_card_entry ('energy',  decklists[deck_num-1].cards.energy.length);   document.write ('<br \>');
	create_note_entry (3);

	// close the right column and decklist row
	document.write ('</td></tr>');

	// close the decklist table and form
	document.write ('</table></form></div>');

	// update the decklist with the data
	update_displayed_decklist();

	// apply the body background
	document.body.style.background = background_style;
	
	// create/insert the vdb html
	vdb_create();

} //function

//--------------------------------------------------------------------------------
// push a blank decklist onto the given decklist array

function push_blank_deck (decklists) {

	return decklists.push ({

		"data":{
			"event"    : {"name":"", "img":""},
			"fav_poke" : {"name":"", "dex":"", "img":""},
			"player"   : {"name":"", "id":"", "dob":"", "div":""}
		},
		"cards":{

			"deck_name" : "",
			"pokemon"   : [{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}],
			"trainer"   : [{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}],
			"energy"    : [{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}]
		}
	});

} //function

//--------------------------------------------------------------------------------
// push a new decklist onto the given decklist array with default data

function push_new_deck (decklists) {

	return decklists.push ({
		"data":{
			"event"    : {"name":"", "img":""},
			"fav_poke" : {"name":"", "dex":"", "img":""},
			"player"   : {"name":"", "id":"", "dob":"", "div":""}
		},
		"cards":{
			"deck_name":"",
			"pokemon":[
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}],
			"trainer":[
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}],
			"energy" :[
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""},
				{"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""}]
		}
	});

} //function

//--------------------------------------------------------------------------------
// create the global array to hold all the decklists

var decklists = new Array();
var deck_num  = push_new_deck (decklists);

//--------------------------------------------------------------------------------
// copy one set of cards of the given type to another (from cards1 to cards2)

function copy_cards (cards1, cards2) {

	// clear the destination cards
	cards2.splice (0, cards2.length);

	// always include at least one line
	if (cards1.length == 0)

		cards2.push ({"qty":"", "name":"", "info":"", "card":"", "img":"", "note":""});

	else

		for (var i=0;  i<cards1.length;  i++)

			with (cards1[i])
			cards2.push ({
				"qty" :((typeof qty  != "undefined") ? qty  : ''),
				"name":((typeof name != "undefined") ? name : ''),
				"info":((typeof info != "undefined") ? info : ''),
				"card":((typeof card != "undefined") ? card : ''),
				"img" :((typeof img  != "undefined") ? img  : ''),
				"note":((typeof note != "undefined") ? note : '')
			});

} //function

//--------------------------------------------------------------------------------
// copy one deck to another (from deck1 to deck2)

function copy_decks (deck1, deck2) {

	if (typeof deck1.data != "undefined") {

		if (typeof deck1.data.event != "undefined") {

			//backward compatibility (v1.3) - else clause below
			if (typeof deck1.data.event.name != "undefined")  deck2.data.event.name = deck1.data.event.name;
			if (typeof deck1.data.event.img  != "undefined")  deck2.data.event.img  = deck1.data.event.img;
			else                                              deck2.data.event.img  = deck1.data.event;

		} //if

		if (typeof deck1.data.fav_poke != "undefined") {

			//backward compatibility (v1.3) - else clause below
			if (typeof deck1.data.fav_poke.name != "undefined")  deck2.data.fav_poke.name = deck1.data.fav_poke.name;
			if (typeof deck1.data.fav_poke.dex  != "undefined")  deck2.data.fav_poke.dex  = deck1.data.fav_poke.dex;
			if (typeof deck1.data.fav_poke.img  != "undefined")  deck2.data.fav_poke.img  = deck1.data.fav_poke.img;
			else                                                 deck2.data.fav_poke.img  = deck1.data.fav_poke;

		} //if

		if (typeof deck1.data.player != "undefined") {

			if (typeof deck1.data.player.name != "undefined")   deck2.data.player.name = deck1.data.player.name;
			if (typeof deck1.data.player.id   != "undefined")   deck2.data.player.id   = deck1.data.player.id;
			if (typeof deck1.data.player.dob  != "undefined")   deck2.data.player.dob  = deck1.data.player.dob;
			if (typeof deck1.data.player.div  != "undefined")   deck2.data.player.div  = deck1.data.player.div;

		} //if

	} //if

	if (typeof deck1.cards != "undefined") {

		if (typeof deck1.cards.deck_name != "undefined")  deck2.cards.deck_name = deck1.cards.deck_name;
		if (typeof deck1.cards.pokemon   != "undefined")  copy_cards (deck1.cards.pokemon, deck2.cards.pokemon);
		if (typeof deck1.cards.trainer   != "undefined")  copy_cards (deck1.cards.trainer, deck2.cards.trainer);
		if (typeof deck1.cards.energy    != "undefined")  copy_cards (deck1.cards.energy,  deck2.cards.energy);

	} //if

} //function

//--------------------------------------------------------------------------------
// copy one set of decklists to another (from decks1 to decks2)

function copy_all_decklists (decks1, decks2) {

	// clear the destination decks
	decks2.splice (0, decks2.length);

	// push each of the source decks onto the destination decks - do error checking
	for (var i=0;  i<decks1.length;  i++) {

		// start with a blank deck & copy the source deck to the destination deck
		push_blank_deck (decks2);
		copy_decks (decks1[i], decks2[i]);

	} //for

} //function

//--------------------------------------------------------------------------------
// add multiple deck functionality

function create_multi_deck_entry (new_decklists) {

	// do some error checking for bad data
	if ((typeof new_decklists != "undefined") && new_decklists.length>0) {

		copy_all_decklists (new_decklists, decklists);
		deck_num = new_decklists.length;

	} //if

	// pass the current deck list
	create_decklist_entry();

} //function
