
TextSuggest = Class.create();

TextSuggest.prototype = {
	
   initialize: function(anId, url, options) {
      this.id          = anId;
      var browser = navigator.userAgent.toLowerCase();
      this.isIE        = browser.indexOf("msie") != -1;
      this.isOpera     = browser.indexOf("opera")!= -1;
      this.textInput   = $(this.id);
      this.suggestions = [];
      this.setOptions(options);
      this.initAjax(url);
      this.injectSuggestBehavior();
	  this.iFrame	   =null;
	  this.height		= 0;
	  this.spanded		= false;
//	  this.onChangeValue	= onChangeValue;
	  document.onclick       = this.DocClickHandler.bindAsEventListener(this);
   },
	onChangeValue: function(){
		//empty
		 window.status="changed"
   },
	DocClickHandler: function(e){
		var src = e.srcElement ? e.srcElement : e.target;
		var sId="";
		try{
				sId= src.id;
				if(sId.indexOf(this.id)<0)
						this.hideSuggestions();
		}catch(e){}
		// Necesario para los calendarios
        if (this.isIE || this.isOpera6) {
	  		winX=event.screenX;
	  		winY=event.screenY;
	  	}
	  	else if (this.isN4 || this.isN6) {
	  		winX=e.screenX;
	  		winY=e.screenY;	
	  		document.routeEvent(e);
	  	}
		
   },
   initAjax: function(url) {
      ajaxEngine.registerRequest( this.id + '_request', url );
      ajaxEngine.registerAjaxObject( this.id + '_updater', this );
   },
	getText: function(){
	   return this.textInput.value;
   },
	getValue:function(){
	   return $( this.id + "_hidden" ).value;
   },
   getValue2:function(){
	   return $( this.id + "_hidden2" ).value;
   },
   clear: function(){
	   this.textInput.value="";
	   $( this.id + "_hidden" ).value="";
	   $( this.id + "_hidden2" ).value="";
	   this.onChangeValue(this);
	},

   setOptions: function(options) {
      this.options = {
         suggestDivClassName: 'suggestDiv',
         suggestionClassName: 'suggestion',
         matchClassName     : 'match',
         matchTextWidth     : true,
         selectionColor     : '#D6F2F8',
         matchAnywhere      : true,
         ignoreCase         : true,
		 ieHeight			: 15		
         
      }.extend(options || {});
   },
	
   injectSuggestBehavior: function() {
      if ( this.isIE )
         this.textInput.autocomplete = "off";

      var keyEventHandler = new TextSuggestKeyHandler(this);
      new Insertion.After( this.textInput,
                           '<input type="hidden" id="'+this.id+'_preventtsubmit'+'" style="display:visible"/>' );
      new Insertion.After( this.textInput,
                           '<input type="hidden" name="'+this.id+'_hidden'+'" id="'+this.id+'_hidden'+'"/>' );
	  new Insertion.After( this.textInput,
				           '<input type="hidden" name="'+this.id+'_hidden2'+'" id="'+this.id+'_hidden2'+'"/>' );

      this.createSuggestionsDiv();
   },
	
   handleTextInput: function() {
     var previousRequest    = this.lastRequestString;
	 	this.lastRequestString =this.textInput.value;
	 
     if ( this.lastRequestString == "" ){

        this.hideSuggestions();
	
	 }
     else if ( this.lastRequestString != previousRequest ) {
		$( this.id + "_hidden" ).value="";
		$( this.id + "_hidden2" ).value="";
		
		 this.onChangeValue(this);
        this.sendRequestForSuggestions();
     }
   },
 
   moveSelectionUp: function() {

      if ( this.selectedIndex > 0 ) {
         this.updateSelection(this.selectedIndex - 1);
      }
   },
	
   moveSelectionDown: function() {

      if ( this.selectedIndex < (this.suggestions.length - 1)  ) {
         this.updateSelection(this.selectedIndex + 1);
      }
   },

   updateSelection: function(n) {

      var span = $( this.id + "_" + this.selectedIndex );
      if ( span ){
         span.style.backgroundColor = ''//this.options.unSelectionColor;
      }
      this.selectedIndex = n;
      var span = $( this.id + "_" + this.selectedIndex );
      if ( span ){
         span.style.backgroundColor = this.options.selectionColor;
      }
   },


   sendRequestForSuggestions: function() {


     if ( this.handlingRequest ) {

        this.pendingRequest = true;
        return;
     }


     this.handlingRequest = true;
     this.callRicoAjaxEngine();
   },

   callRicoAjaxEngine: function() {
	   

      var callParms = [];
      callParms.push( this.id + '_request');
      callParms.push( 'id='             + this.id);
      
      callParms.push( 'query='          + this.lastRequestString);
      callParms.push( 'match_anywhere=' + this.options.matchAnywhere);
      callParms.push( 'ignore_case='    + this.options.ignoreCase);
      var additionalParms = this.options.requestParameters || [];
      for( var i=0 ; i < additionalParms.length ; i++ )
         callParms.push(additionalParms[i]);

      ajaxEngine.sendRequest.apply( ajaxEngine, callParms );
   },

   ajaxUpdate: function( ajaxResponse ) {

      this.createSuggestions( ajaxResponse );

      if ( this.suggestions.length == 0 ) {
         this.hideSuggestions();
         $( this.id + "_hidden" ).value = "";
		 $( this.id + "_hidden2" ).value = "";
      }
      else {
         this.updateSuggestionsDiv();
         this.showSuggestions();
         this.updateSelection(0);

      }

      this.handlingRequest = false;

      if ( this.pendingRequest ) {

         this.pendingRequest    = false;
         this.handleTextInput();
         this.sendRequestForSuggestions();
      }else{

	  }
   },

   createSuggestions: function(ajaxResponse) {

      this.suggestions = [];
      var entries = ajaxResponse.getElementsByTagName('entry');
      for ( var i = 0 ; i < entries.length ; i++ ) {
         var strText  = this.getElementContent(entries[i].getElementsByTagName('text')[0]);
         var strValue = this.getElementContent(entries[i].getElementsByTagName('value')[0]);
		 var strValue2 = '';
		 if (entries[i].getElementsByTagName('value2').length>0){
			strValue2 = this.getElementContent(entries[i].getElementsByTagName('value2')[0]);
		 }
         this.suggestions.push( { text: strText, value: strValue, value2: strValue2 } );
      }
   },
   setInputFromSelection: function() {

     var hiddenInput = $( this.id + "_hidden" );
	 var hiddenInput2 = $( this.id + "_hidden2" );
     var suggestion  = this.suggestions[ this.selectedIndex ];
     this.textInput.value = suggestion.text;
     hiddenInput.value    = suggestion.value;
	 hiddenInput2.value   = suggestion.value2;
     this.hideSuggestions();
	 this.onChangeValue(this);
   },
   showSuggestions: function() {
	  this.spanded = true;	
      var divStyle = this.suggestionsDiv.style;
      if ( divStyle.display == '' )
         return;
      this.positionSuggestionsDiv();
      divStyle.display = '';
   },
	createFrame: function(){
		if (this.iFrame!=null)
		{
			return;
		}

		var elem = null;
		var overID= this.id + "_over";
		document.body.insertAdjacentHTML("beforeEnd", "<iframe id='" + overID + "'  style='filter:Alpha(Opacity=0);position:absolute;left:0px;top:0x;z-index:500;display:none;scrolling=no;frameborder=0' src='../../html/blank.html'></iframe>");
		this.iFrame=$(overID);
		
	},				
	
   positionSuggestionsDiv: function() {

      var textPos = RicoUtil.toDocumentPosition(this.textInput);
      var divStyle = this.suggestionsDiv.style;
	
      divStyle.top  = (textPos.y + this.textInput.offsetHeight ) + "px";
      divStyle.left = textPos.x + "px";
	  
		//alert (this.suggestions.length);
	  if(this.suggestions.length > 16 ){
		divStyle.height= "200px";
	
	  }
	  else{
//			divStyle.top  = (textPos.y + this.textInput.offsetHeight +20) + "px";
			divStyle.height=this.height+"px";
			
	  }
		 
      if ( this.options.matchTextWidth )
         divStyle.width = (this.textInput.offsetWidth- this.padding()) + "px";

	  if(this.isIE){
	  	//window.scrollTo(0,0);
	  	
	  	divStyle.top  = (textPos.y + this.textInput.offsetHeight + document.body.scrollTop)+ "px";
		if(this.iFrame==null){
			this.createFrame();
		}
	//	divStyle.top  = (textPos.y + this.textInput.offsetHeight +20) + "px";
	//	divStyle.height=this.height+"px";  
		this.iFrame.style.top = divStyle.top;
		this.iFrame.style.left = divStyle.left;
		this.iFrame.style.width = divStyle.width;
		this.iFrame.style.height = divStyle.height;
		this.iFrame.style.zIndex=divStyle.zIndex-1
    	this.iFrame.style.display = '';
	  }	

   },
   padding: function() {

     try{
      var styleFunc = RicoUtil.getElementsComputedStyle;
      var lPad    = styleFunc( this.suggestionsDiv, "paddingLeft",      "padding-left" );
      var rPad    = styleFunc( this.suggestionsDiv, "paddingRight",     "padding-right" );
      var lBorder = styleFunc( this.suggestionsDiv, "borderLeftWidth",  "border-left-width" );
      var rBorder = styleFunc( this.suggestionsDiv, "borderRightWidth", "border-right-width" );

      lPad    = isNaN(lPad)    ? 0 : lPad;
      rPad    = isNaN(rPad)    ? 0 : rPad;
      lBorder = isNaN(lBorder) ? 0 : lBorder;
      rBorder = isNaN(rBorder) ? 0 : rBorder;

      return parseInt(lPad) + parseInt(rPad) + parseInt(lBorder) + parseInt(rBorder);
     }catch (e){
      return 0;
     }
   },
   hideSuggestions: function() {
		this.spanded = false;
      this.suggestionsDiv.style.display = 'none';
	  
	  if(this.isIE){
			if(this.iFrame!=null)
				this.iFrame.style.display = 'none';
	  }
   },
   createSuggestionsDiv: function() {

      this.suggestionsDiv = document.createElement("div");
	 
      this.suggestionsDiv.className = this.options.suggestDivClassName;
      var divStyle = this.suggestionsDiv.style;
      divStyle.position = 'absolute';
      divStyle.zIndex   = 505;
      divStyle.display  = "none";
	 
      this.textInput.parentNode.appendChild(this.suggestionsDiv);
   },	
   updateSuggestionsDiv: function() {

		this.suggestionsDiv.innerHTML = "";
	
      var suggestLines = this.createSuggestionSpans();
	  
      for ( var i = 0 ; i < suggestLines.length ; i++ ){
		
			this.suggestionsDiv.appendChild(suggestLines[i]);
	  }
     this.height=suggestLines.length * this.options.ieHeight;	
	 this.positionSuggestionsDiv();
	  
   },
   createSuggestionSpans: function() {

      var regExpFlags = "";
      if ( this.options.ignoreCase )
         regExpFlags = 'i';
      var startRegExp = "^";
      if ( this.options.matchAnywhere )
         startRegExp = '';

      var regExp  = new RegExp( startRegExp + this.lastRequestString, regExpFlags );

      var suggestionSpans = [];
      for ( var i = 0 ; i < this.suggestions.length ; i++ )
         suggestionSpans.push( this.createSuggestionSpan( i, regExp ) )

      return suggestionSpans;
   },
   createSuggestionSpan: function( n, regExp ) {

      var suggestion = this.suggestions[n];

      var suggestionSpan = document.createElement("span");
      suggestionSpan.className = this.options.suggestionClassName;
      suggestionSpan.style.width   = '100%';
      suggestionSpan.style.display = 'block';
      suggestionSpan.id            = this.id + "_" + n;
      suggestionSpan.onmouseover   = this.mouseoverHandler.bindAsEventListener(this);
      suggestionSpan.onclick       = this.itemClickHandler.bindAsEventListener(this);

      var textValues = this.splitTextValues( suggestion.text,
                                             this.lastRequestString.length,
                                             regExp );

      var textMatchSpan = document.createElement("span");
      textMatchSpan.id            = this.id + "_match_" + n;
      textMatchSpan.className     = this.options.matchClassName;
      textMatchSpan.onmouseover   = this.mouseoverHandler.bindAsEventListener(this);
      textMatchSpan.onclick       = this.itemClickHandler.bindAsEventListener(this);

      textMatchSpan.appendChild( document.createTextNode(textValues.mid) );

      suggestionSpan.appendChild( document.createTextNode( textValues.start ) );
      suggestionSpan.appendChild( textMatchSpan);
      suggestionSpan.appendChild( document.createTextNode( textValues.end ) );

      return suggestionSpan;
   },
   mouseoverHandler: function(e) {
		
      var src = e.srcElement ? e.srcElement : e.target;
      var index = parseInt(src.id.substring(src.id.lastIndexOf('_')+1));
      this.updateSelection(index);
   },
   itemClickHandler: function(e) {
		
      this.setInputFromSelection();
      this.textInput.focus();
   },
	selectfirstSuggestion: function(pos) {
      var end = this.textInput.value.length;

      if (this.textInput.setSelectionRange) {

		 this.textInput.setSelectionRange(pos,end);
      }
      else if(this.textInput.createTextRange){

		var m = this.textInput.createTextRange();
		m.findText(this.textInput.value.substring(pos));
		m.select();
        
      }
   },
   splitTextValues: function( text, len, regExp ) {

      var startPos  = text.search(regExp);
      var matchText = text.substring( startPos, startPos + len );
      var startText = startPos == 0 ? "" : text.substring(0, startPos);
      var endText   = text.substring( startPos + len );
      return { start: startText, mid: matchText, end: endText };
   },

   getElementContent: function(element) {

      return element.firstChild.data;
   }
}
TextSuggestKeyHandler = Class.create();

