Ext.ux.grid.filter.CategoryFilter = Ext.extend(Ext.ux.grid.filter.Filter, {
	labelField:  'text',
	loadingText: 'Loading...',
	loadOnShow:  true,
	value:       [],
	loaded:      false,
	phpMode:     false,
	
	init: function(){
		this.menu.add('<span class="loading-indicator">' + this.loadingText + '</span>');
         this.labelField='name';  


    var Tree = Ext.tree;

     loader= new Tree.TreeLoader({
            dataUrl:'/data/categories.php',
	    preloadChildren: true,
        });

    // set the root node
    var root = new Tree.AsyncTreeNode({
        text: 'Kategorier',
        draggable:false,
        id:'source',
        loader: loader,
    });


    this.store=root;
		if(this.store){
			if(this.loadOnShow)
				this.menu.on('show', this.onMenuLoad, this);
		}

  
		this.store.on('loadexception', function() {
alert('loadexception load: ');
});

loader.load(root);
root.expandChildNodes();
//alert("loaded?");


		this.bindShowAdapter();
	},
	
	/**
	 * Lists will initially show a 'loading' item while the data is retrieved from the store. In some cases the
	 * loaded data will result in a list that goes off the screen to the right (as placement calculations were done
	 * with the loading item). This adaptor will allow show to be called with no arguments to show with the previous
	 * arguments and thusly recalculate the width and potentially hang the menu from the left.
	 * 
	 */
	bindShowAdapter: function(){
		var oShow    = this.menu.show;
		var lastArgs = null;
		this.menu.show = function(){
			if(arguments.length == 0){
				oShow.apply(this, lastArgs);
			} else {
				lastArgs = arguments;
				oShow.apply(this, arguments);
			}
		};
	},
	
	onMenuLoad: function(){
if (!this.loaded) {
           this.onLoad(this.store,this.store)				
}
	},
	
	onLoad: function(store,node){
		var visible = this.menu.isVisible();
		this.menu.hide(false);
		
		this.menu.removeAll();
                records=node.childNodes;

		for(var i=0, len=records.length; i<len; i++){
                        var menu2 = new Ext.menu.Menu();
			var item = new Ext.menu.CheckItem({
				text:    records[i].attributes['text'],
				checked: false,
                                menu: menu2,
				hideOnClick: false});
			
			item.itemId = records[i].attributes['id'];
			item.on('checkchange', this.checkChange, this);


//this could be rewritten to some general recursive menu...but who bothers really.
                var subrecords=records[i].attributes['children'];

		for(var j=0, len2=subrecords.length; j<len2; j++){

			var item2 = new Ext.menu.CheckItem({
				text:    subrecords[j]['text'],
				checked: false,
				hideOnClick: true});
			
			item2.itemId = subrecords[j]['id'];
			item2.on('checkchange', this.checkSubChange , this);
			menu2.add(item2);	
        }
	
			this.menu.add(item);
		}
	
		this.setActive(this.isActivatable());
		this.loaded = true;
		
		if(visible)
			this.menu.show(); //Adaptor will re-invoke with previous arguments
	},

	
	checkChange: function(item, checked){
		//Om det är en huvudmeny vi har klickat i
		if (checked) {
		// om klickad i, se till att alla undermenyer är iklickade
		var children=item.menu.items.items;
		for(var i=0, len=children.length; i<len; i++) {
			children[i].setChecked(true,true);
		}
		}else{
		// om klickad ur, se till att alla undermenyer är urklickade
		var children=item.menu.items.items;
		for(var i=0, len=children.length; i<len; i++) {
			children[i].setChecked(false,true);
		}
		}
		this.checkAndUpdate(this);
	},
	checkAndUpdate: function(context) {

		// XXX: Har maste vi skriva fardigt loopen.

		var value = [];

		var myitems=this.menu.items.items;
	
	 	if (myitems) {
		for(var j=0, mylen=myitems.length;j<mylen;j++) {
			if(myitems[j].checked) {
			var children=myitems[j].menu.items.items;
			for(var i=0, len=children.length; i<len; i++) {
				if (children[i].checked) {
					value.push(children[i].itemId);
				}
			}
			}
		}
		}else{
			console.log("Did not find myitems in checkAndupdate");
			console.dir(this.menu.items);
		}
		context.value = value;
		
		context.setActive(this.isActivatable());
		context.fireEvent("update", this);	
	},
	checkSubChange: function(item, checked){

		// XXX: Har maste vi hitta parent.. Antagligen genom att loopa over menyn massa ganger?
		parent=this.menu.activeItem;
		if (checked) {
		// om klickad i, se till att master är iklickad
			parent.setChecked(true,true);
		}else{

		// Om klickad ur, och inga andra items är klickade, klicka ur master
			var fellows=parent.menu.items.items;
			var check_cnt=0;
		     	console.dir(fellows);
			for(var i=0, len=fellows.length; i<len; i++) {
				if (fellows[i].checked) {
					check_cnt++;
//					console.log("Found checked");
//					console.dir(fellows[i]);
				}
			}	
			if (!check_cnt) {
				parent.setChecked(false,true);
			}
		}

		this.checkAndUpdate(this);

	},
	
	isActivatable: function(){
		return this.value.length > 0;
	},
	
	setValue: function(value){
		var value = this.value = [].concat(value);

		if(this.loaded)
			this.menu.items.each(function(item){
				item.setChecked(false, true);
				for(var i=0, len=value.length; i<len; i++)
					if(item.itemId == value[i]) 
						item.setChecked(true, true);
			}, this);
			
		this.fireEvent("update", this);
	},
	
	getValue: function(){
		return this.value;
	},
	
	serialize: function(){
    var args = {type: 'list', value: this.phpMode ? this.value.join(',') : this.value};
    this.fireEvent('serialize', args, this);
		return args;
	},
	
	validateRecord: function(record){
		return this.getValue().indexOf(record.get(this.dataIndex)) > -1;
	}
});