
/** @file
* contains javascript code needed by the getTables.htm page. 
*/

/** @class Set
* store data items in a set and allow basic set algebra with them.
* 
* @ctor
* initialise the Set from an array of data elements (numbers, strings or objects).
*/
function Set(members) {
	this.data = new Object();
	for (var i = 0; i < members.length; i++){
		this.data[members[i]] = members[i];
	}
}

/** 
* update the Set object with the intersection with an array of data elements (not another Set).
*/
Set.prototype.intersect = function (otherData){
	var newData = new Object();
	for (var i = 0; i < otherData.length; i++){
		element = otherData[i]; 
		if (this.contains(element)){
			newData[element] = 1;
		}
	}
	this.data = newData;
}

/** 
* get the data items from the Set object
*
* @treturn Array an array of the current Set members
*/
Set.prototype.getData = function (){
	var members = [];
	for (var i in this.data){
		members[members.length] = i;
	}
	return members;
}

/** 
* test to see if the Set object contains the specified item.
* @treturn boolean 
*/
Set.prototype.contains = function(element){
	return (this.data[element] != null);
}

//end of Set class member functions

function getTables(varName, tableMapping) {
	var tmp = tableMapping[varName];
	return (tmp == null) ? [] : tmp;
}

/**
* convert a list of keywords into a list of tables that use those keywords.
*
* @tparam ArrayOfStrings varList array of keywords
* @tparam dictionary tableMapping maps keywords to table IDs
* @tparam dictionary tableIDToFilename maps table IDs to filenames
* @treturn ArrayOfStrings array of filenames that match all the keywords
*/
function getCommonTables(varList, tableMapping, tableIDToFilename) {
	if (varList.length == 0) {
		return [];
	}
	var commonSet = new Set(getTables(varList[0], tableMapping));
	for (var i = 1; i < varList.length; i++) {
		commonSet.intersect(getTables(varList[i], tableMapping));
	}
	var files = [];
	var IDs = commonSet.getData();
	for (var i = 0; i < IDs.length; i++) {
		if (tableIDToFilename[IDs[i]]) {
			var filenames = tableIDToFilename[IDs[i]];
			for (var j = 0; j < filenames.length; j++) {
				files[files.length] = filenames[j];
			}
		}
	}
	return files;
}

/**
* add a string to a DOM Select object. 
*/
function addToSelectBox(selectBox, str){
	selectBox[selectBox.length] =new Option(str, str, 0,0);
}

/**
* add each string in an array to a DOM Select object.
*/
function addArrayToSelectBox(selectBox, array, replaceFlag) {
	if (replaceFlag) {
		selectBox.length = 0;
	}
	for (var i=0; i<array.length; i++) {
		addToSelectBox(selectBox, array[i]);
	}
}

/**
* extract the items from a DOM Select object and convert to an array of strings
*/
function selectBoxItemsToArray(selectBox) {
	var found = [];
	for (var i=0; i<selectBox.length; i++) {
		found[found.length] = selectBox[i].value;
	}
	return found;
}

/**
* initialise the form elements from the contents of the keyword mapping file
*/
function initialiseForm(form, kwTable, aliases, tableIDs) {
	form.keywordSelectBox.length = 0;
	form.selectedKeywords.length = 0;
	form.selectedFiles.length = 0;
	
	for (var kw in kwTable) {
        if (tableIDs == null){
            addToSelectBox(form.keywordSelectBox, kw );
        }
        else {
            var tables = kwTable[kw]; 
            for (var i=0; i<tables.length; i++) {
                if (tableIDs[tables[i]]){
                    addToSelectBox(form.keywordSelectBox, kw );
                    break;
                }
            }
        }
	}
    if (aliases) {
        applyAliases(form.keywordSelectBox, aliases);
    }
	sortSelectBox(form.keywordSelectBox);
}

/**
* move Option items from one DOM Select object to another.  
* Either move all items or only selected items.
*/
function moveSelectBoxItems( fromSelectBox, toSelectBox, moveAllFlag) {
	for (var i = fromSelectBox.length-1; i >= 0; i-- ) {
		var current = fromSelectBox[i];
		if( moveAllFlag || current.selected ) {
			addToSelectBox( toSelectBox, current.value );
			fromSelectBox[i] = null;
		}
	}
}

/**
* initialise the contents of the toSelectBox Select object with filenames that match the keywords in the fromSelectBox Select object.
*/
function updateFileSelectBox(fromSelectBox, toSelectBox, mapping, tableIDToFilename) {
	var items = selectBoxItemsToArray(fromSelectBox);
	var common = getCommonTables(items, mapping, tableIDToFilename);
	addArrayToSelectBox(toSelectBox, common, true);
}

function compareOptionsText(opt1, opt2) {
    if (opt1.text < opt2.text)
        return -1;
    if (opt1.text > opt2.text)
        return 1;
    return 0;
}

/**
* sort the entries in a Select object.
*/
function sortSelectBox(selectBox) {
	var entries = [];
    for (var i=0; i < selectBox.options.length; i++) {
        entries[entries.length] = new Option(selectBox.options[i].text, selectBox.options[i].value, 0,0); 
    }
    selectBox.length = 0;
	entries.sort(compareOptionsText);
    for (var i=0; i < entries.length; i++) {
        selectBox[selectBox.length] = new Option(entries[i].text, entries[i].value, 0,0); 
    }
}

/**
* Move the selected keywords from the form.keywordSelectBox to the form.selectedKeywords, then update the 
* form.selectedFiles Select listbox. 
*
*/
function addKeywords(form, mapping, tableIDToFilename, aliases) {
	moveSelectBoxItems(form.keywordSelectBox, form.selectedKeywords, false);
    if (aliases) {
        applyAliases(form.selectedKeywords, aliases);
    }
	sortSelectBox(form.selectedKeywords);
	updateFileSelectBox(form.selectedKeywords, form.selectedFiles, mapping, tableIDToFilename);
	sortSelectBox(form.selectedFiles);
}

/**
* Move all or just the selected keywords from the form.selectedKeywords to the form.keywordSelectBox, then update the 
* form.selectedFiles Select listbox. 
*
*/
function removeKeywords(form, mapping, tableIDToFilename, allFlag, aliases) {
	moveSelectBoxItems(form.selectedKeywords, form.keywordSelectBox, allFlag);
    if (aliases) {
        applyAliases(form.keywordSelectBox, aliases);
    }
	sortSelectBox(form.keywordSelectBox);
	updateFileSelectBox(form.selectedKeywords, form.selectedFiles, mapping, tableIDToFilename);
	sortSelectBox(form.selectedFiles);
}

/**
* download the file selected in the selectBox.    
* if there is only one item, download that whether it is selected or not
* @treturn Window the window object that was opened, or null if no file selected.
*/
function downloadFile(selectBox, path, ext) {
	if (selectBox.length == 1) {
		var filename = path+selectBox[0].value+ext;
		return window.open(filename, 'FileDownload');
	}
	for (var i = selectBox.length-1; i >= 0; i-- ) {
		var current = selectBox[i];
		if( current.selected ) {
			var filename = path+current.value+ext;
			return window.open( filename, 'FileDownload');
		}
	}
	return null;
}

/**
* replace the text in selectBox that have an alias defined in aliases.
*/
function applyAliases(selectBox, aliases) {
    for (i=0; i < selectBox.length; i++) {
        var value = selectBox.options[i].value;
    	if (aliases[value]){
            selectBox.options[i].text = aliases[value]; 
        }
    }
}
//==============================================================


