/**
 * Applications.Soek.SoekLibrary>>#toggleSourceJs
 */
function toggle_source(id) { 
	var link=document.getElementById("toggle."+id);
	var src=document.getElementById(id);
	if (src.style.display != "block") {
		link.firstChild.data = "hide source";
		src.style.display = "block";
	} else {	
		link.firstChild.data = "show source";
		src.style.display = "none";
 	}
}
/**
 * Applications.Soek.SoekLibrary>>#forceLoadOfContentAnchor
 */
function forceLoadOfContentAnchor(anchor_id){
	
	var load_element = $(anchor_id);
	if (load_element != null){
		var el_text = load_element.innerHTML.strip();
		setSearchFieldValue(el_text);
		scrollToAnchor(anchor_id);
		/* setSavedSearch(getCurrentTab(), el_text); */

		window.location = load_element.href;
	}
}
/**
 * Applications.Soek.SoekLibrary>>#qsAdditionJs
 */

	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */
var QSAddition = {	
	buildCache: function() {
	  if (window.console && window.console.log) { console.log('building cache'); }
	  QSAddition.rows = $A([]);
	  QSAddition.cache = $A([]);
		$$('#listScroller li a').each(function(element) {
			QSAddition.rows.push(element);
			QSAddition.cache.push(element.innerHTML.toLowerCase());
		});
	},
	
	searchCache: function(term) {
		var term = term.toLowerCase();
		var len = QSAddition.cache.length;
		var scores = $A([]);
		
		for(var i=0; i < len; i++) {
			var score = QSAddition.cache[i].score(term);
			if (score > 0) { scores.push([score, i]); }
		}
		
		sorted = scores.sort(function(a,b) { return b[0] - a[0]; })
		return sorted.length > 0 ? QSAddition.rows[sorted[0][1]] : null;
	}
}
/**
 * Applications.Soek.SoekLibrary>>#scrollListToElementOffsetJs
 */
//this handles the up/down keystrokes to move the selection of items in the list
function scrollListToElementOffset(anchor_id, offset){
	var scroller = $('listScroller');
	var a_array = scroller.getElementsByTagName('a');
	var current_index = findIndexOfAnchor(a_array, anchor_id);
	if ((current_index >= 0) && (current_index < a_array.length)){
		/* depending on extra links in parent, increase offset */
		var anchorNode = a_array[current_index];
		var indexOffset = offset * ( anchorNode.parentNode.getElementsByTagName('a').length );
		scrollListToAnchor(a_array[current_index + indexOffset].id);
		setListActiveAnchor(a_array[current_index + indexOffset].id);
	}
}



// This function was written by Rick DeNatale http://talklikeaduck.denhaven2.com/
// THANKS RICK! This is a great suggestion
RegExp.escape = function(text) {
  if (!arguments.callee.sRE) {
    var specials = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\'' ];
    arguments.callee.sRE = new RegExp('(\'' + specials.join('|\'') + ')', 'g');
  }
  return text.replace(arguments.callee.sRE, '\$1');
}
/**
 * Applications.Soek.SoekLibrary>>#loadPartialJs
 */
function loadPartial(url,targetID) {
	new Ajax.Request(url, {
		method: "get",
		onLoading: changeLoadingStatus("on"),
		onSuccess: function(method_data) {	
			$(targetID).innerHTML = method_data.responseText },
		onComplete: function(request) { changeLoadingStatus("off"); },	
		onFailure: function(response) { alert(response.statusText); }
		});
}
function changeLoadingStatus(onoff) {
}

/**
 * Applications.Soek.SoekLibrary>>#findIndexOfAnchor
 */
function findIndexOfAnchor(a_array, anchor_id){
	var found=false;
	var counter = 0;
	while(!found && counter < a_array.length){
		if (a_array[counter].id == anchor_id){
			found = true;
		}else{
			counter +=1;
		}
	}
	return(counter);
}
/**
 * Applications.Soek.SoekLibrary>>#scrollToNameJs
 */
