/** 
 * @author Kenneth.priisholm
 * requires
 * YAHOO.util.Dom;
 * YAHOO.util.Event;
 * YAHOO.util.Anim;
 * YAHOO.util.Motion;
 * YAHOO.util.DD;
*/
//shortcutting YAHOO libs
var $D = $D || YAHOO.util.Dom;
var $E = $E || YAHOO.util.Event;
var $A = $A || YAHOO.util.Anim;
var $M = $M || YAHOO.util.Motion;
var $DD = $DD || YAHOO.util.DD;
var $ = $D.get;
var Valtech = Valtech || {}; 

/* base formcontrol */
Valtech.FormControl = function(){};
Valtech.FormControl.prototype.init = function(props, dataManager){
	if(!props){
		throw "props not provided.";		
	}
	if(!props.id){
		throw "props.id not provided";		
	}
	if(!dataManager || (dataManager instanceof Valtech.DataManager) == false){
		throw "Valid dataManager not provided";		
	}
	this.id = props.id;
	this.container = $D.get(this.id);
	if(!this.container){
		throw "No container element with id '" + this.id + "'";		
	}
	this.dataManager = dataManager;
	this.dataManager.onUpdate.subscribe(this.update, this, true);
}

/* radiobutton group */
Valtech.RadioButtonGroup = function(props, dataManager){
	if(props){
		this.init(props, dataManager);
	}
}
Valtech.RadioButtonGroup.prototype.superclass = Valtech.FormControl; 
Valtech.RadioButtonGroup.prototype.init = function(props, dataManager){
	this.superclass.prototype.init.call(this, props, dataManager);
	if(!props.groupName){
		throw "missingPropertiesError";		
	}
	this.groupName = props.groupName;
	this.dataField = props.dataField || props.groupName;
	var uncheck = props.uncheck ? function(el){ el.checked = ""} : null;
	this.radioButtons = $D.getElementsByAttribute("name", this.groupName, "input", this.container, uncheck);
	if(!this.radioButtons){
		throw "missingElementsError";		
	}
	$E.addListener(this.radioButtons, "click", this.send, this);
	//$E.addListener(this.radioButtons, "change", this.send, this); kepr: removed due to IE "double-load" issue
}
Valtech.RadioButtonGroup.prototype.send = function(e, c){
	var target = $E.getTarget(e);
	var label = $D.getElementsByAttribute("for", target.id, "label", c.container)[0];
	var data = {};
	//ensure to fetch text, *not* nested elements...
	for(var i = 0, l = label.childNodes.length; i < l; i++){
		if(label.childNodes[i].nodeType == 3 && !label.childNodes[i].nodeValue.match(/^\s*$/)){
			var obj = {};
			obj.value = target.value;
			obj.text = label.childNodes[i].nodeValue;
			data[c.dataField] = obj;
			break;
		}
	}
	c.dataManager.update( c.id, data );
}
Valtech.RadioButtonGroup.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataField] && args[0].provider != this.id){
		var selectedValue = args[0].data[this.dataField];
		for(var i = 0, l = this.radioButtons.length; i < l; i++){
			var radioButton = this.radioButtons[i];
			if(selectedValue.value && selectedValue.value == radioButton.value){
				radioButton.checked = "checked";
				return;
			}
		}
	}
}
Valtech.RadioButtonGroup.prototype.selectItem = function(index){
    var rb = this.radioButtons[index];
    var data = {};
    var obj = {};
    var label = $D.getElementsByAttribute("for", rb.id, "label", this.container)[0];
    for(var i = 0, l = label.childNodes.length; i < l; i++){        
		if(label.childNodes[i].nodeType == 3 && !label.childNodes[i].nodeValue.match(/^\s*$/)){
			obj.value = rb.value;
			obj.text = label.childNodes[i].nodeValue;
			data[this.dataField] = obj;
			this.dataManager.update( this.id, data );
			
			break;
		}
	}
    rb.checked = "checked";
}
/**/
Valtech.RadioButtonSwitch = function(props){
	if(props){
		this.init(props);
	}
}
Valtech.RadioButtonSwitch.prototype.init = function(props){
	if(!props.id || !props.groupName || !props.method || !props.context){
		throw "missingPropertiesError";		
	}
	var container = $D.get(props.id);
	if(!container){
		throw "missingElementsError";		
	}
	var radioButtons = $D.getElementsByAttribute("name", props.groupName, "input", container);
	if(radioButtons){
		throw "missingElementsError";		
	}
	$E.addListener(radioButtons, "click", props.method, props.context);
}

