//需要Prototype支持
//Author: Legen Li.Sz Armitage
//Email : legenli@gmail.com
//Date  : 2009-07-18
//下拉选择框JavaScript（包括Ajax自动完成）
//

var cbw_ie6 = navigator.userAgent.toLowerCase().indexOf("msie 6") > 0;
var cbw_comboboxs = new Object();

function cbw_combobox(id,props,queryFields,sources){
	this.id = id;
	this.masterId = id + "_masterId";
	this.inputId = id + "_";
	this.valueId = id;
	this.dropdownId = "widget_"+id+"_dropdown";
	this.popupId = id + "_popup";
	this.tipTitleId = id + "_tip_title";
	this.oldOver = null;
	this.isShow = false;
	this.type = props[0];
	this.ajaxHref = props[1];
	this.loadMinimumCount = props[2];
	this.loadField = props[3];
	this.debug = props[4];
	this.forceValid = props[5];
	this.matchChar = props[6]?"*":"^";
	this.rowRenderEvent = props[7];
	this.initLoad = props[9];
	this.popupWidth = props[10];
	this.popupAlign = props[11];
	
	this.tipTitleHeight = $(this.tipTitleId) != null?24:0;
	
	if(this.loadField.blank()){
		this.loadField = this.id + "LoadPrefix";
	}
	
	this.queryFields = queryFields;
	this.loadGroup = [];
	
	this.sources = sources;
	this.filterString = null;
	this.showCount = sources.length;
	this.isInFilter = false;
	this.firstRow = null;
	
	this.popupshow = cbs_onpopupshow;
	this.popuphide = cbs_onpopuphide;
	
	this.fireonchange = cbs_fireonchange;
	this.updownhandler = cbs_onupdownhandler;
	this.resetvalue = cbs_resetvalues;
	this.doChange = cbs_doValueChange;
	this.resetscroll = cbs_resetpopupscroll;
	this.resizeHeight = cbs_onresizeheight;
	this.customRowRender = false;
	if(!this.rowRenderEvent.blank()){
		this.doRowRender = eval(this.rowRenderEvent);
		this.customRowRender = true;
	}
	if(this.type == "ajax"){
		this.doFilter = cbs_ajaxFilterDataSource;
		this.callback = cbs_ajaxCallback;
		this.buildajaxdropdown = cbs_buildajaxdropdownpopup;
		$(this.masterId).observe("click",cbs_oncomboxclick.bind(this));
	}else{
		this.doFilter = cbs_filterDataSource;
		this.builddropdown = cbs_builddropdownpopup;
		this.builddropdown(this.sources);
		$(this.masterId).observe("click",cbs_oncomboxclick.bind(this));
	}
	
	this.clearDropDown = cbs_cleardropdownpopup;
	
	var dropdown = $(this.dropdownId);
	//$(this.inputId).observe("focus",cbs_oncomboxfocus.bind(this));
	// $(this.inputId).observe("blur",cbs_oncomboxblur.bind(this));
	dropdown.observe("mouseover",cbs_onpopupmousemove.bind(this));
	dropdown.observe("click",cbs_onpopupmousedown.bind(this));
	dropdown.observe("keydown",cbs_oncomboxkeydown.bind(this));
	$(this.inputId).observe("keydown",cbs_oncomboxkeydown.bind(this));
	$(this.inputId).observe("keyup",cbs_oncomboxkeypress.bind(this));
	
	
	if(cbw_ie6){
		$(this.popupId).setStyle({
			'position':'absolute'
		});
		var iframe = document.createElement('iframe');
	    iframe.hideFocus = true;
	    iframe.frameBorder = 1;
	    iframe.width = "100%";
	    $(iframe).setStyle({
		    'width': '50px',
		    'height': '50px',
		    'position': 'absolute',
		    'zIndex': '778',
		    'left': '0px',
		    'top': '0px',
		    'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=50)'
	    });
	    dropdown.appendChild(iframe);
	    
	    this.iframe = iframe;
	}
	
	cbw_comboboxs[id] = this;
	
	if(this.type == "ajax"&&this.initLoad != "")
		Event.observe(window,"load",cbs_doInitAjaxLoad.bind(this));
}