function scrollToName(searcher_name){
	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */

	var scroller = $('listScroller');
	var a_array = scroller.getElementsByTagName('a');
	
	if (!searcher_name.match(new RegExp(/ +/))){ //if searcher name is blank
		
		var searcher_pattern = new RegExp("^"+RegExp.escape(searcher_name.escapeHTML()), "i"); //the "i" is for case INsensitive
    
		var found_index = -1;

		var found = false;
		var x = 0;
		while(!found && x < a_array.length){
			if(a_array[x].innerHTML.match(searcher_pattern)){
				found = true;
				found_index = x;
			}
			else{
				x++;
			}
		}

		if ((found_index >= 0) && (found_index < a_array.length)) {
			scrollListToAnchor(a_array[found_index].id);//scroll to the item
			setListActiveAnchor(a_array[found_index].id);//highlight the item
		} else {
			var result = QSAddition.searchCache(searcher_name);
			if (result) {
			  if (window.console && window.console.log) { console.log('searching with qs'); }
				scrollListToAnchor(result);
				setListActiveAnchor(result);
			}
		}
	}
}
/**
 * Applications.Soek.SoekLibrary>>#handleMethodSelectedJs
 */
function handleMethodSelected(versionPath,className,focusSelector) {
	new Ajax.Request(versionPath + className + ".phtml", {
		method: "get",
		onLoading: changeLoadingStatus("on"),
		onSuccess: function(method_data) {	
			$("classview").innerHTML = method_data.responseText;
			window.SyntaxHighlighter.highlight(); 
			setFocusToSelector(focusSelector);
		},
		onComplete: function(request) { 
			$("classtitle").innerHTML = className;
		},	
		onFailure: function(response) { alert(response.statusText); }
		});	
}
/**
 * Applications.Soek.SoekLibrary>>#toggleHierarchyJs
 */
function toggle_hierarchy(id) { 
	var link=document.getElementById("toggle."+id);
	var src=document.getElementById(id);
	if (src.style.display != "block") {
		link.firstChild.data = "hide hierarchy";
		src.style.display = "block";
	} else {	
		link.firstChild.data = "show hierarchy";
		src.style.display = "none";
 	}
}
/**
 * Applications.Soek.SoekLibrary>>#scrollToAnchorJs
 */
function scrollToAnchor(anchor_id){
	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */

	var scroller = $('listScroller');
	if ($(anchor_id) != null){
		scrollListToAnchor(anchor_id);
		setListActiveAnchor(anchor_id);
	}
}
/**
 * Applications.Soek.SoekLibrary>>#getYJs
 */
function getY(element){
	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */
	
	var y = 0;
	for( var e = element; e; e = e.offsetParent)//iterate the offset Parents
	{
		y += e.offsetTop; //add up the offsetTop values
	}
	return y;
}
/**
 * Applications.Soek.SoekLibrary>>#findIndexOfAnchorName
 */
function findIndexOfAnchorName(a_array, anchor_name){
	var found=false;
	var counter = 0;
	while(!found && counter < a_array.length){
		if (a_array[counter].name == anchor_name){
			found = true;
		}else{
			counter +=1;
		}
	}
	return(counter);
}
/**
 * Applications.Soek.SoekLibrary>>#handleMethodsSelectedJs
 */
function handleMethodsSelected() {
	loadPartial("selectors.phtml", "listview");
	$("buttonMethods").className = "filterbutton-selected";
	$("buttonClasses").className = "filterbutton";
}
/**
 * Applications.Soek.SoekLibrary>>#hookUpActiveSearchJs
 */
