/**
 * @constructor
 * @extends LoginPanelAgent
 * @param {String} id This Agent's field reference
 * @param {String} type "Country" | "Language" | "FKey" | "FKeySet"
 */
function AlphaListAgent(type,id) {

	this.init(id);
	this.type = type; // XML element tag name
	this.width = 280;

	// procedure callbacks implemented in modRec, filter & collection
	this.update = AgentPCB.update;
	this.onLogin = AgentPCB.onLogin;

	/**
	 * @param {XMLElement} xe Either a xeCountry or a xeLanguage, depending on the type
	 */
	this.openPanel = function(fieldLabel,xe) {

        var guiType = (this.fieldType!=this.type) ? this.type : null;
        var xeCommand = (this.recId) ? this.xeGetFieldValue() : this.xeGetModGUIData({guiType:guiType});
		var eWidgetResult = this.eWidgetResult(xeCommand);
        var eGUI = eWidgetResult.getElementsByTagName('ModGUIData')[0].childNodes[0];

		if (eGUI.tagName=='LoginModGUIData') {
			this.width = 320;
			this.initLoginPanel(eGUI);
			this.openLoginPanel()
		}
        else { // AlphaListModGUIData
        	var guiLabels = this.getMap(eGUI.getElementsByTagName('GUILabels')[0]);
			var colorIconDir = eGUI.getAttribute('colorIconDir');
			var alphaLists = new AlphaLists(eGUI.getElementsByTagName('ParamNames')[0],
				eGUI.getAttribute('firstLetter'),xe);
			var newRecordHref = eGUI.getAttribute('newRecordHref');

	        this.panel = new AlphaListPanel(this.id,xe,guiLabels,fieldLabel,colorIconDir,alphaLists,
	        	newRecordHref);

			this.displayPanel();
			this.setDivTop();
			this.panel.initFocus()}}

	this.filter = function(letter) {
		this.panel.filter(letter)}

	this.deleteItem = function() {
		this.submitValue('<NullValue/>')}

	/**
	 * Supports FKey, FKeySet, Country & Language
	 * @param {String} value 'recId' or 'code' attribute
	 */
	this.submitItem = function(value) {
		var xmlValue = '<NullValue/>';
		var returnHTMLLabel = false;
		if (value && value!='') switch (this.fieldType) {
			case 'FKey' : xmlValue = '<FKey recId="'+value+'"/>'; returnHTMLLabel = true; break;
			case 'FKeySet' :
				if (this.recId || this.mmrId) {
					Manager.getAgent('link_'+this.fieldRef).addFKey(value);
					this.closePanel();
					return}
				else xmlValue = '<FKey recId="'+value+'"/>'; returnHTMLLabel = true; break;
			default : xmlValue = '<'+this.type+' code="'+value+'"/>'} // Country or Language
		this.submitValue(xmlValue,returnHTMLLabel)}

	this.toString = function() {
		return 'AlphaListAgent: {type: ' + this.type + '; agentPrefix: ' + this.agentPrefix
		+ '; fieldRef: ' + this.fieldRef + '}'}
}

AlphaListAgent.prototype = new LoginPanelAgent();


/**
 * @param {Element or XMLElement} xeParamNames
 * @param {String} dfl Default first letter
 * @param {Element or XMLElement} xe Existing PSValue, used to overwrite default first letter.
 */
function AlphaLists(xeParamNames,dfl,xe) {

	this.lists = []; // array of AlphaItems objects
	if (dfl) this.dfl = dfl.toUpperCase(); // default first letter in upper case
	var defCode = (xe) ? xe.getAttribute('code') : null;

	// set AlphaItems objects in lists array
	if (xeParamNames) {
		var cn = xeParamNames.childNodes;
		for (var i=0; i<cn.length; i++) {
			var code = cn[i].getAttribute('code');
			var label = (cn[i].firstChild) ? cn[i].firstChild.data : (cn[i].getChildData) ? cn[i].getChildData() : '';
			var firstLetter = label.charAt(0).toUpperCase();
			if (defCode==code) this.dfl = firstLetter;
			var hasList = false;
			for (var j=0; j<this.lists.length; j++) {
				if (this.lists[j].firstLetter==firstLetter) {
					this.lists[j].add(code,label);
					hasList = true;
					break}}
			if (!hasList) {
				var newList = new AlphaItems(firstLetter);
				newList.add(code,label);
				this.lists.push(newList)}}
		// sort lists by first letter
		var listSorter = function(a,b) {
			if (a.firstLetter < b.firstLetter) return -1;
			if (a.firstLetter > b.firstLetter) return 1;
			return 0}
		this.lists.sort(listSorter);
		// set default first letter if null
		if (!this.dfl && this.lists.length>0) this.dfl = this.lists[0].firstLetter;
		// sort each list alphabetically
		for (var i=0; i<this.lists.length; i++) {
			this.lists[i].sort()}}

	this.size = function() {
		return this.lists.length}

	this.getFirstLetter = function(index) {
		return this.lists[index].firstLetter}

	/**
	 * @return The list for the given first letter, if it exists. Otherwise,
	 * the first list is returned, if there is a list. Otherwise,
	 * null is returned.
	 */
	this.getList = function(firstLetter) {
		for (var i=0; i<this.lists.length; i++) {
			if (this.lists[i].firstLetter==firstLetter) return this.lists[i];}
		return (this.lists.length>0) ? this.lists[0] : null;}
}


