function yhz_Data(pData,pDelimiter){
	this._data = pData;
  this._delimiter = pDelimiter || ",";


	this.getData=function() { return this._data; }
}
yhz_Data.prototype = Hashtable;
function yhz_Metadata(pData,pDelimiter){ this._data=pData; this._delimiter=pDelimiter; }
yhz_Metadata.prototype = yhz_Data;
function yhz_Search(pId,pDelimiter,pData,pMetadata){ //id, delimiter, data to parse, meta to parse
	this._id=pId;
	this._delimiter=(null!=pDelimiter && ""!=pDelimiter && "undefined"!=pDelimiter) ? pDelimiter : ",";//delimiter
	this.isReady=false;
	this._start_time,this._end_time;//for debug times
	
	this.s=null;//search string
	
	//external data
	this._data=new yhz_Data(pData,null);// hash of del.icio.us bookmarks (object)
	this._metadata=new yhz_Metadata(pMetadata,null);//arraylist of del.icio.us tags (object)
	
	this._results=new Hashtable();// hash of delimted hash keys (ex. hash['web'] = 1,2,45,87)
	this._filteredtags="";// comma delimed string of checked metadata
	
	this.finHTMLRslts="";//HTML of results pane
	this.sCurrSrchRslts="";//comma delim string of filtered results
	this.iCurrSrchRslts=0;//number of items found
    
  this.BOOKMARK_TAG_DELIMITER="@@";
    
	// html
	this.HTML_MSG_NO_RESULTS='Please remove any filters if you have any or type in a new keyword.<br/><br/>'
		+'If problems continue to persist, please contact one of our reps.<br/><br/>';
	this.HTML_HIGHLIGHT="strong";//f & r tag
  this.HTML_FILTER_BY_TITLE = '<h3>Filter by:</h3>';
  this.SELECTED_META_ROW="item-metadata-row";
  this.SELECTED_META_ROW_SELECTED="item-metadata-row-selected";
}
yhz_Search.prototype.getData=function(){
  return this._data; 
}
yhz_Search.prototype.traverse=function(){
	var ch=this._data.getData();
	var sStr=this.s.toLowerCase();
  for(var i in ch) {
    if(null!=ch[i]) {
			if(ch[i].title.toLowerCase().indexOf(sStr)!=-1 || ch[i].tag.toLowerCase().indexOf(" "+sStr)!=-1) {
  			this.addResult(i,(ch[i].tag.toLowerCase().indexOf(" "+sStr)!=-1));
	  	}
	  }
  }
	return;
}

/*  parse the subset of results and highlight the search string 
 *  @return (void)
 */
yhz_Search.prototype.highlight=function(pBlob,pS) {
  if (null==pBlob || ""==pBlob) return;
	var tBlob=pBlob.toLowerCase();
  var nBlob="", i=-1, tSrchStr=pS.toLowerCase();
  while (pBlob.length > 0){
    i=tBlob.indexOf(tSrchStr,i+1);
	  if(i<0) {
		  nBlob+=pBlob;
      pBlob="";
    } else {
	    // skip anything inside an HTML tag
	    if(pBlob.lastIndexOf(">",i)>=pBlob.lastIndexOf("<",i)){
	    	// skip anything inside a <script> block
	    	if(tBlob.lastIndexOf("/script>",i)>=tBlob.lastIndexOf("<script",i)){
			  	nBlob+=pBlob.substring(0,i)+"<"+this.HTML_HIGHLIGHT+">"+pBlob.substr(i,pS.length)+"</"+this.HTML_HIGHLIGHT+">";
		      pBlob=pBlob.substr(i+pS.length);
		      tBlob=pBlob.toLowerCase();
		      i=-1;
	      }
	    }
    }
  }
  return nBlob;
}

/*  @return (boolean)
 *  @param p: object, string
 */
yhz_Search.prototype.isNull=function(p){
  return (null==p||""==p||"undefined"==p);
}

/*  @return (string)
 *  @param pT: 
 *  @param isPhrase
 */
yhz_Search.prototype.doPrsRslts=function(pT,isPhrase,pBlob){
	if(this.isNull(pT))return;
	var sAr=(pT&&isPhrase)?[pT]:pT.split(" ");
  	var tBlob=pBlob;
    var ll=sAr.length;
  	for (var i=0;i<ll;i++) tBlob=this.highlight(tBlob,sAr[i]);
	return tBlob;
}

//(bool)has the user set any filters?
yhz_Search.prototype.isFiltering=function(){
    /*
	var isetFilter=false;
	var tFltrs=this._metadata.getData();
	for(var f=0;f<tFltrs.length;f++){
		if(tFltrs[f].isFilterable==true) return true;
	}
    */
	return false;
}