/**/


/* checkbox switch */
Valtech.CheckBoxSwitch = function(props, dataManager){
	if(props){
		this.init(props, dataManager);
	}
}
Valtech.CheckBoxSwitch.prototype.superclass = Valtech.FormControl; 
Valtech.CheckBoxSwitch.prototype.init = function(props, dataManager){
	this.superclass.prototype.init.call(this, props, dataManager);
	this.dataName = props.dataName || props.name;
	this.checkBox = this.container.getElementsByTagName("input")[0];
	if(!this.checkBox){
		throw "missingElementsError";		
	}
	this.label = this.container.getElementsByTagName("label")[0];
	
	if(!this.label){
		throw "missingElementsError";		
	}
	this.labelText = "unset";
	for(var i = 0, l = this.label.childNodes.length; i < l; i++){
        if(this.label.childNodes[i].nodeType == 3 && !this.label.childNodes[i].nodeValue.match(/^\s*$/)){
            this.labelText = this.label.childNodes[i].nodeValue;
            break;
        }
    }
	$E.addListener([this.checkBox, this.label], "click", this.send, this);
}
Valtech.CheckBoxSwitch.prototype.send = function(e, c){
    var data = {};
	data[c.dataName] = {};
    if(c.checkBox.checked){
	    data[c.dataName].value = c.checkBox.value;
	    data[c.dataName].text  = c.labelText;
    }
	c.dataManager.update( c.id, data );
}
Valtech.CheckBoxSwitch.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataField] && args[0].provider != this.id){
	    var selectedValue = args[0].data[this.dataField].value;
	    if(selectedValue == this.checkBox.value){
			this.checkBox.checked = "checked";
		}
		else {
		    this.checkBox.checked = "";
		}
	}
}


/* Suggest multiselect */
Valtech.SuggestSelect = function(props, dataManager){
    var mapToObjectArray = function(el, i, ar){
		var obj = {};
		//obj.value = el.id.replace(this.regExId, "");
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	if(props && dataManager){
		this.init(props, dataManager);
	}
}
Valtech.SuggestSelect.prototype.superclass = Valtech.FormControl;
Valtech.SuggestSelect.prototype.init = function(props, dataManager){
	this.superclass.prototype.init.call(this, props, dataManager);
	this.suggestInput = $D.getElementsByClassName("suggest", "input", this.container )[0];
	this.multiSelect = $D.getElementsByClassName("suggest", "div", this.container )[0];
	this.multiSelectItems = this.multiSelect.getElementsByTagName("a");
	this.focusedItem = null;
	if(!props.dataName){
		throw "missingPropertiesError: dataName not provided.";
	}
	this.dataName = props.dataName;
	this.selectedItems = [];
	this.twoWayToggle = props.twoWayToggle || false;
	this.regExId = new RegExp("^" + this.id);
	this.allOn = false;
	this.btnToggleAll = $D.getElementsByClassName("toggle", "a", this.container )[0];
	if(!!this.btnToggleAll){
	    $E.addListener(this.btnToggleAll, "click", this.toggleAll, this);
	}
	$E.addListener(this.suggestInput, "keyup", this.keyListener, this);
	$E.addListener(this.multiSelect, "keypress", this.keyListener, this);
	$E.addListener(this.multiSelect, "click", this.itemClicked, this);
}
Valtech.SuggestSelect.prototype.keyListener = function(e, c){
	var e = e || window.event;
	var kCode = e.which || e.keyCode;
	//alert("kCode: " + kCode);
	var target = $E.getTarget(e);
	if(!target){
		return false	;
	}
	//return;
	switch(kCode){
		
		case 13: //enter
			//toggle
			if(c.focusedItem){
				//c.focusedItem.focus();
				c.toggle();			
			}
			$E.preventDefault(e);
			return false;
			break;
		case 38: //arrow up
			c.findNext(-1);
			$E.preventDefault(e);
			break;
		case 40: //arrow down
			c.findNext(1);
			$E.preventDefault(e);
			break;
		default:
			if(( kCode > 47 && kCode < 223 ) || kCode == 8 || kCode == 32){ 
				if(c.suggestInput != target && kCode != 32){
					c.suggestInput.focus();
					c.suggestInput.value = String.fromCharCode(kCode);
				}
				c.search(c.suggestInput.value);
			}
			break;
	}
}

Valtech.SuggestSelect.prototype.itemClicked = function(e, c){
	var e = e || window.event;
	var target = $E.getTarget(e);
	if(!target.nodeName || target.nodeName.toLowerCase() != "a"){
	    return;
	}
	c.focusedItem = target;
	c.toggle();
	$E.preventDefault(e);
	return false;
}

Valtech.SuggestSelect.prototype.search = function(query){
    if(query == ""){
		this.focusedItem = null;
		$D.removeClass(this.suggestInput, "invalid");
		return;
	}
	$D.removeClass(this.multiSelectItems, "focused");
	var re = new RegExp("\b" + query, "i");
	var match;
	for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
		var item = this.multiSelectItems[i];
		var itemText = item.innerHTML;
		match = itemText.match(re);
		if(match){
			this.focus(item);
			$D.removeClass(this.suggestInput, "invalid");
			break;
		}
	}
	if(!match){
		this.focusedItem = null;
		$D.addClass(this.suggestInput, "invalid");
	}
}
Valtech.SuggestSelect.prototype.focus = function(elm){
	this.focusedItem = elm;	
	if(!$D.hasClass(elm, "focused")/* && !$D.hasClass(elm, "selected" )*/){
		$D.addClass(elm, "focused");
	}
	elm.scrollIntoView();
}
Valtech.SuggestSelect.prototype.findNext = function(step){
	var nextItem;
	if(!this.focusedItem){
		nextItem = this.multiSelectItems[0];
	}
	else {
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
			if(this.focusedItem == this.multiSelectItems[i]){
				$D.removeClass(this.multiSelectItems[i], "focused");
				var nextstep = step + i;
				
				if(nextstep < 0){
					
					nextstep = l-1;
				}
				else if(nextstep >= l){
					
					nextstep = 0;
				}
				
				nextItem = this.multiSelectItems[nextstep];
				break;
			}
		}
	}
	//this.suggestInput.value = nextItem.innerHTML;
	this.suggestInput.value = "";
	$D.removeClass(this.suggestInput, "invalid");
	//this.suggestInput.focus();
	//this.suggestInput.select();
	this.focus(nextItem);
}

