function str_replace(search,replace,subject)
{
	return subject.split(search).join(replace);
}
function initSearchController(ajaxServiceUrl,initialQuery)
{
	if(window.SearchController == undefined)
	{
		window.SearchController =
		{
			searchContext:
			{
				ontology: null,
				/** @constructor */
				serviceUrls:
				{
					resetSearch: null,
					loadTree: null,
					queryTerms: null,
					treeNodeEvent: null,
					search: null
				},
				/** @constructor */
				serviceUrlParts:
				{
					arguments: null,
					serverUri: null
				},
				/** @constructor */
				setServiceUrl: function(url)
				{
					var parts = url.split("?");
					if(parts.length >= 2)
					{
						
						this.serviceUrlParts.serverUri = parts[0];
						this.serviceUrlParts.arguments = parts[1];
					}else if(parts.length == 1)
					{ // no '?'
						this.serviceUrlParts.serverUri = parts[0];
					}
					if(this.serviceUrlParts.serverUri.charAt(this.serviceUrlParts.serverUri.length - 1) != '/')
					{
						this.serviceUrlParts.serverUri += '/';
					}
				},
				/** @constructor */
				buildServiceUrl: function(scriptPart)
				{
					var tempUri = this.serviceUrlParts.serverUri;
					if(scriptPart != null)
					{
						tempUri += scriptPart;
					}
					
					tempUri += '?' + (this.serviceUrlParts.arguments != null?this.serviceUrlParts.arguments:"0");
					
					return tempUri;
				}
			},
			/** @constructor */
			init: function(ajaxServiceUrl)
			{
				window.SearchController.searchContext.setServiceUrl(ajaxServiceUrl);
				this.searchContext.serviceUrls.resetSearch = window.SearchController.searchContext.buildServiceUrl("resetSearch");
				this.searchContext.serviceUrls.loadTree = window.SearchController.searchContext.buildServiceUrl("loadTree");
				this.searchContext.serviceUrls.querySuggest = window.SearchController.searchContext.buildServiceUrl("querySuggest");
				this.searchContext.serviceUrls.queryTerms = window.SearchController.searchContext.buildServiceUrl("queryTerms");
				this.searchContext.serviceUrls.treeNodeEvent = window.SearchController.searchContext.buildServiceUrl("treeNodeEvent");
				this.searchContext.serviceUrls.currentOntology = window.SearchController.searchContext.buildServiceUrl("currentonto");
				this.searchContext.serviceUrls.search = window.SearchController.searchContext.buildServiceUrl("search");
				if(initialQuery == null)
				{
					this.resetSearch();
				}
				this.fetchTermNodes(null,function(termNodes)
				{
					window.SearchController.searchContext.ontology = termNodes;
				});
			},
			/** @constructor */
			resetSearch: function(rootNodeId,pushTermNodesCallback)
			{
				sendAjaxRequest(this.searchContext.serviceUrls.resetSearch,null,null);
			},
			/** @constructor */
			fetchTermNodes: function(rootNodeId,pushTermNodesCallback)
			{
				termNodeResponse = null;
				sendAjaxRequest(this.searchContext.serviceUrls.loadTree + '&parent=' + rootNodeId,function(transport)
				{
					if(transport.status == 200)
					{
						var jsonResponse = transport.responseText.evalJSON();
						if(jsonResponse != false)
						{
							if(jsonResponse.error == undefined)
							{
								if(pushTermNodesCallback == null)
								{
									termNodeResponse = jsonResponse;
								}else
								{
									pushTermNodesCallback(jsonResponse);
								}
							}else
							{
								alert("Error: " + jsonResponse.error);
							}
						}else
						{
							// alert(transport.responseText);
						}
					}
				},null);
				return termNodeResponse;
			},
			/** @constructor */
			getQueryTerms: function(id,callback)
			{
				termNodeResponse = null;
				sendAjaxRequest(this.searchContext.serviceUrls.queryTerms + (id != null?"&id=" + id:""),function(transport)
				{
					if(transport.status == 200)
					{
						var jsonResponse = transport.responseText.evalJSON();
						if(jsonResponse != false)
						{
							if(jsonResponse.error == null)
							{
								if(callback == null)
								{
									termNodeResponse = jsonResponse;
								}else
								{
									callback(jsonResponse);
								}
							}else
							{
								alert(jsonResponse.error);
							}
						}else
						{
							alert(transport.responseText);
						}
					}
				},null);
				return termNodeResponse;
			},
			/** @constructor */
			treeNodeEvent: function(nodeId,advancedState,expanded)
			{
				argumentSuffix = '&node=' + nodeId;
				if(advancedState != null )
				{
					argumentSuffix += "&state=" + advancedState;
				}
				if(expanded == false || expanded == true)
				{
					argumentSuffix += "&isx=" + (expanded?"true":"false");
				}
				sendAjaxRequest(this.searchContext.serviceUrls.treeNodeEvent + argumentSuffix,function(transport)
				{
				},null);
			},
			getQuerySuggest: function(callback,query,cursorposition)
			{
				sendAjaxRequest(this.searchContext.serviceUrls.querySuggest,callback,"query=" + query + "&cursorpos=" + cursorposition + "&debug=true");
				
			},
			/** @constructor */
			requestSearch: function(query,termQueryInfo,responseInfo,responseCallback)
			{
				requestData = null;
				if(termQueryInfo != null)
				{
					requestData = "&t=" + query;
					requestData += (termQueryInfo.advancedState == "NONE"?'&action=drop':'&action=add');
				}else
				{
					requestData = "&q=" + query;
				}
				if(responseInfo != null)
				{
					requestData += (responseInfo.asHtml?'&response=resulthtml':'');
				}
				responseCallback(sendAjaxRequest(this.searchContext.serviceUrls.search + requestData,function(transport)
				{
					if(transport.status == 200)
					{
						responseData = null;
						if(transport.responseText != null)
						{
							try
							{
								jsonResponse = transport.responseText.evalJSON();
								if(jsonResponse.error != null)
								{
									throw "Failed to retrieve documents with: '" + jsonResponse.error + "'";
								}
							}catch(error)
							{
								responseData = transport.responseText;
							}
						}
						
						if(responseData === undefined || responseData === null || responseData.length == 0)
						{
							throw "Empty Response";
						}
						
						return responseData;
					}else
					{
						throw "" + transport.responseText;
					}
				},null));
				return termNodeResponse;
			}
		};
		window.SearchController.init(ajaxServiceUrl);
	}
	return window.SearchController;
}