function cbs_doInitAjaxLoad(){
	this.callback($(this.inputId),this.initLoad);
	this.loadGroup[0] = this.initLoad;
}

function cbs_getComboBox(id){
	if(cbw_comboboxs[id]){
		return cbw_comboboxs[id];
	}
	
	return null;
}

function cbs_resetpopupscroll(){
	if(this.oldOver == null)return;
	
	var popup = $(this.popupId);
	var ph = popup.getHeight();
	
	if(ph < this.oldOver.offsetTop)
		popup.scrollTop = this.oldOver.offsetTop - this.tipTitleHeight;
	else
		popup.scrollTop = 0;
}

function cbs_fireonchange(){
	var v_field = $(this.valueId);
	if(v_field.onchange){
		if(Prototype.Browser.IE)
			v_field.fireEvent("onchange");
		else
			v_field.onchange();
	}
}
function cbs_resetvalues(el){
	
	var input = $(this.inputId);
	var v_field = $(this.valueId);
	
	if(el != null){
		var key = el.getAttribute("key");
		var text = el.getAttribute("item");
		v_field.value = key;
		input.value = text;
	}else{
		this.doChange();
	}
	
	input.focus();
	input.select();
	
	this.fireonchange();
}

function cbs_onupdownhandler(isUp){
	if(this.oldOver == null){
		var popup = $(this.popupId);
		var curOver = popup.firstDescendant();
		while(curOver != null){
			if(curOver.visible()){
				break;
			}
			curOver = curOver.next();
		}
		if(curOver){
			$(curOver).addClassName("cwb-MenuItemHover");
			this.oldOver = curOver;
		}
		return;
	}
	
	var curOver;
	if(isUp){
		curOver = this.oldOver.previous();
		while(curOver != null){
			if(curOver.visible()){
				break;
			}
			curOver = curOver.previous();
		}
	}else{
		curOver = this.oldOver.next();
		while(curOver != null){
			if(curOver.visible()){
				break;
			}
			curOver = curOver.next();
		}
	}
	if(curOver == null || !curOver.visible())return;
	this.oldOver.removeClassName("cwb-MenuItemHover");
	curOver.addClassName("cwb-MenuItemHover");
	this.oldOver = curOver;
	this.resetscroll();
}

function cbs_oncomboxkeydown(evt){
	
	switch(evt.keyCode){
		case 40:
			this.updownhandler(false);
			break;
		case 38:
			this.updownhandler(true);
			break;
		case 13:
			if(this.isShow){
				this.resetvalue(this.oldOver);
				this.popuphide();
			}
			if(Prototype.Browser.IE)
				evt.returnValue = false;
			else
				evt.preventDefault();
			break;
		case 9:
			if(this.isShow){
				this.resetvalue(this.oldOver);
				this.popuphide();
			}
			break;
		default:
			break;
	}
}

function cbs_oncomboxkeypress(evt){
	if(evt.keyCode > 45 || evt.keyCode == 32 || evt.keyCode == 8){
		this.doFilter(evt);
	}
	if(evt.ctrlKey && evt.keyCode == 86){
		this.doChange();
	}
}