Valtech.SuggestSelect.prototype.toggle = function(item){
	var item = item || this.focusedItem;
	
	var index = this.selectedItems.indexOf(item);
	if(!$D.hasClass(item, "selected") && index == -1){
		$D.addClass(item, "selected");
		this.selectedItems.push(item);
		
	}
	else if(this.twoWayToggle){
		$D.removeClass(item, "selected");
		if(index != -1){
			delete this.selectedItems[index];	
			this.selectedItems = this.selectedItems.filter(function(el, i, ar){ if(el != "undefined") return el });
		}
	}
	this.suggestInput.value = "";
	this.suggestInput.focus();
	$D.removeClass(this.suggestInput, "invalid");
	   
	var mapToObjectArray = function(el, i, ar){
		var obj = {};
		//obj.value = el.id.replace(this.regExId, "");
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	var data = {};
	data[this.dataName] = this.selectedItems.map(mapToObjectArray, this);
	this.dataManager.update( this.id, data );
	this._setBtnToggleAll(this);
}
Valtech.SuggestSelect.prototype._setBtnToggleAll = function (c) {
    if(!c.multiSelectItems){
        return;
    }
    if(c.selectedItems.length == c.multiSelectItems.length && c.selectedItems.length !== 0){
        c.allOn = true;
	    c.btnToggleAll.innerHTML = "Fjern alle &gt;&gt;";
	}
	else if(c.selectedItems.length === 0 ) {
	    c.allOn = false;
	    c.btnToggleAll.innerHTML = "V&aelig;lg alle &gt;&gt;";
	}
};


Valtech.SuggestSelect.prototype.toggleAll = function(e, c){
	var i, l;
	var data = {};
	var mapToObjectArray = function(el, i, ar){
		var obj = {};
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	e = e || window.event;
	c.allOn = !c.allOn;
	if(c.allOn){
	    for(i = 0, l = c.multiSelectItems.length; i < l; i++){
	        c.selectedItems.push(c.multiSelectItems[i]);
	    }
	    $D.addClass(c.multiSelectItems, "selected");
	    data[c.dataName] = c.selectedItems.map(mapToObjectArray, c);
    }
    else {
        c.selectedItems = [];
	    data[c.dataName] = [];
	    $D.removeClass(c.multiSelectItems, "selected");
    }
    
	c.dataManager.update( c.id, data );
	
    $E.preventDefault(e);
	return false;
}

Valtech.SuggestSelect.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataName] && args[0].provider != this.id){
		var mapObjectToSingleValueArray = function(el, i, ar){
			return el.value;
		}
		data = args[0].data[this.dataName].map(mapObjectToSingleValueArray, this);
		
		this.selectedItems = [];
		$D.removeClass(this.multiSelectItems, "selected");
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
			var item = this.multiSelectItems[i];
			if(data.indexOf(item.getAttribute('value')) != -1 && this.selectedItems.indexOf(item) == -1){
				$D.addClass(item, "selected");
				this.selectedItems.push(item);
			}
		}
	}
	this._setBtnToggleAll(this);
}


