ontos.widgets.SearchDataReader = function(meta, recordType)
{
	this.cookieProvider = meta.cookieProvider;
	delete meta.cookieProvider;
	
	ontos.widgets.SearchDataReader.superclass.constructor.call(this, meta, recordType);
}

Ext.extend(ontos.widgets.SearchDataReader, Ext.data.JsonReader, {
	addElement : function(elem, arr) {
		var sz = arr.length;
		arr[arr.length] = elem;
	},
	readRecords : function(o){
		var res = ontos.widgets.SearchDataReader.superclass.readRecords.call(this, o);
		if (res.success) {
			var newrec = []; var newrecpos = 0;
			
			var titles = {};
			newrecpos = this.readStoredRecords(newrec, newrecpos, titles);
			
			// removing doubles
			var first = true;
			Ext.each(res.records, function(r) {
				var newtitle = r.get("title") + "#" + r.get("type");
				var item = titles[newtitle];
				if (_debug || !item) {
					titles[newtitle] = {pos: newrecpos};
					newrec[newrecpos++] = r;
					r.editing = true;
					r.set("flag", first ? "firstFound" : "found");
					first = false;
				} else if (!newrec[item.pos].data.rank || newrec[item.pos].rank > r.get("rank")) {
					newrec[item.pos].data.rank = r.get("rank");
				}
			}, this);
			
			// removing long labels
			var objects = [];
			titles = {}; //title->pos
			var pos = 0;
			Ext.each(newrec, function(r) {
				var uri = r.get("uri");
				var title = r.get("title");
				var mintitlerec = titles[uri];
				if (mintitlerec) {
					this.addElement(mintitlerec.assoc, r);
					if (mintitlerec.title.length > title.length) {
						objects[mintitlerec.pos] = null;
						mintitlerec.title = title;
						mintitlerec.pos = pos;
						objects[pos++] = r;
					}
				} else {
					titles[uri] = {title: title, pos: pos, assoc:[r]};
					objects[pos++] = r;
				}
			}, this);
			
			resultpos = 0;
			var resultrecs = [];
			for (var i = 0; i < pos; ++i) {
				if (objects[i] != null) {
					resultrecs[resultpos++] = objects[i];
				}
			}
			
			res.records = resultrecs;
			res.totalRecords = resultpos;
		}
		return res;
	},
	readStoredRecords : function(arr, pos, titles) {
		var cpos = 0;
		for (;;) {
			var dt = this.cookieProvider.get("ontos-search[0]" + cpos, "");
			if (!dt || dt == "") return pos;
			var parts = dt.split("&");
			var r = new this.recordType({title: decodeURIComponent(parts[0]), uri: decodeURIComponent(parts[1]), type: decodeURIComponent(parts[2])}, decodeURIComponent(parts[1]));				
			r.editing = true;
			r.set("flag", cpos==0?"firstHistory":"history");
			
			var newtitle = r.get("title") + "#" + r.get("type");
			titles[newtitle] = {pos: pos};
				
			arr[pos++] = r;
            ++cpos;
		}
		return pos;
	}
});

ontos.widgets.SearchField = function(container, config) {
	this.dispatcher = config.dispatcher;
	this.addEvents({
        "onSearch" : true
    });
	config = config||{};
	if (config.cookieProvider) {
		this.cookieProvider = aConfig.cookieProvider;
	} else {
		this.cookieProvider = new Ext.state.CookieProvider({});
	}
	this.historyQueueSize = config.historyQueueSize | 4;
	
	var ds = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({method:"POST", url: "data", timeout: 30000}),
		/*
        proxy: new Ext.data.ScriptTagProxy({
            url: 'command?cache=OFF&cmd=search&lang='+_lang,
            timeout: 30000
        }),*/
        reader: new ontos.widgets.SearchDataReader({
            root: 'ds',
            totalProperty: 'totalCount',
            cookieProvider: this.cookieProvider
        }, [
            {name: 'title', mapping: 'label'},
            {name: 'uri', mapping: 'uri'},
            {name: 'type', mapping: 'type'},
            {name: 'flag', mapping: 'flag'},
            {name: 'rank', mapping: 'rank'}
        ])
		,baseParams:{module:'NewsKas', mode: 'json', query:'search', ontology:_ontology, cache:'OFF'}
    });

    config.store=ds;
    //config.displayField='title';
    config.typeAhead=false;
    config.minChars=1;
    config.triggerAction='all';
    config.resizable=false;
    if (!config.loadingText) config.loadingText='Searching...';
    if (!config.width) config.width=270;
    config.height=25;
    config.hideTrigger=false;
    config.selectOnFocus=true;
    config.applyTo = container;
	config.itemSelector = 'div';
	config.queryParam = "text";

    config.tpl = new Ext.XTemplate(
    '<tpl for=".">',
    	'<tpl if="this.isHistory(flag)">',
    		'<div class="spec-search-item"><table id="combo-tbl" cellpadding=0 cellspacing=0 border=0 width="100%"><tr><td width="100%" id=title><h3>{title} [{[this.getType(values.type, values.uri)]}]</h3></td><td valign=top id="tip">' + ontos.locale.history + '</td></tr></table></div>',
    	'</tpl>',
    	'<tpl if="this.isFirstFound(flag)">',
    		'<div class="spec-search-item"><table id="combo-tbl" class="firstFound" cellpadding=0 cellspacing=0 border=0 width="100%"><tr><td width="100%" id=title><h3>{title} [{[this.getType(values.type, values.uri)]}]</h3></td><td valign=top id="tip">' + ontos.locale.found + '</td></tr></table></div>',
    	'</tpl>',
    	'<tpl if="this.isFound(flag)">',
    		'<div class="search-item"><h3>{title} [{[this.getType(values.type, values.uri)]}]</h3></div>',
    	'</tpl>',
    '</tpl>', {
    	isHistory: function(flag){
        	return flag == 'firstHistory';
     	},
     	isFirstFound: function(flag){
        	return flag == 'firstFound';
     	},
     	isFound: function(flag){
        	return flag != 'firstFound' && flag != 'firstHistory';
     	},
     	getType: function(type, uri){
     		var tp = type.split("#")[1].replace(/_/g, " ");
     		//if (_debug) tp += '<br/>' + uri.split("#")[1];
     		return tp;
     	}
    });
    ontos.widgets.SearchField.superclass.constructor.call(this, config);
    
    

    this.on("select", function(combo, record, index) {
    	this.setRawValue(record.data.title);
    	this.setSelectedValue(record.data);
    	this.doFireEvent("onSearch", {id: record.data.uri, label: record.data.title, type: record.data.type.split('#')[1], src:'kas'});
    },this);
    
    if (this.dispatcher) {
    	this.dispatcher.on("objectSelected", function(e, h) {
    		//if ("object-list" == e.eventsource) {
    			//this.setRawValue(e.labelabel);
    		//}
    	}, this);
    }
    
    if (window._search) {
    	this.setRawValue(_search);
    	this.focus(_search);
    	this.doQuery(_search);
    	//this.doQuery.defer(1200, this, [_search]);
    }
}

