//=================
//simple dict object
function dict_item(id, l1, l2, name){
	this.id = id;
	this.l1 = l1;
	this.l2 = l2;
	this.name = name;
}

//dictionary object
DictionaryObject = function(id, intname, author, short_name, normalname, longname, domain, lang_pairs, state, order){
    
    var dict_id;
    var intname;
    var shortname;
    var normalname;
    var longname;
    var author;
    var domain;
    var l1 = new Array();
    var l2 = new Array();
    var lang_pairs;
    var state;
    var order_value;
    
    this.dict_id = id;
    this.intname = intname;
    this.shortname = short_name.replace(/\\/g,"");//short_name;
    this.normalname = normalname.replace(/\\/g,"");//normalname;
    this.longname = longname.replace(/\\/g,"");//longname;
    this.domain = domain;
    this.author = author;
    this.lang_pairs = lang_pairs;
    this.state = state;
    this.order_value = order;
    if (lang_pairs.length > 0)
        this.l1 = lang_pairs[0];
    if (lang_pairs.length > 1)
        this.l2 = lang_pairs[1];
    
    /*
    for(var i=0;i<lang_pairs.length;i++){
        add_new_element(l1, lang_pairs[i][0]);
        if (lang_pairs[i][1] == 1)
            add_new_element(l2, lang_pairs[i][0]);
        else
            add_new_element(l2, lang_pairs[i][1]);
    }
    */
}

DictionaryManager = function(){

    var dicts = new Array();
    this.add = function(id, intname, author, short_name, normalname, langname, domain, lang_pairs, state) {
        var curr_dict = new DictionaryObject(id, intname, author, short_name, normalname, langname, domain, lang_pairs, state, dicts.length);
        dicts.push(curr_dict);
    }
    
    this.dictionaries = dicts;
    
    this.set_state = function(index, state){
        if (index >=0 && index < dicts.length){
            if (state)
                dicts[index].state = "open";
            else
                dicts[index].state = "closed";
        }
    }
    
    this.set_state_by_id = function(id, state){
        this.set_state(get_index_by_id(id), state);
    }

    this.set_state_by_intname = function(intname, state){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].intname == intname){
                this.set_state(i, state);
                return;
            }                
        }
    }

    this.get_dictlist_by_state = function(state){
        var str = "";
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].state == state){
                if (str != "")
                    str += ":";
                str += dicts[i].intname;
            }
        }
        return str;
    }

    //return true, if id1 > id2 (when display entries id1 stands earlier in the list)
    this.greater = function(id1, id2){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].dict_id == id1)
                return true;
            if (dicts[i].dict_id == id2)
                return false;
        }
        return true; //unknown id values
    }
    
    this.get_open_dictionaries = function(){
        var text = ""; 
        for(var i=0; i<dicts.length; i++){
            //if (dicts[i].state == "open")
                text += dicts[i].intname + " ";    
        }
        return text;
    }
    
    this.display_dictionaries = function(dest_obj, show_ordercell){
    
        //add buttons, too
        var html = "<FIELDSET><LEGEND><b>" + get_text('switch dictionaries by group');
        html += "</b></LEGEND>";
        var all_langs = dict_man.get_supported_langs(true);
        var dst_langs = dict_man.get_supported_langs(false);
        for(i=0; i<dst_langs.length; i++)
            add_new_element(all_langs, dst_langs[i]);
        html += "<input type='button' value='"+get_text('all')+"' id='dict_sel_all' onclick='dictionaries_module.set_langs(0)'>";
        html += "<input type='button' value='"+get_text('none')+"' id='dict_sel_none' onclick='dictionaries_module.set_langs(-1)'>";
        for(var i = 1; i<all_langs.length; i++){
            //html += "<input type='image' src='"+flags_path+"/"+get_flag(all_langs[i])+"' value='"+get_text(all_langs[i])+"' name='aaa' onclick='dictionaries_module.set_langs("+all_langs[i]+")'>";
            html += "<input type='button' value='"+get_text(all_langs[i])+"' id='dict_sel_"+all_langs[i]+"' onclick='dictionaries_module.set_langs(\""+all_langs[i]+"\")'>";
        }
        html += "</FIELDSET>";
        dest_obj.content.innerHTML = html;
    
        var max = dicts.length - 1;
        var html = "<table>"; // class='settingtable'
        for(var i=0; i<dicts.length; i++){
            html += show_dictionary(dicts[i].dict_id, dicts[i].state, 
                    dicts[i].l1, dicts[i].l2, 
                    this.get_logo_by_intname(dicts[i].intname),
                    dicts[i].shortname, dicts[i].longname, i, max, show_ordercell, dest_obj.content);//+ " ("+dicts[i].intname+")"
        }
        html += "</table>";
        dest_obj.content.innerHTML += html;	

        //if (font_size != "")
            //dest_obj.content.style.fontSize = font_size;
    }
    
    //get_given_dicts gives the dict_ids for the opened dictionaries, filtered by l1, l2
    this.get_given_dicts = function(l1, l2){
        var lst = new Array();
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].state != "open")
                continue;
            if ((l1 == 0) && (l2 == 0)){
                //all dicts with their langs...
                lst.push(dicts[i].intname);
                /*for(var j=0;j<dicts[i].lang_pairs.length;j++)
                    lst.push(new dict_item(dicts[i].dict_id, 
                                        dicts[i].lang_pairs[j][0], 
                                        dicts[i].lang_pairs[j][1],
					dicts[i].intname));*/
            }else if (l1 == 0){
                for(var j=0;j<dicts[i].lang_pairs.length;j++){
                    if (dicts[i].lang_pairs[j][1] == l2)
                        lst.push(dicts[i].intname);
                        /*lst.push(new dict_item(dicts[i].dict_id, 
                                        dicts[i].lang_pairs[j][0], 
                                        dicts[i].lang_pairs[j][1],
					dicts[i].intname));*/
                }
            }else if (l2 == 0){
                for(var j=0;j<dicts[i].lang_pairs.length;j++){
                    if (dicts[i].lang_pairs[j][0] == l1)
                        lst.push(dicts[i].intname);
                        /*lst.push(new dict_item(dicts[i].dict_id, 
                                        dicts[i].lang_pairs[j][0], 
                                        dicts[i].lang_pairs[j][1],
					dicts[i].intname));*/
                }
            }else if (contains_element(dicts[i].lang_pairs, new Array(l1, l2))){ 
                //lst.push(new dict_item(dicts[i].dict_id, l1, l2, dicts[i].intname));
                lst.push(dicts[i].intname);
            }

            //if dict id has lang id 1
            //repair_special_lang_code(dicts[i].lang_pairs, dicts[i].dict_id, dicts[i].intname, l1, l2, lst);
        }
        return lst;
    }
    
    //get_dicts_to_lang gives the dict_ids filtered by lang_code
    this.get_dicts_to_lang = function(lang_code){
        var lst = new Array();
        for(var i=0; i<dicts.length; i++){
            if (lang_code == 0){
                //all dicts with their langs...
                lst.push(dicts[i].dict_id);
            }else{
                for(var j=0; j<dicts[i].lang_pairs.length; j++){
                    if (contains_element(dicts[i].lang_pairs[j], lang_code)){ 
                        lst.push(dicts[i].dict_id);
                        break;
                    }
                }
            }

            //if dict id has lang id 1
            //repair_special_lang_code(dicts[i].lang_pairs, dicts[i].dict_id, l1, l2, lst);
        }
        return lst;
    }
    
    
    function get_index_by_id(id){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].dict_id == id)
                return i;
        }
        return 0; //unknown id
    }

    this.get_index_by_intname = function(intname){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].intname == intname)
                return i;
        }
        return 0; //unknown id
    }