/**
 * A list of items with labels starting with the same letter.
 * Each item has a code and a corresponding label.
 */
function AlphaItems(firstLetter) {

	this.firstLetter = firstLetter;
	this.items = [];

	this.add = function(code,label) {
		this.items.push({code:code, label:label})}

	this.sort = function() {
		var itemSorter = function(a,b) {
			if (a.label < b.label) return -1;
			if (a.label > b.label) return 1;
			return 0}
		this.items.sort(itemSorter)}

	this.size = function() {
		return this.items.length}

	this.getCode = function(index) {
		return this.items[index].code}

	this.getLabel = function(index) {
		return this.items[index].label}
}


function AlphaListPanel(agentId,xe,guiLabels,fieldLabel,colorIconDir,alphaLists,newRecordHref) {

	this.agentId = agentId;
	this.xe = xe;
	this.guiLabels = guiLabels;
	this.fieldLabel = fieldLabel;
	this.colorIconDir = colorIconDir;
	this.alphaLists = alphaLists; // AlphaLists object
	this.newRecordHref = newRecordHref;
	this.errorMsg = null;

	this.filter = function(firstLetter) {
		$('results_'+this.agentId).innerHTML = this.getListHTML(firstLetter)}

	this.getListHTML = function(firstLetter) {
		var html = '';
		var list = this.alphaLists.getList(firstLetter);
		if (list) for (var i=0; i<list.size(); i++) {
			html += "<a href='javascript: Manager.getAgentWithId(\""
			+ this.agentId+"\").submitItem(\""+list.getCode(i)+"\")' title=\""
			+ this.guiLabels.select+" "+ list.getLabel(i) +"\" tabIndex='"+(i+3)+"'>"
			+ list.getLabel(i).substr(0,80) + "</a>"}
		return html}

	this.initFocus = function() {
		$('letter_'+this.agentId).focus()}

	this.toHTML = function() {

		var agent = "Manager.getAgentWithId('"+this.agentId+"')";

		var html = '<table class="wide ptable">'
		+ '<tr>'
		+ '<td class="ptitbar" onMouseDown="DragAndDrop.start(this,event); return false">'
			+ '<table class="wide" summary="' + this.guiLabels.titleBar + '">'
			+ '<tr>'
			+ '<td>'+this.fieldLabel+'</td>'
			+ '<td align="right" nowrap valign="top">';

			// new record link
			if (this.newRecordHref) {
				var fieldRef = this.agentId.replace(/^[^_]+_/,'');
				html += '<a tabIndex="1" id="popup_' + fieldRef+'" onClick="Manager.openPopup(this,\''
				+ this.newRecordHref + '\'); return false" href="Manager.openPopup" class="new"><img src="'
				+ this.colorIconDir + 'bt_newDoc.gif" class="bt11 m04">' + this.guiLabels.newRecord + '</a>'}

			html += '<input type="image" onClick="'+agent+'.closePanel(); return false" '
			+ 'img src="'+this.colorIconDir+'bt_close_11.gif" class="bt11" '
			+ 'alt="'+this.guiLabels.close+'" tabIndex="1"></td>'
			+ '</tr>'
			+ '</table>'
		+ '</td>'
		+ '</tr>'
		+ '<tr>'
		+ '<td class="alphalist">'
			+ '<table class="wide" summary="' + this.guiLabels.permittedValues + '">'
			+ '<tr>'
			+ '<td>'
			+ '<div class="head">'
			+ '<div>'
			+ '<table summary="' + this.guiLabels.navigationBar + '">'
			+ '<tr>'

			// A-Z index
			+ '<td>' + this.guiLabels.startsWith + '&nbsp;'
			+ '<select onChange="'+agent+'.filter(this.options[this.selectedIndex].value)" id="letter_'
			+ this.agentId+'" tabIndex="2">';
			for (var i=0; i<this.alphaLists.size(); i++) {
				var firstLetter =  this.alphaLists.getFirstLetter(i);
				var selAtt = (firstLetter==this.alphaLists.dfl) ? ' selected' : '';
				html += '<option value="'+firstLetter+'"'+selAtt+'>'+firstLetter+'</option>'}
			html += '</select>'
			+ '</td>'
			+ '</tr>'
			+ '</table>'
			+ '</div>'
			+ '</div>'
			+ '</td>'
			+ '</tr>'
			+ '<tr>'
			+ '<td class="results" id="results_'+this.agentId+'">'
			+ this.getListHTML(this.alphaLists.dfl)+'</td>'
			+ '</tr>'
			+ '</table>'
		+ '</td>'
		+ '</tr>'
		+ '<tr>'
		+ '<td align="center" class="pbuts">'

		+ '<div class="perror"';
		if (!this.errorMsg)  html += ' style="display: none"';
		html += this.errorMsg + '></div>'
		+ '<table summary="' + this.guiLabels.actionButtons + '">'
		+ '<tr>'
		+ '<td><button onClick="'+agent+'.deleteItem(); return false" tabIndex="998">'
		+ this.guiLabels.Delete + '</button></td>'
		+ '</tr>'
		+ '</table>'
		+ '</td>'
		+ '</tr>'
		+ '</table>';
		return html}
}


