Mx.Popup = Class.create();
Mx.Popup.prototype = {
    
    initialize: function(options){
        this.body=$(options.parent||window.document.body);
        this.setOptions(options);
        this._build();
        this._observeBodyShield();
        this._observeClose();
    },
    
    setOptions: function(options) {
        this.options = $H({
            id:                'mx_popup',
            title:             '',
            subTitle:          '', 
            className:         '',
            linksClassName:    '',
            outsetClassName:   '',
            disabledClassName: 'disabled',
            shieldOpacity:      0.5,
            shieldBackground:  '#fff',
            value:             'X'
            
                           
        }).merge(this.options);
        this.options.merge(options);
        
        this.options.title=this.options.title.unescapeHTML();
         this.options.subTitle=this.options.subTitle.unescapeHTML();
    },
    
    _build: function() {
        this.body_shield=Builder.node('div', {
                    id: this.options.id+'-shield'
                } 
        );
        
        $(window.document.body).appendChild($(this.body_shield));
        
        $(this.body_shield).setStyle({background: this.options.shieldBackground, opacity: this.options.shieldOpacity, border: 'solid 0px', width: '0px', height: '0px', 'z-index': 100});
        
        var title=this.options.title;
        
        this.popup_selector=Builder.node('div',{
                id: this.options.id,
                className: this.options.className
            },
            [
                Builder.node('h1', { title: this.options.title},
                    [
                    this.title=Builder.node('strong', {id: this.options.id+'-title'},[
                            title, 
                            this.options.subTitle?' | ':'',
                            this.subTitle=Builder.node('span', {id: this.options.id+'-subtitle'}, this.options.subTitle)
                        ]
                    ),
                    this.close=Builder.node('img',{id: this.options.id+'-close', 'src': '/images/close.gif'}),
                    ]
                ),
                this.data = Builder.node('div', {className: this.options.linksClassName}),
                
                this.outset=Builder.node('div', {className: this.options.outsetClassName, id: this.options.id+'-outset'})
            ]
        );
        
        $(this.popup_selector).setStyle({'z-index': 101, display: 'none', 'background': '#fff'});
        this.data.update('X');
        $(this.body).appendChild(this.popup_selector);
        
        
    },
               
    show: function(link_element){
            
        $(this.popup_selector).show();
            
    },
            
    hide: function(){
        $(this.body_shield).setStyle({width: '0px', height: '0px'});
        $(this.body_shield).hide();
        $(this.popup_selector).hide();
    },
            
    _observeBodyShield: function(){
        this.onClickBodyShieldListener = this.onClickBodyShieldListener || this.onClose.bindAsEventListener(this);
        Event.observe($(this.body_shield),'click', this.onClickBodyShieldListener);
    },
    
    _observeClose: function(){
        this.onClickCloseListener = this.onClickCloseListener || this.onClose.bindAsEventListener(this);
        Event.observe($(this.close),'click', this.onClickCloseListener);
    },
            
    onClose: function(){
        this.hide();
    }    
    
};

