var Item = new Class({ 
	initialize: function(options) {
		this.obj = options.obj;
		this.objName = options.objName;
		this.itemClasses = options.itemClasses;
		this.parent = options.parent;
		this.excludeMovieId = 0;
		this.divId = this.objName + '_' + this.obj.number;
	},
	
	getHtml: function(template){
		var s = template.replace("%id%", ""+this.divId);
		return s.replace("%title%", this.obj.name);
	},		
	
	addEventHandlers: function(eventListener) {
		if (this.isNotFoundItem()) return;
		var div = $(this.divId);
		div.addEvent('click', function() {
			this.parent.itemClickNotify();
		}.bind(this));
		div.addEvent('mouseover', function() {
			if (this.parent.sensitiveToMouse){
				this.parent.selected = this.obj.number;
				this.setCurrent();
			}
		}.bind(this));
		div.addEvent('mouseout', function() {
			if (this.parent.sensitiveToMouse){
				this.setNotCurrent();
			}
		}.bind(this));
	},
			
	setCurrent: function(){
		$(this.divId).className = this.itemClasses['over'];
	},
	
	setNotCurrent: function(){
		$(this.divId).className = this.itemClasses['leave'];
	}, 
	isNotFoundItem: function() {
		return this.obj.id < 1;
	}	
});


var AutoSuggestController = new Class({ 

	initialize: function(options) {
		this.input = options.input;
		//this.mergeForm = options.mergeForm;
		this.listDiv = options.listDiv;
		this.listLimit = 10;
		this.items = [];
		this.remoteFunc = options.remoteFunc;
		this.objName = options.objName;
		this.applyTextNofityFunc = options.applyTextNofityFunc;
		this.changeTextNotifyFunc = options.changeTextNotifyFunc;
		this.typeId = options.typeId;
		this.itemTemplate = options.itemTemplate;
		this.notFoundItemTemplate = options.notFoundItemTemplate;
		this.listPostInfo = options.listPostInfo;
		this.itemClasses = options.itemClasses;
		this.handleKeys = options.handleKeys;
		this.noRecordFoundFunc = options.noRecordFoundFunc;
		this.notFoundLabel = options.notFoundLabel;		
		this.sensitiveToMouse = true;
		this.selected = 0;
		this.excludeMovieId = options.excludeMovieId ? options.excludeMovieId  : 0;
		this.isActive = 0;

		this.CLtimerID = 0;
		this.CLdelay = 700;
		this.CLsending = 0;
		this.input.setProperty('autocomplete','off');
		//this.input.focus();
		
		this.input.addEvent('blur', function() {
			setTimeout(this.hideList.bind(this), 300);
		}.bind(this));		
		
		if (this.handleKeys){
			this.input.addEvent('keydown', function(event) {  
				var event = new Event(event);
			    switch(event.code) {
			        case 13:
			            this.selectItem();
			            this.input.fireEvent('blur');
			            return;       
			    }			
			}.bind(this));	
		}	

		this.input.addEvent('keyup', function(event) {  
			var event = new Event(event);
			var name = this.input.value.trim();
			if (name.length < 2) {
				this.hideList();
				if (this.changeTextNotifyFunc)
					this.changeTextNotifyFunc(name);
				return;
			}
			if (event.key == 'esc'){
				this.hideList();
				return;
			}			
		    switch(event.code) {
		        case 38: //up arrow
		        	if (this.handleKeys){
			        	this.sensitiveToMouse = false;
			            this.goToPrev();
			            return;
		            }
		        case 40: //down arrow
			        if (this.handleKeys){
			        	this.sensitiveToMouse = false;
			            this.goToNext();
			            return;
		            }
		        case 37: return;
		        case 39: return; // ignore left/right keys
		        case 13: //enter - already handled on 'keydown'
		        	return;
		        default:
		        	if (this.changeTextNotifyFunc)
						this.changeTextNotifyFunc(name);
		    		this.remoteFuncTimer();
		    }			
		}.bind(this));		

		this.listDiv.addEvent('mousemove', function(event){
			var event = new Event(event);
			this.sensitiveToMouse = true;
		}.bind(this));		
	},

	remoteFuncTimer: function(){
		if(!this.CLsending){
			if(this.CLtimerID) {
				clearTimeout(this.CLtimerID);
				this.CLtimerID  = 0;
			}
			this.CLtimerID = setTimeout(this.remoteFuncTimerRun.bind(this), this.CLdelay);
		}
	},
	
	remoteFuncTimerRun: function(){
		this.CLsending=1;
		var name = this.input.value.trim();
		this.remoteFunc(name, this.excludeMovieId, this.listLimit, 
		    		this.remoteFuncCallBack.bind(this));
	},

	remoteFuncCallBack: function(list){
		if (list.length < 1) 
			list = [{'id':0, 'name':this.notFoundLabel}];
		this.showList(list);
	},
	
	showList: function(list){
		this.CLsending=0;
		this.selected = 0
		
		if (list.length < 1) {
			this.hideList();
			if (this.noRecordFoundFunc != null)
				this.noRecordFoundFunc();

			return;
		}
		
		this.isActive = 1;
		
		this.items = [];
		var html = '';

		for(var i=0; i < list.length; i++) {
			var item = new Item(
				{obj: list[i], 
				objName: this.objName, 
				itemClasses: this.itemClasses, 
				parent: this
			});

			this.items[item.obj.number] = item;
			if (item.isNotFoundItem)
				html += item.getHtml(this.notFoundItemTemplate);
			else 
				html += item.getHtml(this.itemTemplate);

		}

		this.listDiv.innerHTML = html;
		for(var i=0; i < list.length; i++) {
			var item = this.items[list[i].number];
			item.addEventHandlers(this);
		}
		//this.listDiv.style.top = this.input.getTop() + this.listPostInfo.topOffset + 5;
		this.listDiv.style.display = "";
	},
	
	hideList: function(){
//		this.items = [];
		this.listDiv.style.display = "none";
	},
	
	itemClickNotify: function(){

		var item = this.items[this.selected];

		var name;
		if (!this.notFoundLabel || this.notFoundLabel != item.obj.name){
			this.fillForm(item);
			name = item.obj.name
		} else {
			name = this.input.value;
		}

		this.hideList();
		if (this.applyTextNofityFunc != null)
			this.applyTextNofityFunc(item.obj.id, name, 0, this.typeId);
	},
	
	setCurrent: function(number){	
		$each(this.items, function(item, index){
			if (item){
				if (number == index){
					item.setCurrent();
				} else {
					item.setNotCurrent();
				}
			}
		});		
	},
	
	goToPrev: function(){
		if (this.selected <= 1)
			this.selected = this.items.length;			
		this.setCurrent((--this.selected + this.items.length) % (this.items.length));
	},
	
	goToNext: function(){
		if (this.selected == this.items.length-1)
			this.selected = 0;
		this.setCurrent((++this.selected + this.items.length) % (this.items.length));
	},
	
	selectItem: function(){
		this.itemClickNotify();
	},
	
	fillForm: function(item){
		var name = item.obj.name;
		var resName = "";
		if(name){
			var fontPos = name.indexOf("<font")
			var endPos = name.indexOf("</font>");
			if(endPos == -1) endPos = name.length;

			if(fontPos != -1){
				resName = name.substring(35, endPos);
			}else{
				resName = name;
			}
		}
		this.input.value = resName;
	}	


});