//
// 2006-04-20
// Copyright (c) Art. Lebedev Studio | http://www.artlebedev.ru/
// Author - Leechy | leechy@design.ru
//

var sFAYTHLElemName = 'u';
var sFAYTHLElemClass = null;
var iFAYTMinTextLength = 2;
var bFAYTWordStartOnly = true;
var bFAYTTranslit = false;
var bFAYTAddClass = false;
var sFAYTFoundClassName = 'found';
var sFAYTFilteredClassName = 'filtered';

var rSpaces = new RegExp( '(\\s|' +  String.fromCharCode( 160 ) + '|&nbsp;)+', 'g' );


function defaultOption(oOptions, vOptionValue, vDefault) {
	if (oOptions && oOptions[vOptionValue] != null) return oOptions[vOptionValue];
	else return vDefault;
}

function FAYT(oElem, oOptions) {
	this.oElem = oElem;
	this.sHLElemName = defaultOption(oOptions, 'sHLElemName', sFAYTHLElemName);
	this.sHLElemClass = defaultOption(oOptions, 'sHLElemClass', sFAYTHLElemClass);
	this.iMinTextLength = defaultOption(oOptions, 'iMinTextLength', iFAYTMinTextLength);
	this.bWordStartOnly = defaultOption(oOptions, 'bWordStartOnly', bFAYTWordStartOnly);
	this.bTranslit = defaultOption(oOptions, 'bTranslit', bFAYTTranslit);

	this.bAddClass = defaultOption(oOptions, 'bAddClass', bFAYTAddClass);
	this.sFoundClassName = defaultOption(oOptions, 'sFoundClassName', sFAYTFoundClassName);
	this.sFilteredClassName = defaultOption(oOptions, 'sFilteredClassName', sFAYTFilteredClassName);
	this.sParentClasses = defaultOption(oOptions, 'sParentClasses', null);

	this.aOccurrences = new Array();
	this.iLastSearchTime = 0;
	this.sLastText = '';

	this.clearing = false;
	this.TO = 0;

	return this;
}

FAYT.prototype.find = function(sText) {
	if (this.TO) clearTimeout(this.TO);
	var oThis = this;
	this.TO = setTimeout(function() { oThis.findIt(sText) }, 300);
}

FAYT.prototype.findIt = function(sInputText) {
	if (this.clearing) {
		this.find(sInputText);
	} else if (sInputText != this.sLastText) {
//		var dStart = new Date();
		this.clearSelection();
		if (sInputText.length >= this.iMinTextLength) {
			var sText = sInputText.toLowerCase();
			// array with all the strings we are searching for
			var aText = this.createAdditionalTextsArray(sText, this.iMinTextLength);
			// regexp for speeding the search
			var reText = '';
			for (var i = 0; i < aText.length; i++) { if (i > 0) reText += '|'; reText += aText[i][0] }
			this.reText = new RegExp('(' + reText + ')', 'g');
			// searching
			this.selectText(sText, aText, this.oElem, 0);
			this.aOccurrences.sort(function(a, b){ return a[1] - b[1] });
		}
		this.sLastText = sInputText;
		
		/* если нужно классом помечать родительские элементы,
		   то это делается уже после окончательного поиска */
		if (this.bAddClass) {
			addClassToParents(this.aOccurrences, this.sFoundClassName, this.sParentClasses, this.oElem);
			if (this.aOccurrences.length) addClass(this.oElem, this.sFilteredClassName);
			else removeClass(this.oElem, this.sFilteredClassName);
		}
//		var dEnd = new Date();
//		this.iLastSearchTime = dEnd.getTime() - dStart.getTime();	
//		dalert('чистка с поиском заняли ' + this.iLastSearchTime + 'ms');
		if (window.FAYTResults) FAYTResults(this);
	}
}

FAYT.prototype.selectText = function(sText, aText, oParent, iParentNo) {
	var oNode = (oParent)? oParent.firstChild : this.oElem.firstChild;
	var iNextParentNo = iParentNo + 1;
	while (oNode) {
		switch (oNode.nodeType) {
			case 1:
				// проверяем а есть ли вообще такой текст внутри этой нодой и если есть - ищем дальше
				// ускоряет при сложных HTML-конструкциях и поиске уникального текста
				if ( oNode.innerHTML.replace( /<\/?\w[^>]*>/g, ' ' ).toLowerCase().match(this.reText) )
					iNextParentNo = this.selectText(sText, aText, oNode, iNextParentNo);
				break;
			case 3:
				if (oNode.nodeValue.length > 0) {
					var aNodeOccurrences = getNodeOccurrences(oNode.nodeValue, sText, aText);
					for (var i = 0; i < aNodeOccurrences.length; i++) {
						var oSelectionText = oNode.splitText(aNodeOccurrences[i][0]);
						var oLeftText = oSelectionText.splitText(aNodeOccurrences[i][1]);
						var oSelectionElem = document.createElement(this.sHLElemName);
						if (this.sHLElemClass) oSelectionElem.className = this.sHLElemClass;
						oNode.parentNode.insertBefore(oSelectionElem, oNode.nextSibling);
						oSelectionElem.appendChild(oSelectionText);
						this.aOccurrences[this.aOccurrences.length] = [oSelectionElem, iParentNo];
						oNode = oLeftText;
					}
				}
				break;
		}
		oNode = oNode.nextSibling;
	}
	return iNextParentNo;
}