Mx.PopupSelector=Class.create();
Mx.PopupSelector.prototype={

    initialize: function(options){
        this.body=$(options.parent||window.document.body);
        this.setOptions(options);
        this._build();
        this._observeBodyShield();
        this._observeClose();
    },
    
    setOptions: function(options) {
        this.options = $H({
            id:                'new-popup-selector',
            title:             'Инструмент',
            subTitle:          '', 
            className:         'popup-selector',
            linksClassName:    'links',
            outsetClassName:   'outset',
            leftClassName:     'left',
            rightClassName:    'right',
            disabledClassName: 'disabled',
            shieldOpacity:      0.5,
            shieldBackground:  '#fff',
            
            leftList: [
                            {id: 'daily',    title: 'Ход торгов', hidden: false, disabled: false, url: '/marketdata/quotes', parameters: {}},
                            {id: 'history',  title: 'Результаты торгов', hidden: false, disabled: false, url: '/marketdata/quotes', parameters: {}},
                            {id: 'analisys', title: 'Технический анализ', hidden: false, disabled: false, url: '/marketdata/quotes', parameters: {}}
                       ],
            rightList: [
                            {id: 'passport', title: 'Паспорт ценной бумаги', hidden: false, disabled: false, url: '/marketdata/info', parameters: {}},
                            {id: 'emmitent', title: 'Эммитент', hidden: false, disabled: false, url: '/marketdata/info', parameters: {}},
                            {id: 'emmitent-news', title: 'Новости эммитента', hidden: false, disabled: false, url: '/marketdata/info', parameters: {}}
                       ]
            
        }).merge(this.options);
        this.options.merge(options);
        /* dosn't work in Chrome/IE*/
        this.options.title=this.options.title.unescapeHTML().gsub('&#x0026;','&');
         this.options.subTitle=this.options.subTitle.unescapeHTML().gsub('&#x0026;','&');
    },
    
    
    _buildList: function(list, ol){
        var count=0;
        $A(ol).each(function(e){
            if(!e.hidden){
                var a; count++;
                var li;
                var id=this.options.id+'-'+e.id;
                $(list).appendChild(li=Builder.node(
                    'li',
                    a=Builder.node('a', {id: id, name: id, href: e.url+($H(e.parameters).size()>0?'?':'')+$H(e.parameters).toQueryString()}, e.title)
                ));
                if(e.disabled){
                    a.className=this.options.disabledClassName;
                    a.href='#'+id;
                }
            }
        }.bind(this));
        return count;
    },
    
    _build: function() {
        this.body_shield=Builder.node('div', {
                    id: this.options.id+'-shield'
                } 
        );
        
        $(window.document.body).appendChild($(this.body_shield));
        
        $(this.body_shield).setStyle({background: this.options.shieldBackground, opacity: this.options.shieldOpacity, border: 'solid 0px', width: '0px', height: '0px', 'z-index': 100});
        
        
        var title=''; 
        var sl=this.options.subTitle?this.options.subTitle.length:0;
        if(this.options.title.length+sl>32) {title+=this.options.title.substr(0,10)+'...'; title+=this.options.title.substr(this.options.title.length-10,10);}
        else title=this.options.title;
            
        this.popup_selector=Builder.node('div',{
                id: this.options.id,
                className: this.options.className
            },
            [
                Builder.node('h1', { title: this.options.title},
                    [
                    this.title=Builder.node('strong', {id: this.options.id+'-title'},[
                            title, 
                            this.options.subTitle?' | ':'',
                            this.subTitle=Builder.node('span', {id: this.options.id+'-subtitle'}, this.options.subTitle)
                            /*this.close=Builder.node('a',{id: this.options.id+'-close', 'href': '#'}, (LC_LANG=='ru'?'x':'x'))*/
                        ]
                    ),
                    this.close=Builder.node('img',{id: this.options.id+'-close', 'src': '/images/close.gif'}),
                    ]
                ),
                this.linksBox=Builder.node('div', {className: this.options.linksClassName}, [
                    this.leftList=Builder.node('ul', {className: this.options.leftClassName, id: this.options.id+'-leftlist'}),
                    this.rightList=Builder.node('ul', {className: this.options.rightClassName, id: this.options.id+'-rightlist'})
                ]),
                this.outset=Builder.node('div', {className: this.options.outsetClassName, id: this.options.id+'-outset'})
            ]
        );
        
        $(this.popup_selector).setStyle({'z-index': 101, display: 'none', 'background': '#f00'});
        
        $(this.body).appendChild(this.popup_selector);
        
        this._buildList($(this.leftList), this.options.leftList);
        this._buildList($(this.rightList), this.options.rightList);
    },
    
    _lock_body: function(){
        Position.absolutize($(this.body_shield));
        Position.overlay($(this.body_shield));
        $(this.body_shield).show();
    },
            
    show: function(link_element){
            
        if(!link_element) return ;
            
        this._lock_body();
        $(this.popup_selector).setStyle({opacity:0.0, left:0, top:0, margin:0, padding:0});
        $(this.popup_selector).show();
        
        // fix||IE linksBox
        var h=$(this.leftList).getHeight();
        if($(this.rightList).getHeight()>h)
            h=$(this.rightList).getHeight();
            
        var w=$(this.leftList).getWidth()+$(this.rightList).getWidth();

        var titleWidth = $(this.title).getWidth() + 40;
        if (w < titleWidth) w = titleWidth;
        
        $(this.linksBox).setStyle({height: (h+1)+'px', width: w+'px'});
        
        h=$(this.popup_selector).getHeight();
        Position.absolutize(this.popup_selector);
        var outset_left=parseFloat($(this.outset).getStyle('left')  || 0);
        var link_w=$(link_element).getWidth();
        var offset_link=(link_w>=(outset_left+link_w/2)?0:(outset_left-link_w/2)*(-1));
            
        Position.clone($(link_element), $(this.popup_selector), {setWidth: false, setHeight: false, offsetLeft:offset_link , offsetTop: h*(-1)-2-link_element.getHeight()/2}); 
        
        $(this.popup_selector).show();
        $(this.popup_selector).setStyle({opacity:1.0}); 
    },
            
    hide: function(){
        $(this.body_shield).setStyle({width: '0px', height: '0px'});
        $(this.body_shield).hide();
        $(this.popup_selector).hide();
    },
            
    _observeBodyShield: function(){
        this.onClickBodyShieldListener = this.onClickBodyShieldListener || this.onClose.bindAsEventListener(this);
        Event.observe($(this.body_shield),'click', this.onClickBodyShieldListener);
    },
    
    _observeClose: function(){
        this.onClickCloseListener = this.onClickCloseListener || this.onClose.bindAsEventListener(this);
        Event.observe($(this.close),'click', this.onClickCloseListener);
    },
            
    onClose: function(){
        this.hide();
    }
            
};
            
