var HSUIisOpen = false;
var HSUIisInUse = false;
var HSUIpreviousString = "";
var HSspotResults_a = new Array();
var HSUIactiveLink = -1;
var HSUIspotAll = false;
var HSUImaxResults = 10;

var HLtxt = null;
var HLimg = null;
var HLpages = null;

try {
	HLtxt = new kwasiHighlightText();
} catch ( e ) {
	//debug( "no text highlight" );
}

try {
	HLimg = new kwasiHighlightImages();
} catch ( e ) {
	//debug( "no image highlight" );
}

try {
	HLpages = new kwasiHighlightPages();
} catch ( e ) {
	//debug( "no page highlight" );
}

function debug( DEBUG_STRING ) {
	if ( window.console ) {
		window.console.log( DEBUG_STRING );
		//console.log( "bla" );
		//console.error( "fehler" );
		//console.warn( "waarnung" );
	} else {
		alert( DEBUG_STRING );
	}
}

var activityIndicatorAnimation = null;

function activityIndicator( BOOL ) {
	var itemToAnimate = document.getElementById( "hlAsync" );
	var itemToAnimateStep = 0;

	var animationHandler = function( ANIMATION, CURRENT, START, FINISH ) {
		itemToAnimate.style.backgroundPosition = "0px " + ( -16 * itemToAnimateStep ) + "px";
		itemToAnimateStep++;

//		if ( itemToAnimateStep == 12 ) {
//			itemToAnimateStep = 0;
//		}
	};
	
	if ( BOOL ) {
		if ( activityIndicatorAnimation == null ) {
			itemToAnimate.style.visibility = "visible";
			//itemToAnimate.style.display = "block";
			activityIndicatorAnimation = setInterval( animationHandler, 50 );
		}
	} else {
		clearInterval( activityIndicatorAnimation );
		activityIndicatorAnimation = null;
		itemToAnimate.style.visibility = "hidden";
		//itemToAnimate.style.display = "none";
	}
}

var activePulseAnimation = null;

function activePulse( BOOL ) {
	var itemToAnimate = document.getElementById( "hlButton" );
	var itemToAnimateStep = 0;

	var animationHandler = function() {
		kwasiStyleOpacity( itemToAnimate, 0.75 + 0.25 * Math.sin(itemToAnimateStep) );
		itemToAnimateStep += 0.3;
	};
	
	if ( BOOL ) {
		if ( activePulseAnimation == null ) {
			//itemToAnimate.style.visibility = "visible";
			//itemToAnimate.style.display = "block";
			activePulseAnimation = setInterval( animationHandler, 90 );
		}
	} else {
		clearInterval( activePulseAnimation );
		activePulseAnimation = null;
		kwasiStyleOpacity( itemToAnimate, 1 );
		//itemToAnimate.style.visibility = "hidden";
		//itemToAnimate.style.display = "none";
	}
}

//when close input, show even single letter highlight
//ulla pretium "lorem ipsum" integer
//?highlight=ips%20dolor%20varius%20%22lorem ipsum%22

kwasiAddEventListener( document, "keydown", HSUIonKeyDown, false );

//kwasiAddEventListener( document, "load", init, false );
kwasiAddEventListener( window, "load", getKeywords, false );
//kwasiOnLoad( getKeywords );

/*
function init() {
	//<div onclick="HSUIopen();" id="hlButton" class="inactive"></div>
	hlButton = document.createElement( "div" );
	var newDivId = document.createAttribute( "id" );
	newDivId.nodeValue = "hlButton";
	hlButton.setAttributeNode( newDivId );
	document.getElementById( "gHead" ).insertBefore( hlButton, document.getElementById( "gHeadNavi" ) );
	
	//<div id="hlWindow">
	
	//<div id="hlBar">
	//					<span id="highlightCounter"></span> <input id="hlInput" onChange="HSUIkeyUp( this );" onKeyup="HSUIkeyUp( this );" onFocus="HSUIfocus( this );" onBlur="HSUIblur( this );" type="text" size="24" maxlength="48" value="search" />
	//				</div>
	
	
	hlWindow = document.createElement( "div" );
	var newDivId = document.createAttribute( "id" );
	newDivId.nodeValue = "hlWindow";
	hlWindow.setAttributeNode( newDivId );
	
	hlBar = document.createElement( "div" );
	var newDivId = document.createAttribute( "id" );
	newDivId.nodeValue = "hlBar";
	hlBar.setAttributeNode( newDivId );
	
	hlWindow.appendChild( hlBar );
	
	document.getElementById( "gHead" ).insertBefore( hlWindow, document.getElementById( "gHeadNavi" ) );
}
*/

