function ClassFastNavigation()
{
    this.opKey      = '';
    this.cityKey    = '';
    this.startUrl   = '/orsn';
    this.external   = new Array();
    this.loadedData = false;
    this.regionsLoaded = false;
    this.isSafari = false;
    this.elems = ['fnOp', 'fnCity', 'fnRegions', 'fnType'];

    this.operationsData =   ['buy:Купить', 'rent:Арендовать'];

    this.citiesData = [
        '|buy|:foreign:Зарубежную недв.',
        '|buy|rent|:moscow:В Москве',
        '|buy|rent|:submoscow:В Подмосковье',
        '|buy|rent|:spb_emls:В Санкт-Петербурге',
        '|buy|rent|:subspb_emls:В Ленинградской обл.',
        '|buy|rent|:bashkiriya:В Башкирии',
        '|buy|:volgograd:В Волгограде',
        '|buy|:voronezh:В Воронеже',
        '|buy|rent|:nizhgorod:В Нижнем Новгороде',
        '|buy|rent|:subnizhgorod:В Нижегородской области',
        '|buy|rent|:novosibirsk:В Новосибирске',
        '|buy|rent|:omsk:В Омске',
        '|buy|rent|:rostovnadonu:В Ростове-на-Дону',
        '|buy|rent|:subrostovnadonu:В Ростовской области',
        '|buy|rent|:samara:В Самаре',
        '|buy|rent|:toljatti:В Тольятти',
        '|buy|:tumen:В Тюмени',
        '|buy|:tumen!:В Тюменской обл.',
        '|buy|rent|:kraykrasnodarskii:В Краснодарском крае',
        '|buy|rent|:habarovsk:В Хабаровске',
        '|buy|rent|:minsk:В Минске или области',
        '|buy|rent|:belorusregions:В регионах Белоруссии',
        '|buy|rent|:regions:В Другом регионе:/orsn/regions/getRegionsIntoFlash?enc=1'
    ];

    this.typesData = [
        '|buy|:|foreign|moscow|submoscow|spb_emls|subspb_emls|novosibirsk|samara|tumen|toljatti|omsk|volgograd|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|habarovsk|bashkiriya|voronezh|:flats:Квартиру',
        '|buy|:|tumen!|:subsell:Квартиру',
        '|buy|:|moscow|submoscow|novosibirsk|spb_emls|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|bashkiriya|:newb:Новостройку',
        '|buy|:|moscow|spb_emls|:elite-flats:Элитную квартиру',
        '|buy|:|moscow|:elite-newb:Элитную новостройку',
        '|buy|:|:elite:Элитную недвижимость',
        '|buy|:|moscow|:living:Жилой комплекс',
        '|buy|:|moscow|:penthouse:Пентхаус',
        '|buy|:|moscow|:suburbs:Особняк, таунхаус',
        '|buy|:|foreign|moscow|submoscow|spb_emls|samara|toljatti|omsk|nizhgorod|subnizhgorod|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|habarovsk|novosibirsk|bashkiriya|:commercial-sell:Коммерческую недв.',
        '|buy|:|submoscow|subspb_emls|samara|toljatti|omsk|nizhgorod|subnizhgorod|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|habarovsk|novosibirsk|bashkiriya|voronezh|:house:Дом, коттедж',
        '|buy|:|foreign|:cottage-sell:Дом, коттедж',
        '|buy|:|foreign|submoscow|subspb_emls|nizhgorod|subnizhgorod|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|novosibirsk|bashkiriya|:abutter:Земельный участок',
        '|buy|:|submoscow|subspb_emls|:cottage-st:Коттеджный посёлок',
        '|rent|:|spb_emls|subspb_emls|moscow|samara|toljatti|novosibirsk|omsk|nizhgorod|nizhgorod|rostovnadonu|habarovsk|bashkiriya|:loan:Квартиру',
        '|rent|:|moscow|spb_emls|:elite-loan:Элитную квартиру',
        '|rent|:|moscow|submoscow|spb_emls|omsk|nizhgorod|subnizhgorod|nizhgorod|subnizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|habarovsk|novosibirsk|bashkiriya|:commercial-loan:Коммерческую недв.',
        '|rent|:|submoscow|nizhgorod|subnizhgorod|nizhgorod|rostovnadonu|subrostovnadonu|kraykrasnodarskii|:cottage-loan:Коттедж',
        '|rent|:|submoscow|:elite-cottage-loan:Элитный коттедж'
    ];
    this.regionalTypes = [
        '|buy|:flats:Квартиры и комнаты',
        '|buy|:houses:Дома, участки, дачи',
        '|rent|:loan:Сдам/сниму',
        '|buy|rent|:commercial:Коммерческая'
    ];
}