Ext.extend(ontos.widgets.SearchField, Ext.form.ComboBox, {
	onViewClick : function(doFocus){
		var index = this.view.getSelectedIndexes()[0];
        var r = this.store.getAt(index);
        if(r){
            this.onSelect(r, index);
        } else {
        	for (var idx = 0; idx < this.store.getCount(); ++idx)
        	{
        		var record = this.store.getAt(idx);
        		if (record.data.rank && record.data.rank == 0) {
					this.collapse();
					this.setSelectedValue(record.data);
        			this.doFireEvent("onSearch", {id: record.data.uri, label: record.data.title, type: record.data.type, src:'kas'});
        			break;        			
        		}
        	}
        }
        if(doFocus !== false){
            this.el.focus();
        }
    },
	onLoad : function(){
        if(!this.hasFocus){
            return;
        }
        if(this.store.getCount() > 0){
            this.expand();
            this.restrictHeight();
        	this.selectedIndex = -1;
        	this.view.clearSelections();
        }else{
            this.onEmptyResults();
        }
        //this.el.focus();
    },/*
	select : function(index, scrollIntoView){
		this.selectedIndex = index;
        this.view.select(index);
        if(scrollIntoView !== false){
            var el = this.view.getNode(index);
            if(el){
                this.innerList.scrollChildIntoView(el, false);
            }
        }
    },*/
	doQuery : function(q, forceAll){
		if(q === undefined || q === null){
            q = '';
        }
        var qe = {
            text: q,
            forceAll: forceAll,
            combo: this,
            cancel:false
        };
        if(this.fireEvent('beforequery', qe)===false || qe.cancel){
            return false;
        }
        q = encodeURIComponent(qe.text);
        forceAll = qe.forceAll;
        if(forceAll === true || (q.length >= this.minChars)){
            if(this.lastQuery != q){
                this.lastQuery = q;
                if(this.mode == 'local'){
                    this.selectedIndex = -1;
                    if(forceAll){
                        this.store.clearFilter();
                    }else{
                        this.store.filter(this.displayField, q);
                    }
                    this.onLoad();
                }else{
                    this.store.baseParams[this.queryParam] = q;
                    this.store.load({
                        params: this.getParams(q)
                    });
                    this.expand();
                }
            }else{
                this.selectedIndex = -1;
                this.onLoad();   
            }
        }
    },
	setSelectedValue : function(dt) {
		//debugger;
		var cpos = 0;
		var newval = encodeURIComponent(dt.title)+"&" + encodeURIComponent(dt.uri) + "&" + encodeURIComponent(dt.type);
		var prevval = newval;
		var fpos = 0
		for (; fpos < this.historyQueueSize; ++fpos)
		{
			if (this.cookieProvider.get("ontos-search[0]" + fpos, "") == newval) {
				++fpos;
				break;
			}
		}
		do {
			var nextprevval = this.cookieProvider.get("ontos-search[0]" + cpos, "");
			var last = (!dt || dt == "");
			this.cookieProvider.set("ontos-search[0]" + cpos, prevval);
			prevval = nextprevval;
			++cpos;
		} while (!last && cpos < fpos);
	},
	doFireEvent : function(evname, evargs) {
		if (this.dispatcher) {
			this.dispatcher.fireEvent(evname, evargs);
		} else {
			this.fireEvent(evname, evargs);
		}
	}
});