function AutoSuggestControl(oTextbox, oProvider) {
	//alert(this);
    this.cur		= -1;
    this.layer		= null;
    this.provider	= oProvider;
    this.textbox	= oTextbox;
    this.timeoutId	= null;
    this.userText	= oTextbox.value;
	this.suggestions= null;
    this.init();
	this.debug		= document.getElementById("debug");
}

AutoSuggestControl.prototype.autosuggest = function (aSuggestions, bTypeAhead) {
    this.cur = 0;
    if (aSuggestions.length > 0) {
		this.suggestions = aSuggestions;
        if (bTypeAhead) {
           this.typeAhead(this.suggestions[0].city);
        }
        this.showSuggestions();
    } else {
        this.hideSuggestions();
    }
};

AutoSuggestControl.prototype.getLeft = function () {
    var oNode = this.textbox;
    var iLeft = 0;
    while(oNode.tagName != "BODY") {
        iLeft += oNode.offsetLeft;
        oNode = oNode.offsetParent;        
    }
    return iLeft;
};

AutoSuggestControl.prototype.getTop = function () {
    var oNode = this.textbox;
    var iTop = 0;
    while(oNode.tagName != "BODY") {
        iTop += oNode.offsetTop;
        oNode = oNode.offsetParent;
    }
    return iTop;
};

AutoSuggestControl.prototype.goToSuggestion = function (iDiff) {
	this.unhighlightSuggestion(this.cur);
	this.cur += iDiff;
	if(this.cur<0 || this.cur>=this.suggestions.length) {
		this.cur-=iDiff;
	}
	this.highlightSuggestion(this.cur);
	this.textbox.value = this.suggestions[this.cur].city;
};

AutoSuggestControl.prototype.handleKeyDown = function (oEvent) {
    switch(oEvent.keyCode) {
        case 38: //up arrow
			this.unhighlightSuggestion(this.cur);
            this.goToSuggestion(-1);
            break;
        case 40: //down arrow 
			this.unhighlightSuggestion(this.cur);
            this.goToSuggestion(1);
            break;
        case 27: //esc
            this.textbox.value = this.userText;
            this.selectRange(this.userText.length, 0);
            /* falls through */
        case 13: //enter
            this.hideSuggestions();
            oEvent.returnValue = false;
            if (oEvent.preventDefault) {
                oEvent.preventDefault();
            }
            break;
    }
};

AutoSuggestControl.prototype.handleKeyUp = function (oEvent) {
    var iKeyCode = oEvent.keyCode;
    var oThis = this;
    this.userText = this.textbox.value;
    clearTimeout(this.timeoutId);
	if (oThis.textbox.value=='') {
		oThis.hideSuggestions();
	} else {
        oThis.handleKeyDown(oEvent);
	}
    if (iKeyCode == 8 || iKeyCode == 46) {
        this.timeoutId = setTimeout( function () {
            oThis.provider.requestSuggestions(oThis, false);
        }, 250);
    } else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 65) || (iKeyCode >= 112 && iKeyCode <= 123)) {

    } else {
		if(!IsNumeric(oThis.textbox.value)) {
	        this.timeoutId = setTimeout( function () {
	            oThis.provider.requestSuggestions(oThis, true);
	        }, 250);
		}
    }
};

AutoSuggestControl.prototype.hideSuggestions = function () {
	if(document.getElementById("suggestionlayer")) {
		document.body.removeChild(document.getElementById("suggestionlayer"));
	}
};

AutoSuggestControl.prototype.highlightSuggestion = function (i) {
	if(this.layer) {
		var oNode = this.layer.childNodes[i];
		if(oNode) {
			oNode.className = "current";
		}
	}
};

AutoSuggestControl.prototype.unhighlightSuggestion = function (i) {
	if(this.layer) {
		var oNode = this.layer.childNodes[i];
		if(oNode) {
			oNode.className = "suggestion";
		}
	}
};

AutoSuggestControl.prototype.init = function () {
    var oThis = this;
    this.textbox.onkeyup = function (oEvent) {
        if (!oEvent) {
            oEvent = window.event;
        }    
        oThis.handleKeyUp(oEvent);
    };
    this.textbox.onkeydown = function (oEvent) {
        if (!oEvent) {
            oEvent = window.event;
        }
    };
    this.textbox.onblur = function () {
        oThis.hideSuggestions();
    };
};

AutoSuggestControl.prototype.selectRange = function (iStart, iEnd) {
    if (this.textbox.createTextRange) {
        var oRange = this.textbox.createTextRange(); 
        oRange.moveStart("character", iStart); 
        oRange.moveEnd("character", iEnd - this.textbox.value.length);      
        oRange.select();
    } else if (this.textbox.setSelectionRange) {
        this.textbox.setSelectionRange(iStart, iEnd);
    }     
    this.textbox.focus();      
}; 