function getKeywords() {
	//var doc = new getDomAdapter()
	//var temp = doc.parseXml( '<div id="gHighlight"><a href="javascript:HSUIopen();" id="hlButton" class="inactive"></a><div id="hlWindow"><div id="hlBar"><span id="highlightCounter"> </span> <input id="hlInput" onChange="HSUIkeyUp( this );" onKeyup="HSUIkeyUp( this );" onFocus="HSUIfocus( this );" onBlur="HSUIblur( this );" type="text" size="24" maxlength="48" value="search" /></div><div id="hlOutput" onMouseOver="HSUIdisableKeyboard();"><a href="javascript:HSUIspotToggle();" id="hlWindowShowAll">Alle einblenden (<span id="hlPageCounter">0</span>)</a><div id="hispotResults"></div></div></div></div>' );
	//alert( temp.firstChild.getAttribute( "id" ) );
	//document.getElementById( "gHead" ).insertBefore( temp.firstChild.cloneNode(true), document.getElementById( "gHeadNavi" ) );
	
	document.getElementById( "gHighlight" ).style.display = "block";
	
	kwasiAddEventListener( document.getElementById( "hlButton" ), "click", HSUIopen, false );
	kwasiAddEventListener( document.getElementById( "hlInput" ), "change", HSUIkeyUp, false );
	kwasiAddEventListener( document.getElementById( "hlInput" ), "keyup", HSUIkeyUp, false );
	kwasiAddEventListener( document.getElementById( "hlInput" ), "focus", HSUIfocus, false );
	kwasiAddEventListener( document.getElementById( "hlInput" ), "blur", HSUIblur, false );
	kwasiAddEventListener( document.getElementById( "hlOutput" ), "mouseover", HSUIdisableKeyboard, false );
		
	var keywordStirng = location.href.split( "?highlight=" );

	if ( keywordStirng.length > 1 ) {
		HSUIopen();
		HSUIfocus( document.getElementById( "hlInput" ) );
		document.getElementById( "hlInput" ).value = unescape( keywordStirng[1] );
		HSUIkeyUp( document.getElementById( "hlInput" ) );
		HSUIopen();
	} else if ( document.referrer.indexOf( "q=" ) != -1 ) {
		var temp = document.referrer.split( "q=" )[1];
		temp = temp.split( "&" )[0];
		temp = temp.split( "+" );
		temp = temp.join( "%20" );
		HSUIopen();
		HSUIfocus( document.getElementById( "hlInput" ) );
		document.getElementById( "hlInput" ).value = unescape( temp );
		HSUIkeyUp( document.getElementById( "hlInput" ) );
		HSUIopen();
	}
}

function HSUIopen() {
	//alert( HSUIisOpen );
	if ( HSUIisOpen ) {
		HSUIisOpen = false;
		HSUIdisableKeyboard();
		document.getElementById( "hlWindow" ).style.display = "none";
		
		if ( HSUIisInUse ) {
			document.getElementById( "hlButton" ).setAttribute( "class", "active" );
			activePulse( true );
		} else {
			document.getElementById( "hlButton" ).setAttribute( "class", "inactive" );
			activePulse( false );
		}
	} else {
		HSUIisOpen = true;
		document.getElementById( "hlWindow" ).style.display = "block";
		document.getElementById( "hlButton" ).setAttribute( "class", "open" );
		document.getElementById( "hlInput" ).focus();
		activePulse( false );
	}
}

function HSUIfocus() {
	var self = document.getElementById( "hlInput" );
	
	if ( !HSUIisInUse ) {
		HSUIisInUse = true;
	}
}

function HSUIblur() {
	var self = document.getElementById( "hlInput" );
	
	if ( self.value == "" ) {
		HSUIisInUse = false;
	}
}