function cbs_ajaxCallback(el,v){
	if(this.ajaxHref.blank()){
		alert("ajaxHref error");
		return
	}
	
	if(this.inAction)return;
	this.inAction = true;
	
	var params = new Object();
	params[this.loadField] = v;
	var cbs = this;
	this.queryFields.each(function(fieldId){
		if(fieldId == null)return;

		var field = $(fieldId);

		params[field.getAttribute('name')] = $F(field);
	});
	if(cbs.debug){
		alert(Object.toJSON(params));
	}
	
	new Ajax.Request(this.ajaxHref, {
		method:'post',
		parameters: params,
		onComplete: function(transport) {
			if(transport.status == 200){
				if(cbs.debug){
					alert(transport.responseText);
				}
				cbs.inAction = false;
				var ss = transport.responseText.evalJSON();
				cbs.buildajaxdropdown(ss);
				cbs.doFilter(el);
			}else{
				cbs.inAction = false;
			}
		}
	});
	
}
function cbs_ajaxFilterDataSource(evt){
	var el = evt.element();
	if(el.id != this.inputId)return;

	var v = el.value.toLowerCase();

	if(v.length >= this.loadMinimumCount){
		var subv = v.substring(0,this.loadMinimumCount);
		if(this.loadGroup.indexOf(subv) == -1){
			this.loadGroup[this.loadGroup.length] = subv;
			this.callback(el,subv);
			return;
		}
	}
	
	if(v == this.filterString)return;
	
	if(!this.isShow)
		this.popupshow();

	var popup = $(this.popupId);
	
	var paras;
	
	paras = $A(popup.select("li"));
	paras.each(Element.hide);
	
	var curOver;
	if(!v.blank()){
		paras = $A(popup.select("[lower "+this.matchChar+"= '"+v+"']"));
		paras.each(Element.show);
		this.showCount = paras.length;
		curOver = paras[0];
	}else{
		this.showCount = 0;
		curOver = null;
	}
	

	if(curOver){
		if(this.oldOver != null)
			this.oldOver.removeClassName("cwb-MenuItemHover");
			
		$(curOver).addClassName("cwb-MenuItemHover");
		this.oldOver = curOver;
		this.firstRow = curOver;
	}else{
		if(this.oldOver != null){
			this.oldOver.removeClassName("cwb-MenuItemHover");
			this.oldOver = null;
		}
		$(this.valueId).value = "";
	}
	this.filterString = v;
	this.isInFilter = true;
	this.resizeHeight();
	this.resetscroll();
}

function cbs_filterDataSource(evt){
	var el = evt.element();
	if(el.id != this.inputId)return;
	
	if(!this.isShow)
		this.popupshow();
	
	var v = el.value.toLowerCase();
	
	if(v == this.filterString)return;

	var popup = $(this.popupId);
	
	var paras;
	
	paras = $A(popup.select("li"));
	paras.each(Element.hide);
	
	paras = $A(popup.select("[lower "+this.matchChar+"= '"+v+"']"));
	paras.each(Element.show);
	this.showCount = paras.length;
	
	var curOver = paras[0];
	if(curOver){
		if(this.oldOver != null)
			this.oldOver.removeClassName("cwb-MenuItemHover");
			
		$(curOver).addClassName("cwb-MenuItemHover");
		this.oldOver = curOver;
		this.firstRow = curOver;
	}else{
		if(this.oldOver != null){
			this.oldOver.removeClassName("cwb-MenuItemHover");
			this.oldOver = null;
		}
		$(this.valueId).value = "";
	}
	this.filterString = v;
	this.isInFilter = true;
	this.resizeHeight();
	this.resetscroll();
}

function cbs_findElementByCss(el, cssName, depth, st) {
	var cel = el;

	for ( var i = depth; i > 0; i--) {
		try {
			var tn = cel.tagName.toLowerCase();
			if ((tn == st) && $(cel).hasClassName(cssName)) {
				return cel;
			}
		} catch (e) {
			if (tn == st && cel.className == cssName){
				return $(cel);
			}
		}

		cel = cel.parentNode;
		if (cel == null) {
			return null;
		}
	}
	return null;
}

function cbs_onpopupmousedown(evt){
	var el = evt.element();
	var elli = cbs_findElementByCss(el,"cwb-MenuItem",5,"li");
	if(elli == null)return;
	
	this.resetvalue(elli);
	
	this.popuphide();
}

