/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/
 
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;
	}
 
}


// ------------------------------------------------------------------------------
// common functions
// ------------------------------------------------------------------------------

 function base64_encode(a) 
 {
       var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
       var i, n = a.length, tmp = 0, s = Array();
       i = j = 0;
       while (i < n) 
       {
           tmp = (tmp << 8) | a[i];
           if (i % 3 == 2) 
           {
              s[s.length] = chars[(tmp >> 18) & 0x3f];
              s[s.length] = chars[(tmp >> 12) & 0x3f];
              s[s.length] = chars[(tmp >> 6) & 0x3f];
              s[s.length] = chars[tmp & 0x3f];
              j += 4;
              if (j % 76 == 0) s[s.length] = '\r\n';
              tmp = 0;
           }
           i++;
       }
       switch (i % 3) 
       {
          case 1 :
             s[s.length] = chars[(tmp >> 2) & 0x3f];
             s[s.length] = chars[(tmp << 4) & 0x3f];
             s[s.length] = '=';
             s[s.length] = '=';
             break;
          case 2 :
             s[s.length] = chars[(tmp >> 10) & 0x3f];
             s[s.length] = chars[(tmp >> 4) & 0x3f];
             s[s.length] = chars[(tmp << 2) & 0x3f];
             s[s.length] = '=';
             break;
       }
       return s.join('');
   }

   function utf8_encode(s) {
    var n = s.length, i, a = Array(), ch;
    for (i = 0; i < n; i++) {
        ch = s.charCodeAt(i);
        if (!(ch >> 7)) a[a.length] = ch; 
        else if (!(ch >> 11)) {            
            a[a.length] = 0xc0 | (ch >> 6);
            a[a.length] = 0x80 | (ch & 0x3f);
        } else if (!(ch >> 16)) {
            a[a.length] = 0xe0 | (ch >> 12);
            a[a.length] = 0x80 | ((ch >> 6) & 0x3f);
            a[a.length] = 0x80 | (ch & 0x3f);
        } else {
            a[a.length] = 0xf0 | (ch >> 18);
            a[a.length] = 0x80 | ((ch >> 12) & 0x3f);
            a[a.length] = 0x80 | ((ch >> 6) & 0x3f);
            a[a.length] = 0x80 | (ch & 0x3f);
        }
    }
    return a;
}

 
function URLEncode(sStr) 
{
    return escape(base64_encode(utf8_encode(sStr))).replace(/[+]/g, '%2B');
}

// ------------------------------------------------------------------------------

// address dictionary object:
function AddressDictionary()
{
    // service url:
    this.serviceUrl = "http://cs.rosinter.ru/LCI/NonSecure/dictionary2.aspx";
    // proxy page:
    this.dialogProxyUrl = "";

    // class data:
    // -------------------------------------
    // country field:
    this.countryField = null;
    // region field:
    this.regionField = null;
    // city field:
    this.cityField = null;
    // street field:
    this.streetField = null;
    // house field:
    this.houseField = null;
    // index field:
    this.indexField = null;    
    
    this._codes = new Object();
    this._names = new Object();

    // public methods:
    // -------------------------------------------------------
    // search city:
    this.searchCity = __dictionary_searchCity;
    // reenter city:
    this.reenterCity = __dictionary_reenterCity;
    // search street:
    this.searchStreet = __dictionary_searchStreet;
    // reenter street:
    this.reenterStreet = __dictionary_reenterStreet;
    // set city:
    this.setCity = __dictionary_setCity;
    // set street:
    this.setStreet = __dictionary_setStreet;
    // set city and street:
    this.setCityAndStreet = __dictionary_setCityAndStreet;
    // set index:
    this.setIndex = __dictionary_setIndex;
    // search index:
    this.searchIndex = __dictionary_searchIndex;
    // fix name:
    this.fixName = __dictionary_fixName;

    // open new window:
    this.fixDialogUrl = __dictionary_fixDialogUrl;    
    // evaluate callback:
    this.evaluateCallback = __dictionary_evaluateCallback;
}

// evaluate callback:
function __dictionary_evaluateCallback(data)
{
    var data = Url.decode(data);
    var p = data.split("|");

    // set city:
    if (p[0] == "selectCity")
	this.setCity(p[1], p[2], p[3], p[4], p[5]);
    // set stret:
    else if (p[0] == "setStreet")
	this.setStreet(p[1], p[2], p[3], p[4]);
    // reenter street:
    else if (p[0] == "reenterStreet")
	this.reenterStreet();
    // reenter city:
    else if (p[0] == "reenterCity")
	this.reenterCity();
    // set index:
    else if (p[0] == "setIndex")
        this.setIndex(p[1]);
    // set city and street:
    else if (p[0] == "setCityAndStreet")
    {
        var flag = null;
        if (p.length > 10)
            flag = p[10];
        this.setCityAndStreet(p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], flag); 
    }
}