//(void)iterate thru delim keys and apply filters
//      set to finHTMLRslts
yhz_Search.prototype.applyFilters=function(){

	var h="",tStr="";
	this.finHTMLRslts="";//reset
	var aRsltsKeys=this._results[this.s].split(this._delimiter);

	for(var i=0;i<aRsltsKeys.length;i++){
    var tmpRslt = aRsltsKeys[i].split(this.BOOKMARK_TAG_DELIMITER);
    var hPassed=true;
		var cRslt=(this._data.getData()[tmpRslt[0]]);
		if(this.isNull(cRslt)) return;
    //only check filtering if one is set else give all
		if(this.isFiltering()){
			var tFltrs=this._metadata.getData();
			var tFltrsL=tFltrs.length;
      for(var j=0;j<tFltrsL;j++){
				// if(!hPassed)continue;
				if (!tFltrs[j].isFilterable) continue;
				if (cRslt.assc.indexOf(tFltrs[j].k)<0){
		   			hPassed=false;
		   			break;
				}
			}
		}
		if(hPassed){//found a good result, let's add it
			tStr=this.finHTMLRslts;
			this.finHTMLRslts=tStr+this.formatResult(cRslt,tmpRslt[1]);
			this.iCurrSrchRslts++;
		}
	}

}

/*  insert the html'ized results into element (this.sRslt)
 *  @return (void)
 */
yhz_Search.prototype.writeResults=function(){

	if (this.isNull(this.s)) return;
	var tStr=this.finHTMLRslts;
	var sStr="<em>"+this.iCurrSrchRslts+" Results Found</em>";
  		sStr+=this.doPrsRslts(this.s,false,tStr);//parse, find, replace
		  $('#sRslt').html(sStr);
}

yhz_Search.prototype.hasNoWhtSpaces=function(){
	var tStr=this.s;
	if(!this.isNull(tStr)){
		for(var ck=0;ck<tStr.length;ck++){
			if(tStr.charAt(ck)==" ") return false;
		}
	}
	return true;
}

//(void)start the search
yhz_Search.prototype.search=function(pStr){	
	if (""==pStr || !this.isReady || !this.hasNoWhtSpaces()) return;
  if (null!=pStr && "undefined"!=pStr && ""!=pStr) this.s=pStr;
	this.s=(!this.isNull(pStr))?pStr:this.s;//set hash key
	this.clear();//clear the results pane
	try{
		if (!this._results[this.s]){//check cache
			this._results[this.s]="";
			this.traverse();//first get hash of results
		}
		this.applyFilters();//second filter results
	}
	catch(e){
	}
	finally{
		this.writeResults();//write the results into the results pane
		//this.s=null;//clear search string
		this.isReady=true;
	}
}

//(void)clear results
yhz_Search.prototype.clear=function(){
  $('#sRslt').html('');
	this.iCurrSrchRslts=0;
}

//(void)add new result hash key to results array
//      value == ||key@@is_tag_found||key@@....
yhz_Search.prototype.addResult=function(pHashKey,pIsTagFound){
	var tStr=this._results[this.s];
	this._results[this.s] = tStr + ((this._results[this.s].length >= this.HTML_FILTER_BY_TITLE.length)
    ? this._delimiter + pHashKey.toString()
    : pHashKey.toString()) + this.BOOKMARK_TAG_DELIMITER + pIsTagFound.toString();
}

//(string) html output for each result
yhz_Search.prototype.formatResult=function(pResult,pIsTagFound){
	var s=[];
    	s.push('<dl class="item-result">');
    	s.push('<dt>'+pResult.title+'</dt>');
      s.push('<dd class="uri"><a rel="external" href="'+pResult.url+'">'+pResult.url+'</a></dd>');
      s.push('<dd class="' + (("true"==pIsTagFound) ? "show" : "hide") + '"><label>Tags:</label> '+$.trim(pResult.tag).split(' ').join(', ')+'...</dd>');
      s.push('<dd class="timestamp">'+pResult.timestamp+'</dd>');
      s.push('</dl>');
	return s.join('');
}

yhz_Search.prototype.init=function(){ 
  this.isReady=true;
}

$(document).ready(function(){
  var sr_del_cmd = new yhz_Search('sr_del_cmd','|',yhz_js_data,yhz_js_metadata); 
      sr_del_cmd.init();
  $('#sFormSeartchStrId').html('').keyup(function(event){
    var target = $(event.target);
    if (!target || ""==target.val()) {
      return; 
    }
    tStr=target.val(); 
    sr_del_cmd.search(tStr);     
  }).focus();
});  