/*










*/

function LocalNumbers(hash)
{
    Subscriber.call(this);
	
	
    this._TollFreeMgrNode = hash.mgrNode? hash.mgrNode : $_('TollFreeMgrNode');
	
    this._NumbersList = null;
    this.__construct(hash || {});
    this._cityInfo    = null;
	
    this._setContinue();
    this._setCancel();
    this._setReset();
}
LocalNumbers.prototype = 
{
	
    __construct : function(hash)
    {
        this._CONFIG = hash.config;
		
        this._parent = hash.parent? hash.parent : document.body;
		
		
        this._numberListTemplate = hash.numberListTemplate? hash.numberListTemplate : '';
        if($_('NumberListTemplate') && $_('NumberListTemplate').innerHTML && this._numberListTemplate == '')
        {
            this._numberListTemplate = $_('NumberListTemplate').innerHTML;
        }
		
        if(hash.sortByDefault)
        {
            this._sortByDefault = hash.sortByDefault;
        }
		
        if(!hash.numbersSelect)
        {
		
            this._NumbersList = new NumberList({
					
                numbersSwitchCmd   : 'active-number',
                numberListTemplate : this._numberListTemplate,
                numberItemClassName : 'number',
                defaultItemId      : 0,
                nNumbers_place     : getElementsByClassName('numbers', this._parent)[0],
                proxy_url          : this._CONFIG.api_url,
                type               : hash.type
            });
        }
        else
        {
            this._NumbersList = new Select_Numbers({
                node      : hash.numbersSelect,
                proxy_url : this._CONFIG.api_url
            });
        }
		
					
        this._NumbersList.setObserver('onFailure', function(response)
        {
            if (typeof response != 'undefined' &&
            typeof response.status != 'undefined' &&
            typeof response.status.code != 'undefined' &&
            response.status.code == 6150) {
                window.location = this._CONFIG.error_page;
            } else {
                this._City.disabled(false);
                this._disableSort(false);
                setCssClassName(this._TollFreeMgrNode, 'show', 'error');
                this._fireEvent('onReset');
            }
        }.rcBindAsIs(this));
		
		
		
		
        this._NumbersList.setObserver('onComplete', function()
        {
            this._City.disabled(false);
            setCssClassName(this._TollFreeMgrNode, 'show', 'numbers' );
            setCssClassName(this._TollFreeMgrNode, 'continue_state', 'enable' );
            this._disableReset(false);
            this._disableSort(false);
            this._onAfterChangeNumber();
        }.rcBindAsIs(this));
		
		
        this._NumbersList.setObserver('onChangeNumber', function()
        {
            this._onAfterChangeNumber();
        }.rcBindAsIs(this));
		
		
		
		
		
		
        this._nAreaSort  = getElementsByClassName(hash.area_sort_class, document.body)[0];
        this._nCitySort  = getElementsByClassName(hash.city_sort_class, document.body)[0];
		
		
		
        var nCity  = getElementsByClassName('CitiesSelect', document.body)[0];
        if(nCity)
        {
			
            this._City = new Select_Cities({
                node      : nCity,
                proxy_url : this._CONFIG.api_url,
                firstSort : this.getFirstSort()
            });
			
            this._City.on('onAfterLoading', function()
            {
                setCssClassName(this._TollFreeMgrNode, 'show', 'empty' );
            }.rcBindAsIs(this));
			
			
            this._City.on('onChangeCity', function(cityInfo)
            {
                /*
					cityInfo = Array
					(
					    [value] => 161 - Manchester
					    [city] => Manchester
					    [npa] => 161
					    [state_id] => 536
					)
				*/
                this._cityInfo = cityInfo;
				
                this.loadNumbers(cityInfo.npa, cityInfo.state_id);
                this._disableSort(true);
                this._fireEvent('onReset');
            }.rcBindAsIs(this));
			
			
            this._City.on('onAfterLoading', function(){
                this._disableSort(false);
            }.rcBindAsIs(this));
			
            this._City.on('onDefault', function(){
                this._onReset();
            }.rcBindAsIs(this));
			
			
            this._City.on('onFailureLoading', function(){
                this._onReset();
            }.rcBindAsIs(this));
			
			
			
			
			
			
            if(this._nAreaSort)
            {
                addEvent(this._nAreaSort, 'onclick', this.sortByAreaCode.rcBindAsIs(this));
            }
			
            if(this._nCitySort)
            {
                addEvent(this._nCitySort, 'onclick', this.sortByCity.rcBindAsIs(this));
            }
        }
		
    },
	
	
    getFirstSort : function()
    {
        if(this._nAreaSort && this._nAreaSort.checked)
        {
            return 'area';
        }
        if(this._nCitySort && this._nCitySort.checked)
        {
            return 'city';
        }
        if(this._sortByDefault && (this._sortByDefault == 'area' || this._sortByDefault == 'city') )
        {
            return this._sortByDefault;
        }
        return null;
    },
	
	
    sortByAreaCode : function()
    {
        if(this._City)
        {
            this._City.sortByAreaCode();
        }
    },
	
	
    sortByCity : function()
    {
        if(this._City)
        {
            this._City.sortByCity();
        }
    },
	
	
    loadLocations : function()
    {
        if(this._City)
        {
            this._City.setCities(564, 224);
        }
    },
		
	
    loadNumbers : function(areaCode, stateId)
    {
        this._City.disabled(true);
        setCssClassName(this._TollFreeMgrNode, 'continue_state', 'disable');
        this._disableReset(true);
        setCssClassName(this._TollFreeMgrNode , 'show', 'load' );
		
        this._NumbersList.loadNumbers({
            cmd   : 'getLocalNumbers',
            param :
            {
                localNumbersRequest :
                {
                    areaCode   : areaCode,
                    qty        : 10,
                    stateId    : stateId,
                    countryId  : 224
                }
            },
            type  : 'local'
        });
    },
	
    _setCancel : function()
    {
        this._cancelBut = getElementsByClassName('cancel', this._parent)[0];
        if(this._cancelBut)
        {
            addEvent(this._cancelBut, 'onclick', function(){
                history.back()
                });
        }
		
    },
	
	
    _setReset : function()
    {
        this._resetBut = getElementsByClassName('reset', this._parent)[0];
        if(this._resetBut)
        {
            addEvent(this._resetBut, 'onclick', this._onReset.rcBindAsIs(this));
        }
		
    },
	
	
    _setContinue : function()
    {
        this._continueBut = getElementsByClassName('continue', this._parent)[0];
        if(this._continueBut)
        {
            addEvent(this._continueBut, 'onclick', this._onAfterClickContinue.rcBindAsIs(this));
        }
    },
	
	
    _onReset : function()
    {
        if(getCssClassNameValue(this._TollFreeMgrNode, 'reset_state') == 'enable')
        {
            this._disableReset(true);
            setCssClassName(this._TollFreeMgrNode, 'show', 'empty' );
            this._City.setStart();
            this._fireEvent('onReset');
        }
    },
	
	
    _onAfterClickContinue : function()
    {
        if(getCssClassNameValue(this._TollFreeMgrNode, 'continue_state') == 'enable')
        {
            var numberInfo = this._NumbersList.get();
            /*
				Array
				(
				    [typeNumber] => 800
				    [number] => 448007566793
				    [formattedNumber] => 0800 756 6793
				)
			*/				
            this._fireEvent('ready', numberInfo, this._cityInfo);
        }
    },
	
	
    _disableSort : function(flg)
    {
        if(this._nAreaSort)
        {
            this._nAreaSort.disabled  = !!flg;
        }
        if(this._nCitySort)
        {
            this._nCitySort.disabled  = !!flg;
        }
    },
	
	
	
    _disableReset : function(flg)
    {
        setCssClassName(this._TollFreeMgrNode, 'reset_state', flg? 'disable' : 'enable' );
    },
	
	
    _onAfterChangeNumber : function()
    {
        var numberInfo = this._NumbersList.get();
        this._fireEvent('onChangeNumber', numberInfo, this._cityInfo);
    }
	
}



addEvent(window, 'ondomready', function()
{
	
	
    });

document.write('<SCRIPT language="JavaScript" src="/js/inc/mbox_rc.js"></'+'SCRIPT>');

/*





*/