/* multiselect */
Valtech.MultiSelect = function(props, dataManager){
	if(props && dataManager){
		this.init(props, dataManager);
	}
}
Valtech.MultiSelect.prototype.superclass = Valtech.FormControl;
Valtech.MultiSelect.prototype.init = function(props, dataManager){
	this.superclass.prototype.init.call(this, props, dataManager);
	this.multiSelect = this.container;
	this.multiSelectItems = this.multiSelect.getElementsByTagName("a");
	this.focusedItem = null;
	if(!props.dataName){
		throw "missingPropertiesError: dataName not provided.";
	}
	this.dataName = props.dataName;
	this.selectedItems = [];
	this.twoWayToggle = props.twoWayToggle || false;
	this.ignoredProviders = props.ignoredProviders || [];
	this.ignoredProviders.push(this.id);
	$E.addListener(this.multiSelect, "keypress", this.keyListener, this);
	$E.addListener(this.multiSelect, "click", this.itemClicked, this);
}
Valtech.MultiSelect.prototype.keyListener = function(e, c){
	var e = e || window.event;
	var kCode = e.which || e.keyCode;
	var target = $E.getTarget(e);
	if(!target){
		return false	;
	}
	//return;
	switch(kCode){
		
		case 13: //enter
			//toggle
			if(target.nodeName.toLowerCase() == "a"){
    			c.toggle(target);
    		}
			$E.preventDefault(e);
			return false;
			break;
		default:
			//do nothing
			break;
	}
}

Valtech.MultiSelect.prototype.itemClicked = function(e, c){
	var e = e || window.event;
	var target = $E.getTarget(e);
	if(!target.nodeName || target.nodeName.toLowerCase() != "a"){
	    return;
	}
	c.focusedItem = target;
	c.toggle();
	$E.preventDefault(e);
	return false;
}
Valtech.MultiSelect.prototype.focus = function(elm){
	this.focusedItem = elm;	
	if(!$D.hasClass(elm, "focused")/* && !$D.hasClass(elm, "selected" )*/){
		$D.addClass(elm, "focused");
	}
}
Valtech.MultiSelect.prototype.findNext = function(step){
	var nextItem;
	if(!this.focusedItem){
		nextItem = this.multiSelectItems[0];
	}
	else {
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
			if(this.focusedItem == this.multiSelectItems[i]){
				$D.removeClass(this.multiSelectItems[i], "focused");
				var nextstep = step + i;
				
				if(nextstep < 0){
					
					nextstep = l-1;
				}
				else if(nextstep >= l){
					
					nextstep = 0;
				}
				
				nextItem = this.multiSelectItems[nextstep];
				break;
			}
		}
	}
	this.focus(nextItem);
}