function cbs_onpopupmousemove(evt){
	var el = evt.element();
	var elli = cbs_findElementByCss(el,"cwb-MenuItem",5,"li");
	if(elli == null)return;

	if(this.oldOver != null){
		this.oldOver.removeClassName("cwb-MenuItemHover");
	}
	elli.addClassName("cwb-MenuItemHover");
	this.oldOver = elli;
	
}

function cbs_doValueChange(){
	var v = $(this.inputId).value.toLowerCase();
	if(this.oldOver != null){
		var keyEl = $(this.popupId).select("[lower='"+v+"']")[0];
		if(keyEl == null){
			
			this.oldOver.removeClassName("cwb-MenuItemHover");
			this.oldOver = null;
			
			var v_field = $(this.valueId);
			
			
			
			if(this.forceValid)
				v_field.value = "";
			else
				v_field.value = $(this.inputId).value;
				
			this.fireonchange();
		}
	}else{
		if(this.isShow){
			var v_field = $(this.valueId);
			
			if(this.forceValid)
				v_field.value = "";
			else
				v_field.value = $(this.inputId).value;
			
			this.fireonchange();
		}
		var v_field = $(this.valueId);
		if(!this.forceValid)
			v_field.value = $(this.inputId).value;
	}
}

function cbs_ondocumentmousedownhandler(evt){
	var el = evt.element();
	var p = el.up(".cwb-Popup");
	if(el.hasClassName("cwb-Popup")){
		p = el;
	}
	if(p == null || p.getAttribute("popupParent") != this.masterId){
		this.doChange();
		this.popuphide();
	}
}

function cbs_oncomboxfocus(evt){
	
}

function cbs_oncomboxblur(evt){
	
}

function cbs_onpopuphide(){
	var dropdown = $(this.dropdownId);
	dropdown.hide();
	this.isShow = false;
	
	Event.stopObserving(window.document,'mousedown',cbs_ondocumentmousedownhandler);
	
}

function cbs_buildajaxdropdownpopup(sources){
	
	var popup = $(this.popupId);
	var templ = new Template("<li id='#{id}_popupitem_#{index}' key='#{k}' lower='#{lower}' item='#{v}' class='cwb-Reset cwb-MenuItem'>#{text}</li>");
	var i = 0;
	var id = this.id;
	var cbs = this;
	if(Object.isArray(sources)){
		sources.each(function(item){
			var templModel;
			if(cbs.customRowRender){
				templModel = cbs.doRowRender(item,item);
				templModel.id = id;
				templModel.index = i++;
			}else{
				templModel = {id:id,index:i++,k:item,v:item,lower:item.toLowerCase(),text:item};
			}
			if(popup.select('[key = "' + templModel.k+ '"]').length <= 0)
				popup.insert({top:templ.evaluate(templModel)});
		});
	}else{
	    Object.keys(sources).each(function(key){
	    	var value = sources[key];
	    	var templModel;
	    	if(cbs.customRowRender){
	    		templModel = cbs.doRowRender(key,value);
	    		templModel.id = id;
	    		templModel.index = i ++;
	    	}else{
	    		templModel = {id:id,index:i++,k:key,v:value,lower:value.toLowerCase(),text:value};
	    	}
	    	if(popup.select('[key = "' + templModel.k+ '"]').length <= 0)
	    		popup.insert({top:templ.evaluate(templModel)});
	    });
	}
}