function hookUpActiveSearch(){
	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */
	
	var s_field = $('searchpattern');
	Event.observe(s_field, 'keydown', function(event) {
		var el = Event.element(event);
		var key = event.which || event.keyCode;
		
		switch (key) {
			case Event.KEY_RETURN:
				forceLoadOfContentAnchor(getCurrentAnchor());
				Event.stop(event);
			break;
			case Event.KEY_UP:
				scrollListToElementOffset(getCurrentAnchor(),-1);
			break;
			
			case Event.KEY_DOWN:
				scrollListToElementOffset(getCurrentAnchor(),1);
			break;
			
			default:
			break;
		}

	});
	
	Event.observe(s_field, 'keyup', function(event) {
		var el = Event.element(event);
		var key = event.which || event.keyCode;
		switch (key) {
			case Event.KEY_RETURN:
				Event.stop(event);
			break;
			
			case Event.KEY_UP:
			break;
			
			case Event.KEY_DOWN:
			break;
			
			default:
				scrollToName(el.value);
				/* setSavedSearch(getCurrentTab(), el.value); */
			break;
		}
		
	});
	
	Event.observe(s_field, 'keypress', function(event){
		var el = Event.element(event);
		var key = event.which || event.keyCode;
		switch (key) {
			case Event.KEY_RETURN:
				Event.stop(event);
			break;
			
			default:
			break;
		}
		
	});
}
/**
 * Applications.Soek.SoekLibrary>>#qsScoreJs
 */

// qs_score - Quicksilver Score
// 
// A port of the Quicksilver string ranking algorithm
// 
// "hello world".score("axl") //=> 0.0
// "hello world".score("ow") //=> 0.6
// "hello world".score("hello world") //=> 1.0
//
// Tested in Firefox 2 and Safari 3
//
// The Quicksilver code is available here
// http://code.google.com/p/blacktree-alchemy/
// http://blacktree-alchemy.googlecode.com/svn/trunk/Crucible/Code/NSString+BLTRRanking.m
//
// The MIT License
// 
// Copyright (c) 2008 Lachie Cox
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


String.prototype.score = function(abbreviation,offset) {
  offset = offset || 0 // TODO: I think this is unused... remove
 
  if(abbreviation.length == 0) return 0.9
  if(abbreviation.length > this.length) return 0.0

  for (var i = abbreviation.length; i > 0; i--) {
    var sub_abbreviation = abbreviation.substring(0,i)
    var index = this.indexOf(sub_abbreviation)


    if(index < 0) continue;
    if(index + abbreviation.length > this.length + offset) continue;

    var next_string       = this.substring(index+sub_abbreviation.length)
    var next_abbreviation = null

    if(i >= abbreviation.length)
      next_abbreviation = ''
    else
      next_abbreviation = abbreviation.substring(i)
 
    var remaining_score   = next_string.score(next_abbreviation,offset+index)
 
    if (remaining_score > 0) {
      var score = this.length-next_string.length;

      if(index != 0) {
        var j = 0;

        var c = this.charCodeAt(index-1)
        if(c==32 || c == 9) {
          for(var j=(index-2); j >= 0; j--) {
            c = this.charCodeAt(j)
            score -= ((c == 32 || c == 9) ? 1 : 0.15)
          }

          // XXX maybe not port this heuristic
          // 
          //          } else if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[self characterAtIndex:matchedRange.location]]) {
          //            for (j = matchedRange.location-1; j >= (int) searchRange.location; j--) {
          //              if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[self characterAtIndex:j]])
          //                score--;
          //              else
          //                score -= 0.15;
          //            }
        } else {
          score -= index
        }
      }
   
      score += remaining_score * next_string.length
      score /= this.length;
      return score
    }
  }
  return 0.0
}
/**
 * Applications.Soek.SoekLibrary>>#setListActiveAnchor
 */

	/* this code was copied on 21-10-2009 from Railsbrain.com, created by Brian Chamberlain */