Valtech.MultiSelect.prototype.toggle = function(item){
	var item = item || this.focusedItem;
	
	var index = this.selectedItems.indexOf(item);
	if(!$D.hasClass(item, "selected") && index == -1){
		$D.addClass(item, "selected");
		this.selectedItems.push(item);
		
	}
	else if(this.twoWayToggle){
		$D.removeClass(item, "selected");
		if(index != -1){
			delete this.selectedItems[index];	
			this.selectedItems = this.selectedItems.filter(function(el, i, ar){ if(el != "undefined") return el });
		}
	}
	var mapToObjectArray = function(el, i, ar){
		var obj = {};
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	var data = {};
	data[this.dataName] = this.selectedItems.map(mapToObjectArray, this);
	this.dataManager.update( this.id, data );
	
}

Valtech.MultiSelect.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataName] && this.ignoredProviders.indexOf(args[0].provider) < 0){
		var mapObjectToSingleValueArray = function(el, i, ar){
			return el.value;
		}
		data = args[0].data[this.dataName].map(mapObjectToSingleValueArray, this);
		
		this.selectedItems = [];
		$D.removeClass(this.multiSelectItems, "selected");
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
			var item = this.multiSelectItems[i];
			if(data.indexOf(item.getAttribute('value')) != -1 && this.selectedItems.indexOf(item) == -1){
				$D.addClass(item, "selected");
				this.selectedItems.push(item);
			}
		}
	}
}

/* Text Field */
Valtech.TextInput = function(props, dataManager, validationManager){
    if(props && dataManager){
        this.init(props, dataManager, validationManager);
    }
};
Valtech.TextInput.prototype.init = function(props, dataManager, validationManager){
	if(!props){
		throw "props not provided.";		
	}
	if(!props.id){
		throw "props.id not provided";		
	}
	if(!props.dataName){
		throw "props.dataName not provided";		
	}
	if(!dataManager || (dataManager instanceof Valtech.DataManager) == false){
		throw "Valid dataManager not provided";		
	}
	this.id = props.id;
	this.dataName = props.dataName;
	this.message = props.message || this.id + " is not valid";
	this.textField = $D.get(this.id);
	if(!this.textField){
		throw "No container element with id '" + this.id + "'";		
	}
	this.textField.value = props.initValue || "";
	this.pattern = props.pattern;
	
	$E.addListener(this.textField, "blur", this.send, this);
	$E.addListener(this.textField, "focus", this.resetLayout, this);
	this.validationManager = validationManager || null;
	this.validatorId = props.validatorId || this.id;
	this.dataManager = dataManager;
	this.dataManager.onUpdate.subscribe(this.update, this, true);
}
Valtech.TextInput.prototype.send = function(e, c){
	var target = $E.getTarget(e);
	var obj = {}, valObj;
	var data = {};
	obj["text"] = c.textField.value;
	obj["value"] = c.textField.value;
	if(c.validationManager){
        if(!c.validationManager.validate(c.validatorId)){
            $D.addClass(c.textField, "invalid");
	        return false;
        }
	}
	data[c.dataName] = obj;
	c.dataManager.update( c.id, data );
}
Valtech.TextInput.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataName]){
		data = args[0].data[this.dataName];
		this.textField.value = data["value"];
	}
}
Valtech.TextInput.prototype.resetLayout = function(e, c){
	$D.removeClass(c.textField, "invalid");
}



