/**
 * jquery.rowRepeater.js v0.0.7
 * added: cookie support to display the last page
 * added: datasource support is added. first parameter can be either a url or a json object 
 * added: conditional display support is added.
 * added: soft_paging. true will load the pages on the fly. false will load a new url with page parameter.
 * 
 * @author Yasar Bayar <yasar@navigatormm.com>
 * @example 
 
 Ex:

javascript:
$('#upcomming').rowRepeater(js_dir+'/ajax/handle.php?a=get-upcoming-houses',{
external_data: {domain_id: DOMAIN_ID},
onPageLoad : function($HOLDER){
$HOLDER.find('.listing').each(function(i){
if (i % 2 == 0) $(this).addClass("listing-bgcolor");
});
}
});

html:
<div id="upcomming"><div style="display: none;">
<div class="listing">
<div class="image" style="background:url(/dom/${domain_id}/ads/${id}_1_t.jpg) no-repeat"></div>
<span>
<h2><a title="" href="">Open House</a></h2>
<p>${oh_date}</p>
<p>${time_from}${periodf} - ${time_to}${periodt}
</span>
</div>
<div class="paging">
<a title="" href="javascript:void(0);" class="prev">� Prev</a>
Page ${current_page_nr} of ${total_page_nr} 
<a title="" href="javascript:void(0);" class="next">Next �</a>
</div>
</div></div>

 */
 
 (function(){
	$.fn.rowRepeater= function(datasource,options, callback){
            options = $.extend({},{
                dataschema:[],
                onPageLoad: null, //could be a callback function to be called on each page load
                onBeforeRowLoad: null,
                per_page: 5,
                item_template: '.listing',
                page_holder: '.paging',
                external_data: null,
                primary_field: 'id',
                paging_location: 'bottom',
                remember_last_page: true,
                soft_paging: true,
                cookies: true,
                events: null,
                tunnel: null, //this must be a jquery object that points to an html element in which we will pass in the external data and our code will bind to change event of this object and on trigger it will detect it.
                ids: new Array(), // this will be filled by the plugin with the id of the records parsed.
                messages:{
                    nodata: ''
                }
            },options);
		
		var rowRepeater = this;
		var $HOLDER = null;//$(this);
		rowRepeater._data = null;
                rowRepeater.data = null;
		var total_page_nr = 0;
		var current_page_nr = 1;
		var $templ = null;
		var $pager = null;

        var state = null;
        
        var guid = $(this).attr('id');
        
        if(options.cookies && options.remember_last_page && $.cookie('tii.rowRepeater-'+guid+'.page')){
           current_page_nr = $.cookie('tii.rowRepeater-'+guid+'.page');
        }
        
        if($.tii.GUP('page')!==null){
            current_page_nr = $.tii.GUP('page');
        }
		
        var AddData = function(row){
            var rowdata={},n=0;
            if((n=options.dataschema.length) > 0 && $.isArray(row)){
                for(var i=0; i<n; i++)
                rowdata[options.dataschema[i]]=row[i];
            }else rowdata = row;

            if(typeof(options.onBeforeRowLoad) == 'function'){
                rowdata = options.onBeforeRowLoad(rowdata);
            }
            var html = $templ.outerHTML()
            if(options.external_data !== null) rowdata = $.extend({},options.external_data,rowdata);
            
            for(var key in rowdata){
                if(key === options.primary_field) options.ids.push(rowdata[key]);

                if(rowdata[key] === null) rowdata[key]='null';

                var re=new RegExp('\\$(?:\\{|%7B)'+key+'(?:\\}|%7D)','gi');
                html=html.replace(re,rowdata[key].toString().replace('$','$$$'));
            }
            $html=$(html);
            $html.find('*')
                .filter(function(){return $(this).attr('tii:condition');})
                .each(function(){
                    $EL=$(this);
                    eval('var condition='+$EL.attr('tii:condition'));
                    if(! condition()) $EL.remove();
                });
            return $html.outerHTML();
        };
        
        var ShowData = function(_callback){
            if (current_page_nr ==0) current_page_nr = 1;
            if (current_page_nr>total_page_nr) current_page_nr = total_page_nr;
            var out='';
            var start = (current_page_nr-1)*options.per_page; if(start<0) start=0;
            var end = current_page_nr*options.per_page;
            
            options.cookies && options.remember_last_page && $.cookie('tii.rowRepeater-'+guid+'.page',current_page_nr);
            
            if(end>rowRepeater.data.length) end = rowRepeater.data.length;
            
            //alert(data.length);
            for(var i=start; i<end; i++){
                out+= AddData(rowRepeater.data[i]);
            }
            
            //$HOLDER.find('div.tii-data').html(out);
            $HOLDER.find('div.tii-data').fadeOut('fast',function(){
                $(this).html(out).fadeIn(function(){
                    if(typeof(_callback) == 'function') _callback($HOLDER);
                    if(typeof(options.onPageLoad) == 'function') options.onPageLoad($HOLDER);
                });
            });
        };
        
        var ShowPager = function(){
            $HOLDER.find('div.tii-pager').html('');
            //if(total_page_nr==1) return;
            
            $pager2 = $pager.clone();
            
            var frow=(current_page_nr-1)*options.per_page+1;
            var lrow=current_page_nr*options.per_page;
            var trows=rowRepeater.data.length;
            
            $pager2.html($pager2.html().replace('${total_page_nr}',total_page_nr));
            $pager2.html($pager2.html().replace('${current_page_nr}',current_page_nr));
            $pager2.html($pager2.html().replace('${per_page}',options.per_page));
            $pager2.html($pager2.html().replace('${first_row}',frow));
            $pager2.html($pager2.html().replace('${last_row}',trows>lrow?lrow:trows));
            $pager2.html($pager2.html().replace('${total_rows}',trows));
            
            var $n = $pager2.find('.next');
            var $p = $pager2.find('.prev');
            
            current_page_nr<total_page_nr ? $n.show() : $n.hide();
            current_page_nr<2 ? $p.hide() : $p.show();
            
            $n.click(function(){
                current_page_nr++;
                if(options.soft_paging === false){
                    $.tii.RUP({page:current_page_nr});
                }else{
                    ShowData();
                    ShowPager();
                }
            });
            
            $p.click(function(){
                current_page_nr--;
                if(options.soft_paging === false){
                    $.tii.RUP({page:current_page_nr});
                }else{
                    ShowData();
                    ShowPager();
                }
            });
            
            //$HOLDER.find('div.tii-pager').append($pager2);
            $HOLDER.find('div.tii-pager').each(function(){$(this).append($pager2.clone(true))});
        };
        
        var Init = function(){
            total_page_nr = Math.ceil(rowRepeater.data.length / options.per_page);
            $templ = $HOLDER.find(options.item_template).clone();
            $pager = $HOLDER.find(options.page_holder).clone();
            var tpl_data='<div class="tii-data"></div>';
            var tpl_pager='<div class="tii-pager"></div>';
            switch(options.paging_location){
                case 'bottom': $HOLDER.html(tpl_data+$(tpl_pager).addClass('tii-pager-bottom').outerHTML());break;
                case 'top': $HOLDER.html($(tpl_pager).addClass('tii-pager-top').outerHTML()+tpl_data);break;
                case 'both': $HOLDER.html($(tpl_pager).addClass('tii-pager-top').outerHTML()+tpl_data+$(tpl_pager).addClass('tii-pager-bottom').outerHTML());break;
            }
            
            if(options.tunnel !== null){
                console.log(options.tunnel);
                options.tunnel.change(function(){
                    AddData($(this).data);
                });
            }
            if(options.events !== null){
                $.each(options.events, function(i,event){
                    $('#'+event.id).bind(event.type,{
                        $HOLDER: $HOLDER, 
                        object: this,
                        datasource: rowRepeater.data,
                        page_nr: current_page_nr,
                        internal:{
                            Update: Update,
                            SetDatasource: SetDatasource,
                            Sort: Sort,
                            Filter: Filter,
                            RemoveFilter: RemoveFilter,
                            SetPage: SetPage,
                            SetState: SetState,
                            BindEvent: BindEvent
                        }
                    },event.handler);
                });
            }
        };

        var BindEvent = function(name,func){options.events[name] = func};

        var SetPage = function(i){current_page_nr = i;};
        var SetState = function(s){
            if($.isFunction(options.events['onBeforeStateChange']))options.events['onBeforeStateChange']();
            state = s;
            if($.isFunction(options.events['onAfterStateChange']))options.events['onAfterStateChange']();
        };

        var Update = function(){
            total_page_nr = Math.ceil(rowRepeater.data.length / options.per_page);
            
            if(rowRepeater.data.length==0){
                rowRepeater.children('div').hide();
                rowRepeater.append('<span class="message">'+options.messages.nodata+'</span>');
                return;
            }
            
            rowRepeater.children('.message').remove();
            rowRepeater.children('div').show();
            
            ShowData();
            ShowPager();
        };
        
        var SetDatasource = function(datasource){
            rowRepeater.data = datasource;
            rowRepeater._data = datasource;
        };
        
        var Filter = function(callback,datasource){
            if(typeof(datasource) == 'undefined'){
                datasource = rowRepeater._data;
            }
            rowRepeater.data=new Array();
            $.each(datasource, function(i,item){
                val = callback(item,options.dataschema);
                if(val !== false) rowRepeater.data.push(val);
            });
        };
        
        var RemoveFilter=function(){
            rowRepeater.data = rowRepeater._data;
        }
        
        var Sort = function(field,direction,type){
            //if(rowRepeater.data.length == 0 && rowRepeater._data.length >0) rowRepeater.data = rowRepeater._data;

            if (rowRepeater.data.length == 0) return;

            if (rowRepeater.data[0] == undefined || rowRepeater.data[0][field] == undefined){
                field = $.inArray(field,options.dataschema);
            }

            if (rowRepeater.data[0] == undefined || rowRepeater.data[0][field] == undefined){
                console.log('requested field is not available in the datasource!!');
                return;
            }

            rowRepeater.data.sort(function(a,b){
                switch(type){
                    case 'numeric':
                        if(direction == 'ASC') return a[field] - b[field];
                        return b[field] - a[field];
                        break;
                    
                    default:
                        if(direction == 'ASC') return a[field] < b[field];
                        return a[field] > b[field];
                        break;
                }
            });
        };
        
        var Go = function(){
            rowRepeater.each(function(){
                $HOLDER = $(this);
                //$HOLDER.hide();
                Init();
                ShowData(function(){
                    if(typeof(callback) == 'function') callback();
                });
                ShowPager();
                //$HOLDER.show();
            });
        };
        
        if(rowRepeater.size() == 0) return(this);
        
        if(datasource !== null && typeof(datasource) == 'object') {
            //rowRepeater.data = datasource;
            SetDatasource(datasource);
            if(datasource.length==0)rowRepeater.html(options.messages.nodata).show();
            else Go();
        }
		else $.getJSON(datasource,function(AR){
			if(AR.success){
				//rowRepeater.data = AR.data;
                SetDatasource(AR.data);
                if(rowRepeater.data.length==0)rowRepeater.html(options.messages.nodata);
                else Go();
			}
		});
		
		return(this);
	};
})();