function HSUIkeyUp() {
	var self = document.getElementById( "hlInput" );
	var HLimgCount = 0;
	var HLtxtCount = 0;
	var theQuery = self.value.consolideWhiteSpace().strip();
	
	if ( theQuery == HSUIpreviousString ) {
		return;
	}
	
	activityIndicator( true );
	HSUIpreviousString = theQuery;
	var queryList = keywordListFromString( theQuery );
	
	var callBack = function( RESULT_DATA, DONE ) {
		if ( DONE ) {
			activityIndicator( false );
		}
		
		HSspotResults_a = RESULT_DATA;
		HSUIupdateSpotResults( false );
	};
	
	if ( HLpages ) {
		HLpages.query( queryList, callBack );
	} else {
		callBack( new Array(), true );
	}
	
	if ( HLimg ) {
		HLimgCount = HLimg.query( queryList );
	}
	
	if ( HLtxt ) {
		HLtxtCount = HLtxt.query( queryList );
	}
	
	if ( theQuery != "" ) {
		document.getElementById( "hlCaption" ).style.display = "none";
		
		if ( HLpages ) {
			document.getElementById( "hlOutput" ).style.display = "block";
			document.getElementById( "hlBottomCap" ).style.display = "block";
		}
		
		if ( HLimg ) {
			document.getElementById( "hlImageCounter" ).style.display = "inline";
			
			if ( HLimgCount ) {
				document.getElementById( "hlImageCounter" ).innerHTML = HLimgCount;
				kwasiStyleOpacity( document.getElementById( "hlImageCounter" ), 1 );
			} else {
				document.getElementById( "hlImageCounter" ).innerHTML = "-";
				kwasiStyleOpacity( document.getElementById( "hlImageCounter" ), 0.5 );
			}
		}
		
		if ( HLtxt ) {
			document.getElementById( "hlTextCounter" ).style.display = "inline";
		
			if ( HLtxtCount ) {
				document.getElementById( "hlTextCounter" ).innerHTML = HLtxtCount;
				kwasiStyleOpacity( document.getElementById( "hlTextCounter" ), 1 );
			} else {
				document.getElementById( "hlTextCounter" ).innerHTML = "-";
				kwasiStyleOpacity( document.getElementById( "hlTextCounter" ), 0.5 );
			}
		}
	} else {
		document.getElementById( "hlOutput" ).style.display = "none";
		document.getElementById( "hlBottomCap" ).style.display = "none";
		document.getElementById( "hlTextCounter" ).style.display = "none";
		document.getElementById( "hlImageCounter" ).style.display = "none";
		document.getElementById( "hlCaption" ).style.display = "inline";
		activityIndicator( false );
	}
	
	HSUIdisableKeyboard();
}

function HSUIupdateSpotResults( FULL ) {
	var i;
	var length = document.getElementById( "hlResults" ).childNodes.length;
		
	for ( i = 0; i < length; i++ ) {
		document.getElementById( "hlResults" ).removeChild( document.getElementById( "hlResults" ).lastChild );
	}
	
	length = HSspotResults_a.length;
	document.getElementById( "hlPageCounter" ).innerHTML = length;
	document.getElementById( "hlPageCounterAll" ).innerHTML = length;
	
	if ( length ) {
		document.getElementById( "hlWindowNotFound" ).style.display = "none";
		
		if ( ( !FULL ) && ( length > ( HSUImaxResults + 5 ) ) ) {
			length = HSUImaxResults;
			document.getElementById( "hlWindowShowAll" ).style.display = "block";
			document.getElementById( "hlWindowShowingOne" ).style.display = "none";
			document.getElementById( "hlWindowShowingAll" ).style.display = "none";
		} else {
			document.getElementById( "hlWindowShowAll" ).style.display = "none";
			
			if ( length == 1 ) {
				document.getElementById( "hlWindowShowingOne" ).style.display = "block";
				document.getElementById( "hlWindowShowingAll" ).style.display = "none";
			} else {
				document.getElementById( "hlWindowShowingOne" ).style.display = "none";
				document.getElementById( "hlWindowShowingAll" ).style.display = "block";
			}
		}
	} else {
		document.getElementById( "hlWindowNotFound" ).style.display = "block";
		document.getElementById( "hlWindowShowAll" ).style.display = "none";
		document.getElementById( "hlWindowShowingOne" ).style.display = "none";
		document.getElementById( "hlWindowShowingAll" ).style.display = "none";
	}
		
	for ( i = 0; i < length; i++ ) {
		document.getElementById( "hlResults" ).appendChild( HSspotResults_a[i] );
		
		HSspotResults_a[i].onclick = HSUIgoToURL;
	}
}

