﻿(function($) {
			
    $.fn.extend({  
      databind: function (callback) {  
        if (callback) {  
          return jQuery.event.add(this[0], 'databind', callback, null);  
        } 
        else {  
          var triggers = jQuery.event.trigger('databind', null, this[0], false, null);  
         
          // if there was no return value then the even validated correctly  
          if (triggers === undefined) {
            return true;  
          }
          else {
            return triggers;
          }
        }  
       }                
    }); 
    
    $.extend({      
      msDataFilter : function(data, type) {
        return eval('(' + data.replace(new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)\\)\\\\/\\"', 'g'), "$1new Date($2)") + ')');
      },
           
      getMSJSON : function(url, data, successCallback, errorCallback) {
      	if ( jQuery.isFunction( data ) ) {
			    callback = data;
			    data = null;
		    }		
		    	    
		    return jQuery.ajax({
			    type: 'GET',
			    url: url,
			    data: data,
			    dataFilter: $.msDataFilter,
			    success: successCallback,
			    error: errorCallback
		    });    
      }
    });
			
	  $.fn.listing = function(options, context) {
	    var options = $.extend({}, $.fn.listing.defaults, options);
		    
	    listingControl = function(placeHolder, options, context) {
        this.placeHolder = placeHolder;
        this.options = options;
        this.context = context;
        this.pageSize = this.options.defaultPageSize;
        this.currentPage = 0;
        this.totalCount;
        this.itemsPerPage;
        this.items;
	      this.init();		      
	    }
	    
		  listingControl.prototype = {
		    
		    init : function() {
		      if (this.placeHolder) {
		        $(this.placeHolder).setTemplateURL(this.options.templateUrl, null, {filter_data: false});
		      }
          if (typeof Sys != undefined && Sys && Sys.WebForms) {
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(Function.createDelegate(this, this.retrieveData));
          }
		    },
		    
		    retrieveData : function() {
		      this.clear();
		      this.updateContent();
		    },
		    
		    getPageSize : function() {
		      return this.pageSize;
		    },			    
		    
		    setPageSize : function(value) {
		      this.pageSize = value;
		      this.currentPage = 0;
		      this.clear();
		      this.updateContent();
		    },
		    		    		   
		    getCurrentPage : function() {  
		      return this.currentPage;
		    },		
		    		   		    		    		   
		    setCurrentPage : function(value) {  
		      this.currentPage = value;
		      this.clear();
		      this.updateContent();		      
		    },		
		    		   
		    getTotalCount : function() {  
		      return this.totalCount;
		    },		
		    
		    getPageCount : function() {
		      count = this.getTotalCount();
		      pageSize = this.getPageSize();
          pageCount = Math.floor(count / pageSize);
          if (count % pageSize > 0)
          {
              pageCount++;
          }
          return pageCount;
		    },    
		    
		    getItems : function() {
		      return this.items;
		    },
		    
		    clear : function() {
		      this.items = null;
		      this.totalCount = null;
		    },
		    		    
		    updateContent : function() {		    
		      if (!this.items && !this.totalCount) {		        		        
		        if (this.options.preloader) {
		          blockOptions = {message: this.options.preloader};
		          if (this.options.preloader.jquery) {
		            blockOptions.css = {
							    background: 'transparent',
							    border: '0',
							    width: $(this.options.preloader).width()		            
		            };
		          }
		          $(this.placeHolder).block(blockOptions);		          
		        }		        
		        this.sendItemsRequest();
		        this.sendTotalCountRequest();
		      }		    		      
		      if (this.items != null && this.totalCount != null) {
		        if (this.items.length > 0) {
		          $(this.options.emptyMessage).hide();
              $(this.placeHolder).processTemplate(this.items);
            }
            else {
              $(this.options.emptyMessage).show();
            }
          }
		    },
		    
		    sendItemsRequest : function() {
		      params = {request: this.options.getItemsRequest,
		                pageNumber: this.getCurrentPage(),
		                pageSize: this.getPageSize()};
		      params = $.extend({}, this.context, params);
	        $.getMSJSON(this.options.serviceUrl, params, 
	                    Function.createDelegate(this, this.updateContentHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));
		    },
		    
		    sendTotalCountRequest : function() {
		      params = {request: this.options.getTotalCountRequest};
		      params = $.extend({}, this.context, params);		    
          $.getMSJSON(this.options.serviceUrl, params,
	                    Function.createDelegate(this, this.updateTotalCountHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));
		    },
		    
		    errorRequestHandler : function(response, result) {
	           $.log('WARN', response.responseText);
		    },
		    
		    updateContentHandler : function(data, result) {
		      if (result == 'success') {
		        if (typeof data != 'undefined' && data != null) {
              this.items = data;
		          this.updateContent();
		          if (this.options.preloader) {
		            $(this.placeHolder).unblock();
		          }
              this.fireDatabindEvent();
            }
		      }
		    },		   
		     
		    updateTotalCountHandler : function(data, result) {
		      if (result == 'success') {
		        if (typeof data != 'undefined' && data != null) {
              this.totalCount = data;
		          this.updateContent();
              this.fireDatabindEvent();
            }
		      }
		    },
		    
		    deleteItem : function(id) {		    
		      params = {request: this.options.deleteItemRequest, id : id};
		      params = $.extend({}, this.context, params);		    
          $.getMSJSON(this.options.serviceUrl, params,
	                    Function.createDelegate(this, this.deleteItemHandler),
	                    Function.createDelegate(this, this.errorRequestHandler));		    
		    },
		    
		    deleteItemHandler: function(data, result) {
		      if (result == 'success' && data) {
		        if (data.IsSuccess) {
		          if (this.items.length <= 1 && this.getCurrentPage() > 0) {
		            this.setCurrentPage(this.getCurrentPage() - 1);
		          }
		          this.retrieveData();
		          messageType = "Notification";
		          title = "Success";
		        }
		        else {
		          messageType = "Error";
		          title = "You've got some errors.";
		        }	            
            $('form').messageBox(null, {
              messageType: messageType, 
              title: title,               
              width: 350, 
              top: 10, 
              modal: false, 
              autoClose: true}, 
              '<div class="SysInfo"><p>' + data.Message + '</p></div>');
		      }		    
		    },
		    
		    fireDatabindEvent : function() {
	        if (this.items != null && this.totalCount != null) {
	          this.databind();
	        }		    
		    },
		    
		    databind : function(callback) {
		      if (callback && typeof callback == 'function') {
		        return $(this.placeHolder).databind(callback);
		      }
		      else {
		        return $(this.placeHolder).databind();
		      }
		    }		    	    		     
		  };
		    
	    return new listingControl($(this).get(0), options, context);
		};	
				    
    $.fn.listing.defaults = {
      templateUrl : '', 
      serviceUrl: '',
      getItemsRequest: 'GetItems',
      getTotalCountRequest: 'GetTotalCount',
      deleteItemRequest: 'Delete',
      defaultPageSize: 5,
      preloader : 'Please wait ...',
      emptyMessage : '#emptyMessage'
    };				
    
		$.fn.paginator = function(listing, options) {
	    var options = $.extend({}, $.fn.paginator.defaults, options);
		    
	    paginatorControl = function(placeHolder, listing, options) {
        this.placeHolder = placeHolder;
        this.listing = listing;
        this.options = options;

	      this.init();		      
	    }
	    
		  paginatorControl.prototype = {
		    
		    init : function() {
		      if (this.placeHolder) {
		        $(this.placeHolder).setTemplateURL(this.options.templateUrl, null, {filter_data: true});
		        if (this.listing) {
		          this.listing.databind(Function.createDelegate(this, this.databindHandler));
		        }
		      }
		    },
		    
		    updateContent : function() {
		      currentPage = this.listing.getCurrentPage();
		      pageSize = this.listing.getPageSize();
		      pageCount = this.listing.getPageCount();
		      startIndex = Math.max(currentPage - this.options.visiblePagesRange, 0);
		      endIndex = Math.min(currentPage + this.options.visiblePagesRange, pageCount - 1);
		      showBackLink = currentPage > 0;
		      showNextLink = currentPage < pageCount - 1;
		      
		      $(this.placeHolder).processTemplate({
		        showBackLink: showBackLink, 
		        showNextLink: showNextLink, 
		        currentPage: currentPage,
		        startIndex: startIndex,
		        endIndex: endIndex
		      });
		      
		      currentPaginator = this;
		      $('a', this.placeHolder).each(function() {
		        link = $(this);
		        if (link.html().indexOf('Next') > 0) {
		          link.click(Function.createDelegate(currentPaginator, currentPaginator.goToNextPageHandler));
		        }
		        if (link.html().indexOf('Back') > 0) {
		          link.click(Function.createDelegate(currentPaginator, currentPaginator.goToPrevPageHandler));
		        }
		        if (/\d+/.test(link.html())) {
		          link.click(Function.createCallback(currentPaginator.setPageHandler, {listing: currentPaginator.listing, pageNumber : parseInt(link.html()) - 1}));
		        }
		      });
		    },
		    
		    databindHandler : function() {
		      this.updateContent();
		    },
		    
		    setPageHandler : function(e, context) {
		      context.listing.setCurrentPage(context.pageNumber);
		    },
		    		    
		    goToNextPageHandler : function() {
		      this.listing.setCurrentPage(this.listing.getCurrentPage() + 1);
		    },
		    		    		    
		    goToPrevPageHandler : function() {
		      this.listing.setCurrentPage(this.listing.getCurrentPage() - 1);
		    }
		  };
		    
	    $(this).each(function() {											
        return new paginatorControl(this, listing, options);
      });
		};	
				    
    $.fn.paginator.defaults = {
      templateUrl : '', 
      visiblePagesRange: 2
    };			
    
    $.fn.pageSize = function(listing, options) {	
      var options = $.extend({}, $.fn.pageSize.defaults, options);
      
	    pageSizeControl = function(placeHolder, listing, options) {
        this.placeHolder = placeHolder;
        this.listing = listing;
        this.options = options;
        this.sizesList;

	      this.init();		      
	    }
	    
		  pageSizeControl.prototype = {    
		    
		    init : function() {
		      if (this.placeHolder) {
		        this.buildSizesList();
		        if (this.sizesList) {
		          $(this.sizesList).bind('change', Function.createDelegate(this, this.pageSizeChangedHandler));
		        }
		      }
		    },
		    
		    buildSizesList : function() {
		      this.sizesList = $.create('select').appendTo($(this.placeHolder));
          for (var i in this.options.availableSizes) {
            size = this.options.availableSizes[i];
            newOption = $.create('option', {text: String.format(this.options.textTemplate, size), value: size});
            $(this.sizesList).each(function() {
              if ($.browser.msie) {
                this.options.add(newOption[0]);
              }
              else {
                this.appendChild(newOption[0]);
              }            
            });
          } 		      
		    },
		    
		    pageSizeChangedHandler: function() {
		      if (this.listing) {
		        newPageSize = parseInt();
		        this.listing.setPageSize($(this.sizesList).val());
		      }
		    }
		  };
		    
	    $(this).each(function() {											
        return new pageSizeControl(this, listing, options);
      });      
		};	
				    
    $.fn.pageSize.defaults = {
      availableSizes : [5, 10, 15, 20],
      textTemplate : '{0} items/page'
    };	    
	
})(jQuery);