AutoSuggestControl.prototype.showSuggestions = function () {
	if(this.layer) {
		if(document.getElementById("suggestionlayer")) {
			document.body.removeChild(document.getElementById("suggestionlayer"));
		}
	}
	this.layer = document.createElement("div");
	this.layer.id="suggestionlayer";
    //this.layer.innerHTML = "";
    for (var i=0; i < this.suggestions.length; i++) {
    	v = this.addSuggestion(i);
		this.layer.appendChild(v.displayDIV);
    }
    //this.layer.style.width=(this.textbox.style.width);
	this.layer.className="suggestions";
    this.layer.style.left = this.getLeft() + "px";
    this.layer.style.top = (this.getTop()+this.textbox.offsetHeight) + "px";
    this.layer.style.zIndex = "10000";
	document.body.appendChild(this.layer);
};

AutoSuggestControl.prototype.addSuggestion = function (i) {
	var oSE = new SuggestionElement(i,this.suggestions[i].city,this.suggestions[i].typ,this.suggestions[i].prop_count, this);
	return oSE;
}

AutoSuggestControl.prototype.typeAhead = function (sSuggestion) {
    if ((this.textbox.createTextRange || this.textbox.setSelectionRange) && !(this.textbox.value==sSuggestion+' ') && !(this.textbox.value==this.usertext)){
        var iLen = this.textbox.value.length; 
        this.textbox.value = sSuggestion; 
        this.selectRange(iLen, sSuggestion.length);
    }
};


function SuggestionElement(i,c,t,cc,p) {
	this.index			= i;
	this.city			= c;
	this.proptype		= t;
	this.propcount		= cc;
	this.displayDIV		= null;
	this.parent			= p;
	this.start();
}
SuggestionElement.prototype.handleFocus = function (oEl) {
	oEl.parent.unhighlightSuggestion(oEl.parent.cur);
	oEl.parent.highlightSuggestion(oEl.index);
	oEl.displayDIV.className = "current";
}
SuggestionElement.prototype.handleBlur = function (oEl) {
	oEl.parent.unhighlightSuggestion(oEl.parent.cur);
	oEl.displayDIV.className = "suggestion";
}
SuggestionElement.prototype.handleClick= function (oEl) {
	oEl.displayDIV.className = "suggestionClick";
	var oCol = oEl.displayDIV.parentNode.childNodes;
	for(i=1;i<=oCol.length;i++) {
		if(oCol[i]==oEl.displayDIV) {
			oEl.parent.cur=i;
			oEl.parent.typeAhead(oEl.parent.suggestions[i].city);
			this.parent.hideSuggestions();
		}
	}
}

SuggestionElement.prototype.start = function () {
	var v = document.createElement("div");
	var c = document.createElement("span");
	var cc = document.createElement("span");
	c.appendChild(document.createTextNode(this.city));
	c.className="msug";
    cc.appendChild(document.createTextNode(this.propcount));
	cc.className="msugc";
    v.appendChild(c);
	v.appendChild(cc);
	v.className="suggestion";
	this.displayDIV=v;
	var oThis = this;
	oThis.displayDIV.onmouseover=function () { oThis.handleFocus(oThis) };
	oThis.displayDIV.onmouseout =function () { oThis.handleBlur(oThis) };
	oThis.displayDIV.onmousedown=function () { oThis.handleClick(oThis) };
}

function IsNumeric(sText) {
   var ValidChars = "0123456789";
   var IsNumber=true;
   var Char;
   for (i = 0; i < sText.length && IsNumber == true; i++) { 
      Char = sText.charAt(i); 
      if (ValidChars.indexOf(Char) == -1) {
         return false;
      }
   }
   return IsNumber; 
}

function CitySuggestionProvider() {
    this.http = zXmlHttp.createRequest();
}

CitySuggestionProvider.prototype.requestSuggestions = function (oAutoSuggestControl, bTypeAhead) {
    var oHttp = this.http;
    if (oHttp.readyState != 0) {
        oHttp.abort();
    }
	var sTyp =(document.getElementById("TYP").options[document.getElementById("TYP").selectedIndex].value);
	var sURL ="/AutoSuggest/cities.aspx?text="+ oAutoSuggestControl.userText +"&typ="+sTyp;
    oHttp.open("get", sURL, true);
    oHttp.onreadystatechange = function () {
        if (oHttp.readyState == 4) {
            var aSuggestions = JSON.parse(oHttp.responseText);
            oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);        
        }
    };
    oHttp.send("");
};