Mx.PopupSelector.create = function (table, trade_engine, market){
    var parameters={secid: table.selected_row.secid, boardid: table.selected_row.boardid, trade_engine: trade_engine, market: market};
    var popup_selector=new Mx.PopupSelector({
        shieldOpacity: 0.0, 
        title:    table.selected_row.title, 
        subTitle: table.selected_row.secid,
        leftList: [
                    {id: 'daily',   title: [['Ход торгов'],['Market Data']][LC_Index], url: '/marketdata/quotes', parameters: $H(new Hash(parameters)).merge({data_type: 'daily'})},
                    {id: 'history', title: [['Результаты торгов'],['Statistics      ']][LC_Index], url: '/marketdata/quotes', parameters: $H(new Hash(parameters)).merge({data_type: 'history'})}
                ],
        rightList:[
                    {id: 'card',   title: [['Описание инструмента'],['Description']][LC_Index], url: '/marketdata/quotes', parameters: $H(new Hash(parameters)).merge({type_of_info: 'instrument-info-passport'})},
                    {id: 'analisys', title: [['Технический анализ'],['Technical Analysis']][LC_Index], url: '/marketdata/analysis', 
                        parameters: $(new Hash(parameters)).merge({linetype:'candle', period:'-1M'})}
                ]
    });
    
    popup_selector.show($(table.selected_link));
};
    

MxChart={};
MxChart.Transport={};
MxChart.Interface={};
MxChart.Helper={};
MxChart.Preview = {};

MxChart.Preview.Tab= Class.create()