/*
    this.get_id_by_intname = function(intname){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].intname == intname)
                return dicts[i].dict_id;
        }
        return 0; //unknown id
    }*/

    //returns the default language directory
    this.get_langs_by_intname = function(intname){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].intname == intname)
                return new Array(dicts[i].l1[0], dicts[i].l2[0]);
        }
        return 0; //unknown id
    }

    this.get_dstlangs_by_intname = function(intname, srclang){
        for(var i=0; i<dicts.length; i++){
            if (dicts[i].intname == intname){
                if (srclang == '') return dicts[i].l2;
                var ret = new Array();
                for(var j=0; j<dicts[i].l2.length; j++){
                    if (srclang != dicts[i].l2[j]) ret.push(dicts[i].l2[j]);
                }
                if (ret.length == 0 && dicts[i].l2.length != 0) ret.push(dicts[i].l2[0]);
                return ret;
            }
        }
        return 0; //unknown id
    }

/*
    this.get_dict_by_id = function(id, property){
         if (property == "intname")
		return dicts[get_index_by_id(id)].intname; //faster than eval
        return eval("dicts[get_index_by_id(id)]." + property); 
    }
        */    
    
    this.get_longname_by_id = function(id){
         return dicts[id].longname; 
    }

    this.get_shortname_by_id = function(id){
         return dicts[id].shortname; 
    }

    this.get_intname_by_id = function(id){
         return dicts[id].intname; 
    }

    this.get_shortname_by_intname = function(intname){
        var id = this.get_index_by_intname(intname);
        return dicts[id].shortname; 
    }

    this.get_longname_by_intname = function(intname){
        var id = this.get_index_by_intname(intname);
        return dicts[id].longname; 
    }

    this.get_domain_by_intname = function(intname){
        var id = this.get_index_by_intname(intname)
        return dicts[id].domain; 
    }


    this.get_logo_by_intname = function(intname){
        var html = "<img src='"+logo_path+"/"+this.get_logo(intname)+"' ";
        var id = this.get_index_by_intname(intname);
        var desc = dicts[id].longname + " [" + dicts[id].author + "] "; //dicts[id].shortname + " | " + 
        if (bubble){
            var title = '';
            //var img = "<img src=\\'"+logo_path+"/"+this.get_logo(intname)+"\\'/>  ";
            html = '<span OnMouseover="showTooltip(0, 0, \''+title+'\', \''+ desc+'\')" OnMouseout="hideTooltip();">' + html + '</span>';
        }else
            html += "title='" + desc + "'/>"; 
        return html;
    }
    
    this.get_logo = function(intname){
        for(var i=0; i< DictionaryLogo.length; i++){
            if (DictionaryLogo[i][0] == intname){
                return DictionaryLogo[i][1];
            }
        }
        //general
        return DictionaryLogo[0][1];
    }



    this.get_supported_langs = function(trg){
        var index = 1;
        if (trg)
            index = 0;
        var langs = new Array(); 
        langs.push(0); //any
        for(var i=0; i<dicts.length; i++){
            for(var j=0;j<dicts[i].lang_pairs[index].length;j++){ 
                var langcode = dicts[i].lang_pairs[index][j];
                if (langcode != 1)
                    add_new_element(langs, langcode);
            }
        }
        return langs;
    }
    
    this.move = function(dict_id, where){
        log_info(1, "move start", "");
        var index = get_index_by_id(dict_id);
        if ((where == "orderup") && (index > 0)){
            dicts[index].order_value--;
            dicts[index-1].order_value++;
        }else if ((where != "orderup") && (index < dicts.length-1)){
            dicts[index].order_value++;
            dicts[index+1].order_value--;
        }
        //log_info(1, "value was modified", "");
        dicts.integerSort("order_value");
        //log_info(1, "sorted", "");
    }    
    
    this.set_order_value = function(index, value){
        dicts[index].order_value = value;
    }
    
    this.sort = function(){
        dicts.integerSort("order_value");
    }
    
    this.order_by = function(arr){
        for(var i=0; i<arr.length; i++){
            var g = this.get_index_by_intname(arr[i]);
            this.set_order_value(g, i);
        }
        this.sort();
    }
    
    this.get_order = function(){
        var str = "";
        for(var i=0; i<dicts.length; i++){
            if (i!=0)
                str += ":";
            str += dicts[i].intname;
        }
        return str;
    }

    this.load_dictionaries = function(xmlobj){
        var x = xmlobj.getElementsByTagName("mbm_dict");
        for(var i=0; i<x.length; i++){
            var node = x.item(i);
            if (node.getElementsByTagName("dict_intname")[0].firstChild != null){
                var intname = node.getElementsByTagName("dict_intname")[0].firstChild.nodeValue; 
                if (check_dictionary(intname)){
                    var normalname = "";
                    var longname="";
                    var shortname="";
                    if ( x[i].getElementsByTagName("dict_names").length > 0){//[0].getElementsByTagName("dictname");
                        var d = x[i].getElementsByTagName("dict_names")[0].getElementsByTagName("dict_name");
                
                        for(var j=0; j<d.length; j++){
                            var lang = d[j].getAttribute("lang");
                            if (lang == ui_lang){
                                if (d[j].getElementsByTagName("normalname")[0].firstChild)
                                    normalname = d[j].getElementsByTagName("normalname")[0].firstChild.nodeValue;
                                if (d[j].getElementsByTagName("longname")[0].firstChild)
                                    longname = d[j].getElementsByTagName("longname")[0].firstChild.nodeValue;
                                if (d[j].getElementsByTagName("shortname")[0].firstChild)
                                    shortname = d[j].getElementsByTagName("shortname")[0].firstChild.nodeValue;
                            }
                        }
                    }
                    //var status = x.item(i).getElementsByTagName("status")[0].firstChild.nodeValue;//.getAttribute("status");
                    var dict_id = x.item(i).getElementsByTagName("dict_id")[0].firstChild.nodeValue;
                    var curr_langs = collect_tag_pairs(x[i], "langpair", "src_lang_id", "dst_lang_id");
                    //var src_langs = collect_tags(x[i], "langpair", "src_lang_id");
                    //var dst_langs = collect_tags(x[i], "langpair", "dst_lang_id");
                    
                    this.add(dict_id, intname, shortname, normalname, longname, curr_langs, "open");
                }
            }
        } 
    }
    
    this.load_dictionariesJS = function(JSobj){
        for(var i=0; i<JSobj.length; i++){
            if (!check_dictionary(JSobj[i].intname)) continue;
            var langindex = 0;
            for(var k = 0; k<JSobj[i].shortnames.length; k++){
                if (JSobj[i].shortnames[k][0] == ui_lang){
                    langindex = k;
                    break;
                }
            }
            var shortname = JSobj[i].shortnames[langindex][1];
            langindex = 0;
            for(var k = 0; k<JSobj[i].names.length; k++){
                if (JSobj[i].names[k][0] == ui_lang){
                    langindex = k;
                    break;
                }
            }
            var name = JSobj[i].names[langindex][1];
            langindex = 0;
            for(var k = 0; k<JSobj[i].domains.length; k++){
                if (JSobj[i].domains[k][0] == ui_lang){
                    langindex = k;
                    break;
                }
            }
            var domain = (JSobj[i].domains.length > langindex) ? JSobj[i].domains[langindex][1] : '';

            this.add(i, JSobj[i].intname, JSobj[i].author, shortname, "", name, domain, JSobj[i].langpairs, "open");
        }
    }
}


var Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

//==============
//ajax functions
//==============

function GetXmlHttpObject()
{ 
    var objXMLHttp=null;
    if (window.XMLHttpRequest)
    {
        objXMLHttp=new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return objXMLHttp;
}

function getXml_base(url, callback, method, async, data, urlencoded, name){
    log_info(2, "getXml_base", url ); //+ " asyncron: " + async
    var xmlHttp=GetXmlHttpObject(); //local variable!!!
    if (xmlHttp==null)
    {
        alert ("Browser does not support HTTP Request");
        return;
    }    

	var readychange = function() {
    if (xmlHttp.readyState == 4) {// only if xmlHttp shows "loaded"
        if (xmlHttp.status < 400) {// only if "OK"
				if (method=="POST") {
					callback(xmlHttp);
					delete callback;
				} else {
					callback(xmlHttp,data);
					delete callback;
				}
			} else if (typeof xmlHttp == "undefined" || typeof xmlHttp.status == "undefined") {
				// don't do anything. user has navigated away
				delete callback;
			} else if (xmlHttp.status == 401) { // unauthorized
				callback(xmlHttp);
				delete callback;
			} else if (xmlHttp.status == 404) {
				// should not happen, but ignore it for now
			} else {
				//if (App.errorShowing) return false;
				//App.errorShowing = true;
				switch(xmlHttp.status) {
					// windows error codes
					case 12002: // server timeout
					case 12029: case 12030: case 12031: // dropped connection
					case 12152: // connection closed by server
					case 13030:
						//alert(name + ("There was a network problem. Please reload the page."));
						break;
					case 500: case 503:
						//alert(name + ("There was an internal server error. Please try later."));
						break;
					default:
						//alert(("There was a problem loading data:") + "\nstatus: " + xmlHttp.status+ "/" + xmlHttp.statusText + "\n" + url);
				//App.errorShowing = false;
				}
				delete callback;
			}
		}
	};

    if (method=="POST") {
        xmlHttp.open("POST", url, async);
        if (async){
            if (urlencoded) xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xmlHttp.onreadystatechange = readychange;
        }
        xmlHttp.send(data);
        if (!async){
            var ret = callback(xmlHttp);
            delete callback;
            return ret;
        }
    } else {
        xmlHttp.open("GET", url, async);
        if (async){
            xmlHttp.onreadystatechange = readychange;
        }
        xmlHttp.send(null);
        /* "When you use synchronous loading in Mozilla (ie. browser waits until the XML file has been loaded before doing anything else), 
            the readystatechange event is not available." (http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_2.html)
        */
        if (!async){
            var ret = callback(xmlHttp,data);
            delete callback;
            return ret;
        }
    }
	return xmlHttp;
}

//asyncron download
function getXml(url, callback) {
    return getXml_base(url, callback, "GET", true, "", false, "");
}

//asyncron download with param
function getXml2(url, callback, data) {
    return getXml_base(url, callback, "GET", true, data, false, "");
}

//syncron download
function getXml_sync(url, callback) {
    return getXml_base(url, callback, "GET", false, "", false, "");
}

//=================
//mobidic functions
//=================

//connect to mobidic
//  fast_connect:   true: only connect
//                  false: connect + get dictionaries info

/*

//no need to connect
function mbd_connect(fast_connect)
{ 
    var url;
    if (offline == true)
        url = "xml/conn.xml";
    else
        url=server_url+"?do=connect";
    if (!fast_connect)
        getXml(url, mbd_connect_parse);
    else
        getXml_sync(url, mbd_connect_parse); //this call is synron, so mbd_query will wait to its result

    function mbd_connect_parse(response){
        log_info(4, "mbd_connect_parse", response.responseText); 
        
        if (response.responseText == ""){
            log_info(0, "MoBiDic Server is not running...", "");
            return;
        }
        var root = response.responseXML.documentElement;

        if (root.getElementsByTagName("connect_client_id")[0].firstChild != null){
            connect_client_id = root.getElementsByTagName("connect_client_id")[0].firstChild.nodeValue; 

            if (!fast_connect){
                //get dict info
                mbd_dict_list();
            }else{
                var text = dict_man.get_open_dictionaries();//dictionaries
                mbd_open_dicts(text);
            }
        }else{
            show_error(root.getElementsByTagName("error")[0].firstChild);
        }
        mbd_reconnect_process = false;
    }
}
*/

//check state of dictionary (enable, disable)
function check_dictionary(short_name){
    if ((enableDicts.length == 0) && (disableDicts.length == 0))
        return true; //every dictionary is welcome
    
    //only disableDicts is given
    if ((enableDicts.length == 0) && (disableDicts.length != 0)){
        if (contains_element(disableDicts, short_name))
            return false;
        else
            return true;
    }
    
    //enableDict is given (in this case disableDict is don't care)
    if (contains_element(enableDicts, short_name))
        return true;
    return false;
}

//get list of dictionaries
function mbd_dict_list(){ 
    var url, dict_list;
    if (offline == true)
        url = path_prefix+"xml/list.xml";
    else
        url=server_url+"?do=listdicts&cid="+connect_client_id;
    getXml(url, mbd_dict_list_parse);
    
    function mbd_dict_list_parse(response){
        log_info (4, "mbd_dict_list_parse", response.responseText);

        var root = response.responseXML.documentElement;
        //dictionaries = root;
    
        //dict_man = new DictionaryManager();
        dict_man.load_dictionaries(root);
        var text = dict_man.get_open_dictionaries();
        //var text = get_open_dictionaries(root);//dictionaries);
        log_info (4, "mbd_dict_list", text);
        
        if (text == ""){
            show_error(root.getElementsByTagName("error")[0].firstChild);
        }//else
            //mbd_open_dicts(text);
            
    }
}


//opens dictionaries
/*
function mbd_open_dicts(dicts){
    var url;
    dicts = encodeURIComponent(dicts);
    //dicts = dicts.replace(/ /g, "+");
    if (offline == true)
        url = "xml/open.xml";
    else
        url=server_url+"?do=open&cid="+connect_client_id+"&dict="+dicts;
    getXml(url, mbd_open_dicts_parse);

    function mbd_open_dicts_parse(response){
        var root = response.responseXML.documentElement;
    
        log_info(4, "mbd_open_dicts_parse", response.responseText); 
        
        //dictionaries = response.responseXML.documentElement;

        var x = root.getElementsByTagName("opendict");

        if (x.length == 0){
            show_error(root.getElementsByTagName("error")[0].firstChild);
        }

        
        var lic_error = "";
        for(var i=0; i<x.length; i++){
            var err = x[i].getElementsByTagName("error");
            if (err.length != 0 && err[0].firstChild != null){
                var errormsg = err[0].firstChild.nodeValue;
                var dict_name = x[i].getAttribute("dict_intname");
                if (errormsg == "Not enough licenses")
                    lic_error += " " + dict_name;
            }
        }
        if (lic_error.length != 0){
            var s = get_text('not enough licenses');
            log_info(0, s.replace("%s", lic_error), "");
            close_loading();    
            return;
        }    
        


        //indicates that mobidic initialization has finished
        mbd_obj.initialized();
    }
}
*/
/*
function mbd_fast_connect(fast_connect){
    var url=server_url+"?do=connect_Ex&dict="+fast_open_dicts_params;
    if (!fast_connect)
        getXml(url, mbd_fast_connect_parse);
    else
        getXml_sync(url, mbd_fast_connect_parse); //this call is synron, so mbd_query will wait to its result

    function mbd_fast_connect_parse(response){
        log_info(4, "mbd_fast_connect_parse", response.responseText); 
        
        if (response.responseText == ""){
            log_info(0, "MoBiDic Server is not running...", "");
            return;
        }
        var root = response.responseXML.documentElement;

        if (root.getElementsByTagName("connect_client_id")[0].firstChild != null){
            connect_client_id = root.getElementsByTagName("connect_client_id")[0].firstChild.nodeValue; 
        }else{
            show_error(root.getElementsByTagName("error")[0].firstChild);
        }
        mbd_reconnect_process = false;
    }
}
*/

function init(obj){
    mbd_obj = obj;
    
    dict_man = new DictionaryManager();
    dict_man.load_dictionariesJS(Dictionaries);

    //we are ready, dicts are loaded
    mbd_obj.initialized();

    //add extra dicts
    //mbd_dict_list();
}


/*function checkbox_is_checked(id){
    var obj = document.getElementById(id);
    if (obj)
        return obj.checked;
    log_info(2, "debug "+id+" not found", obj);
    return false;
}
*/
/*
function update_client_id(xml_object){
    var c = xml_object.getElementsByTagName("connect_client_id");
    if (c && c[0] && c[0].firstChild != null)
        connect_client_id = c[0].firstChild.nodeValue; 
}

function mbd_check_invalid_client_id(response, info){
    
    //log_info(4, "mbd_check_invalid_client_id", response.responseText);
    var root = response.responseXML.documentElement;
    if (root && root.getElementsByTagName("error").length != 0){
        var errormsg = root.getElementsByTagName("error")[0].firstChild.nodeValue;
        //no connection
        if (errormsg.indexOf("Invalid Client ID") != -1)
            //repair? or just tell
            return false;
        if (errormsg.indexOf("Invalid") != -1){
            //there is an error: show it...
                //alert(info);
                show_error(root.getElementsByTagName("error")[0].firstChild);
            }
    }
    return true;
}

function reconnect(info){
    var infos = info.split(":");
    var curr_client_id = infos[0];
    if (mbd_reconnect_process || curr_client_id == invalid_client_id)
        return false; //reconnection is in process or it is a result of a previous query
    mbd_reconnect_process = true;
    invalid_client_id = curr_client_id;
    log_info(4, "mbd_reconnect started", "");    
    if (fast_open_dicts_params == "")
        mbd_connect(true); 
    else
        mbd_fast_connect(true);
    return true;
}
*/
//mobidic lookup
function mbd_query(l1, l2, str, mode, dicts, dest_module, dest_element, offset, concat_result){
    
    if (str == ""){
        //nothing to do
        dest_module.restore_caption();
        return false;
    }
    
    //no cache
/*    if(dest_module.check_query_params(l1, l2, dictionary_id, str, mode, offset))
           {dest_module.restore_caption(); return;}
    if(dest_module.obj.getModuleName() != "expressions_module"){
        dest_module.save_query_params(l1, l2, dictionary_id, str, mode, offset);
    }*/
        

    //start timer
    start_time = new Date();
    log_info(1, " query starts", "'"+str+"'");

    //is there connection with server?
/*    if (!mbd_check_connection()) {
        log_info(4, "mbd_reconnect started", "");    
        mbd_connect(true); 
    }
*/        

/*    var dicts = new Array();
    if (dictionary_id != -1){
	    //var dict_intname = dict_man.get_dict_by_id(dictionary_id, "intname");
        dicts.push(dictionary_id);//new dict_item(dictionary_id, l1, l2, dict_intname)); //one dict or it is an array?
    }else{
        //get the list of dictionaries (selected language and/or dictionaries)
        dicts = dict_man.get_given_dicts(l1, l2);
    }
  */  
    
    if (dicts == '')
        dicts = dict_man.get_given_dicts(l1, l2);
    
    //for(var t=0;t<dicts.length;t++)
        //log_info(4, " dicts in query "+dicts[t].id+" "+dicts[t].l1+" "+dicts[t].l2, "");

    
    var url;
    //variable will be used in results
    var unknown_word = true;
    var arrived = 0;
    var all_queries = dicts.length;
    var first_entry_params = new Array();
    var default_context_and_expressions = true;
    var exact_entry_found = -1;
    var entries_array = new Array();
    //to decide: unknown or not
    var used_dict = dict_man.get_dictlist_by_state("open").split(":");

    //is there dict(s) for this lang pair?
    if (dicts.length == 0){
        show_message(get_text('not supported langs'), dest_element);
        if (used_dict.length != dict_man.dictionaries.length)
            show_message(' ' + get_text('try to open dictionaries'), dest_element);
        dest_module.restore_caption();
        return false;
    }


    log_info(4, "mbd_query started", "");

    //if (mode == 1) 
      //  default_context_and_expressions = true;
 
    if (offline == true){
        url = "xml/entry.xml";
        getXml(url, mbd_query_parse);
    }
    else{
        var str_encode = Url.encode(str);//encodeURIComponent(str);
	if(false && dest_module.obj.getModuleName() == "expressions_module"){
		for(var i=0; i<dicts.length; i++){
		   /*if (dicts[i].l1 == 1031){
			var upper_str = str.substr(0,1).toUpperCase() + str.substr(1, str.length-1);
			str_encode = Url.encode(upper_str);
		  }*/
		    url = server_url + "?do=searchword&dicts="+dicts[i]+"&l1=0&l2=0&find="+str_encode+"&fmode="+mode; 
		    var result_limit = dest_module.get_limit();
	//            if (offset != 0 && result_limit<30)
	//                result_limit = 30;
		    url += "&num="+result_limit+"&offs="+offset; //number_of_hits
		    var log_params = connect_client_id + ":" + str_encode + ":0:0:" + encodeURIComponent(url);
		    getXml2(url, mbd_query_parse, log_params);
		    //getXml(url, mbd_query_parse);
		}
       }else{  
		all_queries=1;
		url = server_url + "?do=searchword&dicts=";
		//for(var i=0; i<dicts.length; i++){
		   // url += dicts[i]+"|";
		//}
        url += dicts.join("|");
		url += "&find="+str_encode+"&fmode="+mode+"&l1="+l1+"&l2="+l2; 
		var result_limit = dest_module.get_limit();
		url += "&num="+result_limit+"&offs="+offset; //number_of_hits
		var log_params = connect_client_id + ":" + str_encode + ":" + encodeURIComponent(url);
		getXml2(url, mbd_query_parse, log_params);
	}        
    }
    


    function mbd_query_parse(response, info){
    
        //check if there is newer query 
/*        if(dest_module.obj.getModuleName() == "expressions_module"){
            if (!expressions_module.check_query_params(l1, l2, dicts.join(","), str))
                return;
        }else{
            if(!dest_module.check_query_params(l1, l2, dicts.join(","), str, mode, offset))
                return;
        }
*/
/*        if (!concat_result){
            if(dest_module.obj.getModuleName() == "expressions_module")
                expressions_module.ClearContent();
            else
                entries_module.ClearContent();
        }
*/	
        log_info(4, "mbd_query_parse", response.responseText);
        var root = response.responseXML.documentElement;
	    root.normalize();
        
        //lic error handling
        var error_tag = root.getElementsByTagName("error");
        if (error_tag && error_tag[0]){
        
            errormsg = error_tag[0].firstChild.nodeValue;
            if (errormsg.indexOf('Not enough licenses') != -1){
                errormsg = errormsg.replace(/Not enough licenses/, '');
                errormsg = get_text('not enough licenses').replace("%s", errormsg);
            }

            show_message(errormsg + "\n", dest_element);
        }
        //update client_id if necessary
        //update_client_id(root);

        var x = root.getElementsByTagName("dict_entry");
        var last_result = false;
    
        //counting asyncron answers: last one can decide: unknown or not...
        arrived++;
        if (arrived == all_queries){
            last_result = true;
        }

        //check num of result (maybe a "next result from this dictionary" link is necessary
        var next_results = false;
        var next_results_offset, number_of_result;
        
        
        //check if answer exists
        if (response.responseText == ""){
            show_message(get_text('MoBiDic Server 2006 is down... :('), dest_element);
            dest_module.restore_caption();
            return;
        }else if (!x || x.length == 0){
            //mobidic gives a message "lookup string not found in dictionary", 
            //but we have a better one :)
            if (last_result && unknown_word && !concat_result){
                var no_hit = get_text("no hit");
            
                if (dest_module.obj.getModuleName() != 'entries_module')
                    //no_hit = get_text("no exact hit");
                
                    //put in table
                    //show_entry('', '', '', '', '', '',no_hit, dest_module, dest_element);
                    show_message(get_text("no hit"), dest_element); 
            }
        }else
            unknown_word = false;
            
        //next results...
        var lres = root.getElementsByTagName("lookup_result");
        if (lres != null &&
            lres.length != 0){
            //alert("hali"+root.getElementsByTagName("lookup_result"));
            number_of_result = parseInt(lres[0].firstChild.nodeValue);
	        dest_module.set_hit_counter(number_of_result);
            if (number_of_result > dest_module.get_limit()){
                //next_results_offset = parseInt(root.getElementsByTagName("next_lookup_offset")[0].firstChild.nodeValue);
                next_results_offset = parseInt(result_limit) + parseInt(offset);
                if (result_limit < number_of_result)
                    next_results = true;
                
                /*next_results += "&num="+number_of_hits+"&offs="+next_results_offset;
                log_info(1, "next_results: ", next_results);
                next_results_url = server_url + "?do=searchword&cid=" + connect_client_id + "&dict="+dict_id+"&srclang="+src_lang+"&dstlang="+dst_lang+"&find="+str+"&fmode="+mode; 
                next_results_url += next_results;
                */
            }
            /*if (offset == 0)
                dest_module.add_hit_counter(number_of_result);*/
        }
            

        for(var i=0; i<x.length; i++){
            var node = x[i];
            var dict_id = node.getElementsByTagName("dict_id")[0].firstChild.nodeValue; 
            var src_lang = node.getElementsByTagName("src_lang")[0].firstChild.nodeValue; 
            //var dst_lang = '';//node.getElementsByTagName("dst_lang")[0].firstChild.nodeValue; 
            var def_langpair = dict_man.get_dstlangs_by_intname(dict_id, src_lang);
            //var src_lang = def_langpair[0]; 
            var dst_lang = (def_langpair.length == 1 ? def_langpair[0] : 'mu'); //it can be more langs...
            
            var entry_id = node.getElementsByTagName("entry_id")[0].firstChild.nodeValue; 
            var headword_str = node.getElementsByTagName("headword_text")[0].firstChild.nodeValue; 
            var headword_id = node.getElementsByTagName("headword_id")[0].firstChild.nodeValue; 
            var entry = node.getElementsByTagName("entry_text");
            if (entry && entry[0] && entry[0].firstChild)
                entry = entry[0].firstChild.nodeValue; 
            else
                entry = headword_str + ' <i>(' + get_text('demo dictionary') + ")</i>"; //it is demo dict
            //var entry = response.responseText; 

            //fixme ~ replace: ennek a helye a szerverben lesz
            //headword_str = headword_str.replace(/([^~]+)~.*/g,"$1");
            
            //fixme: filter entries: ennek a helye a szerverben lesz
            //if (contains_element(entries_array, dict_id+"_"+entry_id))
            //    continue;
            entries_array.push(dict_id+"_"+entry_id);
            
            //filter expression: basic word is not expression
            /*if(dest_module.obj.getModuleName() == "expressions_module" &&
                headword_str == str){
                dest_module.add_hit_counter(-1);
                continue;
            }*/

 	    //if((l1 != 0 || l1 != '') && (l2 != 0 || l2 != '')){
	    if(!((l1 == 0) || (l2 == 0 ))){
		//in this case  we dont want flags
		src_lang = '';
		dst_lang = '';
	    }
            var curr_entry = show_entry(src_lang, dst_lang, dict_id, headword_str, headword_id, entry_id, 
                                            entry, dest_module, dest_element);
            var curr_entry_id = curr_entry[0];
            var curr_pos = curr_entry[1];
            
            //save params to start context call later
            if (!default_context_and_expressions && exact_entry_found != dict_id && curr_pos == 0){
                first_entry_params = new Array(src_lang, dst_lang, dict_id, headword_str, headword_id, entry_id, curr_entry_id);
                exact_entry_found = -1;
                if (headword_str == str)
                    exact_entry_found = dict_id;
            }



            //dest_module.add_hit_counter(1); //amig a kliensnel szurunk, nem tudjuk az osszeset elore megmondani
            //dest_module.increase_hit_counter(); //a osszeset mutassa, ne a mutatottakat
        }



        //put a "next results" link, if necessary
        if (next_results){
            var dest_module_name = dest_module.obj.getModuleName();
            var dict_intname = '';
            //if (dest_module_name == "expressions_module") dict_intname = dict_id;
            var next_results_text = '<a onclick="show_next_results(\''+l1+'\', \''+l2+'\', \''+str.replace("'", "\\'")+'\', '+mode+', \''+dict_intname+'\', '+dest_module_name+', '+dest_module_name+'.obj.content, ';
            
            var postfix = '); return false;" href="javascript: return false;" class="more_hits">';
            var extra = getPageNavigation(next_results_text, postfix, '</a>', parseInt(offset), parseInt(result_limit), number_of_result);
            //next_results_text += next_results_offset+'); return false;">';
            //next_results_text += '<a href="javascript: return false;" class="more_hits">';
            //next_results_text += get_text('more results')+ ' (' + (number_of_result-next_results_offset) + ')</a><br><br>';
            
            next_results_text = extra;
            //log_info(1, "next_results_text", next_results_text);
            
            //dest_element.innerHTML += next_results_text;  //does not work
            var helper_node = document.createElement("div");
            helper_node.innerHTML = next_results_text;
            dest_element.appendChild(helper_node);
/*            
            if ((dest_module_name != "expressions_module") &&
                (typeof( dest_module.viewer) != 'undefined')){
                //insert_into_tree(dict_id, "a", next_results_text);
                var helper_node = document.createElement("div");
                helper_node.innerHTML = next_results_text;
                //dest_module.viewer.insert_item(dict_id, "", "", "", helper_node); 
                var flag_text = show_flags_of_dictionary(src_lang, dst_lang, dict_id); 
                var dict_longname = dict_man.get_longname_by_intname(dict_id);
                var dict_shortname = dict_man.get_shortname_by_intname(dict_id);
                dest_module.viewer.insert_item(dict_man.get_index_by_intname(dict_id), '', '', '', helper_node); 
            }else
                show_message(next_results_text, dest_element);
*/                
        }

        //related info was not started and this item is the first OR the last and we use the available first item
        if (false && !default_context_and_expressions && 
            (dict_id == dicts[0] || (last_result && first_entry_params.length != 0))){ 
            //first hit
            default_context_and_expressions = true;
            if ((exact_entry_found!=-1) || last_result){
                src_lang = first_entry_params[0];
                dst_lang = first_entry_params[1];
                dict_id = first_entry_params[2];
                headword_str = first_entry_params[3];
                headword_id = first_entry_params[4];
                entry_id = first_entry_params[5];
                curr_entry_id = first_entry_params[6];
            }
            if (typeof dict_id != "undefined"){
                highlight_entry(curr_entry_id);
                var restore_var = false;
                if (mode == 1 && want_expression){
                    want_expression = false;
                    restore_var = true;
                }
                show_related(src_lang, dst_lang, dict_id, headword_str, headword_id, entry_id);
                if (restore_var)
                    want_expression = true;

                var e_obj = document.getElementById('entry_'+curr_entry_id);
                if (e_obj)
                    show_related_info(dict_man.get_shortname_by_intname(dict_id), headword_str, e_obj.innerHTML);
            }
        }

        //start lookup for each word, if necessary: unknown and it contains more words
        if (unknown_word && !concat_result && dest_module.obj.getModuleName() == 'entries_module' && str.split(" ").length > 1){
            //put delimiter
            //show_entry('', '', '', '', '', '','&lt;hr&gt;', dest_module, dest_element);
            start_each_word(l1, l2, dicts, str, mode);
        }

        if (last_result){
            //calculate query time in millisec
            var end_time = new Date();
            var timediff = end_time.getTime() - start_time.getTime();
            log_info(1, "time in query:", timediff/1000 + "s" + "(mode:"+mode+")");

            //debug
            //logg query
            //relative unknown: the given dictionaries (for example english-hungarian) gives no result
            //absolutely unknown: no dict gives result
            if (unknown_word && used_dict.length != dict_man.dictionaries.length)
                unknown_word = false; //it was only relative unknown word
            if ((dest_module.obj.getModuleName() != "expressions_module") &&
                (log_words || (log_only_unknown_words && unknown_word))){
                if (!offline && (other_services_url!="")){
                    var infos = info.split(":");
                    var logg_url=other_services_url+"?do=logg&word="+infos[1]+"&unknown="+Number(unknown_word)+"&l1="+infos[2]+"&l2="+infos[3]+"&url=";//+infos[4];
		if (infos.length < 4) //some variables missing...
			logg_url=other_services_url+"?do=logg&word="+infos[1]+"&unknown="+Number(unknown_word)+"&l1=&l2=&url=";
                    getXml(logg_url, function (){});
                }
            }
            
            //and
            dest_module.restore_caption();
            //if (!concat_result)
              //  dest_element.innerHTML += "<br/><br/>";
        }
        log_info(4, "function mbd_query_parse ends", "");
    }
    return true;
}

//mobidic context
function mbd_context(l1, l2, dict_id, head_str, head_id, start_entry_id, dest_obj){
    
    var url;
    if (offline == true){
        url = "xml/context.xml";
        getXml(url, mbd_context_parse);
    }else{

        //todo:
        /*
        1. do=gethwcntx&cid=1&dict=5&srclang=2057&dstlang=1038&hword=5132731&cntxnum=10
        2. headword_str
            do=gethword&cid=1&dict=5&srclang=2057&dstlang=1038&hword=5132731+5132919+5132936
        
        nem lehetne ehelyett pl, hogy a szócikk (do=searchword) tartalmazza a 
            headword_id, headword_str, dst_lang infót,
        es a do=gethwcntx tartalmazza a címszót?
        */

	//dict to help proxy 2008.10.14
	var dict_name = dict_id; //dict_man.get_dict_by_id(dict_id, "intname");
	if (typeof dict_name =="undefined")
		dict_name = "";
        //majd leirom
        var context_limit_buffer = parseInt(context_limit)+30;
        url = server_url + "?cid=" + connect_client_id + "&do=gethwcntx&dict="+dict_id+"&dictname="+dict_name+"&srclang="+l1+"&dstlang="+l2+"&hword="+head_id+"&cntxnum="+context_limit_buffer; 
        var log_params = connect_client_id + ":" + head_id;
        getXml2(url, mbd_context_parse, log_params);
        //getXml(url, mbd_context_parse);
    }

    
            function mbd_context_parse(response, info){
            
                log_info(3, "mbd_context_parse", response.responseText);
                if (response.responseText == ""){
                    show_message(get_text('MoBiDic Server 2006 is down... :('), dest_obj.content);
                    dest_obj.restore_caption();
                    return;
                }
                
                //check if there is newer query 
                //if(!context_module.check_query_params(dict_id, head_str))
                //    return;
                
                //check: client id is valid or not?...
                /*if (!mbd_check_invalid_client_id(response, info)){
                    if (reconnect(info))
                        mbd_context(l1, l2, dict_id, head_str, head_id, start_entry_id, dest_obj);
                    return;
                }*/

                var root = response.responseXML.documentElement;
                var headword_ids = root.getElementsByTagName("headword_id");
                var id_list = "";

                //update client_id if necessary
                //update_client_id(root);
                
                for(var i=0; i<headword_ids.length; i++){
                    if (i != 0)
                        id_list += "+";
                    id_list += headword_ids[i].firstChild.nodeValue;
                }
                
                if (offline == true){
                    url = "xml/context2.xml";
                    getXml(url, mbd_context_parse_2);
                }else{
                    url = server_url + "?cid=" + connect_client_id + "&do=gethword&dict="+dict_id+"&dictname="+dict_name+"&srclang="+l1+"&dstlang="+l2+"&hword="+id_list; 
                    var param = connect_client_id;
                    getXml2(url, mbd_context_parse_2, param);
                }
                

            }

            function mbd_context_parse_2(response, info){
                
                //check: client id is valid or not?...
                /*if (!mbd_check_invalid_client_id(response, info)){
                    if (reconnect(info))
                        mbd_context(l1, l2, dict_id, head_str, head_id, start_entry_id, dest_obj);
                    return;
                }*/

                //check if there is newer query 
                //if(!context_module.check_query_params(dict_id, head_str))
                //    return;

                log_info(3, "mbd_context_parse_2", response.responseText);
                var root = response.responseXML.documentElement;
                var headwords = root.getElementsByTagName("headword");
                var vip_headwords_array = new Array(); //
                var headwords_array = new Array(); //to filter them: unique list
                var id_list = "";
                var selected_index = 0;
                for(var i=0; i<headwords.length; i++){
                    var headword_str = headwords[i].getElementsByTagName("headword_str")[0].firstChild.nodeValue;
                    var curr_headword_id = headwords[i].getElementsByTagName("title_id")[0].firstChild.nodeValue;
                    

                    //fixme: filter context: ennek a helye a szerverben lesz
                    if (contains_element(vip_headwords_array, headword_str)){
                        if (selected_index == 0){
                            if ((curr_headword_id == head_id)) 
                                selected_index = vip_headwords_array.length-1;
                        }
                        continue;
                    }
                    vip_headwords_array.push(headword_str);
                    if ((curr_headword_id == head_id)) //(headword_str == head_str) || 
                        selected_index = vip_headwords_array.length-1;

                }
                var tmp_array = new Array();
                var min = 0;//context_limit_buffer;
                var tmp = parseInt((context_limit/2));
                if ((selected_index-tmp)>0)
                    min = selected_index-tmp;
                var max = vip_headwords_array.length-1;
                if ((selected_index+tmp)<vip_headwords_array.length)
                    max = selected_index+tmp;
                for(var i=min; i<=max; i++){
                    tmp_array.push(vip_headwords_array[i]);
                }
                vip_headwords_array = tmp_array;
                
                for(var i=0; i<headwords.length; i++){
                    var entry_id = headwords[i].getElementsByTagName("entry_id")[0].firstChild.nodeValue; 
                    var headword_str = headwords[i].getElementsByTagName("headword_str")[0].firstChild.nodeValue;
                    var current_headword_id = headwords[i].getElementsByTagName("title_id")[0].firstChild.nodeValue;
                    var selected = false;

                    //
                    if (!contains_element(vip_headwords_array, headword_str))
                        continue;
                    //fixme: filter context: ennek a helye a szerverben lesz
                    if (contains_element(headwords_array, headword_str))
                        continue;

                    headwords_array.push(headword_str);
                    if (headword_str == head_str)
                        selected = true;
                    //end of filter

                    //if (start_entry_id == entry_id) //head_str can be compared too
                    if (head_id == current_headword_id) //head_str can be compared too
                        selected = true;

                    show_context(headword_str, entry_id, selected, dest_obj.content, true);
                }

                //var flag_text = show_flags_of_dictionary(l1, l2, dict_id);
                var dict_shortname = dict_man.get_dict_by_id(dict_id, "shortname");
                var context_title = dict_shortname;
                dest_obj.restore_caption("'" + head_str +"' " + get_text("context of") + " " + context_title);
            }
}

/*
function get_supported_langs(trg){
  //parse the dictionary xml for this, once
  if (trg == true){
    if (L1 == null){
        //L1 = collect_tags(dictionaries, "src_langs", "lang_id", "1");
        L1 = collect_tags(dictionaries, "langpair", "src_lang_id", "1");
        //L1.push(0);
        L1.splice(0, 0, 0); // Syntax; Array.splice(index, howMany, [element1][, ..., elementN])  
        
//L1 = new Array(0, 1038, 2057, 1036);
      }
    return L1;
  }else{
    if (L2 == null){
        L2 = collect_tags(dictionaries, "langpair", "dst_lang_id", "1");
        //L2.push(0);
        L2.splice(0, 0, 0); 
//L2 = new Array(0, 1038, 2057, 1036);
    }
    return L2;
  }
}
*/

function collect_tags(xml, tag_name, sub_tag_name, except){
    var x = xml.getElementsByTagName(tag_name);
    var tags = new Array();
    for(var i=0; i<x.length; i++){
        var node = x[i];
        var sub = node.getElementsByTagName(sub_tag_name);
        for(var j=0; j<sub.length; j++){
            val = sub[j].firstChild.nodeValue; 
            if (val != except)
                add_new_element(tags, val);
            //log_info(5, "collect tags", val);
        }
    }
    
  return tags;
}

function collect_tag_pairs(xml, tag_name, sub_tag_name1, sub_tag_name2, except){
    var x = xml.getElementsByTagName(tag_name);
    var tags = new Array();

    for(var i=0; i<x.length; i++){
        var node = x[i];
        var sub1 = node.getElementsByTagName(sub_tag_name1);
        var sub2 = node.getElementsByTagName(sub_tag_name2);
        var val1 = sub1[0].firstChild.nodeValue; 
        var val2 = sub2[0].firstChild.nodeValue; 

        add_new_element(tags, new Array(val1, val2));
        //log_info(4, "collect tags", val1 + " " + val2);
       
    }
    
  return tags;
}

//dst lang code 1 means: every scr lang codes
/*
<opendict dict_intname="eujog">
<status>open</status>
<id>0</id>
<langpairs>
	<langpair no="0">
        <src_lang_id>2057</src_lang_id>
        <dst_lang_id>1</dst_lang_id>
    </langpair>
	<langpair no="1">
        <src_lang_id>1038</src_lang_id>
        <dst_lang_id>1</dst_lang_id>
    </langpair>
	<langpair no="2">
        <src_lang_id>1036</src_lang_id>
        <dst_lang_id>1</dst_lang_id>
    </langpair>
	<langpair no="3">
        <src_lang_id>1031</src_lang_id>
        <dst_lang_id>1</dst_lang_id>
    </langpair>
</langpairs>
*/
function repair_special_lang_code(lang_pairs, dict_id, intname, l1, l2, list){
    if ((l1==0 && l2==0) || (l2==0) || lang_pairs.length == 0)
        return; // these cases are already finished 

    //for(var i=0; i<lang_pairs.length; i++){
        if (lang_pairs[0][1] == 1){
        
            if (l1 == 0){
                for(var j=0;j<lang_pairs.length;j++){
                    //if this dict has src_lang_id == l2, then it will fit (because dest_lang_code=1 means its entries are in src languages)
                    if (lang_pairs[j][0] == l2)
                        list.push(new dict_item(dict_id, lang_pairs[j][0], lang_pairs[j][1], intname));
                }
            }else { 
                var lang1_ok = false;
                var lang2_ok = false;
                for(var j=0;j<lang_pairs.length;j++){
                    if (lang_pairs[j][0] == l2){
                        lang1_ok = true;
                    }
                    if (lang_pairs[j][0] == l1){
                        lang2_ok = true;
                    }
                }
                if (lang1_ok && lang2_ok){
                    list.push(new dict_item(dict_id, l1, 1, intname));
                }
            }
        }
    //}
}

function contains_element(arr, value){
    for(var i=0; i<arr.length; i++){
        if (String(arr[i]) == String(value))
            return true;
    }
    return false;
}

function add_new_element(arr, value){
    if (!contains_element(arr, value))
        arr.push(value);
}

function get_flag(lang_code){
    for(var i=0; i< LanguageSettings.length; i++){
        if (LanguageSettings[i][0] == lang_code){
            return LanguageSettings[i][2];
        }
    }
}


/*
http://www.experts-exchange.com/Web/Web_Languages/JavaScript/Q_21808626.html
*/
/*function isArray()
{
  if (typeof arguments[0] == 'object')
  {  
    var criterion = arguments[0].constructor.toString().match(/array/i);
    return (criterion != null);  
  }
  return false;
}
*/
/*
//
function isArray(obj) {
   if (obj.constructor.toString().indexOf("Array") == -1)
      return false;
   else
      return true;
}

function isArray(object)
{
return (object instanceof Array);
} 

function isObject(a)
 {
     return (typeof a == 'object' && !!a);
 }
 
function isArray(a)
 {
  return isObject(a) && a.constructor == Array;
 }
*/
//function isArray(object) { return (object instanceof Array);}
function isArray(testObject) {	 
    return testObject && !(testObject.propertyIsEnumerable('length')) && typeof testObject === 'object' && typeof testObject.length === 'number';
}

//show the flags of the given lang codes...
//src_lang, dst_lang: lang code of dict
//dict_id: some dictionary has dst_lang == 1, which means: every src_langs... :(
function show_flags_of_dictionary(src_lang, dst_lang, dict_id){
    var flag_text = "";
    if (dst_lang == 1){
        return show_flags_of_dictionary_array( dict_man.get_dict_by_id(dict_id, "l1"), new Array());
    }
    flag_text += "<img src='"+flags_path+"/"+get_flag(src_lang)+"'> ";
    flag_text += "<img src='"+flags_path+"/"+get_flag(dst_lang)+"'> ";
    return flag_text;
}

//its input are arrays
function show_flags_of_dictionary_array(src_langs, dst_langs){
    var flag_text = "";
   
    var all_flags = src_langs;
    for(var t=0; t<dst_langs.length; t++){
        if (!contains_element(all_flags, dst_langs[t])) all_flags.push(dst_langs[t]);
    }
    if (src_langs.length == 1 && dst_langs.length == 1) all_flags.push(dst_langs[0]); //for example mltez
    //it is optimized for speed   
    //log_info(1, "show_flags_of_dictionary start", "");
    //src contains all languages, so i will use only that (for example eujog: src 1038, 2057, 1036, 1031, dst: 1, 1, 1, 1)
    for(var i=0;i<all_flags.length; i++){
        flag_text += "<img src='"+flags_path+"/"+get_flag(all_flags[i])+"' title='"+get_text(all_flags[i])+"'> ";
    }
    
/*    if (src_langs.length == 1){
        //log_info(1, "show_flags_of_dictionary start 1", "");    
        for(var i=0;i<dst_langs.length; i++){
            flag_text += "<img src='"+flags_path+"/"+get_flag(dst_langs[i])+"'> ";
        }
    }*/
    return flag_text;
}



//==========
//skin funcs
//==========

function show_languages_basic(trg, obj, name, def_language){
    var langs = dict_man.get_supported_langs(trg);
    log_info(4, "supported langs into "+name, langs);

    obj.options.length = 0;
    for(var i=0;i<langs.length; i++){
        obj.options[i] = new Option(get_text(langs[i]),langs[i]);
        if (langs[i] == def_language)
          obj.selectedIndex = i;
    }
}

function setstyle(task, id){
	var x = document.getElementById(id);
   //log_info(1, "setstyle "+task, id);
    if (task=="over"){
        if (x.className == "selected_item")
            x.className="selected_item_on";
        else
            x.className="list_item_on";
    }else if (task =="out"){
        if ((x.className == "selected_item_on") ||
            (x.className == "selected_item"))
            x.className="selected_item";
        else
            x.className="list_item";
    }
    return false;
}

function setstyle2(task, x){
	//var x = document.getElementById(id);
   //log_info(1, "setstyle2 "+task, '');
    if (task=="over"){
        if (x.className == "selected_item")
            x.className="selected_item_on";
        else
            x.className="list_item_on";
    }else if (task =="out"){
        if ((x.className == "selected_item_on") ||
            (x.className == "selected_item"))
            x.className="selected_item";
        else
            x.className="list_item";
    }
}


function highlight_entry(id){
    var x = document.getElementById(id);
    if (x){ 
        //if(typeof x.scrollIntoView!="undefined"){x.scrollIntoView(false);}
        x.className="selected_item";
    }
    var prev = document.getElementById(previous_selected_id);
    if (prev){
        prev.className="list_item";
    }
    previous_selected_id = id;
}





/*
function fill_dict_debug(dicts){
    var obj = document.mobidic.dicts;
    obj.options.length = 0;
    for(var i=0; i<dicts.length; i++){
       var name = dict_man.get_dict_by_id(dicts[i], "normalname"); 
       obj.options[i] = new Option(name,dicts[i]);
    }
    obj.style.visibility='visible';
}


*/

function fill_dict_on_sel(){
    return; //this feature is not used now, perhaps once...
    var l1 = getSelected(document.getElementById("L1"));
    var l2 = getSelected(document.getElementById("L2"));
    var dicts = dict_man.get_given_dicts(l1, l2);
    //fill_dict_debug(dicts);
}