function HSUIgoToURL() {
	window.location.href = this + "?highlight=" + escape( HSUIpreviousString );
	return false;
}

function HSUIspotToggle() {
	HSUIspotAll = !HSUIspotAll;
	HSUIupdateSpotResults( HSUIspotAll );
}

function HSUIonKeyDown( EVENT ) {
	if ( !HSUIisOpen ) {
		return true;
	}
	
	var keyCode = kwasiKeyCode( EVENT );
	var links_a = document.getElementById( "hlOutput" ).getElementsByTagName( "a" );
	var linkCount = links_a.length;
	
	switch ( keyCode ) {
			//key-up
		case 38:
			HSUIactiveLink--;
			
			if ( HSUIactiveLink < 0 ) {
				HSUIactiveLink = 0;
			}
			
			HSUIselectLink( HSUIactiveLink );
			return false;
			
			//key-down
		case 40:
			HSUIactiveLink++;
			
			if ( HSUIactiveLink >= linkCount ) {
				HSUIactiveLink = linkCount - 1;
			}
			
			HSUIselectLink( HSUIactiveLink );
			return false;
			
			//return
		case 13:
			switch ( HSUIactiveLink ) {
				case -1:
					return true;
				case 0:
					HSUIspotToggle();
					return false;
				default:
					window.location.href = document.getElementById( "hlOutput" ).getElementsByTagName( "a" )[HSUIactiveLink] + "?highlight=" + escape( HSUIpreviousString );
					return false;
			}
			
		default:
			return true;
	}
}

function HSUIselectLink( ACTIVE_LINK ) {
	var links_a = document.getElementById( "hlOutput" ).getElementsByTagName( "a" );
	
	for ( var i = 0; i < links_a.length; i++ ) {
		links_a[i].style.background = "";
		links_a[i].style.color = "";
	}
	
	if ( ACTIVE_LINK >= 0 ) {
		links_a[ACTIVE_LINK].style.background = "#811";
		links_a[ACTIVE_LINK].style.color = "#fff";
	}
}

function HSUIdisableKeyboard() {
	HSUIactiveLink = -1;
	HSUIselectLink( -1 );
}