TextSuggestKeyHandler.prototype = {

   initialize: function( textSuggest ) {

      this.textSuggest = textSuggest;
      this.input       = this.textSuggest.textInput;
      this.addKeyHandling();
   },
   addKeyHandling: function() {

      this.input.onkeyup    = this.keyupHandler.bindAsEventListener(this);
      this.input.onkeydown  = this.keydownHandler.bindAsEventListener(this);
//      this.input.onblur     = this.onblurHandler.bindAsEventListener(this);
	  this.input.onkeypress     = this.keypressHandler.bindAsEventListener(this);
	   
      if ( this.isOpera )
         this.input.onkeypress = this.keyupHandler.bindAsEventListener(this);
   },
	 	
   keydownHandler: function(e) {
	
      var upArrow   = 38;
      var downArrow = 40;
	  var enterKey  = 13;
	  var keyTab	= 9;	
	 
	  if (e.keyCode== keyTab)
	  {
		this.textSuggest.hideSuggestions();	
	  }	
      else if ( e.keyCode == upArrow ) {
         this.textSuggest.moveSelectionUp();
         setTimeout( this.moveCaretToEnd.bind(this), 1 );
      }
      else if ( e.keyCode == downArrow ){
         this.textSuggest.moveSelectionDown();
      }
	  else if ( e.keyCode == enterKey ){
		   
          return false;
      }
	  
   },
	keypressHandler: function(e){
		var enterKey  = 13;
		if ( e.keyCode == enterKey ){
			
		  return false;
		}
	},
   keyupHandler: function(e) {
		var enterKey  = 13;
		
      if ( this.input.value.length < 3 && !this.isOpera ){
         this.textSuggest.hideSuggestions();
		 	
	  }	

		if ( !this.handledSpecialKeys(e) && this.input.value.length >= 3  ){
			if (!this.textSuggest.handlingRequest )
				this.textSuggest.handleTextInput();
		}
		if ( e.keyCode == enterKey ){
			  if ( this.textSuggest.suggestionsDiv.style.display == '' )
			    this.textSuggest.setInputFromSelection();
			this.textSuggest.hideSuggestions();
      }
		
   },
   handledSpecialKeys: function(e) {

      var enterKey  = 13;
      var upArrow   = 38;
      var downArrow = 40;
	  

      if ( e.keyCode == upArrow || e.keyCode == downArrow ) {
         return true;
      }
      else if ( e.keyCode == enterKey ) {
        
         return true;
      }
	  
      return false;
   },
   moveCaretToEnd: function() {

      var pos = this.input.value.length;
      if (this.input.setSelectionRange) {
         this.input.setSelectionRange(pos,pos);
      }
      else if(this.input.createTextRange){
         var m = this.input.createTextRange();
         m.moveStart('character',pos);
         m.collapse();
         m.select();
      }
   },
   onblurHandler: function(e) {
	  
	  this.textSuggest.hideSuggestions();
	
   }

};