var NS_CONFIG = new function()
{
    var _api_url = '/api/index.php';
    var _error_page = '/ordernow/ErrorNumberMessage.html';
    //var service  = 'https://qaproweb.dins.ru';
    //var service  = 'https://service.ringcentral.com';
    /*
	var actions =
	{
		trial : '/',
		buy   : '/ordernow/'
	}
	*/
    var service = location.protocol+'//'+location.host;
    var actions =
    {
        trial    : '/s-gate.html',
        trial_90 : '/s-gate.html',
        trial30 : '/s-gate.html',
        buy      : '/s-gate.html'
    }

    this.pages =
    {
        choose_800 :
        {
            init     : true,
            api_url  : _api_url,
            error_page : _error_page,
            next_page :
            {
                host : '',
                path : '/ordernow/0800-pick-plan.html',
                vars : {}
            }

        },
        choose_0845 :
        {
            init     : true,
            api_url  : _api_url,
            error_page : _error_page,
            next_page :
            {
                host : '',
                path : '/ordernow/0845-pick-plan.html',
                vars : {}
            }

        },
        choose_local :
        {
            init     : true,
            api_url  : _api_url,
            error_page : _error_page,
            next_page :
            {
                host : '',
                path : '/ordernow/local-pick-plan.html',
                vars : {}
            }

        },
        lp_local :
        {
            init     : true,
            api_url  : _api_url,
            error_page : _error_page,
            next_page :
            {
                host : '',
                path : '/ordernow/local-pick-plan.html',
                vars : {}
            }

        },
        number_800 :
        {
            init          : true,
            api_url       : _api_url,
            error_page : _error_page,
            redirect      : '/ordernow/choose-your-0800-number.html',
            need_redirect : !(getSearchVar('s')&&getSearchVar('upgradetier')&&getSearchVar('action')),

            trial_90  :
            {
                host : service,
                path : actions['trial_90'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial  :
            {
                host : service,
                path : actions['trial'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial30  :
            {
                host : service,
                path : actions['trial30'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            buy :
            {
                host : service,
                path : actions['buy'],
                vars :
                {
                    ns          : 1,
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            }
        },
        number_0845 :
        {
            init          : true,
            api_url       : _api_url,
            error_page    : _error_page,
            redirect      : '/ordernow/choose-your-0845-number.html',
            need_redirect : !(getSearchVar('s')&&getSearchVar('upgradetier')&&getSearchVar('action')),

            trial_90  :
            {
                host : service,
                path : actions['trial_90'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial30  :
            {
                host : service,
                path : actions['trial30'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial  :
            {
                host : service,
                path : actions['trial'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            buy :
            {
                host : service,
                path : actions['buy'],
                vars :
                {
                    ns          : 1,
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            }
        },
        number_local :
        {
            init          : true,
            api_url       : _api_url,
            error_page    : _error_page,
            redirect      : '/ordernow/choose-your-local-number.html',
            need_redirect : !(getSearchVar('s')&&getSearchVar('upgradetier')&&getSearchVar('action')),

            trial_90  :
            {
                host : service,
                path : actions['trial_90'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial30  :
            {
                host : service,
                path : actions['trial30'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial  :
            {
                host : service,
                path : actions['trial'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            buy :
            {
                host : service,
                path : actions['buy'],
                vars :
                {
                    ns          : 1,
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            }
        },
        number_fax :
        {
            init          : true,
            api_url       : _api_url,
            error_page    : _error_page,
            redirect      : '/fax/plansandpricing.html',
            need_redirect : !(getSearchVar('s')&&getSearchVar('upgradetier')&&getSearchVar('action')),

            trial_90  :
            {
                host : service,
                path : actions['trial_90'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial30  :
            {
                host : service,
                path : actions['trial30'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            trial  :
            {
                host : service,
                path : actions['trial'],
                vars :
                {
                    ns          : 1,
                    c           : 'signup',
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            },
            buy :
            {
                host : service,
                path : actions['buy'],
                vars :
                {
                    ns          : 1,
                    sp          : 'b',
                    s           : getSearchVar('s'),
                    upgradetier : getSearchVar('upgradetier'),
                    pc          : getSearchVar('pc'),
                    action		: getSearchVar('action')
                }
            }
        }
    }

    this.getConfig = function(page_name, event)
    {
        var curPlan = this.pages[page_name];

        var action  = getSearchVar('action')? getSearchVar('action'): 'next_page';
        switch(event)
        {
            case 'ready':
                if(action)
                {
                    return this.pages[page_name][action];
                }
                break;
        }
        return false;
    }

    this.getFullConfig = function(page_name)
    {
        return this.pages[page_name];
    }

    function getServicePath(action)
    {
        return !!actions[action]? actions[action] : actions['trial'];
    }


    this.isset = function(page_name)
    {
        return !!this.pages[page_name];
    }



    this.hasInit = function(page_name)
    {
        return !!this.pages[page_name].init;
    }

    function getSearchVar( varName , str){
        var regexS = "[?&]"+varName+"=([^&#]*)";
        var regex = new RegExp( regexS ,'i');
        var tmpURL = str? str : window.location.href;
        var results = regex.exec( tmpURL );
        if( results == null )
        {
            return null;
        }
        else
        {
            return results[1].replace(/%20/g,' ');
        }
    }

}


if(typeof page_name == 'string' && NS_CONFIG.isset(page_name) && NS_CONFIG.hasInit(page_name))
{
    if(NS_CONFIG.pages[page_name].redirect && typeof NS_CONFIG.pages[page_name].need_redirect != 'undefined' && NS_CONFIG.pages[page_name].need_redirect)
    {
        window.location = NS_CONFIG.pages[page_name].redirect;
    }
    else
    {
        window.addEvent(window, 'ondomready', function()
        {

            var callBack = function(CONFIG, numberInfo, cityInfo)
            {

                /*
						printArray(numberInfo);
						Array
						(
						    [typeNumber] => 800
						    [number] => 448007566793
						    [formattedNumber] => 0800 756 6793
						)
					*/
                /*
						printArray(CONFIG);
						Array
						(
						    [path] => https://service.ringcentral.com/ordernow/
						    [vars] => Array
						        (
						            [ns] => 1
						            [c] => signup
						            [sp] => b
						            [s] => 3710
						            [upgradetier] => 3726
						        )

						)
					*/
                /*
						Array
						(
						    [value] => 161 - Manchester
						    [city] => Manchester
						    [npa] => 161
						    [state_id] => 536
						)
					*/
                switch(numberInfo.typeNumber)
                {
                    case '800':case '845':case '0845':
                        CONFIG.vars.number           = numberInfo.number;
                        CONFIG.vars.formatted_number = numberInfo.formattedNumber;
                        break;

                    case 'local':
                        CONFIG.vars.number           = numberInfo.number;
                        CONFIG.vars.formatted_number = numberInfo.formattedNumber;
                        CONFIG.vars.state_id         = cityInfo.state_id;
                        CONFIG.vars.area             = cityInfo.npa;
                        CONFIG.vars.city             = cityInfo.city;
                        break;
                }

                if(typeof getMboxSessionId == 'function')
                {
                    CONFIG.vars.mboxSession = getMboxSessionId();
                }


                var new_page = LocationManager.buildUrl(CONFIG);
                window.location = new_page;

            }.rcBindAsIs(this, NS_CONFIG.getConfig(page_name, 'ready'));






            switch(page_name)
            {
                case 'number_800':
                    var newTollFreeNumbers = new TollFreeNumbers({
                        config : NS_CONFIG.getFullConfig(page_name)
                    });
                    newTollFreeNumbers.loadNumbers('800');
                    newTollFreeNumbers.on('ready', callBack);
                    break;

                case 'number_0845':
                    var newTollFreeNumbers = new TollFreeNumbers({
                        config : NS_CONFIG.getFullConfig(page_name)
                    });
                    newTollFreeNumbers.loadNumbers('845');
                    newTollFreeNumbers.on('ready', callBack);
                    break;

                case 'number_local': case 'choose_local':
                    var newLocalNumbers = new LocalNumbers({
                        config               : NS_CONFIG.getFullConfig(page_name),
                        area_sort_class      : 'areaSort',
                        city_sort_class      : 'citySort'
                    });
                    newLocalNumbers.loadLocations();
                    newLocalNumbers.on('ready', callBack);
                    break;
                case 'lp_local':
                    var newLp = new Lp_Ns({
                        localConfig :
                        {
                            config               : NS_CONFIG.getFullConfig(page_name),
                            mgrNode              : $_('LpMenuLocNum'),
                            sortByDefault        : 'area',
                            numbersSelect        : $_('numbersSelect'),
                            callBack             : callBack
                        },
                        localInfoBlockConfig :
                        {
                            parent : getElementsByClassName('LocalInfoBlockMgrNode')[0]
                        }
                    });
                    break;

                case 'number_fax':
                    var newNumberSelectPage = new NumberSelectPage({
                        config : NS_CONFIG.getFullConfig(page_name),
                        localConfig  :
                        {
                            area_sort_class      : 'areaSort',
                            city_sort_class      : 'citySort'
                        }
                    });
                    newNumberSelectPage.on('ready', callBack);
                    break;

                case 'choose_800':
                    var newTollFreeNumbers = new TollFreeNumbers({
                        config : NS_CONFIG.getFullConfig(page_name)
                    });
                    newTollFreeNumbers.loadNumbers('800');
                    newTollFreeNumbers.on('ready', callBack);
                    break;

                case 'choose_0845':
                    var newTollFreeNumbers = new TollFreeNumbers({
                        config : NS_CONFIG.getFullConfig(page_name)
                    });
                    newTollFreeNumbers.loadNumbers('845');
                    newTollFreeNumbers.on('ready', callBack);
                    break;






            }






        });
    }

}


var LocationManager = {
	is_var : function( varName ){
		var regexS = "[?&]"+varName+"=([^&#]*)";
		var regex = new RegExp( regexS ,'i');
		var tmpURL = window.location.href;
		var results = regex.exec( tmpURL );
		if( results == null ){
			return null;
		}else{
			return results[1].replace(/%20/g,' ');
		}
	},
	get_hash: function( varName , str){
		var regexS = "[#&]"+varName+"=([^&]*)";
		var regex = new RegExp( regexS ,'i');
		var tmpURL = str? str : window.location.hash;
		var results = regex.exec( tmpURL );
		if( results == null ){
			return null;
		}else{
			return results[1].replace(/%20/g,' ');
		}
	}, 
	get_var : function( varName , str){
		var regexS = "[?&]"+varName+"=([^&#]*)";
		var regex = new RegExp( regexS ,'i');
		var tmpURL = str? str : window.location.href;
		var results = regex.exec( tmpURL );
		if( results == null ){
			return null;
		}else{
			return results[1].replace(/%20/g,' ');
		}
	},
	get_refer : function()
	{
		return document.referrer;
	},
	get_hostname : function(str)
	{
		if(typeof str == 'undefined')
		{	
			return window.location.hostName;
		}
		else
		{	
			// exemple
			//http://www.google.com.ua/?asa=df&PID=GG_080919RC&aaa
			var res = null;
			
			if(res = str.match(/^http(s|):\/\/(www\.|)(.+?)\//))
			{
				return res[3];
			}
			
			return null; 
		}	
	},
	get_pathname : function(str)
	{
		// exemple
		//str = 'http://devorigin.ringcentral.com/features/local-numbers/overview.html';
		var res = null;
		if(typeof str == 'undefined')
		{
			return window.location.pathname
		}
		else
		{
		if(res = str.match(/^http(s|):\/\/(www\.|)(.+?)(\/.*)/))
			{
				return res[4];
			}
		}
	},
	is_hash : function(varName){
		var hash  = window.location.hash.replace(/^#/,'');
		var aHash = hash.split('&');
		return in_array(varName,aHash);
	},
	buildUrl : function(hash){
		var fullUrl = '';
		// 	hash
		// 	Array {
		//		host
		//		path
		//		vars : Array{
		//			varName1 : varNameValue1,
		//			varName2 : varNameValue2,
		//		}
		//	}
		if(hash){
		//if(hash && hash.host){
			fullUrl += hash.host;
			if(hash.path ){
				fullUrl += hash.path;
			}
			if(hash.vars){
				var vars = Array();
				for(var key in hash.vars){
					if(hash.vars[key] != hash.path && hash.vars[key] != null)
					{
						vars.push(key + '=' + hash.vars[key]);
					}
				}
				if(!empty(vars)){
					fullUrl += '?' + vars.join('&');
				}
			}
		}else{
			return false;
		}
		return fullUrl;
	},
	getLocationState : function()
	{
		var pathname = window.location.pathname;
		if(res = pathname.match(/([a-z]{2})(|\-n|\-s)\.html$/))
		{
			return res[1].toUpperCase();
		}
		return null;
	},
	getLocationCode : function()
	{
		var pathname = window.location.pathname;
		if(res = pathname.match(/area\-code\-(\d+)\.html$/))
		{
			return res[1];
		}
		return null;
	}
}




function $_(id){
	return document.getElementById(id);
}
if(!$_('showControl'))
{
	document.write('<span id="showControl" ondblclick ="this.innerHTML = \'\'" style="background-color:white;position:absolute;left:0px;top:0px;z-Index:10000"></span>')
}


if(!/msie 6/i.test(navigator.userAgent))
{
	if(!$_('showStopper'))
	{
		document.write('<iframe id="showStopper" style="display: none"></iframe>');
	}
}


function showStopper(time)
{
	var param = time? 'param[sleep]=' + time : '';
	if($_('showStopper'))
	{
		$_('showStopper').src = '/api/index.php?cmd=showStopper&api=collector&' + param;
	}
}


function hash_to_string(hash)
{
	arr = [];
	for(key in hash){
		try{
			arr.push(key+':'+ hash[key]);
		}catch(e){}
	}
	return arr.join(',');
}

function show(obj,cmd){
	str = '';
	for(key in obj){
		try{
			str += '&nbsp;&nbsp;&nbsp;&nbsp;<b>'+key+'</b>='+(obj[key]&&obj[key][cmd] ? obj[key][cmd]:obj[key])+'<br>';
		}catch(e){}
	}
	switch(cmd){
		case 'inTail':
			$_('showControl').innerHTML += str!=''? str:'<b>EMPTY</b>';
			break;
		default:
			$_('showControl').innerHTML = str!=''? str:'<b>EMPTY</b>';
			break;
	}
}
function printArray(arr){
	$_('showControl').innerHTML = '<pre>' + print_r(arr, true);
}
function print_r( array, return_val ) {
	var output = "", pad_char = " ", pad_val = 4;
	var formatArray = function (obj, cur_depth, pad_val, pad_char) {
		if (cur_depth > 0) {
			cur_depth++;
		}
		var base_pad = repeat_char(pad_val*cur_depth, pad_char);
		var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
		var str = "";
		if (obj instanceof Array || obj instanceof Object) {
			str += "Array\n" + base_pad + "(\n";
			for (var key in obj) {
				//if (obj[key] instanceof Array) {
					str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char) + '<br>';
				//} else {
				//	str += thick_pad + "["+key+"] => " + obj[key] + "\n";
				//}
			}
			str += base_pad + ")\n";
		} else {
			if(obj && obj.toString){
				str = obj.toString();
			}
		}
		return str;
	};
	var repeat_char = function (len, pad_char) {
		var str = "";
		for(var i=0; i < len; i++) {
			str += pad_char;
		};
		return str;
	};
	output = formatArray(array, 0, pad_val, pad_char);
	if (return_val !== true) {
		document.write("<pre>" + output + "</pre>");
		return true;
	} else {
		return output;
	}
}
Function.prototype.bind = function(obj) {
    var method = this;
    var arg = Array();
    for(var i = 0; i < arguments.length; i++){
    	if(i){
    		arg.push(arguments[i])
    	}
    }
    return function(E) {
    	var arg_ = Array();
	    for(var i = 0; i < arguments.length; i++){
	    	if(arguments[i] instanceof Array || arguments[i] instanceof Object){
	    		arg_.push(arguments[i]);
	    	}
	    }
    	if(arg_.length){
    		arg = arg_.concat(arg);

    	}
    	returnVal = method.apply(obj, arg);
    	window.addEvent( window, 'onunload', function(){method = null; arg = null; obj = null;})
		return returnVal;
    }
}

Function.prototype.rcBind = function(obj)
{
	var m = this;
	var a = arguments.length>1 ? arguments[1] : {};
	return function(e)
	{
		if(arguments.length)
		{
			if(arguments[0].srcElement || arguments[0].target)
			{
				a['oEvent'] = arguments[0];
			}
			else
			{
				for(var key in arguments[0])
				{
					a[key] = arguments[0][key];
				}
			}

		}
		return m.call(obj, a);
	}
}

Function.prototype.rcBindAsIs = function(obj)
{
	var method = this;
	var arg = [];
	for(var i = 1; i < arguments.length; i++)
	{
		arg.push(arguments[i]);
	}
	return function()
	{
		if(arguments.length)
		{
			for(var i = 0; i < arguments.length; i ++)
			{
				arg.push(arguments[i]);
			}
		}
		//var res = null;
		//try
		//{
			res = method.apply(obj, arg);
		//}
		//catch(e){}
		if(arguments.length)
		{
			for(var i = 0; i < arguments.length; i ++)
			{
				arg.pop();
			}
		}
		return res;
	}
}


function addEvent(obj, ev, func){
	if(ev == 'ondomready')
	{
		onDomReady(func);
		return;
	}
	if(ev != 'onunload'){
		window.addEvent( window, 'onunload', function(){window.removeEvent(obj, ev, func); func = null;})
	}
	if (window.addEventListener){
		obj.addEventListener(ev.replace(/^on/i,''), func, false);
	}
	if (window.attachEvent){
		obj.attachEvent(ev,func);
	}
	
	
	
}


function onDomReady(callback)
	{	
		var _timer;
		
		
		
		var onDomReadyCallBack = function()
		{		
			if (arguments.callee.done) return;		
			arguments.callee.done = true;
			if (_timer)
			{
				clearInterval(_timer);
				_timer = null;
			}
			
			
			callback();		
			
		};	
		
		
		
		if (document.addEventListener)
		{
			document.addEventListener("DOMContentLoaded", onDomReadyCallBack, false);
		}
		
		if(document.attachEvent && !$_('__ie_onload'))
		{
			/*document.write("<script id='__ie_onload' defer src='" + (location.protocol == "https:" ?  "https://javascript:void(0)" : "javascript:void(0)") + "'><\/script>");
			var script = document.getElementById("__ie_onload");
			if(script)
			{
				script.onreadystatechange = function()
				{
					if (this.readyState == "complete")
					{
						onDomReadyCallBack(); 
					}
				};
			}*/			
		}
		
		if (document.attachEvent && document.documentElement.doScroll && window == window.top)
		{
			(
				function()
				{
					try
					{
						document.documentElement.doScroll("left");
					}
					catch(error)
					{
						setTimeout( arguments.callee, 0 );
						return;
					}
					onDomReadyCallBack();
				}
			)();
		}
		
		if (document.attachEvent)
		{
			/*document.onreadystatechange = function()
			{
				alert(document.readyState);
				if(document.readyState == "interactive")
				{
					alert(11);
					onDomReadyCallBack();
				}
			}*/
		}
		
		
	
		if (/WebKit/i.test(navigator.userAgent))
		{ 
			_timer = setInterval(function()
			{
				if (/loaded|complete/.test(document.readyState))
				{
					onDomReadyCallBack(); 
				}
			}, 10);
		}	
	
		addEvent(window, 'onload', onDomReadyCallBack);
	
	}




function removeEvent(obj, ev, func){
	if (window.addEventListener){
		obj.removeEventListener(ev.replace(/^on/i,''), func, false);
	}
	if (window.detachEvent){
		obj.detachEvent(ev, func);
	}
}
function in_array(needle, haystack, strict) {
    var found = false, key, strict = !!strict;

    for (key in haystack) {
        if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
            found = true;
            break;
        }
    }

    return found;
}
function count( mixed_var, mode ) {
   var key, cnt = 0;

    if( mode == 'COUNT_RECURSIVE' ) mode = 1;
    if( mode != 1 ) mode = 0;

    for (key in mixed_var){
        cnt++;
        if( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){
            cnt += count(mixed_var[key], 1);
        }
    }

    return cnt;
}
function is_string( mixed_var ){
    return (typeof( mixed_var ) == 'string');
}
function is_numeric( mixed_var ) {
    return !isNaN( mixed_var );
}

function is_dom(obj){
	return obj && obj.style;
}

function is_oObj(obj){
	return obj && obj.getView && obj.getView();
}
is_vObj = is_oObj;

function is_array(mixed_var) {
    return ( mixed_var instanceof Array );
}


function is_object( mixed_var ){
     if(mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}

function is_numeric(mixed_var) {
    return !isNaN( mixed_var );
}

function empty(mixed_var) {
	var is_object_empty = false;
	if(is_object(mixed_var)){
		for(key in mixed_var){
			return is_object_empty;
		}
		is_object_empty = true;
	}
    return ( mixed_var === "" || mixed_var === 0   || mixed_var === "0" || mixed_var === null  || mixed_var === false  ||  ( is_array(mixed_var) && mixed_var.length === 0 ) || is_object_empty );
}

function is_obj(obj){
	return obj && typeof(obj);
}
/*function in_array(arr,str){
	for(var i=0;i<arr.length;i++)
		if(arr[i] == str)
			return true;
	return false;
}*/
function getChilds(obj, nodeName, attr, style, arr){
	if(!arr){
		arr = Array();
	}
	if(obj.hasChildNodes()){
		for(var i=0; i < obj.childNodes.length; i++){
			if(obj.childNodes[i].nodeName == '#text'){
				continue;
			}
			if(!nodeName || obj.childNodes[i].nodeName == nodeName){
				if(!attr){
					if(!style){
						arr.push(obj.childNodes[i]);
					}else{
						if(obj.childNodes[i].style){
							var flg = false;
							for(key in style){
								var re = new RegExp(style[key])
								if(obj.childNodes[i].style[key].match(re)){
									flg = true;
								}else{
									flg = false;
									break;
								}
							}
							if(flg){
								arr.push(obj.childNodes[i]);
							}
						}
					}
				}else{
					var flg = false;
					for(key in attr){
						if(obj.childNodes[i].getAttribute(key) == attr[key]){
							flg = true;
						}else{
							flg = false;
							break;
						}
					}
					if(flg){
						if(!style){
							arr.push(obj.childNodes[i]);
						}else{
							if(obj.childNodes[i].style){
								var flg = false;
								for(key in style){
									if(obj.childNodes[i].style[key] == style[key]){
										flg = true;
									}else{
										flg = false;
										break;
									}
								}
								if(flg){
									arr.push(obj.childNodes[i]);
								}
							}
						}
					}
				}
			}
			getChilds(obj.childNodes[i], nodeName, attr, style, arr);
		}
	}
	return arr;
}
function errorMsg( method, msg){
	alert("Error:\r\r\n\n    " + method + "                        \r\n    " + msg);
}
function noticeMsg( method, msg){
	alert('Notice!!!:\r\r    ' + method + '                        \r    ' + msg + '!');
}

// зарезервирования ретурн ложь , нужна для что бы потом можно было снять событие с обьекта
function returnFalse(event){
	event.cancelBubble = true;
	return false;
}

// нахрена?
function getNextBrother(obj){
	if(!is_dom(obj)){
		errorMsg('tools.js -> Window :: getNextBrother','Object in not DOM element');
		return;
	}
}


/*function parseXML(xml){
	var arr = Array();
	if(xml){
		var root=xml.getElementsByTagName('result')[0];
		if( root != null ){
			for( var i = 0; i < root.childNodes.length; i++ ){
				item_=root.childNodes[i];
				if( item_.nodeName != '#text'){
					var index = arr.length;
					arr[index] = Array();
					arr[index]['nodeName'] = item_.nodeName;
					arr[index]['textContent'] = item_.text||item_.textContent;
					for( var k = 0; k < item_.attributes.length; k++){
						var attr = item_.attributes[k];
						arr[index][attr.name] = attr.value;
					}
				}
			}
		}
	}
	return arr;
}*/

/*function parseXML(xml, arr){
	if(!arr){
		arr = Array();
	}
	if(xml.nodeName == '#document'){
		var root = xml.firstChild;
	}else{
		var root = xml;
	}
	if(root){
		if(root.hasChildNodes()){
			for( var i = 0; i < root.childNodes.length; i++ ){
				var item_    = root.childNodes[i];
				var nodeName = item_.nodeName;
				if( nodeName != '#text'){
					if(!arr[root.nodeName]){
						arr[root.nodeName] = Array();
					}
					if(!arr[root.nodeName][item_.nodeName]){
						arr[root.nodeName][item_.nodeName] = Array();
					}
					var val = parseXML(item_);
					if(is_array(val)){
						arr[root.nodeName][item_.nodeName].push(val);
					}else{
						arr[root.nodeName][item_.nodeName] = val;
					}
				}
			}

		}else{
			var textContent = root.text||root.textContent;
			var attributes  = getAttributes(xml);
			if(attributes){
				attributes['textContent'] = textContent;
				return attributes;
			}
			return textContent;
		}
	}else{
		return '';
	}
	return arr;
}*/

function parseXML(xml){
	var arr = Array();
	if(!xml || !xml.firstChild){
		return '';
	}

	var root = xml.nodeName=='#document'? xml.firstChild : xml;
	if(root.nodeName == '#text'){
		root = root.nextSibling;
	}
	if(root.nodeName == 'xml'){
		root = root.nextSibling;
	}
	if(root){
		for( var i = 0; i < root.childNodes.length; i++ ){
			var item    = root.childNodes[i];
			var nodeName = item.nodeName;
			var attributes = getAttributes(item);
			if(nodeName != '#text'){
				if(nodeName != "#comment" ){
					switch(nodeName){
						case 'length':case 'push':
							nodeName = '_' + nodeName;
							break;
					}
					var val = parseXML(item);
					if(!arr[nodeName]){
						if(attributes){
							var temp = Array();
							temp['attrs']  = attributes;
							temp['textContent'] = val;
							arr[nodeName] = temp;
						}else{
							arr[nodeName] = val;
						}
					}else{
						if(!is_array(arr[nodeName])){
							var temp = arr[nodeName];
							arr[nodeName] = Array(temp);
						}
						if(arr[nodeName].length == 0){
							var temp = arr[nodeName];
							arr[nodeName] = Array(temp);
						}
						if(attributes){
							var temp = Array();
							temp['attrs']  = attributes;
							temp['textContent'] = val;
							arr[nodeName].push(temp);
						}else{
							arr[nodeName].push(val);
						}
					}
				}
			}
		}
		var flg = false;
		for(key in arr){
			flg = true;
			break;
		}
		
		
		
		//return flg? arr : (root.text||root.textContent||(root.firstChild? root.firstChild.nodeValue : undefined));
		return flg? arr : (root.text||root.textContent);
	}
	return null;
}

function getAttributes(node){
	var arr = Array();
	if(node && node.attributes && node.attributes.length > 0){
		for( var i = 0; i < node.attributes.length; i++){
			var attr = node.attributes[i];
			arr[attr.name] = attr.value;
		}
		return arr;
	}
	return null;
}

function formatPhoneNumber(number){
	return number.substring(0,1)+' ('+number.substring(1,4)+') '+number.substring(4,7)+'-'+number.substring(7,11);
}

function templater(str, hash)
{

	var leftQ  = '<%';
	var rightQ = '%>';
	var re1 = new RegExp("((^|"+ rightQ +")[^\t]*)'",'g');
	var re2 = new RegExp("\t=(.*?)\\" + rightQ,'g');
	var my_str = "var a=[];with(hash){a.push('" + str
					.replace(/[\t\r\n]/g, " ")
					.split(leftQ)
					.join("\t")
					.replace(re1, "$1\r")
					.replace(re2, "',$1,'")
					.split("\t")
					.join("');")
					.split(rightQ)
					.join("a.push('")
					.split("\r")
					.join("\\'")+ "');} return a.join('');";
	
	my_str = 'try{' + my_str + '}catch(e){throw e;}';

	return new Function("hash", my_str)(hash);

}

function getCssClassNamevalue(o, className)
{
	var sClasses = o.className.replace(/\n|\r|\t/g,' ');
	var aClasses = sClasses.split(' ');
	
	
	var re       = new RegExp('^' + className + '(\-|)([^\-]+|)','') ;
	for(var i = 0; i < aClasses.length; i++)
	{
		var class_ = aClasses[i];
		if(res = class_.match(re))
		{
			return res[2];
		}
	}
	return null;
}
getCssClassNameValue = getCssClassNamevalue

function setCssClassName(o, className, value)
			{
				
				if(getCssClassNameValue(o, className) == value)
				{
					return;
				}
				
				if(typeof value == 'undefined')
				{
					o.className = className;
				}
				else
				{
					var sClasses = o.className.replace(/\n|\r|\t/g,' ');
					var aClasses = sClasses.split(' ');
					var re       = new RegExp('^' + className + '\-[^\-]+','') ;
					for(var i = 0; i < aClasses.length; i++)
					{
						var class_ = aClasses[i];
						if(class_.match(re))
						{
							aClasses.splice(i,1);
						}
					}

					if(value == '' && value != 0)
					{
						aClasses.push(className);
					}
					else
					{
						aClasses.push(className + '-' + value);
					}
					o.className = aClasses.join(' ');
					if(o.firstChild && o.firstChild.tagName == 'B')
					{
						o.firstChild.innerHTML = o.className;
					}
				}
				//alert(o.className)
			}

			function addClassName(o, className)
			{
				var aClasses = o.className.replace(/\n|\r|\t/g,' ').split(' ');
				for(var i = 0; i < aClasses.length; i++)
				{
					if(aClasses[i] == className)
					{
						return;
					}
				}
				o.className += ' ' + className;
			}

function initCss(rules)
{
	if(!rules || typeof rules != 'string')
	{
		return false;
	}
	try
	{
		var oStyle = document.createElement('DIV');
		oStyle.innerHTML = '*<style>' + rules + '</style>*';
		document.getElementsByTagName('HEAD')[0].appendChild(oStyle);
	}
	catch(e)
	{
		var oStyle = document.createElement('STYLE');
		oStyle.innerHTML = rules;
		document.body.appendChild(oStyle);
	}
	return true;
}

function getElementsByClassName(classNameVal, parent, tag)
{
	var res =[];
	parent = parent||document;
	var nodes = parent.getElementsByTagName(tag || '*');
	var l = nodes.length; 
	if(l) 
	{
		var re = new RegExp("(^|\\s)" + classNameVal + "(\\s|$)");
		  
		for(var i = 0; i < l; i++)
			if (re.test(nodes[i].className) ) res.push(nodes[i]);
	}
	return res;
}

/*
 function getElementsByClassName(classNameVal, parent)
 {
 	var res =[];
 	parent = parent||document;
 	var nodes = parent.getElementsByTagName('*');
 	var l = nodes.length;
 	if(l)
 	{
 		for(var i = 0; i < l; i++)
 		{
 			var node = nodes[i];
 			var aClasses = node.className.replace(/\n|\r|\t/g,'').split(' ');
 			if(inArray (aClasses, classNameVal) != -1)
 			{
 				res.push(node);
 			}
 		}
 	}
 	return res;
 }
 */

function each(obj, callBack, space)
{
	if(!obj)
	{
		throw new Error('Each\nObject is undefined')	;
	}
	if(typeof callBack != 'function')
	{
		throw new Error('Each\nCallBack undefined or not a function')	;
	}

	space = space || obj;

	if(obj.length)
	{
		for (var i = 0, l = obj.length; i < l; i++) {
			if (callBack.call(space, obj[i], parseInt(i), obj) === false)
					return false;
		}
	}
	else
	{
		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				if (callBack.call(space, obj[key], key, obj) === false)
					return false;
			}
		}
	}
	return true;
}

function getCurrentStyle(o, name)
{
	if( window.getComputedStyle )
	{
	   return window.getComputedStyle(o,null)[name];
	} else if( o.currentStyle )
	{
	    return o.currentStyle[name];
	}
	return  null;
}

function each_r(obj, callBack, space)
{
	if(!obj)
	{
		throw new Error('Each\nObject is undefined')	;
	}
	if(typeof callBack != 'function')
	{
		throw new Error('Each\nCallBack undefined or not a function')	;
	}

	space = space || obj;

	var res = [];

	if(obj.length)
	{
		for (var i = 0, l = obj.length; i < l; i++) {
			var ret_val = callBack.call(space, obj[i], i, obj);
			if(ret_val)
			{
				res.push(ret_val);
			}
		}
	}
	else
	{
		for (var key in obj) {
			if (obj.hasOwnProperty(key)) {
				var ret_val = callBack.call(space, obj[key], key, obj);
				if(ret_val)
				{
					res.push(ret_val);
				}
			}
		}
	}
	return res.length? res : null;
}

function getCssPropValueBySelectorAndProp(selector, prop)
	{
		var css = window.document.styleSheets;
		if(css.length)
		{
			var res =
			each_r(css,
				(
					function(selector, prop, cssGroup)
					{
						try
						{
							var fullRules = cssGroup.cssRules || cssGroup.rules
							if(fullRules)
							{
								var res =
								each_r(fullRules,
									(
										function(selector, prop, rule)
										{
											if(rule.selectorText == selector)
											{
												return rule.style[prop];
											}
											return null;
										}
									).rcBindAsIs(this, selector, prop)
								);
								return res? res : null;
	
							}
						}catch(e){}
					}
				).rcBindAsIs(this, selector, prop)
			);
			return res? res[0] : null;
		}
	}

function inArray (arr, val)
{
	if(arr)
	{
		for(var i = 0, l = arr.length; i < l; i++)
		{
			if(arr[i] == val)
			{
				return i;
			}
		}
	}
	return -1;
}



function opacity(id, opacStart, opacEnd, millisec) {
	
		var speed = Math.round(millisec / 100);
		var timer = 0;
	
		
		if(opacStart > opacEnd) {
			for(i = opacStart; i >= opacEnd; i--) {
				setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
				timer++;
			}
		} else if(opacStart < opacEnd) {
			for(i = opacStart; i <= opacEnd; i++)
				{
				setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
				timer++;
			}
		}
	}
	
	
	function changeOpac(opacity, id) {
		var object = document.getElementById(id).style; 
		object.opacity = (opacity / 100);
		object.MozOpacity = (opacity / 100);
		object.KhtmlOpacity = (opacity / 100);
		object.filter = "alpha(opacity=" + opacity + ")";
	}
	
function getParentByTagsName(arr, node)
	{
		while(inArray(arr, node.nodeName) == -1)
		{	
			if(node.nodeName == 'BODY')
			{
				return null;
			}		
			node = node.parentNode;
		}
		return node;
		
	}
	
	
	
function fireEvent(el, ev)
{
	if (document.createEventObject)
	{
	    var E = document.createEventObject();
	    el.fireEvent(ev, E);
	    return true;
	}
	else if(document.createEvent)
	{
	    var E = document.createEvent("MouseEvents");
	    E.initEvent(ev.replace(/^on/,''), true, false);
	    el.dispatchEvent(E);
	    
	     var E = document.createEvent("HTMLEvents");
	    E.initEvent(ev.replace(/^on/,''), true, false);
	    el.dispatchEvent(E);
	    
	    return true;
	}
	else
	{
	    return false;
	}
}

function rand( min, max ) {
    var argc = arguments.length;
    if (argc == 0) {
        min = 0;
        max = 2147483647;
    } else if (argc == 1) {
        throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
    }
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function concatHash()
{
	var r = {};
	for(var i = 0; i < arguments.length; i++)
	{
		var parent = arguments[i];
		for(var key in parent)
		{
			r[key] = parent[key];
		}
	}
	return r;
}


/*




*/

function Subscriber(){
	EventsPack.call(this);
	this._observers = Array();
	
	this.setObserver = function(eventName, callBack, obj){
		if(obj == undefined){
			obj = this._view;
		}
		if(obj){
			if(!this[eventName]){
				window.addEvent(obj, eventName, callBack);
			}else{
				if(!this._observers[eventName]){
					this._observers[eventName] = Array();
				}
				this._observers[eventName].push(callBack);
			}
		}else{
			if(!this._observers[eventName]){
				this._observers[eventName] = Array();
			}
			this._observers[eventName].push(callBack);
		}
	}
	
	
	this.on = this.setObserver;
	
	
	
	this.removeObserver = function(eventName, callBack, obj){
		if(!this[eventName]){
			if(obj == undefined){
				obj = this._view;
			}
			window.removeEvent(obj,eventName,callBack);	
		}else{
			if(this._observers[eventName]){
				var len = this._observers[eventName].length;
				for(var i = 0; i < len; i++){
					if(this._observers[eventName][i] == callBack){
						this._observers[eventName][i] = undefined;
						return;
					}
				}
			}
		}
	}
				
	this._informObservers = function(eventName){
		
		var arg = [];
		for(var i = 1; i < arguments.length; i++)
		{
			arg.push(arguments[i]);
		}
		if(this._observers[eventName]){
			for( var i = 0; i < this._observers[eventName].length; i++){
				if(this._observers[eventName][i]){
					if(arg.length)
					{
						this._observers[eventName][i].apply(this, arg);
					}
					else
					{
						this._observers[eventName][i]();
					}
				}
			}
		}
	}
	
	this._fireEvent = this._informObservers;
	this.fireEvent = this._informObservers;
	
}

function EventsPack(){
	this.onselection = function(){
		this._informObservers('onselection');
	}
	this._attachEvent = function(eventName,obj){
		if(!this[eventName]){
			this[eventName] = function(arg, e){
				this._informObservers(eventName, e);
			}
		}
	}
}

var CookiesManager = {
	setCookie : function (name, value, expires, path, domain, secure) {
		name = name.toLowerCase();
		if(!path){
			path = '/';
		}
		if(typeof expires != 'number'){
			expires = '';
		}else{
			var expires_date = new Date( (new Date()).getTime() + (expires*24*60*60*1000) );
			expires = ' expires=' + expires_date.toGMTString() + ';';
		}

		var d = (domain) ? ';domain=' + domain : '';
		var s = ( secure ) ? ";secure" : "";
		document.cookie = name + "=" + value + ";" + expires + " Path=" + path + d + s;
	},
	getCookie : function (name){
		var c = document.cookie;
		var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)", "i"));
		return (matches ? decodeURIComponent(matches[1]) : null);
	},
	attachCookie : function(cookieName, str){
		var value = CookiesManager.getCookie(cookieName);
		var re = new RegExp("(&|\\\?)"+cookieName+"=");
		if(value && !str.match(re)){
			str += '&' + cookieName + '=' + value;
		}
		return str;
	},
	delCookie : function( name, path, domain ) {
		document.cookie = name + "=" +
			( ( path ) ? ";path=" + path : "") +
			( ( domain ) ? ";domain=" + domain : "" ) +
			";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	},

	delAlienCookies : function(cookies, write) {

		var src = window.location.protocol + '//' + window.location.host +'/inc/php/clearc.php?' + cookies.join('&');
		cookies.push((new Date())*1);
		if ( write && write == true ) {
			document.write('<iframe style="display:none;" src="'+ src + '"></iframe>');
		} else {
			var ifr = document.createElement('iframe');
			ifr.style.display = 'none';
			ifr.src = src;
			document.body.appendChild(ifr);
		}
	}
}

/*







*/




function NumberList(hash)
{
	Subscriber.call(this);
	this._numbers = {};
	this._type  = null;
	
	this.__construct(hash || {});
}
NumberList.prototype =
{ 
	
	__construct : function(hash)
	{
		this._proxy_url  = hash.proxy_url;
		
		this._numbersSwitchCmd = hash.numbersSwitchCmd;
		
		this._defaultItemId = hash.defaultItemId; 
		
		this._numberItemClassName = hash.numberItemClassName;
        
        this._numberType = hash.type || '';
		
		//this._parent             = hash.parent;
		
		this._numberListTemplate = hash.numberListTemplate;
	
		this._nNumbers_place      = hash.nNumbers_place;
		
		
		this._NumberBlock = document.createElement('DIV');
		this._nNumbers_place.appendChild(this._NumberBlock);
	},
	
	
	loadNumbers : function(data)
	{
		this._type = data.type;
		this._informObservers('onBeforeLoading');
		var Ajax = new GetNumbersJEDI();
		var arr =     {
							'url'           : this._proxy_url,
							repeatOnFailure : 1,
							//timeout : 2 * 1000,
							data  : data
					 };
		
		
		Ajax.setData(arr);
		Ajax.sendPost();	
		
			
		
		Ajax.setObserver('onempty'    , this._onfailureGetNumbers.rcBindAsIs(this));							
		Ajax.setObserver('onfailure'  , this._onfailureGetNumbers.rcBindAsIs(this));
		Ajax.setObserver('oncomplete' , this._oncompleteGetNumbers.rcBindAsIs(this));
	},
	
	_onfailureGetNumbers : function(response)
	{
		this._informObservers('onFailure', response);
	},
	
	_oncompleteGetNumbers : function(numbers)
	{
		
		
		
		/*
			numbers=Array
			(
			    [0] => Array
			        (
			            [formattedNumber] => (650) 491-0926
			            [number] => 16504910926
			        )
			     .....
		*/
		var template = templater(this._numberListTemplate, 
									{
										numbers : numbers,
										type    : this._type,
                                        numberType : this._numberType
									});
		this._setNumbers(template);
		this._informObservers('onComplete');
	},
	
	_setNumbers : function(template)
	{
		
		this._NumberBlock.innerHTML = template;
		
		setCssClassName(this._NumberBlock, this._numbersSwitchCmd, this._defaultItemId);
		
		addEvent(this._NumberBlock, 'onmouseup', this._onAfterClickOnNumber.rcBindAsIs(this));
		
		var items = getElementsByClassName(this._numberItemClassName, this._NumberBlock);
		each(items, function(item, i)
		{
			if(!i)
			{
				fireEvent(item, 'onmouseup');
			}
		})
		
		
	},
	
	
	
	_onAfterClickOnNumber : function(e)
	{
		var target = e.target||e.srcElement;
		while(!target.getAttribute('item_id'))
		{
			target = target.parentNode;
			if(target.nodeName == 'BODY')
			{
				return;
			}
		}
		
		var item_id         = target.getAttribute('item_id');
		var number          = target.getAttribute('number');
		var formattedNumber = target.getAttribute('formatted_number');
		var typeNumber      = target.getAttribute('type_number');
		
		if(item_id && number && formattedNumber)
		{
			setCssClassName(this._NumberBlock, this._numbersSwitchCmd, item_id);
			this._setNumbersInfo(number, formattedNumber, typeNumber);
		}
	},
	
	_setNumbersInfo : function(number, formattedNumber, typeNumber)
	{
		this._numbers = {
								typeNumber      : typeNumber,
								number          : number,
								formattedNumber : formattedNumber
							};
	},
	
	get : function()
	{
		return this._numbers;
	}
	
		
}


/*



*/


function GetNumbersJEDI(){
    AjaxTransfer.call(this);
    Subscriber.call(this);
	
    this.numbers  = undefined;
    //this.newStart = undefined;
    var newStart  = undefined;
			
    this.callBack = function(response){
        var data = response.responseArr;
        if(data && data.status && data.status.success == '1'){
            if(data.result)
            {
                if(data.result.length)
                {
                    this.numbers = data.result;
                }
                else
                {
                    this.numbers = Array(data.result);
                }
                if(data.newStart != undefined)
                {
                    this.newStart = data.newStart;
                }
				
                this._informObservers('oncomplete', this.numbers);
            }
            else
            {
                this._informObservers('onempty');
            }
        }else{
            this.failure(response);
        }
    }
    this.setFailure = function(response){
        if(LocationManager.is_hash('monitor')){
        //alert('Error : GetNumber');
        //printArray(response);
        }else{
        //this._informObservers('onempty');
        //alert('We are temporarily unable to satisfy your request. We apologize for any inconvenience. Please check back with us shortly or call us at 1-800-574-5290 if you have any questions. Thank you.');
        //window.location = '/ordernow/errormessage.html';
        }
        if (typeof response != 'undfined') {
            this._informObservers('onFailure', response.responseArr);
        }
    }
    this.getNumbers = function(){
        return this.numbers;
    }
    this.getNewStart = function()
    {
        return this.newStart;
    }
	
	
	
}



function AjaxTransfer(){
	Subscriber.call(this);

	this.data        = undefined;
	this.HttpRequest = undefined;
	this.cnt         = 0;
	this.method      = undefined;
	this.timer       = undefined;


	this.setData = function(json){
		this.data = json;
		if(!this.data.callBack){
			this.data.callBack = this.callBack.bind(this)
		}
		if(LocationManager.is_hash('debugProxy') && this.data.data){
			this.data.data['debug'] = true;
		}
		if(!this.data.failure){
			this.data.failure = this.failure.bind(this)
		}
		if(!this.data.cache){
			this.data.cache = false;
		}
		if(!this.data.timeout){
			this.data.timeout = 30*1000;
		}
		if(!this.data.tail){
			this.data.tail = false;
		}
		if(!this.data.headers){
			this.data.headers =
			{
				'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
			};
		}
		// need check on integer
		if(!this.data.repeatOnFailure){
			this.data.repeatOnFailure = 3;
		}
	}
	this.getData = function(){
		if(this.HttpRequest){
			return this.HttpRequest.getData();
		}
		return {error : 'HTTP transport is not send now'}
	}
	this.changeData = function(arr){
		if(this.HttpRequest){
			 this.HttpRequest.changeData(arr);
		}
	}
	this.getTimer  = function(){
		return this.timer;
	}
	this.sendPost = function(){
		setTimeout(function(){
			this.method = 'post';
			this.cnt++;
			this._setHttpRequest();
			this.HttpRequest.sendPost(this.data);
		}.rcBindAsIs(this), 0);
	}
	this.sendGet = function(){
		setTimeout(function(){
			this.method = 'get';
			this.cnt++;
			this._setHttpRequest();
			this.HttpRequest.sendGet(this.data);
		}.rcBindAsIs(this), 0);
	}
	this._setHttpRequest = function(){
		if(!this.HttpRequest){
			this.HttpRequest = new HttpRequest();
		}
	}
	this.callBack = function(){

	}
	this.failure = function(response){
		this.onfailure(response.responseArr);
		if(this.data.repeatOnFailure > this.cnt){
			switch(this.method){
				case 'post':
					this.onrepeat();
					this.sendPost();
					break;
				case 'get':
					this.onrepeat();
					this.sendGet();
					break;
			}
		}else{
			this.setFailure(response);
		}
	}
	this.getNumTry = function(){
		return this.cnt;
	}

	this.onrepeat = function(){
		this._informObservers('onrepeat');
	}
	this.onrepeatByTimer =  function(){
		this._informObservers('onrepeatByTimer');
	}
	this.onfailure = function(response){
		this._informObservers('onfailure', response);
	}
	this.oncomplete = function(){
		this.cnt = 0;
		this._informObservers('oncomplete');
		if(this.data.repeatOnTimer && !isNaN(this.data.repeatOnTimer)){
			switch(this.method){
				case 'post':
					this.onrepeatByTimer();
					this.timer = setTimeout(this.sendPost.bind(this), this.data.repeatOnTimer);
					break;
				case 'get':
					this.onrepeatByTimer();
					this.timer = setTimeout(this.sendGet.bind(this), this.data.repeatOnTimer);
					break;
			}
		}
	}
	this.setFailure = function(){

	}
}

/*
	
*/

//**************************************************************************
function HttpTranspors(){
	httpTransports = Array();	
	//*******************************************************************
	// Возвращает свободный (readyState == 4) объект httpTransport из массива  
	// thid._httpTransports или создает новый;
	//*******************************************************************
	this.getHttpTransport = function(){
		for(var i = 0; i < httpTransports.length; i++){
			if(httpTransports[i].readyState == 4){
				return httpTransports[i];
			}
		}
		var httpTransport = null;
		try {httpTransport = new ActiveXObject("Msxml2.XMLHTTP");}
		catch(e){
			try{
				httpTransport = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(f){}
		}
		if(!httpTransport && typeof(XMLHttpRequest) != 'undefined'){
			httpTransport = new XMLHttpRequest();
		}
		httpTransports.push(httpTransport);
		return httpTransport;
	}
}
var HttpTranspors = new HttpTranspors();
//**************************************************************************

function HistoryRequest(){
	var data = Array();
	this.setHistory = function(key,val){
		data[key] = val;
	}
	this.getVal = function(key){
		return data[key];
	}
}
var HistoryRequest = new HistoryRequest();


function HttpRequest(){
	var transport  = undefined;
	var insetData  = undefined
	var url        = undefined;
	var data       = undefined;  
	var callBack   = undefined;
	var charset    = 'UTF-8';
	var cache      = false;
	var headers    = Array();
	var tail       = true;
	var failure    = undefined;
	var timeout    = 30000;
	var timerId    = undefined;
	var requestLogger = new AJAXErrorLogger();
	var logHelper   = undefined;
	
	function  setAttr(arr){
		cacheVal   = HistoryRequest.getVal(arr);
		insetData  = arr;
		url        = arr.url;
		callBack   = arr.callBack; 
		cache      = arr.cache;
		headers    = arr.headers;
		tail       = arr.tail;
		failure    = arr.failure;
		timeout    = arr.timeout? arr.timeout : timeout;
		//data       = getDataToStr.bind(this)(arr.data);
		data       = arr.data;
		logHelper  = requestLogger.invokeRequestTracing(arr.url + '?' + getDataToStr(arr.data));  
	}
	this.getData = function(){
		return data;
	}
	this.changeData = function(arr, data_){
		if(!data_){
			data_ = data;
		}
		for(key in arr){
			if(is_string(arr[key]) || is_numeric(arr[key])){
				data_[key] = arr[key];
			}else{
				if(!data_[key]){
					data_[key] = {};
				}
				this.changeData(arr[key], data_[key]);
			}
		}
	}	
	this.sendGet = function(arr){
		setTransport();
		setAttr(arr);
		if(!cache||!cacheVal){
			if(url){
				transport.open('GET',url + '?' + getDataToStr.bind(this)(data),true);
				transport.onreadystatechange = analysisResponse.bind(this);
				send(null);
			}else if(callBack){
				logHelper.makeLogRecord('url is undefiend');
				callBack({'error':true});
			}
		}else if(callBack){
			cacheVal['cache'] = true;
			this.Event = cacheVal;
			callBack(cacheVal);
		}
	}
	this.sendPost = function(arr){
		setTransport();
		setAttr(arr);
		if(!cache||!cacheVal){
			if(url){
				transport.open('POST', url, true);
				transport.onreadystatechange =  analysisResponse.bind(this);
				sendRequestHeaders();
				send(getDataToStr.bind(this)(data));
			}else if(callBack){
				logHelper.makeLogRecord('url is undefiend');
				callBack({'error' : 'url is undefiend'});
			}
		}else if(callBack){
			cacheVal['cache'] = true;
			callBack(cacheVal);
		}
	}
	function send(val){
		transport.send(val);
		if(failure){
			timerId = setTimeout(ontimeout.bind(this) , timeout);
		}
	}
	function ontimeout(){
		transport.abort();
		failure({error : 'timeout'});
	} 
	function sendRequestHeaders(){
		for(key in headers){
			transport.setRequestHeader(key , headers[key]);
		}
	}
	function getDataToStr(param, str, parent){
		var now = new Date;
		str     = str? str : '';
		switch(typeof(param)){
			case 'object':
				for(var key in param){
					if(typeof(param[key]) == 'object'){
						str = getDataToStr(param[key], str, parent? parent + '[' + key + ']' : key);
						continue;
					}
					str+=(str == ''? '':'&') + (parent? parent + '[' + key + ']' : key ) + '=' + param[key];
				}
			break;
			case 'string':
				str = param;
			break;
		}
		if(tail){
			str = str +  '&tail='+now.getTime();
		}
		return str;
	}
	function analysisResponse(){
		if(transport.readyState == 4){
			var arr = Array();
			clearTimeout(timerId);
			try{transport.status}catch(e){return;}
			arr['status']       = transport.status;
			arr['readyState']   = transport.readyState;
			arr['responseText'] = undefined;
			arr['responseArr']  = undefined;
			arr['responseXML']  = undefined;
			if(transport.status == 200){
				arr['status']       = transport.status;
				arr['responseText'] = transport.responseText;
				arr['responseArr']  = parseXML(transport.responseXML);
				arr['responseXML']  = transport.responseXML;
				logHelper.makeLogRecord(transport.responseText);
				
			}else{
				if(failure){
					logHelper.makeLogRecord(transport.status);
					failure({ error : transport.status});
					return;
				}
			}
			HistoryRequest.setHistory(insetData, arr);
			if(callBack){
				callBack(arr);
			}
		}
	}
	//function setTransport(obj){
	//	transport = obj;
	//}
	function setTransport(){
		transport = HttpTranspors.getHttpTransport();
	}
	//setTransport(HttpTranspors.getHttpTransport())
}

function AJAXErrorLogger(hash) {
	this.__construct(hash || {})
}

AJAXErrorLogger.prototype = {
	__construct: function(hash) {
		this._createLogArea(hash.id || 'debugerrors');
	},
	
	_createLogArea: function(id) {
		this._div = document.getElementById(id);
		if(!this._div) {
			this._div = document.createElement('div');
			this._div.style.display = 'none';
			this._div.id = id;
			this._div.className = 'logcount-0';
			document.body.appendChild(this._div);
		}
	},
	
	invokeRequestTracing: function(url) {
		
		var isTestMode = !!CookiesManager.getCookie('automatic_test');
		
		var logger = (function(errorArea, requestURL, isTest){
			
			if (isTest) {
				var count = errorArea.className.replace(/\D+/g, '');
				
				var div = document.createElement('div');
				div.className = 'log-' + count;
				errorArea.appendChild(div);
				count++;
				errorArea.className = 'logcount-' + count;
				
				var requestArea = document.createElement('div');
				requestArea.className = 'request';
				var requestValue = document.createTextNode(requestURL);
				requestArea.appendChild(requestValue);
				div.appendChild(requestArea);
				
				var responseArea = document.createElement('div');
				responseArea.className = 'response';
				div.appendChild(responseArea);
			}
			
			return {
				makeLogRecord: function(responseInfo) {
					if (isTest && responseArea) {
						var responseValue = document.createTextNode(responseInfo);
						responseArea.appendChild(responseValue);
					}
				}
			};
		})(this._div, url, isTestMode);
		
		return logger;
	}
};

/*














*/



function Select_Cities(hash)
{
	Subscriber.call(this);
	
	
	this.__construct(hash);
}
Select_Cities.prototype = 
{
	
	__construct : function(hash)
	{
		
		this._node       = hash.node;
		
		this._firstSort  = hash.firstSort;
		
		addEvent(this._node, 'onchange', this._onAfterChange.rcBindAsIs(this))
		this._Select     = new Select_View();
		this._Select.setView(this._node);
		
		var noAvailabe = this._Select.removeOptionByAttr({type : 'noAvailable'});
		if(noAvailabe)
		{
			this._noAvailabe = noAvailabe;
		}
		
		var wait = this._Select.removeOptionByAttr({type : 'wait'});
		if(wait)
		{
			this._wait = wait;
		}
		
		var selectArea = this._Select.removeOptionByAttr({type : 'select_area'});
		if(selectArea)
		{
			this._selectArea = selectArea;
		}
		
		var selectCity = this._Select.removeOptionByAttr({type : 'select_city'});
		if(selectCity)
		{
			this._selectCity = selectCity;			
		}
		
		if(this._selectArea)
		{
			this._Select.setOptionAsObject(this._selectArea, 0, true);
		}
		
		this._proxy_url  = hash.proxy_url;
		
	
	},
	
	
	setCities : function(stateId, countryId)
	{
		
		this._Select.disabled(true);
		
		if(this._wait)
		{
			this._Select.setOptionAsObject(this._wait, 0, true);
		}
		
	
		
		if(typeof countryId == 'undefined')
		{
			countryId = 1;
		}
		if(typeof stateId == 'undefined')
		{
			stateId = 16;
		}
		this._loadCities(stateId, countryId);
	},
	
	
	_loadCities : function(stateId, countryId)
	{
		this._informObservers('onBeforeLoading');
		var Ajax = new GetListLocationsJEDI();
		var arr =     {
							'url'           : this._proxy_url,
							repeatOnFailure : 1,
							//timeout : 2 * 1000,
							data  : 
							{
								cmd : 'getLocations',
								param :
								{
									listLocationsRequest : 
									{
										stateId : stateId,
										countryId : countryId
									}
								}
							}
					 }
		
		Ajax.setData(arr);
		Ajax.sendPost();	
		
		Ajax.setObserver('onempty'    , this._onfailureGetLocations.rcBindAsIs(this));							
		Ajax.setObserver('onfailure'  , this._onfailureGetLocations.rcBindAsIs(this));
		Ajax.setObserver('oncomplete' , this._oncompleteGetLocations.rcBindAsIs(this, stateId));
		
			
	},
	
	
	_onfailureGetLocations : function()
	{
		if(this._noAvailabe)
		{
			this._Select.setOptionAsObject(this._noAvailabe, 0, true);
		}
		this._informObservers('onFailureLoading');
	},
	
	
	_oncompleteGetLocations : function(stateId, cities)
	{
		/*
			cities = Array
			(
			    [0] => Array
			        (
			            [city] => Georgetown
			            [npa] => 203
			        )
			    ....
		*/
		
		this._fillSelect(cities, stateId);
		
		if(this._firstSort)
		{
			switch(this._firstSort)
			{
				case 'area':
					setTimeout(this.sortByAreaCode.rcBindAsIs(this, true), 100);
					break;
				case 'city':
					setTimeout(this.sortByCity.rcBindAsIs(this, true), 100);
					break;
			}
		}
		
		this._informObservers('onLoadCity');
		this._informObservers('onAfterLoading');
		
		
			
	},
	
	
	_removeInfoOptions : function()
	{
		/*
			cities = Array
			(
			    [0] => Array
			        (
			            [city] => Georgetown
			            [npa] => 203
			        )
			    ....
		*/
		if(this._wait)
		{
			this._Select.removeOptionAsObj(this._wait);
		}
		
		if(this._noAvailabe)
		{
			this._Select.removeOptionAsObj(this._noAvailabe);
		}
		
		if(this._selectArea)
		{
			this._Select.removeOptionAsObj(this._selectArea);
		}
		
		if(this._selectCity)
		{
			this._Select.removeOptionAsObj(this._selectCity);
		}
		//this._informObservers('onInsertCity');
	},
	
	
	_fillSelect : function(cities, stateId)
	{
		this._removeInfoOptions();
		this._Select.clear();
		
		each(cities, function(city, i)
		{			
			
			this._Select.setOption((city.npa.toString().length == 4? city.npa : '&nbsp; ' + city.npa) + ' - ' + city.city, 
			{
				city     : city.city,
				npa      : city.npa,
				state_id : city.stateId? city.stateId : stateId,
				type     : 'city_list'
			});
		}, this);
		
		this._Select.disabled(false);
	},
	
	
	_onAfterChange : function()
	{
		
		var res = this._Select.get();
		/*
			res = Array
			(
			    [value] => 860 - Norwich
			    [city] => Norwich
			    [npa] => 860
			)	   
		*/
		if(typeof res.npa != 'undefined')
		{
			this._informObservers('onChangeCity', res);
		}
		else
		{
			this._informObservers('onDefaultState');
			this._informObservers('onDefault');
		}
	},
	
	setDefault : function()
	{
		this._Select.disabled(true);
		this._Select.selectedByIndex(0);
	},
	
	_sort : function(type)
	{
		
		var curState = this._Select.get();		
		/*
			Array
			(
			    [value] => 303 - Brighton
			    [city] => Brighton
			    [npa] => 303
			)
		*/		
			
		var dump = this.getDump();		
		/*
			Array
			(
			    [0] => Array
			        (
			            [0] => Georgetown
			            [1] => 203
			        )
			    ....

		*/
		
		if(type == 'area')
		{
			dump.sort(
				function (a,b) {
					if (a[1]<b[1]) return -1;
					if (a[1]>b[1]) return 1;
					return 0;
				});
		}
		if(type == 'city')
		{
			dump.sort(
				function (a,b) {
					if (a[0]<b[0]) return -1;
					if (a[0]>b[0]) return 1;
					return 0;
				});
		}
		var res = [];
		
		each(dump, function(item)
		{
			res.push({
				city    : item[0],
				npa     : item[1],
				stateId : item[2]
			});
		});
		this._fillSelect(res);
		
		return {city : curState.city};
	},
	
	sortByAreaCode : function(flg)
	{
		var selectedData = this._sort('area');		
		if(this._selectArea)
		{
			this._Select.setOptionAsObject(this._selectArea, 0, true);
		}
		if(!flg)
		{
			this._Select.setSelectedOptionByAttr(selectedData);
		}
	}, 
	
	
	sortByCity : function(flg)
	{
		var selectedData = this._sort('city');		
		if(this._selectCity)
		{
			this._Select.setOptionAsObject(this._selectCity, 0, true);
		}
		if(!flg)
		{
			this._Select.setSelectedOptionByAttr(selectedData);
		}
	}, 
	
	
	getDump : function()
	{
		var res = [];
		
		var l = this._Select.getOptionsLength();
		
		for(var i = 0; i < l; i++)
		{
			var opt  = this._Select.getOptionByIndex(i);
			if(opt.getAttribute('type') == 'city_list')
			{			
				res.push([
							opt.getAttribute('city'),
							parseInt(opt.getAttribute('npa')),
							parseInt(opt.getAttribute('state_id'))
						]);
			}
		}
		return res;
	},
	
	get : function()
	{
		return this._Select.get();
	},
	
	
	setStart        : function()
	{
		this._Select.selectedByIndex(0);
	},
	
	
	selectedByIndex    : function(index)
	{
		this._Select.selectedByIndex(index);
	},
	
	
	selectByAreaCode : function(npa)
	{
		this._Select.setSelectedOptionByAttr({npa : npa});
		this._onAfterChange();
	},
	
	
	selectByAreaCodeAndCityName : function(npa, city)
	{
		this._Select.setSelectedOptionByAttr({npa : npa, city : city});
		this._onAfterChange();
	},
	
	
	disabled : function(flg)
	{
		this._Select.disabled(!!flg);
	}
	
	
	
	
	
}












/*


*/

function Select_View(){
	View.call(this);
	
	this.getValue = function(){
		if(this._view){
			return this._view.value;
		}
	}
	
	this.get = function()
	{
		if(this._view)
		{
			var index = this.getSelectedOptionIndex();
			var opt   = this.getOptionByIndex(index);
			var res = {
				value : this._view.value
			};			
			for(var i = 0; i < opt.attributes.length; i++)
			{
				var attr = opt.attributes[i];
				if(attr.nodeValue)
				{
					res[attr.nodeName] = attr.nodeValue;
				}
			}
			
			return res;
		}
	}
	
	this.blur = function(){
		this._view.blur();
	}
	
	this.setOptionAsObject = function(newOpt, index, selected)
	{
		if(typeof index != 'undefined' && newOpt && newOpt.nodeName)
		{
			var opt = this.getOptionByIndex(index);
			if(opt)
			{
				this._view.insertBefore(newOpt, opt);
			}
			else
			{
				this._view.appendChild(newOpt);
			}
			if(selected)
			{				
				this.selectedByIndex(index);
			}
		}
		
		
		
	}
	
	this.setOption = function(val, attrs){
		var vOption = new View();
		vOption.setView('OPTION');
		vOption.innerHTML(val);
		if(attrs){
			for(var key in attrs){
				var arr = {};
				arr[key] = attrs[key];
				vOption.setAttr(arr);
			}
		}
		vOption.insertIn(this._view);
	}
	
	this.clear = function(){
		this.innerHTML('');
	}
	
	this.selectedByIndex = function(ind)
	{
		for(var i = 0 ; i < this._view.options.length; i++)
		{
			if(i == ind)
			{
				this._view.options[i].selected = 'true';
				return;
			}
		}
	}
	
	this.getOptionsLength = function()
	{
		return this._view.options.length;
	}
	
	this.getOptionByIndex = function(index)
	{
		return this._view.options[index]? this._view.options[index] : null;
	}
	
	this.getSelectedOptionIndex = function()
	{
		for(var i = 0 ; i < this._view.options.length; i++)
		{
			if(this._view.options[i].selected == true)
			{
				return i;
			}		
					
		}
		return null;
	}
	
	this.removeOptionByAttr = function(hash)
	{
		var opt = this.getOptionByAttr(hash);
		if(opt)
		{
			return this._view.removeChild(opt);
		}
		return null;
	}
	
	this.removeOptionAsObj = function(obj)
	{
		for(var i = 0 ; i < this._view.options.length; i++)
		{
			var opt = this._view.options[i];
			if(obj == opt)
			{
				try
				{
					return this._view.removeChild(obj);
				}
				catch(e)
				{}
			}
		}		
	}
	
	this.removeOptionByIndex = function(index)
	{
		if(typeof index != 'undefined')
		{
			if(this._view.options[index])
			{
				return this._view.removeChild(this._view.options[index]);
			}
		}
		return null;
	}
	
	this.getOptionByAttr = function(hash)
	{
		for(var i = 0 ; i < this._view.options.length; i++)
		{
			var continue_flag = false;
			var opt = this._view.options[i];
			for(var key in hash)
			{
				if(opt.getAttribute(key) != hash[key])
				{
					continue_flag = true;
					continue;
				}
			}
			if(continue_flag)
			{
				continue;
			}
			return opt;
		}
		return null;
	}
	
	
	
	this.setSelectedOptionByAttr = function(hash)
	{
		
		for(var i = 0 ; i < this._view.options.length; i++)
		{
			var continue_flag = false;
			var opt = this._view.options[i];
			for(var key in hash)
			{
				var value = opt.getAttribute(key)||'';
				//alert(i + ' ' + key + ' ' + hash[key] + ' - ' + value);
				if(!hash[key] || value.toLowerCase() != hash[key].toLowerCase())
				{
					
					continue_flag = true;
					continue;
				}				
			}
			if(continue_flag)
			{
				continue;
			}
			
			try
			{
				opt.selected = true;				
			}
			catch(e)
			{
			}
			return;
		}
		
	}
	
}

/*







*/



function View(){
	Subscriber.call(this);
	Resize.call(this);
	Base.call(this);
	Move.call(this);
	States.call(this);
	
	this._view = undefined;
	
	this.getView = function(obj){
		return this._view;
	}
	this.setViewAsClone = function(obj){
		if(is_dom(obj)){
			this.setView(obj.cloneNode(true));
		}
	}
	this.remove = function(){
		this._view.parentNode.removeChild(this._view);
	}
	this.setView = function(obj){
		if(is_dom(obj)){
			this._view = obj;
		}else{
			this._view = document.createElement(obj);
		}
	}
	this.insertIn = function(parent){
		if(is_dom(parent)){
			parent.appendChild(this._view);
		}else{
			if(parent.getView &&parent.getView()){
				parent.getView().appendChild(this._view);
			}else{
				errorMsg('View :: insertIn','Object has not View');
				return;
			}
		}
	}
	
	this.insertInBefore = function(parent,beforeObj){
		if(!is_dom(beforeObj)){
			if(beforeObj.getView && beforeObj.getView()){
				var ViewBeforeObj =  beforeObj.getView();
			}else{
				errorMsg('View :: insertInBefore','beforeObj has not View');
				return;
			}
		}else{
			var ViewBeforeObj = beforeObj;
		}
			
		if(is_dom(parent)){
			noticeMsg('View :: insertInBefore','Dodelat dejstviya v slychae is_dom')
		}else{
			if(parent.getView &&parent.getView()){
				parent.getView().insertBefore(this._view, ViewBeforeObj);
			}else{
				errorMsg('View :: insertInBefore','Parent has not View');
				return;
			}
		}
	} 
	this.none = function(){
		if(is_dom(this._view)){
			this._view.style.display = 'none';
		}
	}
	this.display = function(){
		if(is_dom(this._view)){
			this._view.style.display = (this._view.nodeName == 'IFRAME')? 'block':'';
		}
	}
	this.setStyle = function(arr){
		if(is_obj(arr)){
			for(key in arr){
				try{
					this._view.style[key] = arr[key];
				}catch(E){errorMsg('View :: setStyle',E.description +' ' + key +'-' + arr[key])}
			}
		}
	}
	this.setAttr = function(arr){
		if(is_obj(arr)){
			for(key in arr){
				this._view.setAttribute(key, arr[key]);
			}
		}
	}
	this.getAttr = function(name){
		return this._view.getAttribute(name);
	}
	this.setValue = function(val){
		this._view.value = val;
	}
	this.getValue = function(){
		return this._view.value;
	}
	this.is_visible = function(){
		return this._view.offsetWidth? true : false;
	}
	this.visibility = function(flg){
		if(this._view){
			this._view.style.visibility = flg? 'visible' : 'hidden';
		}
		return this._view.offsetWidth? true : false;
	}
	this.disabled = function(flg){
		this._view.disabled = flg;
	}
	this.setCssClassName = function(str){
		this._view.className = str
	}
	this.getCssClassName = function(str){
		return this._view.className;
	}
	this.innerHTML = function(obj){
		if(!is_oObj(obj)){
			this._view.innerHTML = obj;
		}else{
			this._view.innerHTML = '';
			obj.insertIn(this);
		}
	}
	this.getContent = function(){
		return this._view.innerHTML;
	}
	this.pasteObj = this.innerHTML;
	this.getVisualWidth  = function(){
		return this._view.offsetWidth;
	}
	this.getVisualHeight = function(){
		return this._view.offsetHeight;
	}
	this.getLeft = function(){
		return parseInt(this._view.style.left);
	}
	this.getTop = function(){
		return parseInt(this._view.style.top);
	}
	
	
	this.getStyleProp = function(propName){
		return this._view.style[propName];
	}
	this.disableSelection = function(){
		// oh ie, ie!!!!!
		window.addEvent(this._view,'onselectstart',returnFalse)
	}
	this.enableSelection = function(){
		// oh ie, ie!!!!!
		window.removeEvent(this._view,'onselectstart',returnFalse)
	}
	this.focus = function(){
		this._view.focus();
	}
	this.getElementsByTagName = function(str){
		return this._view.getElementsByTagName(str);
	}
	this.getNodeName = function(){
		return this._view.nodeName;
	}
	
	 
	
	this.setViewCopy = this.setView;
}


function Base(){
	//this._embeddingObjects =Array();

	this.getClassName = function() {
		var str = this.constructor;
		if(res = /function +(.*)\(/.exec(str))
			return res[1];
	}
}

function Resize(){
	
	var startX      = undefined;
	var startY      = undefined;
	var startWidth  = undefined;
	var startHeight = undefined;
	var resize      = false;
	
	this.startResize = function(arg){
		if(this.Event){
			oBody.disableSelection();
			startX      = this.Event.screenX;
			startY      = this.Event.screenY;
			startWidth  = this.getVisualWidth();
			startHeight = this.getVisualHeight();
			resize      = true;
		}
		return false;
	}
	
	this.resize = function(e){
		if(resize && this.Event){
			var dX = this.Event.screenX - startX;
			var tempWidth = startWidth + dX ;
			if(tempWidth > 0){
				this.setStyle({'width':tempWidth + 'px'});
			}
			
			var dY = this.Event.screenY - startY;
			var tempHeight = startHeight + dY;
			if(tempHeight > 0){
				this.setStyle({'height':tempHeight + 'px'})
			}
		}
	}
	
	this.finishResize = function(){
		if(resize){
			oBody.enableSelection();
			resize = false;
		}
	}
}

function Move(){
	
	var startX      = undefined;
	var startY      = undefined;
	var startLeft   = undefined;
	var startTop    = undefined;
	var move        = false;
	
	this.startMove = function(event){
		if(event){
			oBody.disableSelection();
			startX      = event.screenX;
			startY      = event.screenY;
			startLeft   = this.getLeft();
			startTop    = this.getTop();
			move      = true;
		}
		return false;
	}
	
	this.move = function(event){
		if(move && event){
			var dX = event.screenX - startX;
			var tempLeft = startLeft + dX ;
			this.setStyle({'left':tempLeft + 'px'});
			
			var dY = event.screenY - startY;
			var tempTop = startTop + dY;
			this.setStyle({'top':tempTop + 'px'})
		}
	}
	
	this.finishMove = function(){
		if(move){
			oBody.enableSelection();
			move = false;
		}
	}
}

function States(){
		
	this.setActive  = function(){
		this.setStyle({cursor : 'pointer'});
		this.disabled(false);
		this.setSuffixClassName('_a');
		this.setSuffixSrc('_a');
	}
	this.setPassive = function(){
		this.setStyle({cursor : 'default'});
		this.disabled(true);
		this.setSuffixClassName('');
		this.setSuffixSrc('');
	}
	this.setOver    = function(){
		this.setStyle({cursor : 'pointer'});
		this.disabled(false);
		this.setSuffixClassName('_o');
		this.setSuffixSrc('_o');
	}	
	this.setSuffixClassName = function(suf){
		var className = this.getCssClassName();
		if(!empty(className)){
			var newClassName = className.replace(/(_[^_]+)*$/,'') + suf;
			this.setCssClassName(newClassName);
		}
		return newClassName;
	}
	
	this.setSuffixSrc = function(suf){
		if(this.getNodeName() == 'IMG'){
			var src = this.getAttr('src');
			if(!empty(src)){
				var newSrc = src.replace(/(_[^_]{1})*(\.(gif|jpeg|jpg|png))$/,suf + '$2');
				this.setAttr({src : newSrc});
			}
			return newSrc;
		}
		return false;
	}	
	this.serError = function(){
		
	}
	
	
}

/*




*/


function GetListStatesJEDI(){
	AjaxTransfer.call(this);
	Subscriber.call(this);
	
	this.states;
			
	this.callBack = function(response){
		var data = response.responseArr;
		/*
			data = Array
			(
			    [spent] => 1188
			    [status] => Array
			        (
			            [code] => 0
			            [success] => 1
			        )
			
			    [result] => Array
			        (
			            [0] => Array
			                (
			                    [alive] => 
			                    [countryId] => 1
			                    [name] => Alabama
			                    [shortName] => AL
			                    [stateId] => 12
			                )
			            ......
		*/
		
		
		if(data && data.status && data.status.success == '1' && data.result && data.result.length)
		{
			this._informObservers('oncomplete', data.result);
		}
		else
		{
			this._informObservers('onfailure');
		}
		
	}
	
	
}

GetListStatesJEDI.prototype = 
{
	_static : []
}

/*



*/


function GetListLocationsJEDI(){
	AjaxTransfer.call(this);
	Subscriber.call(this);
	
	
			
	this.callBack = function(response){
		var data = response.responseArr;
		/*
			Array
			(
			    [spent] => 703
			    [status] => Array
			        (
			            [code] => 0
			            [success] => 1
			        )
			
			    [result] => Array
			        (
			            [0] => Array
			                (
			                    [city] => Georgetown
			                    [npa] => 203
			                )
                         ......
		*/
		
		if(data && data.status && data.status.success == '1')
		{
			if(data.result)
			{
				if(data.result.length)
				{
					var cities = data.result;
				}
				else
				{
					var cities = Array(data.result);
				}
				this._informObservers('oncomplete', cities);
			}
			else
			{
				this._informObservers('onempty');
			}
		}else{
			this._informObservers('onfailure');
		}
	}
	
}

/*














*/



function Select_Numbers(hash)
{
	Subscriber.call(this);
	
	
	this.__construct(hash);
}
Select_Numbers.prototype = 
{
	
	__construct : function(hash)
	{
		
		this._node       = hash.node;
		
	
		
		addEvent(this._node, 'onchange', this._onAfterChange.rcBindAsIs(this))
		this._Select     = new Select_View();
		this._Select.setView(this._node);
		
		var noAvailabe = this._Select.removeOptionByAttr({type : 'noAvailable'});
		if(noAvailabe)
		{
			this._noAvailabe = noAvailabe;
		}
		
		var wait = this._Select.removeOptionByAttr({type : 'wait'});
		if(wait)
		{
			this._wait = wait;
		}
		
		var selectArea = this._Select.removeOptionByAttr({type : 'select_area'});
		if(selectArea)
		{
			this._selectArea = selectArea;
		}
		
		var selectCity = this._Select.removeOptionByAttr({type : 'select_city'});
		if(selectCity)
		{
			this._selectCity = selectCity;			
		}
		
		if(this._selectArea)
		{
			this._Select.setOptionAsObject(this._selectArea, 0, true);
		}
		
		this._proxy_url  = hash.proxy_url;
		
	
	},
	
	
	loadNumbers : function(hash)
	{
		
		this._Select.disabled(true);
		
		if(this._wait)
		{
			this._Select.setOptionAsObject(this._wait, 0, true);
		}
		
	
		this._informObservers('onBeforeLoading');
		this._type = hash.type;
		this._informObservers('onBeforeLoading');
		var Ajax = new GetNumbersJEDI();
		var arr =     {
							'url'           : this._proxy_url,
							repeatOnFailure : 1,
							data  : hash
					 };
		
		
		Ajax.setData(arr);
		Ajax.sendPost();		
			
		
		Ajax.setObserver('onempty'    , this._onfailureGetNumbers.rcBindAsIs(this));							
		Ajax.setObserver('onfailure'  , this._onfailureGetNumbers.rcBindAsIs(this));
		Ajax.setObserver('oncomplete' , this._oncompleteGetNumbers.rcBindAsIs(this));
	
		
	},	
	
	
	
	_onfailureGetNumbers : function()
	{
		if(this._noAvailabe)
		{
			this._Select.setOptionAsObject(this._noAvailabe, 0, true);
		}
		this._informObservers('onFailure');
	},
	
	
	_oncompleteGetNumbers : function(numbers)
	{
		/*
			numbers = Array
			(
			    [0] => Array
			        (
			            [formattedNumber] => 0151 808 0157
			            [number] => 441518080157
			        )
			    ....
		*/
		
		this._fillSelect(numbers);		
		
		
		setTimeout(this._informObservers.rcBindAsIs(this, 'onComplete'), 10);
		
		
		
			
	},
	
	
	_removeInfoOptions : function()
	{
		if(this._wait)
		{
			this._Select.removeOptionAsObj(this._wait);
		}
		
		if(this._noAvailabe)
		{
			this._Select.removeOptionAsObj(this._noAvailabe);
		}
		
		if(this._selectArea)
		{
			this._Select.removeOptionAsObj(this._selectArea);
		}
		
		if(this._selectCity)
		{
			this._Select.removeOptionAsObj(this._selectCity);
		}
		//this._informObservers('onInsertCity');
	},
	
	
	_fillSelect : function(numbers)
	{
		this._removeInfoOptions();
		this._Select.clear();
		
		each(numbers, function(number, i)
		{			
			
			this._Select.setOption(number.formattedNumber, 
			{
				number           : number.number,
				formatted_number : number.formattedNumber
			});
		}, this);
		
		this._Select.disabled(false);
	},
	
	
	_onAfterChange : function()
	{
		
		var res = this._Select.get();
		/*
			res = Array
			(
			    [value] => 860 - Norwich
			    [city] => Norwich
			    [npa] => 860
			)	   
		*/
		if(typeof res.number != 'undefined')
		{
			this._informObservers('onChangeNumber', res);
		}
		else
		{
			this._informObservers('onDefaultState');
			this._informObservers('onDefault');
		}
	},
	
	setDefault : function()
	{
		this._Select.disabled(true);
		this._Select.selectedByIndex(0);
	},		
	
	
	get : function()
	{
		var numberInfo = this._Select.get();
		/*
			Array
			(
			    [formatted_number] => 01223 790 050
			    [number] => 441223790050
			)
		*/
		return {
					typeNumber      : this._type,
					number          : numberInfo.number,
					formattedNumber : numberInfo.formatted_number
				};		
	},
		
	
	disabled : function(flg)
	{
		this._Select.disabled(!!flg);
	}
	
	
	
	
}