function cbs_builddropdownpopup(sources){
	
	var popup = $(this.popupId);
	var templ = new Template("<li id='#{id}_popupitem_#{index}' key='#{k}' lower='#{lower}' item='#{v}' class='cwb-Reset cwb-MenuItem'>#{text}</li>");
	var i = 0;
	var id = this.id;
	var cbs = this;
	if(Object.isArray(sources)){
		sources.each(function(item){
			var templModel;
			if(cbs.customRowRender){
				templModel = cbs.doRowRender(item,item);
				templModel.id = id;
				templModel.index = i++;
			}else{
				if(Object.isArray(item)){
					templModel = {id:id,index:i++,k:item[0],v:item[1],lower:item[1].toLowerCase(),text:item[1]};
				}else{
					templModel = {id:id,index:i++,k:item,v:item,lower:item.toLowerCase(),text:item};
				}
			}
			popup.insert(templ.evaluate(templModel));
		});
	}else{
		Object.keys(sources).each(function(key){
	    	var value = sources[key];
	    	var templModel;
	    	if(cbs.customRowRender){
	    		templModel = cbs.doRowRender(key,value);
	    		templModel.id = id;
	    		templModel.index = i ++;
	    	}else{
	    		templModel = {id:id,index:i++,k:key,v:value,lower:value.toLowerCase(),text:value};
	    	}
	    	popup.insert(templ.evaluate(templModel));
	    });
	}
}

function cbs_cleardropdownpopup(){
	var popup = $(this.popupId);
	popup.innerHTML = "";
}

function cbs_onresizeheight(){
	var master = $(this.masterId);
	var dropdown = $(this.dropdownId);
	var popup = $(this.popupId);
	var tipTitle = $(this.tipTitleId);
	var t = master.offsetTop + master.getHeight() - 1;
	var l = master.offsetLeft;
	var w = this.popupWidth;
	if(this.popupWidth <= 0){
	    w = master.getWidth() - 4;
	}
	if(this.popupAlign != 'left'){
		l = l + master.getWidth() - w - 4;
	}
	var bh = document.viewport.getDimensions().height - t - 10;
	var th = t - master.getHeight() - 10;
	var popupH = this.showCount * 20;
	
	if(!cbw_ie6){		
		if(this.firstRow != null && this.firstRow.getHeight() > 0){
			popupH = this.firstRow.getHeight() * this.showCount;
		}
		if(bh < 230){
			bh = 230;
		}
//		if(popupH > 80 && bh < 100 && th > 200){
//			bh = th;
//			if(popupH < th)
//				t = th - popupH;
//			else
//				t = 10;
//		}

		dropdown.setStyle({
			top:t + "px",
			left:l + "px"
		});
		popup.setStyle({
			width:w + "px",
			height:(popupH > bh && bh>20)?bh+"px":""
		});
		if(tipTitle != null){
			tipTitle.setStyle({
				width:w+"px"
			});
		}
	}else{
		dropdown.setStyle({
			top:t + "px",
			left:l + "px"
		});
		w += 4;
		var h;
		h = 230;
		popup.setStyle({
			width:w + "px",
			height:h + "px"
		});
		this.iframe.setStyle({
			width:w + "px",
			height:h + "px"
		});
		if(tipTitle != null){
			tipTitle.setStyle({
				width:w+"px"
			});
		}
	}
}

function cbs_onpopupshow(){
	this.resizeHeight();
	var dropdown = $(this.dropdownId);
	dropdown.show();
	var key = $(this.valueId).value;
	var keyEl = dropdown.select("li[key='"+key+"']")[0];
	if(keyEl != null){
		if(this.oldOver != null){
			this.oldOver.removeClassName("cwb-MenuItemHover");
		}
		keyEl.addClassName("cwb-MenuItemHover");
		this.oldOver = keyEl;
		this.resetscroll();
	}
	this.isShow = true;
	Event.observe(window.document,"mousedown",cbs_ondocumentmousedownhandler.bind(this));
}

function cbs_oncomboxclick(evt){
	var el = evt.element();
	
	if(el.hasClassName("cwb-ArrowButtonInner")||
			el.hasClassName("cwb-ArrowButton")){
		var popup = $(this.popupId);
		var paras = $A(popup.select("li"));
		if(this.isInFilter){
			paras.each(Element.show);
			this.isInFilter = false;
			this.filterString = null;
		}
		if(this.oldOver == null){
			this.oldOver = popup.firstDescendant();
			this.firstRow = this.oldOver;
		}
		this.showCount = paras.length;
		this.popupshow();
		$(this.inputId).focus();
		$(this.inputId).select();
	}
}