function getNodeOccurrences(sNodeValue, sText, aText) {
	var aNodeOccurrences = new Array();
	var sNodeValue = sNodeValue.toLowerCase();

	for (var i = 0; i < aText.length; i++) {
		var iIteration = 0;
		while (sNodeValue.indexOf(aText[i][0]) >= 0) {
			var iTextOffset = sNodeValue.indexOf(aText[i][0]);
			aNodeOccurrences[aNodeOccurrences.length] = [iTextOffset + aText[i][1], aText[i][0].length];
			sNodeValue = sNodeValue.substr(iTextOffset + aText[i][0].length);
			iIteration++;
		}
	}

	return aNodeOccurrences;
}



FAYT.prototype.clearSelection = function() {
	this.clearing = true;
	if (this.bAddClass) {
		removeClassFromParents(this.aOccurrences, this.sFoundClassName, this.sParentClasses, this.oElem);
	}
	for (var i = this.aOccurrences.length - 1; i >= 0 ; i--) {
		if (this.aOccurrences[i][0]) {
			var oOccurrence = this.aOccurrences[i][0];
			if (oOccurrence && oOccurrence.firstChild) {
				var oParent = oOccurrence.parentNode;
				oParent.insertBefore(oOccurrence.firstChild, oOccurrence);
				oParent.removeChild(oOccurrence);
				if (i == 0 || this.aOccurrences[i][1] != this.aOccurrences[i-1][1]) {
					if (document.all && !window.opera) oParent.innerHTML = oParent.innerHTML;
					else oParent.normalize();
				}
			}
		}
	}
	this.aOccurrences.length = 0;
	this.clearing = false;
}

FAYT.prototype.createAdditionalTextsArray = function(sText, iMinTextLength) {
	var aText = new Array();
	var aSplit = sText.replace(/(\s|,(\s)?)/g, '±').split('±');
	var iWordStart = (this.bWordStartOnly)? 1 : 0;
	for (var i = 0; i < aSplit.length; i++) if (aSplit[i].length >= iMinTextLength) aText[aText.length] = [aSplit[i], 0, iWordStart];
	if (this.bTranslit && window.translitToLat) {
		var sLat = translitToLat(sText);
		var sCyr = translitToCyr(sText);
		if (sText != sLat) aText[aText.length] = [sLat, 0, iWordStart];
		if (sText != sCyr) aText[aText.length] = [sCyr, 0, iWordStart];
	}
	if (this.bWordStartOnly) {
		aText[aText.length] = ['"' + sText, 1, 1];
		aText[aText.length] = [' ' + sText, 1, 1];
		aText[aText.length] = ['\t' + sText, 1, 1];
	}
	return aText;
}

function checkEvent(oEvt){
	oEvt=(oEvt) ? oEvt : ( (window.event) ? window.event : null );
	if(oEvt && oEvt.srcElement && !window.opera)
		oEvt.target=oEvt.srcElement;
	return oEvt;
}

/* function FAYTResults(oResult){
	if(oResult.aOccurrences.length)
		addClass(document.getElementById('Alphabet'), 'hidden');
	else
		removeClass(document.getElementById('Alphabet'), 'hidden');
} */

function FAYTResults(FAYTObject) {
	var eFAYTResults = document.getElementById('fayt-results');
	var eAlphabet = document.getElementById('Alphabet');
	if (!eFAYTResults) return;
	if (!FAYTObject.sLastText || FAYTObject.sLastText.length < FAYTObject.iMinTextLength) {
		/* ничего не искали */
		eFAYTResults.className = eAlphabet.className = '';
	} else if (FAYTObject.aOccurrences.length) {
		/* ничего не найдено */
		eFAYTResults.className = 'filtered';
		eAlphabet.className='hidden';
	} else {
		/* фильтр применен */
		eFAYTResults.className = 'no-results';
		eAlphabet.className='';
	}
}

var aContainers=[];

function RescanContainers(){
	var oParent=document.getElementById('fayt-content');
	var aDiv=oParent.getElementsByTagName('div');
	aContainers=[];
	for(var i=0; i<aDiv.length; i++){
		if(cmnMatch_class(aDiv[i], 'container'))
			aContainers[aContainers.length]=aDiv[i];
	}
}

function SwitchContainer(evt){
	if((evt=checkEvent(evt))){
		if(evt.cancelable){
			evt.preventDefault();
			evt.stopPropagation();
		}
		
		var elemHref=evt.target;
		do{
			if(elemHref.nodeType == 1 && elemHref.tagName == 'A')
				break;
		}while(elemHref = elemHref.parentNode);
		
		if(elemHref && !cmnMatch_class(elemHref, 'selected')){
			var oParent=document.getElementById('fayt-content');
			var sID='cnt'+elemHref.href.substr(elemHref.href.indexOf('#')+1);
			
			if(!aContainers.length){
				RescanContainers();
			}
			
			//~ показываем нужную секцию
			for(var i=0; i<aContainers.length; i++){
				if(aContainers[i].id == sID)
					cmnRemove_class(aContainers[i], 'hidden');
				else
					cmnSet_class(aContainers[i], 'hidden');
			}
			
			//~ подсвечиваю нужную букву
			var aHref=elemHref.parentNode.getElementsByTagName('a');
			for(var i=0; i<aHref.length; i++){
				if(aHref[i] == elemHref){
					cmnSet_class(aHref[i], 'selected');
					aHref[i].blur();
				}
				else
					cmnRemove_class(aHref[i], 'selected');
			}
			
		}
	}
	
	return false;
}

addEvent(window, 'load', RescanContainers);