MxChart.Preview.Tab.prototype = {
    
    initialize: function(holder, options) {
    
        this.holder=$(holder);
        this.setOptions(options);
        if(!this.options.selectedSpan)
            this.options.selectedSpan='-1d';
        this.selectedSpan=this.options.selectedSpan;
        this._buildSelector();
        
        if(this.options.shield && !(this.options.shield instanceof Mx.Shield)){
            this.shield=new MxTable.Shield(this.options.shield);
            this.shield.setOptions({parent: $(this.holder)});
        }
        else if(this.options.shield instanceof Mx.Shield){
            this.shield=this.options.shield;
            this.shield.setOptions({parent: $(this).holder});
        }
    },
    
    setOptions: function(options) {
        this.options = $H({
            shield:             $('chart-shield'),
            selectFrom:         ['-1d', '-7d','-1M','-1y', 'all'],
            selectedSpan:       '-1d',
            firstSelectorClass: '', 
            lastSelectorClass:  '', 
            selectorClass:      'chart-preview-selector',
            listSelectorClass:  '',
            leftElementClass:   'no-left-border',
            selectedClass:      'selected',
            refreshTime:        0, /*no refresh*/
            timeLineHelper:     '/issrpc/marketdata/chart/timeline',
            //chartHelper:        '/marketdata/analysis/chart_preview',
            chartHelper:        '/cs_compat',
            warnConsole:        undefined,
            parameters:         {secid: 'MICEXINDEXCF', boardid: 'SNDX'},
            issParameters:      {market: 'index', trade_engine: 'stock'},
            candleInterval:     undefined,
            chartTemplate:      'micexpreview',
            onClick:                undefined
        }).merge(this.options);
        this.options.merge(options);
    },
    
    hide: function() { $(this.holder).hide();},
    show: function() { $(this.holder).show();},
            
    _buildSelector: function(){
        if(this.options.selectFrom && this.options.selectFrom.size()>0){
            this.selector=Builder.node('div', {className: this.options.selectorClass},[
                    this.list=Builder.node('ul', {className: this.options.listSelectorClass, id: $(this.holder).id+'-list'})
            ]);
            this._buildList();
            $(this.holder).appendChild(this.selector);
        }
    },
    
    _buildList: function(){
        var list=$A(this.options.selectFrom);
        list.each(function(e,index){
            var title=new Date.getTimeSpanById(e).short_title;//.toLowerCase();
            var li=Builder.node('li', {className: (index==0?this.options.leftElementClass:'')},
                Builder.node('a',{href:'#', name: e}, title)
            );
            
            this.list.appendChild(li);
            
            if(e==this.selectedSpan)
                $(li).addClassName(this.options.selectedClass);
            if(index==list.length-1)
                $(li).addClassName(this.options.lastSelectorClass);
            if(index==0)
                $(li).addClassName(this.options.firstSelectorClass);
        }.bind(this));
        
        if(!this.links){
            this.links = $(this.list).getElementsBySelector('a[name]');
            this._observe();
        }
    },
    
    _observe: function(){
        this.onSelectListener = this.onSelectListener || this.onSelect.bindAsEventListener(this);
        $A(this.links).invoke('observe', 'click', this.onSelectListener);
    },
    
    onSelect: function(e){
        Event.stop(e);
        
        var sel=Event.element(e);
        var sli=sel.up();
        if(sli.hasClassName(this.options.selectedClass))
            return;
        
        this.lock();
        
        $(this.links).each(function(a){
            var li=a.up();
            if(li.hasClassName(this.options.selectedClass))
                li.removeClassName(this.options.selectedClass);
            if(a.name==sel.name)
                li.addClassName(this.options.selectedClass);
        }.bind(this));
        
        this.onChange(sel.name);
    },
        
    onChange: function(span){
        this.selectedSpan=span;
        var days=new Number(new Date().addTimeSpanString(this.selectedSpan).daysTillNow());  if (days==1) days+=1;
        this._getTimeLine(days.valueOf());
    },
    
    _viewWarnConsole: function(){
        if(this.options.warnConsole){
            $(this.options.warnConsole).show();
            if(this.selector) $(this.selector).hide();
            if(this.chart_image) $(this.chart_image).hide();
        }
        this.unlock();
    },
    
    _spanToInterval: $H({'-1d': 10, '-7d': 60, '-3M': 24, '-1M': 24, '-1y':7, '-12M': 7, 'all': 31}),
    
    _getTimeLine: function(days){
    
        this._interval= this._spanToInterval[this.selectedSpan] || this.options.candleInterval || 10;
        
        if(this.options.timeLineHelper){
            new Ajax.Request(this.options.timeLineHelper+'/result.json', {
                method: 'get',
                parameters: $H({
                        candle_interval: this._interval,
                        secid: this.options.parameters.secid, 
                        boardid: this.options.parameters.boardid, 
                        market: this.options.issParameters.market, 
                        trade_engine: this.options.issParameters.trade_engine,
                        days: days
                    }),
                onSuccess: function(transport, json){
                            json=transport.responseText.evalJSON(false);
                            if(!json){
                                this._viewWarnConsole();
                                return;
                            }
                            var data=$H(json[1]);
                            if(!data['end'] || !data['start']){
                                this._viewWarnConsole();
                                this.hide();
                                return;
                            }
                            this.timeLine=data['start']+'-'+data['end'];
                            this.show();
                            this._getAndDrawChart();
                        }.bind(this),
                onFailure: function(transport, json){
                        return;
                }
            });
        }
        else{
            this.timeLine='';
            this._getAndDrawChart();
        }
    },
    
    
    _idle_time: function(idle){ //sec
        var t=(new Date()).getTime();
        return (t-t%(idle*1000));
    },
    
    _getAndDrawChart: function(){
        try{
            var parameters=$H(new Hash(this.options.parameters));
            
            parameters.merge({
                market: this.options.issParameters.market,
                trade_engine: this.options.issParameters.trade_engine,
                template: this.options.chartTemplate, 
                timeline: this.timeLine, 
                interval: this._interval,
                period:   this.selectedSpan, 
                ltime:    this._idle_time(60),
                lang:     LC_LANG
            });
            
            var src   = this.options.chartHelper+'?'+parameters.toQueryString();
            
            if(!this.chart_image){
            
                this.chart_image=Builder.node('img', {src: src, name: ($(this.holder).id+'chart-image')});
                
                $(this.holder).appendChild(this.chart_image);
                
                Event.observe($(this.chart_image), 'load', function(event){
                    Event.stop(event);
                    this.chart_image.show();
                    this.unlock();
                }.bind(this));
                
                Event.observe($(this.chart_image), 'click', function(event){
                    Event.stop(event);
                    this.onClick();
                }.bind(this));
            }
            
            $(this.chart_image).src=src;
            $(this.chart_image).setStyle({cursor: 'pointer'});
            
            if(!$(this.holder).visible())
                $(this.holder).show();
                
            if(this.selector) $(this.selector).show();
            $(this.holder).show();
            
        }catch(e){
        }
    },
        
    run: function(){
        if(!this.timeLine)
            this.reload();
         if(this.options.refreshTime){
            if(this.image_updater) this.image_updater.stop();
                this.image_updater=new PeriodicalExecuter( function(pe){
                        this.onChange(this.selectedSpan);
                    }.bind(this),
                    this.options.refreshTime
                );
         }
    },
    
    stop: function(){
        if(this.image_updater) this.image_updater.stop();
    },
    
    reload: function(){
        this.lock();
       	if (!this.selectedSpan)
       		this.selectedSpan = "-1d";
       	this.onChange(this.selectedSpan);
    },
    
    _defaultClick: function(){
        var p=$H({
            secid: $(this.options).parameters.secid,
            boardid: $(this.options).parameters.boardid,
            linetype: 'candles',
            period: '-1d'
        })
        window.location='/marketdata/analysis?'+p.toQueryString();
    },
    
    onClick: function(){
        (this.options.onClick || this._defaultClick).bind(this)();
    },
    
    lock: function(){
        if(this.shield)  this.shield.show();
    },
    
    unlock: function(){
        if(this.shield)  this.shield.hide();
    }
}
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
*
*/