function createMultiCharCombinations( STRING ) {
	var charPos_a = new Array();
	var keyword_a = new Array();
	var byPosInv = function( A, B ) { return B.p - A.p; };
	var bin = 1;
	var unicodeMultiCharList = new Array( { c:"§", d:"SS" }, { c:"©", d:"(C)" }, { c:"«", d:"<<" }, { c:"®", d:"(R)" }, { c:"±", d:"+-" }, { c:"»", d:">>" }, { c:"¼", d:"1/4" }, { c:"½", d:"1/2" }, { c:"¾", d:"3/4" }, { c:"Æ", d:"AE" }, { c:"ß", d:"ss" }, { c:"æ", d:"ae" }, { c:"Ĳ", d:"IJ" }, { c:"ĳ", d:"ij" }, { c:"Œ", d:"OE" }, { c:"œ", d:"oe" }, { c:"ƕ", d:"hv" }, { c:"Ƣ", d:"OI" }, { c:"ƣ", d:"oi" }, { c:"ǁ", d:"||" }, { c:"Ǆ", d:"DZ" }, { c:"ǅ", d:"Dz" }, { c:"ǆ", d:"dz" }, { c:"Ǉ", d:"LJ" }, { c:"ǈ", d:"Lj" }, { c:"ǉ", d:"lj" }, { c:"Ǌ", d:"NJ" }, { c:"ǋ", d:"Nj" }, { c:"ǌ", d:"nj" }, { c:"Ǣ", d:"AE" }, { c:"ǣ", d:"ae" }, { c:"Ǳ", d:"DZ" }, { c:"ǲ", d:"Dz" }, { c:"ǳ", d:"dz" }, { c:"Ƕ", d:"Hv" }, { c:"Ǽ", d:"AE" }, { c:"ǽ", d:"ae" }, { c:"Ȣ", d:"OU" }, { c:"ȣ", d:"ou" }, { c:"ȸ", d:"db" }, { c:"ȹ", d:"qp" } );

	//first reassemble potentially disassembled characters to avoid sß -> sss -> ßs and instead have sss -> ßs -> sss
	for ( var ass = 0; ass < unicodeMultiCharList.length; ass++ ) {
		if ( STRING.indexOf( unicodeMultiCharList[ass].d ) != -1 ) {
			STRING = STRING.replace( new RegExp( unicodeMultiCharList[ass].d, "g" ), unicodeMultiCharList[ass].c );
		}
	}

	for ( var ass = 0; ass < unicodeMultiCharList.length; ass++ ) {
		var string = STRING;
		var pos = string.indexOf( unicodeMultiCharList[ass].c );
		var head = 0;
		
		while ( pos != -1 ) {
			charPos_a.push( { c:unicodeMultiCharList[ass].c, d:unicodeMultiCharList[ass].d, p:(head + pos), b:0 } );
			head += ( pos + 1 );
			string = string.substring( ( pos + 1 ), string.length );
			pos = string.indexOf( unicodeMultiCharList[ass].c );
		}
	}
	
	//we need to sort this because we want to replace characters from the back so the position does not get shifted
	charPos_a.sort( byPosInv );
	
	for ( var oc = 0; oc < charPos_a.length; oc++ ) {
		charPos_a[oc].b = bin;
		bin *= 2;
	}
	
	for ( var i = 0; i < bin; i++ ) {
		var string = STRING;
		
		for ( var ass = 0; ass < charPos_a.length; ass++ ) {
			if ( charPos_a[ass].b & i ) {
				string = string.substring( 0, charPos_a[ass].p ) + charPos_a[ass].d + string.substring( charPos_a[ass].p+1, string.length );
			}
		}
		
		keyword_a.push( string );
	}
	
	return keyword_a;
}

function keywordListFromString( STRING ) {
	var keyword_a = new Array();
	var multiChar_a = new Array();
	var quoteSeparated = STRING.toLowerCase().kwasiCUTBL().split( "\"" );
	
	for ( var i = 0; i < quoteSeparated.length; i += 2 ) {
		var spaceSeparated = quoteSeparated[i].kwasiSNLC().split( " " );
		
		for ( var j = 0; j < spaceSeparated.length; j++ ) {
			if ( spaceSeparated[j].length > 0 ) {
				keyword_a.push( spaceSeparated[j] );
			}
		}
	}
	
	for ( var i = 1; i < quoteSeparated.length; i += 2 ) {
		if ( quoteSeparated[i].length > 0 ) {
			keyword_a.push( quoteSeparated[i] );
		}
	}
	
	//remove duplicates before processing
	for ( var key = keyword_a.length-1; key >= 0; key-- ) {
		for ( var keyb = key-1; keyb >= 0; keyb-- ) {
			if ( keyword_a[key] == keyword_a[keyb] ) {
				keyword_a.splice( key, 1 );
				break;
			}
		}
	}
	
	for ( var j = 0; j < keyword_a.length; j++ ) {
		if ( keyword_a[j].length ) {
			multiChar_a.push( createMultiCharCombinations( keyword_a[j] ) );
		}
	}
	
	for ( var key = multiChar_a.length-1; key >= 0; key-- ) {
		for ( var keyb = 0; keyb < multiChar_a[key].length; keyb++ ) {
			multiChar_a[key][keyb] = multiChar_a[key][keyb].kwasiSNLC().strip().consolideWhiteSpace();
		}
		
		//remove duplicates after processing (some duplicates may not be obvious like strasse == straße)
		for ( var keyb = key-1; keyb >= 0; keyb-- ) {
			if ( multiChar_a[key][0] == multiChar_a[keyb][0] ) {
				multiChar_a.splice( key, 1 );
				break;
			}
		}
		
		//remove empty items
		if ( multiChar_a[key][0].length == 0 ) {
			multiChar_a.splice( key, 1 );
		}
	}
	
	return multiChar_a;
}