function setListActiveAnchor(active_anchor){
	if ((getCurrentAnchor() != null) && ($(getCurrentAnchor()) != null)){
		$(getCurrentAnchor()).parentNode.className = "listitem";
	}
	setCurrentAnchor(active_anchor);
	var ca = $(getCurrentAnchor());
	if (ca != null) { ca.parentNode.className = "selected listitem"; }
}
/**
 * Applications.Soek.SoekLibrary>>#scrollListToAnchorJs
 */
function scrollListToAnchor(scroll2_anchor){
	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */

	var scroller = $('listScroller');
	scroller.scrollTop = getY($(scroll2_anchor)) - 100;
}
/**
 * Applications.Soek.SoekLibrary>>#currentAnchorJs
 */

	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */

var Anchor_ID_Of_Current = null; // holds the last highlighted anchor tag in the scroll lsit
function getCurrentAnchor(){
	return(Anchor_ID_Of_Current);
}

function setCurrentAnchor(a_id){
	Anchor_ID_Of_Current = a_id;
}
/**
 * Applications.Soek.SoekLibrary>>#setSearchFieldValue
 */
function setSearchFieldValue(s){
	
	$('searchpattern').value = s;
}
/**
 * Applications.Soek.SoekLibrary>>#toggleCommentJs
 */
function toggle_comment(id) { 
	var link=document.getElementById("toggle."+id);
	var src=document.getElementById(id);
	if (src.style.display != "block") {
		link.firstChild.data = "hide comment";
		src.style.display = "block";
	} else {	
		link.firstChild.data = "show comment";
		src.style.display = "none";
 	}
}
/**
 * Applications.Soek.SoekLibrary>>#handleClassesSelectedJs
 */
function handleClassesSelected() {
	loadPartial("classes.phtml", "listview");
	$("buttonMethods").className = "filterbutton";
	$("buttonClasses").className = "filterbutton-selected";
}
/**
 * Applications.Soek.SoekLibrary>>#handleClassSelectedJs
 */
function handleClassSelected(versionPath,className) {
	new Ajax.Request(versionPath + className + ".phtml", {
		method: "get",
		onLoading: changeLoadingStatus("on"),
		onSuccess: function(method_data) {	
			$("classview").innerHTML = method_data.responseText;
			window.SyntaxHighlighter.highlight(); },
		onComplete: function(request) { 
			$("classtitle").innerHTML = className;
		},	
		onFailure: function(response) { alert(response.statusText); }
		});	
}
/**
 * Applications.Soek.SoekLibrary>>#setSavedSearchJs
 */

	/* this code was copied on 10-10-2009 from Railsbrain.com, created by Brian Chamberlain */

//These globals should not be used globally (hence the getters and setters)
var File_Search = "";
var Method_Search = "";
var Class_Search = "";
function setSavedSearch(tab_name, s_val){
	switch(tab_name){
		case "methods":
			Method_Search = s_val;
			break;
		case "files":
			File_Search = s_val;
			break;
		case "classes":
			Class_Search = s_val;
			break;
	}
}
/**
 * Applications.Soek.SoekLibrary>>#setFocusToSelectorJs
 */

var FocusNode;
var FocusSourceNodeID;
function setFocusToSelector(focusSelector,meta) {
	// clear old focus
	if (FocusNode != null) {
		FocusNode.className = "mdf";
		toggle_source(FocusSourceNodeID);
	}
	var classView = $("classview");
	var selectors = classView.getElementsByTagName("a");
	var anchorName = focusSelector;
	if (meta) { anchorName = "class_" + anchorName }
	var index = findIndexOfAnchorName(selectors,anchorName);
	selectors[index].parentNode.className = "mdf focus";

	// toggle source
	var mdf_children = selectors[index].parentNode.childNodes;
	var source_id = mdf_children[mdf_children.length-1].id.split(".").pop();
	toggle_source(source_id);
	selectors[index].parentNode.scrollIntoView("true");

	// save focus info
	FocusNode = selectors[index].parentNode;
	FocusSourceNodeID = source_id;
}