MxTable.SpreadNChart=Class.create();
MxTable.SpreadNChart.prototype={
    initialize: function(options){
        this.meta_cache={};
        this.setOptions(options);
    },

    setOptions: function(options) {
        this.options = $H({
            metaFieldList:[
                            { id: "SHORTNAME", type: 'string'} ,
                            { id: "LAST", trend_by: "LASTCHANGEPRCNT", type: 'number'} ,
                            { id: "LASTCHANGEPRCNT", has_percent: 'true' , is_signed: 'true', trend_by: "LASTCHANGEPRCNT", type: 'number'},
                            { id: "UPDATETIME", type: 'time'}
                          ],
            selectFrom:  ['-1d', '-7d','-1M','-12M', 'all'],
            metaHelper:   undefined,
            preloadMeta:  undefined,
            metaName:     'small',
            helper:       undefined,
            holder:       $('holder'),
            header:       $('header'),
            footer:       $('foter'),
            table:        $('table'),
            shield:       $('shield'),
            chartHolder:  $('chart-holder'),
            chartShield:  $('chart-shield'),
            issParameters:{},
            parameters:   {},
            selectedRow:  {},
            selectFirstRow: true,
            limit         :        5,
            selectorClass:         '',
            listSelectorClass:     'period-selector float-container',
            lastSelectorClass:     'last',
            selectedSelectorClass: 'selected',
            firstSelectorClass:    '',
            leftElementClass:      '',
            timeLineHelper:        '/issrpc/marketdata/chart/timeline2',
            //chartHelper:           '/marketdata/analysis/chart_preview',
            chartHelper:           '/cs_compat',
            onClickChart:          undefined,
            refreshTime:           0,
            spread_options:	$H(),
            
            passportMarker:	'X-MicexPassport-Marker',
            passportInfoBar:	undefined

        }).merge(this.options);
        this.options.merge(options);
    },

    _processMeta: function(json,meta){
        var fields=json[this.options.metaName+'_field_list']||json.preview_field_list;
        var _metas=$A(this.options.metaFieldList||[]);
        fields.each(function(e){
            if(_metas.indexOf(e['id'])>=0){
                meta.push(e);
            }else if(this.options.metaFieldList==undefined){
                meta.push(e);
            }
        }.bind(this));
        this.meta_cache[this.options.metaHelper]=meta;
        
    },

    run: function(){
        var meta= this.meta_cache[this.options.metaHelper] || $A(new Array());
        if(meta.size()==0)
            if(!this.options.preloadMeta)
                new Ajax.Request(this.options.metaHelper, {
                    method: 'get',
                    onComplete: function(transport,json){
                            if(!json){
                                json = transport.responseText.evalJSON(false);
                            }
                            this._processMeta(json,meta);
                            this._createTable(meta);
                    }.bind(this)
                });
            else{
                this._processMeta(this.options.preloadMeta,meta);
                this.options.preloadMeta=undefined;
                this._createTable(meta);
            }
        else
            this._createTable(meta);
    },

    _createTable: function(meta){
        var options=   $H({

            fieldsMeta:    meta,
            onClickField: 'SHORTNAME',

            //shield:        new MxTable.Shield($($(this.options).shield), { opacity: 1.0, duration: 0.2}),
            shield:        $(this.options).shield,

            refreshTime:   this.options.refreshTime,
            limit:         this.options.limit,
            url:           this.options.helper+'/result.json',
            downloadUrl:   undefined,
            countUrl:      undefined,
            preloadData:   this.options.preloadData,
            preloadCount:  this.options.preloadCount,
            issParameters: this.options.issParameters,
            parameters:    this.options.parameters,
            responseWarn:  this.options.responseWarn,

            noLinked:          '',
            selectedRow:       'selected',
            firstRow:          'first',
            onClickField:      'SHORTNAME',
            upCell:            'delta up',
            downCell:          'delta down',
            arrowUpCell:       'amount up',
            arrowDownCell:     'amount down',
            stayCell:          'delta',
            arrowStayCell:     'amount',
            dateColumn:        'time',

            hideThead:     true,
            
//            passportMarker:	this.options.passportMarker,
//            passportInfoBar:	this.options.passportInfoBar,

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

            onOrder: function(){
                this.order_proccessing=true;
                return true;
            },

            onPage: function(){
                this.order_proccessing=true;
                return true;
            },

            afterSelect: function(){
                if(this.order_proccessing)
                    this.unlock();
                this.order_proccessing=false;
                return true;
            },

            onSelect: function(){
                try{
                    if($(this.table).selected_row) {
                        if(!$(this.table).order_proccessing){
// ttt[
	try{
		var element = this.table.table_body.getElementsBySelector('tr[key="'+this.table._selectedRowID()+'"]')[0]
		if(element.readAttribute('market')){
			this.table.options.issParameters.market = element.readAttribute('market');
		}
	} catch(e){alert(e);}
// ]ttt
                            this._viewIndexChart();
                        }
                    }
                    else{
                        $(this.table).unlock();
                    }
                    $(this.table).unlock();
                }catch(e){alert('onSelect: '+e);}
                return true;
            }.bind(this),

            onClick: function(){
                this._popupSelector();
                return false;
            }.bind(this),

            onLoad: function(){
                if(this.table.isEmpty)
                    if($(this.chart)) $(this.chart).hide();
                return true;
            }.bind(this)
        });
        options.merge(this.options.spread_options);

        this.options.merge(options);
                
        this.table=new MxTable.Spread(
            $(this.options.holder),
            $(this.options.header),
            $(this.options.table),
            $(this.options.footer),
            this.options
         );

        if(this.options.selectFirstRow){
            this.table.selectFirstRow();
        }
        else if(this.options.selectedRow) this.table.selectRow(this.options.selectedRow.boardid,this.options.selectedRow.secid);

        this.table.run();
    },

    _viewIndexChart: function(){
        if(!this.options.chartHolder) return;
        if(!this.chart){
            try{
            this.chart=new MxChart.Preview.Tab($(this.options.chartHolder),{
                shield:           $(this.options.chartShield),
                parameters:        {secid: this.table.selected_row.secid, boardid: this.table.selected_row.boardid},
                issParameters:      this.options.issParameters,
                selectedSpan:       this.options.selectedSpan,
                candleInterval:     this.options.candleInterval,
                selectFrom:         this.options.selectFrom,
                warnConsole:        this.options.chartWarnConsole,
                selectorClass:      this.options.selectorClass,
                listSelectorClass:  this.options.listSelectorClass,
                leftElementClass:   this.options.leftElementClass,
                selectedClass:      this.options.selectedSelectorClass,
                firstSelectorClass: this.options.firstSelectorClass,
                lastSelectorClass:  this.options.lastSelectorClass,
                timeLineHelper:     this.options.timeLineHelper,
                chartHelper:        this.options.chartHelper,
                onClick:            this.options.onClickChart
            });

            if(this.options.chartTemplate)
                this.chart.setOptions({chartTemplate: this.options.chartTemplate});
            if(this.options.candleInterval)
                this.chart.setOptions({candleInterval: this.options.candleInterval});

            this.chart.run();

            }catch(e){alert('_viewIndexChart:' + e);}
        }
        else{
            this.chart.setOptions({
                parameters:   {secid: this.table.selected_row.secid, boardid: this.table.selected_row.boardid}
            });
            this.chart.reload();
        }
    },

    _popupSelector: function(){
        new Mx.PopupSelector.create($(this.table), $($(this.options).issParameters).trade_engine, $($(this.options).issParameters).market);
    }
}