/* Suggest Filter */
Valtech.SuggestFilter = function(props, dataManager){
    var mapToObjectArray = function(el, i, ar){
		var obj = {};
		//obj.value = el.id.replace(this.regExId, "");
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	if(props && dataManager){
		this.init(props, dataManager);
	}
}
// Constant map of values to translate
Valtech.SuggestFilter.translateMap = { 'ae': '\346', 'oe': '\370', 'aa': '\345' };

Valtech.SuggestFilter.prototype.superclass = Valtech.FormControl;
Valtech.SuggestFilter.prototype.init = function(props, dataManager){
	this.superclass.prototype.init.call(this, props, dataManager);
	this.suggestInput = $D.getElementsByClassName("suggest", "input", this.container )[0];
	this.multiSelect = $D.getElementsByClassName("suggest", "div", this.container )[0];
	this.multiSelectItems = this.multiSelect.getElementsByTagName("a");
	this.focusedItem = null;
	if(!props.dataName){
		throw "missingPropertiesError: dataName not provided.";
	}
	this.dataName = props.dataName;
	this.selectedItems = [];
	this.twoWayToggle = props.twoWayToggle || false;
	this.tabStart = props.tabStart || this.suggestInput.tabIndex && this.suggestInput.tabIndex != "" ? parseInt(this.suggestInput.tabIndex) : 1000;
	this.suggestInput.tabIndex = this.tabStart.toString();
	this.regExId = new RegExp("^" + this.id);
	this.allOn = false;
	
	this.btnToggleAll = $D.getElementsByClassName("toggle", "a", this.container )[0];
	this.btnSelectAll = $D.getElementsByClassName("select-all", "a", this.container )[0];
	this.btnDeselectAll = $D.getElementsByClassName("deselect-all", "a", this.container )[0];
	
	if(!!this.btnToggleAll) $E.addListener(this.btnToggleAll, "click", this.toggleAll, this);
	if(!!this.btnSelectAll) $E.addListener(this.btnSelectAll, "click", this.selectAll, this);
	if(!!this.btnDeselectAll) $E.addListener(this.btnDeselectAll, "click", this.deselectAll, this);
	
	$E.addListener(this.suggestInput, "keyup", this.keyListener, this);
	$E.addListener(this.multiSelect, "keypress", this.keyListener, this);
	$E.addListener(this.multiSelect, "click", this.itemClicked, this);
};
Valtech.SuggestFilter.clear = function () {
    this.multiSelect.innerHTML = "";
    this.suggestInput.value = "";
    $D.removeClass(this.suggestInput, "invalid");
};
Valtech.SuggestFilter.prototype.keyListener = function(e, c){
	var e = e || window.event;
	var kCode = e.which || e.keyCode;
	//alert("kCode: " + kCode);
	var target = $E.getTarget(e);
	if(!target){
		return false	;
	}
	//return;
	switch(kCode){
		case 9: //tab
			//c.focusedItem = target;
			break;
		case 13: //enter
			if(target.nodeName.toLowerCase() == "a"){
			    c.toggle(target);
			}
			$E.preventDefault(e);
			return false;
			break;
		default:
			if(( kCode > 47 && kCode < 223 ) || kCode == 8 || kCode == 32){ 
				if(c.suggestInput != target && kCode != 32){
					c.suggestInput.focus();
					c.suggestInput.value = String.fromCharCode(kCode);
				}
				c.search(c.suggestInput.value);
			}
			break;
	}
}

Valtech.SuggestFilter.prototype.itemClicked = function(e, c){
	var e = e || window.event;
	var target = $E.getTarget(e);
	if(!target.nodeName || target.nodeName.toLowerCase() != "a"){
	    return;
	}
	c.toggle(target);
	$E.preventDefault(e);
	return false;
}

Valtech.SuggestFilter.prototype.search = function(query){
    $D.removeClass(this.multiSelectItems, "hide");
    var tabIndex = this.tabStart;
    
	var translate = /(aa|ae|oe)/gi;
	query = query.replace(translate, function($0, $1) {
		return Valtech.SuggestFilter.translateMap[$1.toLowerCase()];
	});
    
    if(query == ""){
		this.focusedItem = null;
		$D.removeClass(this.suggestInput, "invalid");
		$D.removeClass(this.multiSelectItems, "hide");
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
		    var item = this.multiSelectItems[i];
		    item.tabIndex = (++tabIndex).toString();
	    }
		return;
	}
	$D.removeClass(this.multiSelectItems, "focused");
	var re = new RegExp("(\\W|^)" + query, "i");
	
	var match;
	var hasMatch = false;

	
	for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
		var item = this.multiSelectItems[i];
		var itemText = item.innerHTML + ", " + item.innerHTML.replace(translate, function($0, $1) {
			return Valtech.SuggestFilter.translateMap[$1.toLowerCase()];
		});
		match = itemText.match(re);
		if(match){
		    hasMatch = true;
		    item.tabIndex = (++tabIndex).toString();
		    $D.removeClass(item, "hide");
			$D.removeClass(this.suggestInput, "invalid");
		}
		else {
		    $D.addClass(item, "hide");
		    item.tabIndex = "";
		}
	}
	if(!hasMatch){
		$D.addClass(this.suggestInput, "invalid");
	}
	else if(!!this.btnToggleAll){
	    this.btnToggleAll.tabIndex = (++tabIndex).toString();
	}
}


Valtech.SuggestFilter.prototype.selectAll = function(e, c) {
	var data = {};
    for (var i=0, l=c.multiSelectItems.length; i<l; i++) {
        var item = c.multiSelectItems[i];
        if (!$D.hasClass(item, "hide") && !$D.hasClass(item, "selected") && c.selectedItems.indexOf(item) == -1) {
            c.selectedItems.push(item);
            $D.addClass(item, "selected");
        }
    }
    c._updateSelection();
};