// function to open new window:
function __dictionary_fixDialogUrl(url)
{
   if (url.indexOf("?") > -1)
       return url + "&_loc=" + this.dialogProxyUrl + "&_id=cb"; 
   else
       return url + "?_loc=" + this.dialogProxyUrl + "&_id=cb"; 
}

// method to fix name:
function __dictionary_fixName(val)
{
    var name = new String(val);
    var match = name.match(/^([^,]+)[,]\s[^,]+$/);
    if (match)
    {
        return match[1];
    }
    return name;
}

// method to reenter city:
function __dictionary_reenterCity()
{
    document.getElementById(this.cityField).focus();
}

// method to reenter street:
function __dictionary_reenterStreet()
{
    document.getElementById(this.streetField).focus();
}

// method to set index for specified street:
function __dictionary_setIndex(postIndex)
{
    this._names["__byIndex"] = false;
    // set index value:
    document.getElementById(this.indexField).value = postIndex;   
}

// method to set city and street:
function __dictionary_setCityAndStreet(streetCode, streetName, streetSocr, postIndex,
                                       cityCode, cityName, citySocr, regionName, regionSocr, flag)
{
    // set city:
    this.setCity(cityCode, cityName, citySocr, regionName, regionSocr);
    // set street:
    this.setStreet(streetCode, streetName, streetSocr, postIndex);     
    if (flag && typeof(flag) != "undefined" && flag != null)
    {
        this._names["__byIndex"] = true;
    }
    else
    {
        this._names["__byIndex"] = false;
    }   
}

// method to set street name:
function __dictionary_setStreet(streetCode, streetName, streetSocr, postIndex)
{
   this._names["__byIndex"] = false;
   // set country:
   document.getElementById(this.countryField).value = "РОССИЯ";
   // set street:
   document.getElementById(this.streetField).value = streetName.toUpperCase() + ", " + streetSocr;
   this._names["street"] = streetName.toUpperCase() + ", " + streetSocr;   
   // set city code:
   this._codes["street"] = streetCode; 
   // if specified index:
   if (postIndex && typeof(postIndex) != "undefined" && postIndex != "")
   {
       document.getElementById(this.indexField).value = postIndex;
       this._names["street_index"] = postIndex;
   }
   else
   {
       document.getElementById(this.indexField).value = "";
       this._names["street_index"] = "";
   }  
}

// method to set city name:
function __dictionary_setCity(cityCode, cityName, citySocr, regionName, regionSocr)
{
   this._names["__byIndex"] = false;
   // set country:
   document.getElementById(this.countryField).value = "РОССИЯ";
   // set region:
   if (regionName && typeof(regionName) != "undefined" && regionName != "")
   {
       document.getElementById(this.regionField).value = regionName.toUpperCase() + " " + regionSocr;
       this._names["region"] = regionName.toUpperCase() + " " + regionSocr;
   }
   else
   {
       document.getElementById(this.regionField).value = cityName.toUpperCase() + " " + citySocr;
       this._names["region"] = cityName.toUpperCase() + " " + citySocr;
   }
   // set city:   
   document.getElementById(this.cityField).value = cityName.toUpperCase() + ", " + citySocr;
   this._names["city"] = cityName.toUpperCase() + ", " + citySocr;   
   // set city code:
   this._codes["city"] = cityCode;   
   // clear all fields:
   document.getElementById(this.streetField).value = "";
   document.getElementById(this.indexField).value = "";
   this._codes["street"] = "";
   this._codes["index"] = "";
}

