
var MxTable={
    IssUrl: '/issrpc/marketdata'
};

MxTable.Shield=Mx.Shield;

MxTable.Spread=Class.create();
MxTable.Spread.prototype = {
    default_fieldsMeta: [
        { id: "#NUM#",      title: "№",                  short_title: "№", type: 'string'} ,
        { id: "SHORTNAME",  title: "Краткое наименование", short_title: "Наименование" , is_ordered: 'true' , type: 'string'} ,
        { id: "SECID",      title: "Название инструмента", short_title: "Инструмент" ,   is_ordered: 'true' , type: 'string'} ,
        { id: "BOARDID",    title: "Режим",              short_title: "Режим" , type: 'string'} ,
        { id: "BID",        title: "Спрос",               short_title: "Спрос" , type: 'number'} ,
        { id: "OFFER",      title: "Предложение",         short_title: "Предложение" , type: 'number'} ,
        { id: "LAST",       title: "Последняя",           short_title: "Последняя" ,   trend_by: "LASTCHANGEPRCNT" ,
                            is_ordered: 'true' , type: 'number'} ,
        { id: "LASTCHANGEPRCNT",  title: "Изменение цены последней сделки к цене предыдущего дня, %",
                            short_title: "Изменение к цене пред. дня, %" ,             trend_by: "LASTCHANGEPRCNT" ,
                            is_ordered: 'true' ,
                            has_percent: 'true' ,
                            is_signed: 'true' , type: 'number'} ,
        { id: "VALTODAY",   title: "Объем за сегодня",           short_title: "Объем за сегодня" , is_ordered: 'true' , type: 'number'} ,
        { id: "UPDATETIME", title: "Время последнего обновления", short_title: "Время" ,           is_ordered: 'true' , type: 'time'}
    ],

    initialize: function(holder, header, table, footer, options) {

            this._is_digit=/^\s?(\-|\+)?[0-9]+\.?[0-9]*\s?$/;

            this.setOptions(options);

            this.holder = $(holder);

            this.holder.appendChild(Builder.node('div', {id: 'table-console'},''));

            this.header = $(header);
            this.table  = $(table);

            this.footer = $(footer);

            this.current_page=1;
            this.pages=0;

            this.sort_order_counter=0;

            this._makeTabelHeader();
            if($(this.options).shield){
                if($(this.options.shield) && !($(this.options.shield) instanceof MxTable.Shield)){
                    this.shield=new MxTable.Shield($(this.options.shield));
                    $(this.shield).setOptions({parent: $(this.holder)});
                }
                else if($(this.options.shield) instanceof MxTable.Shield){
                    this.shield=$(this.options.shield);
                    $(this.shield).setOptions({parent: $(this).holder});
                }
            }

            $(this.holder).makePositioned();

            this.lock_count=0;
            this.last_response_time = {};

            this._retriesReset();

            this.cookies = new Mx.Cookies();
    },

    hide: function(){
        Effect.Fade(this.holder, {duration: 0.2});
    },

    setOptions: function(options) {
        this.options = $H({

            shield:          $('table-shield'),

            hideThead:       false,

            pager:           $('pager'),
            pagerPrev:       $('pager-prev'),
            pagerNext:       $('pager-next'),
            pagerList:       $('pager-list'),
            verticalBar:     $('vertical-bar'),
            rowCount:        $('table-row-count'),

            downloader:      $('table-downloader'),
            maxDownloadRows: 10000,

            responseWarn:     undefined,

            linked:            '',
            selectedPage:      'selected',
            selectedBearField: 'selectedbear',
            selectedBulField:  'selectedbul',
            unselectable:      true,
            column:            '',
            row:               '',
            leftColumn:        '',
            rightColumn:       '',
            onClickColumn:     'shortname',
            rowIndexColumn:    'position',

            sortOrderAction:   'action',
            sortOrderField:    undefined,
            sortOrderDesc:     undefined,
            sortOrderOverList: undefined,
            sortOrderOverKeys: ['BOARDID','SECID'],

            noLinked:          'disabled',
            selectedRow:       'selected',
            firstRow:          'first',

            onClickField:      undefined,
            rowIndex:          ['BOARDID','SECID','TRADEDATE'],

            amountClass:       'amount',
            numberClass:       'value',
            stringClass:       '',
            timeClass:         'time',
            deltaClass:        'delta',
            upClass:           'up',
            downClass:         'down',
            stayClass:         'stay',

            fieldsMeta:    this.default_fieldsMeta,

            customHandlers: {},

            pagerLength:   10,
            limit:         10,//rows
            refreshTime:   0, //seconds
            url:           '/issrpc/marketdata/stock/shares/daily/preview/result.json',
            countUrl:      '/issrpc/marketdata/count/daily/result.json',
            downloadUrl:   '/issrpc/marketdata/stock/shares/daily/preview',
            preloadData:   undefined,
            preloadMarker: undefined,
            preloadCount:  undefined,

            retriesLimiter:  5,

            passportMarker:  'X-MicexPassport-Marker',
            passportInfoBar: undefined,

            parameters:     {collection_id: 12, board_group_id: 6},

            issParameters:  {market: 'shares', trade_engine: 'stock'},

            onOrder: function(){
                this._remakeNavigator(1);
                return true;
            },

            onSelect: function(){
                return true;
            },

            onClick: function(){
                return true;
            },

            beforeSelect: function(){
                this.suspend();
                this.lock();
                return true;
            },

            afterSelect: function(){
                this.unlock();
                this.resume();
                return true;
            },

            onPage: function(){
                return true;
            },

            onLoad: function(){
                return true;
            },

            onFailureLoad: function(transport){
                return true;
            }

        }).merge(this.options);
        this.options.merge(options);
        this.sort_order_field=this.options.sortOrderField;
        this.sort_order_desc=this.options.sortOrderDesc;
        this.on_click_field=this.options.onClickField;

        if(!this.sort_order_field || !this.sort_order_desc || !this.on_click_field){
            this.options.fieldsMeta.each(function(f){
                if(f.is_default_sort) this.sort_order_field=(this.sort_order_field||f.id)||'';
                if(f.sort_order) this.sort_order_desc=(this.sort_order_desc||f.sort_order)||'';
                if(f.is_linked) this.on_click_field=(this.on_click_field||f.id)||'';
            }.bind(this));
        }

        this.on_click_fields=$A([]);
        try{
            this.on_click_field.scan(/\w+/, function(match){ this.on_click_fields.push(match[0])}.bind(this));
        }catch(e){}
        if(!this.on_click_fields) this.on_click_fields.push[''];
    },


    _startUpdater: function(){
        if(!this.periodical_updater){
            if(this.options.refreshTime>0)
                this.periodical_updater=new PeriodicalExecuter( function(pe){
                        this._loadAjaxData();
                    }.bind(this),
                    this.options.refreshTime * this._retriesMultiplier()
                );
        }
    },

    _stopUpdater: function(){
        if(this.periodical_updater){
            this.periodical_updater.stop();
            this.periodical_updater=undefined;
        }
    },

    run: function(){
            this._loadAjaxData();
            this._startUpdater();
    },

    suspend: function(){
        this._stopUpdater();
    },

    resume: function(){
        if(!this.links){
            if(this.table_body) this.links = $(this.table_body).getElementsBySelector('a[name]','td[name]');
            this._observe();
        }
        this._startUpdater();
    },

    clear: function(){
        this.suspend();
        this.current_page=1;
        $(this.table).getElementsBySelector('thead').each(function(th){
            $(th).up().removeChild(th); delete th;
        });
        this._clearTable();
        if(this.footer) $(this.footer).hide();
        if(this.options.verticalBar) this.options.verticalBar.setStyle({width: '0px', height: '0px'});
    },

    reload: function(){
        try{
            this.current_page=1;
            this.pages=0;
            this.last_response_time = {};
            this.lock_count=0;
            this.suspend();
            this.lock();
            this.current_page=1;
            this.header_columns=undefined;
            this._deleteAllPageLinks();
            this._makeTabelHeader();
            this.table_body=undefined;
            this._loadAjaxDataRowCount(true);
            this._loadAjaxData();
            this.resume();
        }catch(e){alert('reload:'+e);}
    },

    update: function(){
        this._loadAjaxData();
        this.resume();
    },

    lock: function(){
    	this.lock_count++;
        if(this.shield && this.table_body && this.lock_count>=0) this.shield.show();
    },
    unlock: function(){
        if(this.lock_count>=0) {this.lock_count--;
        if(this.shield && this.lock_count<=0) this.shield.hide();}
    },

    _observeHeader: function(){
        this.onClickHeaderListener = this.onClickHeaderListener || this.onClickHeader.bindAsEventListener(this);
        $A(this.headerLinks).invoke('observe', 'click', this.onClickHeaderListener);
    },

    _makeTabelHeader: function(){

        if(!this.header_columns){
            $(this.table).getElementsBySelector('thead').each(function(th){
                $(th).up().removeChild(th); delete th;
            });


            if(this.options.hideThead){
                this._resizeBar(true);
                return ;
            }

            $(this.table).appendChild((this.table_head=Builder.node('thead', (this.header_columns = Builder.node('tr')))));

            $(this.options.fieldsMeta).each(function(c,ci) {
                var order_class='';

                if (c.id==this.sort_order_field){
                    if(this.sort_order_desc=='desc')
                        order_class=this.options.selectedBulField;
                    else
                        order_class=this.options.selectedBearField;
                }

                var th=Builder.node('th',{'title': c['title']||''});

                $(th).addClassName(order_class);

                if(c.id=='#NUM#')
                    $(th).addClassName(this.options.rowIndexColumn);

                else //if(c.id==this.on_click_field)
                    if(this.on_click_fields.include(c.id))
                    $(th).addClassName(this.options.onClickColumn);

                else if(c.type=='time')
                    $(th).addClassName(this.options.timeClass)
                else if(c.type=='string')
                    $(th).addClassName(this.options.stringClass)
                else if(c.type=='number')
                    $(th).addClassName(this.options.numberClass)
                else
                    $(th).addClassName(this.options.numberClass);

		if (c.customClass)
		    $(th).addClassName(c.customClass);

                if(ci==0)
                    $(th).addClassName(this.options.leftColumn);
                else if(ci==($A(this.options.fieldsMeta).length-1))
                    $(th).addClassName(this.options.rightColumn);

                if(c['is_ordered']){
                    a=Builder.node('a',
                        {'href':  '#',
                        'name':  'order_field',
                        'id':    $(this.table).id+'-field-order-by-'+c['id']
                        },
                        c['short_title']||''
                    );
                    $(a).addClassName($(this.options).sortOrderAction);
                    $(th).appendChild(a);
                }
                else{
                    $(th).innerHTML=c['short_title']||'';
                }
                this.header_columns.appendChild($(th));

            }.bind(this));

            this.headerLinks = $(this.table_head).getElementsBySelector('a[name]');
            this._observeHeader();
        }
        else{
            $(this.header_columns).getElementsBySelector('th').each(function(th) {
                var a=th.down();
                th.removeClassName(this.options.selectedBulField);
                th.removeClassName(this.options.selectedBearField);
                if(a && a.id==$(this.table).id+'-field-order-by-'+this.sort_order_field){
                    if(this.sort_order_desc=='desc')
                        th.addClassName(this.options.selectedBulField);
                    else
                        th.addClassName(this.options.selectedBearField);
                }
            }.bind(this));
        }
        this._resizeBar(true);
    },

    setUrl: function(helper){
        this.options['url']=helper;
    },

    setParameters: function(parameters){
        this.options['parameters']=parameters;
    },

    _observe: function() {
        this.onClickListener = this.onClickListener || this.onClick.bindAsEventListener(this);
        $A(this.links).invoke('observe', 'click', this.onClickListener);
    },

    _stopObserve: function() {
        $A(this.links).invoke('stopObserving', 'click', this.onClickListener);
        delete this.links; this.links=undefined;
    },


    _toSiteString: function (cell,prec){
        if (this._is_digit.test(new String(cell))){
            return new Number(cell).toSiteString(prec);
        }
        return cell;
    },

    _linkID: function(obj){
        return $A(this.options.rowIndex).collect(function(e,index){ return new String((obj[e]||'undefined')).unescapeHTML().gsub('&#x0026;','&');  }).join(':').sub(':$','');
    },

    _selectedRowID: function(){
        if (!this.selected_row) return undefined;
        var h=$H(this.selected_row);
        var id  = h['boardid'] + ':' + h['secid']+':'+h['tradedate'];
        return id;
    },

    _rowID: function(id){
        var splited_id=new String(id).split(':'); id=splited_id[0]+':'+splited_id[1]+':'+splited_id[2];
        return id;
    },



    _processRow: function(_td, ri, ci, c, row, rownum){
        var td=$(_td);
        var inner_object=td;


        //if(c.id==this.on_click_field){
         if(this.on_click_fields.include(c.id)){
            td.addClassName(this.options.onClickColumn);
            if(!td.innerHTML){
                td.setAttribute('name','load_info_cell');
                td.setStyle({cursor: 'pointer'});
            }
            td.getElementsBySelector('a').each(function(e){
                $(e).up().removeChild(e);
            });
            td.appendChild((inner_object=Builder.node('a', {name: 'load_info', id: this._linkID($(row)), href: '#'})));
        }

        td.addClassName(this.options.column);
        if(c.id=='#NUM#'){
            inner_object.innerHTML=rownum;
            td.addClassName(this.options.rowIndexColumn);
        }
        else{

    	    if(c.customClass)
    		td.addClassName(c.customClass);

            if(c.is_datetime){
                td.addClassName(this.options.timeClass);
                inner_object.innerHTML= new Date().fromDbString(row[c.id]).toSiteDateString();
            }
            else if(c.type=='time'){
                td.addClassName(this.options.timeClass);
                inner_object.innerHTML= row[c.id];
            }
            else if(c.type=='date'){
                td.addClassName(this.options.timeClass);
                inner_object.innerHTML= new Date().fromDbString(row[c.id]).toSiteDateString();
            }
            else{
                if (c.type=='number'){
                    var decimals=(c.has_percent?2:(row['DECIMALS']?row['DECIMALS']:4));
                    var value_src=new Number(row[c.id]).toFixed(decimals);
                    var value= this._toSiteString(row[c.id],decimals);

                    if(!value)
                        value='-';

                    var inner_object_old=inner_object.innerHTML;

                    inner_object.innerHTML='<nobr>'+
                        (c.is_signed?(value_src>=0?(value_src==0?'':'+'):''):'')+
                        value+
                        (c.has_percent?(value!='-'?'%':''):'')+'</nobr>';

                    td.addClassName(this.options.numberClass);

                    var trend=value_src;
                    if (c.trend_by!=c.id){
                        td.removeClassName(this.options.deltaClass);
                        td.addClassName(this.options.amountClass);
                        trend=new Number(row[c.trend_by]).toFixed(decimals);
                    }
                    else{
                        td.removeClassName(this.options.amountClass);
                        td.addClassName(this.options.deltaClass);
                    }
                    if (c.trend_by) {
                    	if(trend>0){
	                        td.removeClassName(this.options.downClass);
                        	td.removeClassName(this.options.stayClass);
                        	td.addClassName(this.options.upClass);
                        	if(inner_object_old!=inner_object.innerHTML)
                        		new Effect.Highlight(td, {
                        			duration: 1.0,
                        			startcolor: '#3488B1',
                        			opacity:.5,
                        			afterFinish: function() {
                        				this.setStyle({'background-color': ''});
                        			}.bind(td)
                        		});
                    	}
                    	else if(trend<0){
	                        td.removeClassName(this.options.upClass);
                        	td.removeClassName(this.options.stayClass);
                        	td.addClassName(this.options.downClass);
                        	if(inner_object_old!=inner_object.innerHTML)
                        		new Effect.Highlight(td, {
                        			duration: 1.0,
                        			startcolor: '#3488B1',
                        			opacity:.5,
                        			afterFinish: function() {
                        				this.setStyle({'background-color': ''});
                        			}.bind(td)
                        		});
                    	}
                    	else{
	                        td.removeClassName(this.options.downClass);
                        	td.removeClassName(this.options.upClass);
                        	td.addClassName(this.options.stayClass);
                    	}
                    }
                }
                else {
                    td.addClassName(this.options.stringClass);
                    inner_object.innerHTML= row[c.id]?new String(row[c.id]).replace(/&(?!(#x\d+;|amp;))/g,'&amp;'):'-';
                }
            }

            if(this.options.customHandlers[c.id])
                this.options.customHandlers[c.id](_td, ri, ci, c, row, rownum, this);
        }
        if(ci==0)
            td.addClassName(this.options.leftColumn);
        else if(ci==($A(this.options.fieldsMeta).length-1))
            td.addClassName(this.options.rightColumn);
        if(ri==0)
            td.addClassName(this.options.firstRow);
        return td;
    },

    _clearTable: function(){
        this.links=undefined;
        $(this.table).getElementsBySelector('tbody').each(function(tb){
            $(tb).up().removeChild(tb); delete tb;
        });
        this.table_body=undefined;
    },


    _sortByOverList: function(data){
        var new_data=$A();
        this.options.sortOrderOverList.each(function(e){
            try{
            data.each(function(d){
                var k=(new String(d[this.options.sortOrderOverKeys[0]])+':'+new String(d[this.options.sortOrderOverKeys[1]]));
                /*string.unescapeHTML() - dosn't work in Chrome/IE :(*/
                if(k.gsub('&#x0026;','').gsub('&','')==e.gsub('&#x0026;','').gsub('&','')) {
                    new_data.push(d);
                }
            }.bind(this));
            }catch(e){}
        }.bind(this));
        return new_data;
    },

    _processAjaxData: function(json){

        this.isEmpty=false;
        var data = json.shift(); data=json;

        this._loadAjaxDataRowCount();

        if($A(data).size()==0 || !$A(data)[0]/*fix IE*/){
            $(this.table).hide();
            this.footer?$(this.footer).hide():{};
            if(this.options.responseWarn) $(this.options.responseWarn).show();
            this.isEmpty=true;
            if((this.options.onLoad || Prototype.emptyFunction).bind(this)()){
                this.unlock();
            }
            return;
        }

        if(!this.table_body){
            this._clearTable();
            this.table_body=Builder.node('tbody');
            $(this.table).appendChild(this.table_body);
        }

        var handleOnSelect=false;

        if(this.options.sortOrderOverList) data=this._sortByOverList(data);


        data.each(function(row,row_index){
            var num=(this.current_page-1)*this.options.limit+1+row_index;
            var rkey=this._rowID(this._linkID(row));
            var trid='tr-'+$(this.table).id+'-'+row_index;
            var tr=$(trid);

            if(!tr){

                $(this.table_body).appendChild((tr=Builder.node('tr', {id: trid, className: this.options.row})));
                $A(this.options.fieldsMeta).each(function(c,column_index){
                    var title_op=row['title0xf00'+c.id];
                    title_op=this.options.hideThead?{title: title_op?title_op:c.title?c.title:''}:'';
                    $(tr).appendChild(this._processRow(Builder.node('td', title_op), row_index, column_index,c,row,num));
                }.bind(this));
                handleOnSelect=true;

                $(tr).addClassName(row_index%2?'even':'odd');
            }
            else
                $(tr).getElementsBySelector('td').each(function(td,column_index){
                    this._processRow(td,row_index, column_index,this.options.fieldsMeta[column_index],row,num);
                }.bind(this));

            $(tr).setAttribute('key', rkey);

            if(this.selectedRowIndex==num-1){
                this.selected_row=this._getIdByRowIndex();
                this.selectedRowIndex=undefined;
                handleOnSelect=true;
            }

            $(tr).removeClassName(this.options.selectedRow);
            if(rkey!='undefined:undefined:undefined' && rkey==this._rowID(this._selectedRowID()))
                $(tr).addClassName(this.options.selectedRow);

			if(row['market']!=undefined){
				tr.setAttribute('market', row['market'])
			}

            //if(row[this.on_click_field])
            if(row[this.on_click_fields[0]])
                $(tr).setAttribute('name', row[this.on_click_fields[0]]);

        }.bind(this));

        this._makeDownLoader();

        if((this.options.onLoad || Prototype.emptyFunction).bind(this)()){
            this.resume();
            this.unlock();
        }

        if(!$(this.holder).visible())  Effect.Appear($(this.holder), {duration: 0.3});

        if(!$(this.table).visible())  $(this.table).show();

        if(this.options.responseWarn && $(this.options.responseWarn).visible()) Effect.Fade($(this.options.responseWarn), {duration: 0.2});


        if(handleOnSelect && this.selected_row){
            var eid=this._selectedRowID();
            $(this.table_body).getElementsBySelector('tr').each(function(tr){
                if(this._rowID(eid)==$(tr).readAttribute('key')){
                    var title=$(tr).readAttribute('name');
                    var selected_=new String(eid).split(':');
                    this.selected_row=$H({boardid: selected_[0], secid: selected_[1], tradedate: (selected_[2]=='undefined'?undefined:selected_[2]), trade_engine: this.options.issParameters.trade_engine, market: this.options.issParameters.market, title: title});
                }
            }.bind(this));

            (this.options.beforeSelect || Prototype.emptyFunction).bind(this)();
            (this.options.onSelect || Prototype.emptyFunction).bind(this)();
            (this.options.afterSelect || Prototype.emptyFunction).bind(this)();
        }

        this._resizeBar();
    },

    _resizeBar: function(no_show){
        this.options.verticalBar?$(this.options.verticalBar).setStyle({height: $(this.table).getHeight() + 'px'}):{};
        if(!no_show)
            this.footer?$(this.footer).show():{};
    },
    
    _loadAjaxData_complete: function(transport, json){
        try{
    	    
    	    this.last_response_time.data=new Date().getTime();

            this.passport_marker=this.data_request.getHeader(this.options.passportMarker);

	    if(this.options.passportInfoBar && transport.status==200) {
    	        if( this.passport_marker=='denied') this.options.passportInfoBar.show();
        	else this.options.passportInfoBar.hide();
            }

	    if(!json){
    	        json = transport.responseText.evalJSON(false);
            }

	    if(!json)
    	        throw 'Errors evaluating json';

            this._processAjaxData(json);
		this._retriesReset()

        }catch(e){
            alert(e);
            throw e;
            if(this.options.responseWarn){
                Effect.Appear($(this.options.responseWarn), {duration: 0.2});
                Effect.Fade($(this.table), {duration: 0.2});
            }
            else
                throw e;
        }
    },

    _loadAjaxData: function(){
        try{
        if(this.options.url){
            if( this.options.refreshTime>0 && (new Date().getTime() - (this.last_response_time.data || 0)) < this.options.refreshTime*1000)
                return;

            this.suspend();

            var parameters=$H(new Hash(this.options.parameters));

            parameters.merge({
                limit: $(this.options.limit),
                start: new Number(this.current_page-1).valueOf()*this.options.limit
            });

            if(this.sort_order_field)
                parameters['sort_order']=this.sort_order_field;
            if(this.sort_order_desc)
                parameters['sort_order_desc']=this.sort_order_desc?this.sort_order_desc:'';

            if(LC_LANG)
                parameters['lang']=LC_LANG;

            if(!this.options.preloadData)
            {
                this.data_request = new Ajax.Request(this.options.url, {
                    method: 'get',
                    parameters: parameters,
                    onComplete: function(transport, json) {
                        
                        setTimeout(function(){this._loadAjaxData_complete(transport,json)}.bind(this,transport, json), 100);
                        
                    }.bind(this),

                    onFailure: function(transport){
                        alert ("table.ajax.failure");
                    try{
						if (this._retryOnServerFailure(transport))
							return;
                        this.isEmpty=true;
                        (this.options.onFailureLoad || Prototype.emptyFunction).bind(this)(transport);
                    }catch(e){alert('_loadAjaxData:'+e);}
                    }.bind(this)

                });
            }
            else{
                this._processAjaxData(this.options.preloadData);
                if(this.options.passportInfoBar){
                    if(this.options.preloadMarker[this.options.passportMarker]=='denied') this.options.passportInfoBar.show();
                    else this.options.passportInfoBar.hide();
                }
                this.options.preloadData=undefined;
            }
        }
        }catch(e) {       }
    },

	_retryOnServerFailure: function(transport){
		if (this.options.retriesLimiter == 0 || transport.status != 500)
			return false;

		this._retriesCounter += 1;

		if ((this.options.retriesLimiter!=-1) && (this.options.retriesLimiter <= this._retriesCounter))
			return false;

		this.resume();
		return true;
	},

	_retriesMultiplier: function(){
		return this._retriesCounter+1;
	},

	_retriesReset: function(){
		this._retriesCounter = 0;
	},

    _parametersMerge: function (parameters){
        if(this.options.data_type=='history'){
            if(this.options.date)
                parameters.merge({
                    date_from: this.options.date,
                    date_till: this.options.date
                });
            else if(this.options.date_from && this.options.date_till)
                    parameters.merge({
                        date_from: this.options.date_from,
                        date_till: this.options.date_till
                    });

            parameters.merge({
                    boardid: this.options.boardid,
                    secid: this.options.secid
            });
        }
        return parameters;
    },

    _currentPager: function(){
        return new Number(Math.ceil(this.current_page/this.options.pagerLength-1)*this.options.pagerLength+1);
    },

    _replaceClassName: function(element,oldclass,newclass){
        element.removeClassName(oldclass);
        element.addClassName(newclass);
    },

    _observeNavigator: function(){
        this.onClickNavigatorListener = this.onClickNavigatorListener || this.onClickNavigator.bindAsEventListener(this);
        $A(this.navigatorLinks).invoke('observe', 'click', this.onClickNavigatorListener);
    },

    _deleteAllPageLinks: function(){
        if(this.options.pagerList){
             if($(this.navigatorLinks)) $A(this.navigatorLinks).invoke('stopObserving', 'click', this.onClickNavigatorListener);
            $(this.options.pagerList).getElementsBySelector('li').each(function(e){
                $(this.options.pagerList).removeChild(e); delete e;
            }.bind(this));
         }
        this.navigatorLinks=undefined;
    },

    _clearNavigator: function(new_page){

        var current_pager=this._currentPager();

        if(new_page<(current_pager) || new_page>=current_pager+this.options.pagerLength){
            this._deleteAllPageLinks();
            return true;
        }
        return false;
    },

    _remakeNavigator: function (new_page){

        if(!$(this.options.pagerList)) return false;

        if(this.pages<=1) {
            $(this.options.pager).hide();
            return false;
        }

        if(this._clearNavigator(new_page)){
            delete this.navigatorLinks; this.navigatorLinks=undefined;
            this.current_page=new Number(new_page).valueOf();
            this._makeNavigator();
            return true;
        }

        this.current_page=new_page;

        $(this.options.pagerPrev).name=this.current_page-1;
        $(this.options.pagerNext).name=this.current_page+1;

        if(new Number($(this.options.pagerPrev).name).valueOf()==0){
            $(this.options.pagerPrev).className=this.options.noLinked;
        }
        else
            $(this.options.pagerPrev).className=this.options.linked;
        if(new Number($(this.options.pagerNext).name).valueOf()>this.pages){
            $(this.options.pagerNext).className=this.options.noLinked;
        }
        else
            $(this.options.pagerNext).className=this.options.linked;

        $(this.options.pagerList).getElementsBySelector('li').each(function(e){

            var epage=e.readAttribute('name');

            if(this.current_page==epage){

                $(e).addClassName(this.options.selectedPage);
                $(e).getElementsBySelector('a').each(function(a){ a.className=this.options.noLinked; }.bind(this));
            }
            else{
                $(e).className=this.options.linked;
                $(e).getElementsBySelector('a').each(function(a){ a.className=this.options.linked; }.bind(this));
            }
        }.bind(this));

        return true;
    },

    _makeNavigator: function(){

        if(this.pages<=1){
            $(this.options.pager).hide();
            return ;
        }
        else $(this.options.pager).show();

        var pagerlist=$(this.options.pagerList);
        var current_pager=this._currentPager();

        $(this.options.pagerPrev).name=this.current_page-1;
        $(this.options.pagerNext).name=this.current_page+1;

        if(this.current_page>1) $(this.options.pagerPrev).className=this.options.linked;
        else                    $(this.options.pagerPrev).className=this.options.noLinked;

        if(this.current_page<this.pages)  $(this.options.pagerNext).className=this.options.linked;
        else                    $(this.options.pagerNext).className=this.options.noLinked;


        if (current_pager>1){
            var a=Builder.node('a', {href: '#', name: current_pager-1}); a.innerHTML='&hellip;';
            pagerlist.appendChild(Builder.node('li', {name: current_pager-1}, a));
        }

        for(var i=current_pager, icount=1; i <= this.pages &&  icount<=(this.options.pagerLength+1); i++, icount++){
            var li = Builder.node('li', {name: i}), a;

            if(icount<=this.options.pagerLength){
                a   = Builder.node('a', {href: '#', name: i});
                a.innerHTML=i;
            }
            else{
                a   = Builder.node('a', {href: '#', name: i});
                a.innerHTML='&hellip;';
            }
            if (this.current_page==i){
                $(li).addClassName(this.options.selectedPage);
                $(a).addClassName(this.options.noLinked);
            }

            li.appendChild(a);
            pagerlist.appendChild(li);
        }

        if(!this.navigatorLinks){
            this.navigatorLinks = $(this.options.pager).getElementsBySelector('a[name]','li[name]');
            this._observeNavigator();
        }

        return this.options.pagerList;
    },

    _processNavigator: function(json){
        try{
            var data = json.shift(); data=json;

            this.rowCount=new Number(data[0]['COUNT']);
        }catch(e){
            this.rowCount = json
        }

        $(this.options.rowCount)?this.options.rowCount.innerHTML=this.rowCount:{};

        this.pages=new Number(Math.ceil(this.rowCount/this.options.limit));

        if(this.pagerList)
            this._deleteAllPageLinks();

        this.pagerList=this._makeNavigator();
    },

    _loadAjaxDataRowCount: function(doit){
        if(!this.options.countUrl || !this.options.pager)
            return;

        if(!doit){
            if(this.footer && $(this.footer).visible())
                return;
        }else if(this.footer && $(this.footer).visible()){
            delete this.navigatorLinks; this.navigatorLinks=undefined;
            this.current_page=1;
        }

        var parameters=$H(new Hash(this.options.parameters));

        parameters=this._parametersMerge(parameters);

        parameters.merge(this.options.issParameters);

        delete parameters['start'];
        delete parameters['limit'];

        if( this.options.refreshTime>0 && (new Date().getTime() - (this.last_response_time.count || 0)) < this.options.refreshTime*1000)
            return;

        if(!this.options.preloadCount)
            new Ajax.Request(this.options.countUrl, {
                method: 'get',
                parameters: parameters,
                onComplete: function(transport,json){
                    try{

                        this.last_response_time.count=new Date().getTime();

                        if(!json){
                            json = transport.responseText.evalJSON(false);
                        }
                        if(!json)
                            throw 'Errors evaluating json';

                        this._processNavigator(json);

                    }catch(e){
                        if(this.options.responseWarn){
                            Effect.Appear($(this.options.responseWarn), {duration: 0.2});
                            Effect.Fade($(this.table), {duration: 0.2});
                        }
                        else
                            alert('_loadAjaxDataRowCount: '+e);
                    }
                }.bind(this)
            });
        else{
            this._processNavigator(this.options.preloadCount);
            this.options.preloadCount=undefined;
        }
    },

    _dateAsFileName: function(){

        var current_date=undefined;
        if(this.options.parameters['date'])
            current_date=new String(this.options.parameters['date']).replace('-','_','g');
        else if(this.options.parameters['date_from'] && this.options.parameters['date_till'])
            current_date=new String(this.options.parameters['date_from']).replace('-','_')+'-'+new String(this.options.parameters['date_till']).replace('-','_','g');
        else
            current_date=new Date().toFileNameString();
        return current_date;
    },

    _downloadParameters: function(){
        var parameters=$H({}).merge(new Hash(this.options.parameters));

        parameters.merge(this._parametersMerge($H(
                {
                    start: 0,
                    limit: this.options.maxDownloadRows
                })
         ));

        return parameters;
    },


    _makeDownLoader: function(){

         if(!this.options.downloader) return ;

	try {

        var current_date=this._dateAsFileName();
        var csv_settings_string = this.cookies.get("Micex.CSVSettings");

	var csv_settings = $H();

	if (csv_settings_string)
	    csv_settings = csv_settings_string.toQueryParams();

        $(this.options.downloader).getElementsBySelector('a').each(function(a){

	    if (a.name != '')
	    {
        	var helper   =this.options.downloadUrl+'/micex_'+this.options.issParameters.trade_engine+'_'+this.options.issParameters.market+'_'+current_date+'.'+a.name;

        	var parameters = this._downloadParameters();
        	parameters['lang'] = LC_LANG;
        	parameters.merge(csv_settings);

        	a.href=helper+'?'+parameters.toQueryString();
    	    }
        }.bind(this));
        }
        catch(e) {alert(e);}
    },

    onClickHeader: function(e){

        this.suspend();
        this.lock();

        Event.stop(e);

        this.last_response_time = {};

        var element=Event.element(e);
        var na=element.readAttribute('name');

        this.table_body=undefined;

        var current_order_field=element.id.split($(this.table).id+'-field-order-by-')[1];

        if (current_order_field!=this.sort_order_field){
            this.sort_order_counter=0;
            this.sort_order_desc='desc';
            this.sort_order_field=current_order_field;
        }
        /*if(this.sort_order_counter==2){
            if(this.sort_order_field==this.options.sortOrderDesc)
                this.sort_order_desc=this.sort_order_desc==this.options.sortOrderDesc?undefined:this.options.sortOrderDesc;
            else
                this.sort_order_desc=this.options.sortOrderDesc;
            this.sort_order_field=this.options.sortOrderField;
            this.sort_order_counter=0;
        }*/
        else{
            this.sort_order_counter++;
            this.sort_order_field=current_order_field;
            this.sort_order_desc=(this.sort_order_desc=='desc'?undefined:'desc');
        }

        this._makeTabelHeader();

        if((this.options.onOrder || Prototype.emptyFunction).bind(this)())
            this._loadAjaxData();
    },

    _getIdByRowIndex: function(){
        if(this.table_body){
            var selected_row=undefined;
            $(this.table_body).getElementsBySelector('tr').each(function(e,index){
                if(this.selectedRowIndex==index){
                    var element_id=e.readAttribute('key')
                    selected_row=this._idToSelectedRow(element_id);
                    return;
                }
            }.bind(this));
            return selected_row;
        }
        return undefined;
    },

    _reselectRow: function(old_selected_row, new_selected_row){
        if(this.table_body && (new_selected_row!=old_selected_row)){
            this._resetSelectedRow(new_selected_row);
            (this.options.beforeSelect || Prototype.emptyFunction).bind(this)();
            (this.options.onSelect || Prototype.emptyFunction).bind(this)();
            (this.options.afterSelect || Prototype.emptyFunction).bind(this)();
        }
    },

    selectFirstRow: function(){
        this.selectedRowIndex=0;
        var old_selected_row=this._selectedRowID();
        this.selected_row=this._getIdByRowIndex();
        var new_selected_row=this._selectedRowID();
        this._reselectRow(old_selected_row,new_selected_row);
    },

    selectRow: function(boardid,secid,tradedate){
        var old_selected_row=this._selectedRowID();
        this.selected_row=$H({boardid: boardid, secid:secid, tradedate:tradedate, trade_engine: this.options.issParameters.trade_engine, market: this.options.issParameters.market});
        var new_selected_row=this._selectedRowID();
        this._reselectRow(old_selected_row,new_selected_row);
    },

    _idToSelectedRow: function(element_id, title){
        var selected_=new String(element_id).split(':');

        return $H({boardid: selected_[0], secid: selected_[1], tradedate: (selected_[2]=='undefined'?undefined:selected_[2]), trade_engine: this.options.issParameters.trade_engine, market: this.options.issParameters.market, title: title});
    },

    _resetSelectedRow: function(element_id, dontit){
        if(!this.table_body) return;
        $(this.table_body).getElementsBySelector('tr').each(function(tr){
            if(this._rowID(element_id)==$(tr).readAttribute('key') && !dontit){
                var title=$(tr).readAttribute('name');
                if(tr.hasClassName(this.options.selectedRow)){
                    if(!this.options.unselectable){
                        this.selected_row=undefined;
                        this.selectedRowIndex=undefined;
                        tr.removeClassName(this.options.selectedRow);
                    }
                }
                else{
                    this.selected_row=this._idToSelectedRow(element_id,title);
                    this.selectedRowIndex=undefined;
                    if(!dontit)
                        tr.addClassName(this.options.selectedRow);
                }
            }
            else{
                tr.removeClassName(this.options.selectedRow);
            }

        }.bind(this));
    },

    onClick: function(e) {
        try{
            Event.stop(e);
            var element=Event.element(e);
            var na=element.readAttribute('name');

            if(na=='load_info' || na=='load_info_cell'){

                ($(this.options).beforeSelect || Prototype.emptyFunction).bind(this)();

                var selectedRow = (na=='load_info_cell'?element.up():element.up().up());
                var element = (na=='load_info_cell'?element.down():element);

                this.selected_link=element;

                var onclick_result=undefined;

                if(na=='load_info' && this._selectedRowID()==element.id){
                    onclick_result=($(this.options).onClick || Prototype.emptyFunction).bind(this)();
                }

                if(onclick_result==undefined || onclick_result==true){
                    this._resetSelectedRow(element.id);
                }

                ($(this.options).onSelect || Prototype.emptyFunction).bind(this)();

                ($(this.options).afterSelect || Prototype.emptyFunction).bind(this)();
            }
        }catch(e){alert('mxtable onClick: '+e);}
    },

    onClickNavigator: function(e){
        Event.stop(e);

        this.last_response_time.data=0;

        var new_page=new Number(Event.element(e).readAttribute('name')).valueOf();

        if(this.current_page==new_page || new_page==0 ||  new_page>this.pages ) return false;
        this.suspend();
        this.lock();
        if(this._remakeNavigator(new_page)){
            this.table_body=undefined;
            if((this.options.onPage || Prototype.emptyFunction).bind(this)())
                this._loadAjaxData();
        }
        else{
            this.resume();
            this.unlock();
        }
    }
};

/**
*
* @updated: 2008-09-15
* @version: 0.9.6
*
*/