ClassFastNavigation.prototype = {
    init : function()
    {
        var ops = this.operationsData;
        var opsAr = new Array();
        // document.getElementsByTagName doesn't work with Safari.
        if (navigator.appVersion.indexOf("Safari") != -1) {
            this.isSafari = true;
        }

        this.rewindAndClear(-1);
        var selOps = this.getObject('fnOp');
        selOps.disabled = false;
        for (var i = 0; i < ops.length; i++) {
            opsAr = ops[i].split(':');
            selOps.options[selOps.options.length] = new Option(opsAr[1], opsAr[0]);
        }
    },

    getCities : function(obj)
    {
        this.opKey = obj.options[obj.selectedIndex].value;
        var selCity = this.getObject('fnCity');
        var cities = this.citiesData;
        var tdata = new Array();
        this.rewindAndClear();
        for (var i = 0; i < cities.length; i++) {
            tdata = cities[i].split(':');
            var s = '|'+ this.opKey +'|';
            if (tdata[0].indexOf(s) > -1) {
                selCity.options[selCity.options.length] = new Option(tdata[2],tdata[1]);
                if (tdata[3] != undefined)
                    this.external[tdata[1]] = tdata[3];
            }
        }
        if (selCity.options.length > 1)
            selCity.disabled = false;
    },

    thinkOfLoading : function(obj)
    {
        this.cityKey = obj.options[obj.selectedIndex].value;
        if (this.external[this.cityKey] != undefined) {
            this.clearObject('fnType');
            if (!this.regionsLoaded) {
                var xml = new AjaxRequestClass();
                this.loadedData = xml.fetchUrl(this.external[this.cityKey], this);
            } else {
                this.regionalDisplay(true);
            }
        } else {
            this.regionalDisplay(false);
            this.getTypes();
        }
    },

    dataFromXML : function(xmlObj)
    {
        if (this.isSafari) {
            var rows = xmlObj.firstChild.firstChild.firstChild.childNodes;
        }
        else{
            var rows = xmlObj.documentElement.getElementsByTagName('row');
        }

        if (rows.length < 1) return;
        var selRegs = this.getObject('fnRegions');
        this.clearObject('fnRegions');
        selRegs.options[0] = new Option('-- выбор из списка --', '');

        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            if (!row.childNodes) continue;
            if (parseInt(row.childNodes[3].firstChild.nodeValue) == -1) continue;
            var name = row.childNodes[1].firstChild.nodeValue;
            var val = row.childNodes[2].firstChild.nodeValue;
            selRegs.options[selRegs.options.length] = new Option(name, val);
        }
        this.regionsLoaded = true;
        this.regionalDisplay(true);
    },
    regionalDisplay : function(arg)
    {
        var selRegs = this.getObject('fnRegions');
        var dd = this.getObject('regions');
        if (dd)
            dd.style.display = (arg) ? '' : 'none';
        else
            selRegs.style.display = (arg) ? '' : 'none';
        selRegs.disabled = !arg;
        selRegs.selectedIndex = 0;
    },

    getRegionalTypes : function()
    {
        var regions = this.getObject('fnRegions');
        if (regions.selectedIndex == 0) {
            this.clearObject('fnType');
            return;
        }
        var types = this.regionalTypes;
        var tdata = new Array();
        var selTypes = this.getObject('fnType');
        for (var i = 0; i < types.length; i++) {
            tdata = types[i].split(':');
            var s = '|'+ this.opKey +'|';
            if (tdata[0].indexOf(s) < 0) continue;
            selTypes.options[selTypes.options.length] = new Option(tdata[2], tdata[1]);
        }
        if (selTypes.options.length > 1)
            selTypes.disabled = false;
    },

    getTypes : function()
    {
        var types = this.typesData;
        var tdata = new Array();
        this.clearObject('fnType');
        var selTypes = this.getObject('fnType');
        for (var i = 0; i < types.length; i++) {
            tdata = types[i].split(':');
            var s = '|'+ this.opKey +'|';
            var p = '|'+ this.cityKey +'|';
            if (tdata[0].indexOf(s) < 0) continue;
            if (tdata[1].indexOf(p) < 0) continue;
            selTypes.options[selTypes.options.length] = new Option(tdata[3], tdata[2]);
        }
        if (selTypes.options.length > 1)
            selTypes.disabled = false;
    },

    getObject : function(id)
    {
        var obj = document.getElementById(id);
        return obj;
    },

    clearObject : function(id)
    {
        var obj = this.getObject(id);
        obj.disabled = true;
        for (var i = obj.options.length-1; i > 0; i--) {
            obj.options[i] = null;
        }
    },

    rewindAndClear : function(depth)
    {
        if (!depth) depth = 0;
        var c = 0;
        for (var i = 0; i < this.elems.length; ++i) {
            var sel = this.getObject(this.elems[i]);
            var id = sel.id;
            if (id.indexOf('fn') == 0) {
                if (c > depth) {
                    if (id.indexOf('Regions') == 2) this.regionalDisplay(false);
                    else this.clearObject(id);
                }
                c++;
            }
        }
    },

    composeUrl : function()
    {
        var url = new Array();
        var c = 0;
        for (var i = 0, max = this.elems.length; i < max; ++i) {
        	var sel = this.getObject(this.elems[i]);
            var id = sel.id;
            if (c >= 1 && id != 'fnOp' && id != undefined && id.indexOf('fn') == 0 && sel.disabled == false) {
                var val = sel.options[sel.selectedIndex].value;
                if (val != '') url[url.length] = val;
            }
            c++;
        }
        return url.join('/');
    },

    initSubmit : function()
    {
        var url = this.composeUrl();
        if (url == '') {
            alert('Недостаточно информации.')
            return;
        }
        url = url.replace(/!/g,'');
        document.location = this.startUrl + '/' + url;
        return false;
    }
}