// method to find index:
function __dictionary_searchIndex()
{
    // check if nothing changed:
    if (document.getElementById(this.regionField).value == this._names["region"]
        && document.getElementById(this.cityField).value == this._names["city"]
        && document.getElementById(this.streetField).value == this._names["street"])
    {
        var streetCode = this._codes["street"];
        
        // if prev. by index flag:
        if (typeof(this._names["__byIndex"]) != "undefined" && this._names["__byIndex"] == true)
        {
             var indexValue = new String(document.getElementById(this.indexField).value);
             if (indexValue == null || indexValue == "")
             {
                 document.getElementById(this.indexField).value = this._names["street_index"];
                 return;                 
             }
             else
             {
                 // if specified wrong length:
                 if (indexValue.length != 6)
                 {
                     alert("Почтовый индекс должен иметь длину в 6 символов");
                     document.getElementById(this.indexField).focus();
                     return;
                 }
                 // if wrong digits:
                 var re = new RegExp(/^\d+$/);
                 if (!indexValue.match(re))
                 {
                     alert("Почтовый индекс должен состоять только из цифр");
                     document.getElementById(this.indexField).focus();
                     return;
                 }     
        
                 // get city value:
                 var cityName = this.fixName(document.getElementById(this.cityField).value);                  
                 // get street value:
                 var streetName = this.fixName(document.getElementById(this.streetField).value);
        
                 // open new window:
                 var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchByIndex&index=' + indexValue + '&city=' + URLEncode(cityName) + '&street=' + URLEncode(streetName)), 'Dictionary', 'width=500,height=400' +		   ',status=no,resizable=yes,top=200,left=200,dependent=yes,alwaysRaised=yes,scrollbars=yes'); 
                 return;
             }
        }
        
        // if got index:
        if (typeof(this._names["street_index"]) != "undefined" && this._names["street_index"] != "")
        {
            document.getElementById(this.indexField).value = this._names["street_index"];
            return;
        }
        // open new window:
        var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchIndex&streetCode=' + streetCode), 'Dictionary', 'width=500,height=400' + ',status=no,resizable=yes,top=200,left=200,dependent=yes,alwaysRaised=yes,scrollbars=yes');
    }   
    // else:
    else
    {
        var indexValue = new String(document.getElementById(this.indexField).value);
        // if not specified:
        if (indexValue == null || indexValue == "")
        {
            alert("Для осуществления поиска по индексу необходимо указать почтовый индекс");
            document.getElementById(this.indexField).focus();
            return;
        }
        // if specified wrong length:
        if (indexValue.length != 6)
        {
            alert("Почтовый индекс должен иметь длину в 6 символов");
            document.getElementById(this.indexField).focus();
            return;
        }
        // if wrong digits:
        var re = new RegExp(/^\d+$/);
        if (!indexValue.match(re))
        {
            alert("Почтовый индекс должен состоять только из цифр");
            document.getElementById(this.indexField).focus();
            return;
        }     
        
        // get city value:
        var cityName = this.fixName(document.getElementById(this.cityField).value);                  
        // get street value:
        var streetName = this.fixName(document.getElementById(this.streetField).value);
        
        // open new window:
        var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchByIndex&index=' + indexValue + '&city=' + URLEncode(cityName) + '&street=' + URLEncode(streetName)), 'Dictionary', 'width=500,height=400' +		   ',status=no,resizable=yes,top=200,left=200,dependent=yes,alwaysRaised=yes,scrollbars=yes'	    );    
    } 
}

// method to search city:
function __dictionary_searchCity()
{
    // check if given city name:
    if (document.getElementById(this.cityField).value == "")  
    {
        alert("Для поиска необходимо указать начальные буквы наименования города (населенного пункта)");
        document.getElementById(this.cityField).focus();
        return;
    }
    
    // city to search:
    var citySearch = this.fixName(document.getElementById(this.cityField).value);    
    
    // open new window:
    var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchCity&city=' + URLEncode(citySearch)), 'Dictionary', 'top=200,left=200,width=500,height=400,status=no,resizable=yes,dependent=yes,scrollbars=yes');	
}

// method to search street:
function __dictionary_searchStreet()
{
    // check if given city name:
    if (document.getElementById(this.streetField).value == "")  
    {
        alert("Для поиска необходимо указать начальные буквы наименования улицы");
        document.getElementById(this.streetField).focus();
        return;
    }
    
    // check if city not specified:
    if (document.getElementById(this.cityField).value == "")
    {
        alert("Для поиска улицы необходимо указать название города (населенного пункта)");
        document.getElementById(this.cityField).focus();
        return;
    }
    
    // if already got city:
    // check if nothing changed:
    if (document.getElementById(this.regionField).value == this._names["region"]
        && document.getElementById(this.cityField).value == this._names["city"])
    {
        var searchStreet = this.fixName(document.getElementById(this.streetField).value);
        // open new window:
        var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchStreet&cityCode=' + this._codes["city"] + '&street=' + URLEncode(searchStreet)), 'Dictionary', 'width=500,height=400'+		    ',status=no,resizable=yes,top=200,left=200,dependent=yes,alwaysRaised=yes,scrollbars=yes'	    );	    
    }
    // else:
    else
    {
        var searchCity = this.fixName(document.getElementById(this.cityField).value);
        var searchStreet = this.fixName(document.getElementById(this.streetField).value);
        // open new window:
        var obj_calwindow = window.open(this.fixDialogUrl(this.serviceUrl + '?mode=searchCityAndStreet&city=' + URLEncode(searchCity) + '&street=' + URLEncode(searchStreet)), 'Dictionary', 'width=500,height=400'+		    ',status=no,resizable=yes,top=200,left=200,dependent=yes,alwaysRaised=yes,scrollbars=yes'	    );	    
    }    
}
