/**
* takes an ol or ul (ordered list or unordered list) and makes a register based on it.
* 
* currently only works in ie (tested in ie6), not in mozilla.
* 
* dependencies:
* <script type="text/javascript" src="/_bsJavascript/core/lang/Bs_Misc.lib.js"></script>
* 
* @param  string divName
* @param  string objName
* @since bs-4.6
*/
function Bs_ListRegister(divName, objName) {
	
	/**
	* the separator to use between the a-z letters. default is a dash.
	* @access public
	* @var    string separator
	*/
	this.separator = ' - ';
	
	/**
	* what to do with empty characters. 
	* 
	* example: if your list from A to Z does not have content for 
	* the characters H and Y, how do you want to show that?
	* 
	* possible definitions:
	*   TYPE              SYNTAX           EXAMPLE
	*   different color   color:myColor    color:gray
	*   hidden            hide             hide
	* 
	* @access public
	*/
	this.emptyChar = 'color:gray';
	
	/**
	* 
	* @access public
	*/
	this.sort = false;
	
	/**
	* @access private
	* @var    array _options
	*/
	this._options;
	
	/**
	* @access private
	* @var    string _currentChar
	*/
	this._currentChar;
	
	/**
	* name of this instance of Bs_ListRegister.
	* @access private
	*/
	this._objName;
	
	/**
	* name of the div around the ul or ol tag.
	* @access private
	* @see    _divElm
	*/
	this._divName;
	
	/**
	* reference to the div around the ul or ol tag.
	* @access private
	* @see    _divName
	*/
	this._divElm;
	
	/**
	* reference to the ul or ol element.
	* @access private
	*/
	this._listElm;
	
	
	/**
	* init function.
	* @access public
	* @param  array dataArray
	* @return void
	*/
	this.initByArray = function(dataArray) {
		this._init(dataArray);
	}
	
	/**
	* init function.
	* @access public
	* @return void
	*/
	this.initByList = function() {
		this._init();
	}
	
	/**
	* basic init.
	* @access private
	* @param  array dataArray
	* @return void
	*/
	this._init = function(dataArray) {
		this._divElm = document.getElementById(this._divName);
		
		for (var i=0; i<this._divElm.childNodes.length; i++) {
			if ((this._divElm.childNodes[i].nodeName.toUpperCase() == 'UL') || (this._divElm.childNodes[i].nodeName.toUpperCase() == 'OL')) {
				this._listElm = this._divElm.childNodes[i];
				break;
			}
		}
		
		if (typeof(dataArray) == 'undefined') {
			this._importToLetterArray();
		} else {
			this._options = this.arrayToLetterArray(dataArray);
		}
		
		if (this.sort) {
			this._sort();
		}
		
		var html = new Array();
		var elms = new Array();
		html[html.length] = '<div id="' + this._objName + '_letterSpanDiv">';
		for (var i=0; i<26; i++) {
			var chr = String.fromCharCode(65+i).toUpperCase();
			var isEmpty = ((typeof(this._options[chr]) == 'undefined') || (this._options[chr].length == 0));
			if (isEmpty && (this.emptyChar == 'hide')) continue;
			
			var t = '';
			t += '<span';
			t += ' id="' + this._objName + '_letterSpan_' + chr + '"';
			if (isEmpty) {
				//let's see how to format. example: 'color:gray'
				var color = this.emptyChar.substr(6);
				t += ' style="cursor:default; color:' + color + ';">' + chr + '</span>';
			} else {
				t += ' onclick="' + this._objName + '.switchChar(\'' + chr + '\');"';
				t += ' style="cursor:hand;cursor:pointer;">' + chr + '</span>';
			}
			elms[elms.length] = t;
		}
		html[html.length] = elms.join(this.separator);
		
		html[html.length] = '</div>';
		this._divElm.insertAdjacentHTML('afterBegin', html.join(''));
		
		/*
		var status = this.switchChar('A');
		if (!status) {
			document.getElementById(this._objName + '_letterSpanDiv').style.display = 'none';
		} else {
			//takes a long time with many elements, should be optimized, 
			//for example done directly in switchChar():
			//this.markEmptyLetters();
		}
		*/
	}
	
	/**
	* @access public
	* @param  string chr (a character, eg "B".)
	* @return bool
	*/
	this.switchChar = function(chr) {
		chr = chr.toUpperCase();
		
		//NEW CODE
		var out = new Array();
		if (typeof(this._options[chr]) == 'object') {
			for (var i=0; i<this._options[chr].length; i++) {
				out[out.length] = '<li>' + this._options[chr][i] + '</li>';
			}
		}
		this._listElm.innerHTML = out.join('');
		
		/*
		//OLD CODE
		for (var i=0; i<this._divElm.childNodes.length; i++) {
			if ((this._divElm.childNodes[i].nodeName.toUpperCase() == 'UL') || (this._divElm.childNodes[i].nodeName.toUpperCase() == 'OL')) {
				for (var j=0; j<this._divElm.childNodes[i].childNodes.length; j++) {
					var currentElm = this._divElm.childNodes[i].childNodes[j];
					if (typeof(currentElm.lrKey) != 'undefined') {
						if (currentElm.lrKey == this._currentChar) {
							currentElm.style.display = 'none';
						} else if (currentElm.lrKey == chr) {
							currentElm.style.display = 'block';
						}
						if (this.isOrdered && (currentElm.lrKey > this._currentChar) && (chr > this._currentChar)) {
							break;
						}
						continue;
					}
					
					//alert(currentElm.innerText);
					//alert(currentElm.value);
					//break;
					if (typeof(currentElm.innerText) == 'undefined') return false; //throw
					var currentStr = currentElm.innerText;
					var currentChr = currentStr.substr(0, 1).toUpperCase();
					currentElm.style.display = (currentChr == chr) ? 'block' : 'none';
					currentElm.lrKey = currentChr;
				}
				break;
			}
		}
		this._currentChar = chr;
		return true;
		*/
	}
	
	
	this._importToArray = function() {
		var lst = this.fetchList();
	}
	
	/**
	* @access private
	* @return void
	*/
	this._importToLetterArray = function() {
		var lst = new Object();
		
		//initialize the letter arrays so we can avoid the 'undefined' check in the loop.
		//does not speed it up remarkably :(
		for (var i=0; i<26; i++) {
			var chr = String.fromCharCode(65+i); //.toUpperCase();
			lst[chr] = new Array();
		}
		
		for (var i=0; i<this._divElm.childNodes.length; i++) {
			if ((this._divElm.childNodes[i].nodeName.toUpperCase() == 'UL') || (this._divElm.childNodes[i].nodeName.toUpperCase() == 'OL')) {
				var childNodes = this._divElm.childNodes[i].childNodes;
				var numNodes = childNodes.length;
				for (var j=0; j<numNodes; j++) {
					if (childNodes[j].innerText) { //ie
						var txt = childNodes[j].innerText;
					} else { //fox
						var txt = '';
						if (childNodes[j].nodeType == 1 /* ELEMENT_NODE */) {
							txt += this._getInnerText(childNodes[j]);
						}
						if (childNodes[j].nodeType == 3 /* TEXT_NODE */) {
							txt += childNodes[j].nodeValue;
						}
					}
					var chr = txt.substr(0, 1).toUpperCase();
					if (chr.length == 1) {
						if (typeof(lst[chr]) == 'undefined') lst[chr] = new Array();
						lst[chr][lst[chr].length] = txt;
					}
				}
				break;
			}
		}
		this._options = lst;
	}
	
	/**
	* returns a list of all available nodes.
	* @access public
	* @return array (vector)
	*/
	this.fetchList = function() {
		var lst = new Array();
		for (var i=0; i<this._divElm.childNodes.length; i++) {
			if ((this._divElm.childNodes[i].nodeName.toUpperCase() == 'UL') || (this._divElm.childNodes[i].nodeName.toUpperCase() == 'OL')) {
				for (var j=0; j<this._divElm.childNodes[i].childNodes.length; j++) {
					lst[lst.length] = this._divElm.childNodes[i].childNodes[j].innerText;
				}
				break;
			}
		}
		return lst;
	}
	
	
	/**
	* @access public
	* @param  array dataArray
	* @return array
	*/
	this.arrayToLetterArray = function(dataArray) {
		var lst = new Object();
		
		//initialize the letter arrays so we can avoid the 'undefined' check in the loop.
		//does not speed it up remarkably :(
		for (var i=0; i<26; i++) {
			var chr = String.fromCharCode(65+i); //.toUpperCase();
			lst[chr] = new Array();
		}
		
		for (var i=0; i<dataArray.length; i++) {
			var txt = dataArray[i];
			var chr = txt.substr(0, 1).toUpperCase();
			//if (typeof(lst[chr]) == 'undefined') lst[chr] = new Array();
			lst[chr][lst[chr].length] = txt;
		}
		return lst;
	}
	
	
	/**
	* @access private
	* @return void
	*/
	this._sort = function() {
		for (var i=0; i<26; i++) {
			var chr = String.fromCharCode(65+i); //.toUpperCase();
			if (typeof(this._options[chr]) != 'undefined') {
				//for (var j=0; j<this._options[chr].length; j++) {
				//}
				this._options[chr].sort();
			}
		}
	}
	
	
	this._getInnerText = function(o) {
		var txt = '';
		for (var i=0; i<o.childNodes.length; i++) {
			switch(o.childNodes[i].nodeType) {
				case 1 : txt += this._getInnerText(o.childNodes[i]); break
				case 3 : txt += o.childNodes[i].nodeValue; break
				case 8 : txt += "\n"; break
			}
		}
		return txt;
	}
	
	
	/**
	* marks all letters a-z gray that have no content since it makes
	* no sense to push them.
	* @access public
	* @return void
	*/
	this.markEmptyLetters = function() {
		//NEW CODE
		//this._options
		
		/*
		//OLD CODE
		var lst  = this.fetchList();
		var done = new Object();
		for (var i=0; i<lst.length; i++) {
			var chr = lst[i].substr(0, 1).toUpperCase();
			if (typeof(done[chr]) == 'undefined') {
				done[chr] = true;
			}
		}
		for (var i=0; i<26; i++) {
			var chr = String.fromCharCode(65+i).toUpperCase();
			var spanElm = document.getElementById(this._objName + '_letterSpan_' + chr);
			if (typeof(done[chr]) == 'undefined') {
				spanElm.style.color  = 'gray';
				spanElm.style.cursor = 'default';
				spanElm.onclick      = '';
			} else {
				spanElm.style.color = '#000000';
				//spanElm.style.cursor = 'hand';
				//spanElm.onclick      = '';
			}
		}
		*/
	}
	
	//constructor
	this._objName = objName;
	this._divName = divName;
}