Valtech.SuggestFilter.prototype.deselectAll = function(e, c) {
    var data = {};
    for (var i=0, l=c.multiSelectItems.length; i<l; i++) {
        var item = c.multiSelectItems[i];
        var index = c.selectedItems.indexOf(item);
        if (!$D.hasClass(item, "hide") && $D.hasClass(item, "selected") && index >= 0) {
            delete c.selectedItems[index];
            $D.removeClass(item, "selected");
			c.selectedItems = c.selectedItems.filter(function(el, i, ar) { if(el != "undefined") return el; });
        }
    }
    c._updateSelection();
};
Valtech.SuggestFilter.prototype._updateSelection = function() {
    var mapToObjectArray = function(el, i, ar){
		return {
		    text: el.innerHTML,
		    value: el.getAttribute("value")
		};
	}
	data[this.dataName] = this.selectedItems.map(mapToObjectArray, this);
	this.dataManager.update( this.id, data );
};


    
Valtech.SuggestFilter.prototype.toggle = function(item){
	var item = item || this.focusedItem;
	var index = this.selectedItems.indexOf(item);
	if(!$D.hasClass(item, "selected") && index == -1){
		$D.addClass(item, "selected");
		this.selectedItems.push(item);
		
	}
	else if(this.twoWayToggle){
		$D.removeClass(item, "selected");
		if(index != -1){
			delete this.selectedItems[index];	
			this.selectedItems = this.selectedItems.filter(function(el, i, ar){ if(el != "undefined") return el });
		}
	}
	//this.suggestInput.value = "";
	//this.suggestInput.focus();
	$D.removeClass(this.suggestInput, "invalid");
	   
	var mapToObjectArray = function(el, i, ar){
		var obj = {};
		//obj.value = el.id.replace(this.regExId, "");
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	var data = {};
	data[this.dataName] = this.selectedItems.map(mapToObjectArray, this);
	this.dataManager.update( this.id, data );
	this._setBtnToggleAll(this);
}
Valtech.SuggestFilter.prototype._setBtnToggleAll = function (c) {
    if (c.btnToggleAll) {
        if(!c.multiSelectItems){
            return;
        }
        if(c.selectedItems.length == c.multiSelectItems.length && c.selectedItems.length !== 0){
            c.allOn = true;
	        c.btnToggleAll.innerHTML = "Fjern alle &gt;&gt;";
	    }
	    else if(c.selectedItems.length === 0 ) {
	        c.allOn = false;
	        c.btnToggleAll.innerHTML = "V&aelig;lg alle &gt;&gt;";
	    }
	}
};


Valtech.SuggestFilter.prototype.toggleAll = function(e, c){
	var i, l;
	var data = {};
	var mapToObjectArray = function(el, i, ar){
		var obj = {};
		obj.value = el.getAttribute("value");
		obj.text = el.innerHTML;
		return obj;
	}
	e = e || window.event;
	c.allOn = !c.allOn;
	if(c.allOn){
	    for(i = 0, l = c.multiSelectItems.length; i < l; i++){
	        c.selectedItems.push(c.multiSelectItems[i]);
	    }
	    $D.addClass(c.multiSelectItems, "selected");
	    data[c.dataName] = c.selectedItems.map(mapToObjectArray, c);
    }
    else {
        c.selectedItems = [];
	    data[c.dataName] = [];
	    $D.removeClass(c.multiSelectItems, "selected");
    }
    
	c.dataManager.update( c.id, data );
	
    $E.preventDefault(e);
	return false;
}

Valtech.SuggestFilter.prototype.update = function(type, args){
	if(args[0].provider && args[0].data[this.dataName] && args[0].provider != this.id){
		var mapObjectToSingleValueArray = function(el, i, ar){
			return el.value;
		}
		data = args[0].data[this.dataName].map(mapObjectToSingleValueArray, this);
		
		this.selectedItems = [];
		$D.removeClass(this.multiSelectItems, "selected");
		for(var i = 0, l = this.multiSelectItems.length; i < l; i++){
			var item = this.multiSelectItems[i];
			if(data.indexOf(item.getAttribute('value')) != -1 && this.selectedItems.indexOf(item) == -1){
				$D.addClass(item, "selected");
				this.selectedItems.push(item);
			}
		}
	}
	this._setBtnToggleAll(this);
}
