﻿function ListUtils() {
    this.topGroups = new Array(),
	this.contentByGroup = new Array(),
	this.list = String,
	this.disableColapseExpand = false,
	this.removeGrouping = function () {

	    if ($('.list-group', this.list).length > 0) {
	        var rows = new Array();
	        $('.list-group', this.list).each(function (e) {
	            $('.list-view', this).each(function (e) {
	                $('.list-view-row', this).each(function (e) {
	                    rows.push(this);
	                });
                });
                $(this).remove();
	            
	        });
	        var list = $(this.list);
	        //$(this.list).empty();
	       // alert(rows.length);
	        $(rows).each(function (e) {
	            list.append(this);
	        })
	    }

	}

    this.quickFilter = function (filterAttr, filterVal) {
		    $('.list-view-row', this.list).each(function (e) {
		        if ($('*[' + filterAttr + ']:first', this).attr(filterAttr).toLowerCase().indexOf(filterVal.toLowerCase()) == -1) {
		            //alert($('*[' + filterAttr + ']:first', this).attr(filterAttr) + '::' + filterVal);
		            $(this).hide();
		        }
		        else {
		            $(this).show();
		        }
		    });
		}
    this.clearFilter = function () {
        $('.list-view-row', this.list).each(function (e) {
            $(this).show();
        });
    }
    this.sort = function (sortKey, asc) {
        
        var sortedGroups = this.topGroups;
        var contentByGroup = this.contentByGroup;

        $('.list-view-row', this.list).each(function (e) {
            var sortValue = $('*[' + sortKey + ']:first', this).attr(sortKey);
            //alert(sortValue +  ':' + $.inArray(sortValue, sortedGroups));
            if ($.inArray(sortValue, sortedGroups) == -1) {

                sortedGroups.push(sortValue);
            }
            //alert(contentByGroup[sortValue]);
            if (contentByGroup[sortValue] == null || contentByGroup[sortValue] == undefined) {
                var content = new Array();
                content.push(this);
                contentByGroup[sortValue] = content;
            }
            else {
                var content = contentByGroup[sortValue];
                content.push(this);
                contentByGroup[sortValue] = content;
            }
            $(this).remove();
        });
        sortedGroups.sort();
        if (!asc) {
            sortedGroups.reverse();
        }
    }

    this.groupBy = function (groupKeys, sortOrders, groupSortOptions) {
        var sortedGroups = this.topGroups;
			var contentByGroup = this.contentByGroup;
		
			var groupKey = groupKeys[0];
			var sortOrder = sortOrders[0];

			var asc = sortOrder == 0 ? true : false;
			this.sort(groupKey, asc);
			
			for(var i = 0; i < sortedGroups.length; i++)
			{
				var key = sortedGroups[i];
				var value = contentByGroup[key];
				var state  = this.disableColapseExpand ? 'expanded' : 'colapsed';
				var groupHeader = $('<div class="list-group"><div class="group-'+state+'"><span class="group-list-header">'+sortedGroups[i]+'</span></div></div>');
				var sortedContent;
				if(groupKeys.length > 1)
				{
					
					var subKeys = new Array();
					for(var k = 1; k < groupKeys.length; k++)
					{
						subKeys.push(groupKeys[k]);
					}
					var subSortOrders = new Array();
					for(var k2 = 1; k2 < sortOrders.length; k2++)
					{
						subSortOrders.push(sortOrders[k2]);
					}
					var subSorter = new ListUtils();
					var container = $('<div class="list-view"></div>');
					$(value).each(function(e){
						var row = $(this).wrap('<div class="list-view-row" />');
						$(row).appendTo(container);
					});

					subSorter.list =  container;
					sortedContent = subSorter.groupBy(subKeys, subSortOrders, groupSortOptions);	
					value = new Array();
					$('.list-group', sortedContent).each(function(e){
						value.push(this);
					});
					//alert(value.length);
				}
				else
				{
					if(groupSortOptions != null){
						
						var subSorter = new ListUtils();
						var container = $('<div class="list-view"></div>');
						$(value).each(function(e){
							var row = $(this).wrap('<div class="list-view-row" />');
							$(row).appendTo(container);
						});
						subSorter.list =  container;
						sortedContent = subSorter.orderBy(groupSortOptions['orderBy'], groupSortOptions['sortDirections']);	
						value = new Array();
						$('.list-view-row', sortedContent).each(function(e){
							value.push(this);
						});
					}
					
					
				}
				var groupBody = $('<div class="list-view"></div>');
				$(value).each(function(e){
						$(this).appendTo(groupBody);
					});
				$(groupBody).hide();
				$(groupHeader).append(groupBody);
				$(this.list).append(groupHeader);
			}

			return this.list;
    }

    this.orderBy2 = function (sortKeys, sortOrder)//sortOrder: 0 - asc, 1 - desc
    {
        var sortOrders = new Array();
        for (var i = 0; i < sortKeys.length; i++) {
            sortOrders.push(sortOrder);
        }
        this.orderBy(sortKeys, sortOrders);
    }

    this.orderBy = function (sortKeys, sortOrders) {
        
        var sortedGroups = this.topGroups;
        var contentByGroup = this.contentByGroup;

        var sortKey = sortKeys[0];
		
        //			$('.list-view-row', this.list).each(function(e){
        //				var sortValue = $('*[' + sortKey + ']:first', this).attr(sortKey);
        //				//alert(sortValue +  ':' + $.inArray(sortValue, sortedGroups));
        //				if($.inArray(sortValue, sortedGroups) == -1){
        //					
        //					sortedGroups.push(sortValue);
        //				}
        //				//alert(contentByGroup[sortValue]);
        //				if(contentByGroup[sortValue] == null || contentByGroup[sortValue] == undefined){
        //					var content = new Array();
        //					content.push(this);
        //					contentByGroup[sortValue] = content;
        //				}
        //				else
        //				{
        //					var content = contentByGroup[sortValue];
        //					content.push(this);
        //					contentByGroup[sortValue] = content;
        //				}
        //				$(this).remove();
        //				
        //			});

        //alert(JSON.stringify(contentByGroup));
        //sortedGroups.sort();
        var asc = sortOrders[0] == 0 ? true : false;
        
        this.sort(sortKey, asc);
        //			if(!asc)
        //			{
        //				sortedGroups.reverse();
        //			}

        for (var i = 0; i < sortedGroups.length; i++) {
            var key = sortedGroups[i];
            var value = contentByGroup[key];

            if (sortKeys.length > 1) {
                var subKeys = new Array();
                for (var k = 1; k < sortKeys.length; k++) {
                    subKeys.push(sortKeys[k]);
                }
                var subSortOrders = new Array();
                for (var k2 = 1; k2 < sortOrders.length; k2++) {
                    subSortOrders.push(sortOrders[k2]);
                }
                var subSorter = new ListUtils();
                var container = $('<div class="list-view"></div>');
                $(value).each(function (e) {
                    var row = $(this).wrap('<div class="list-view-row" />');
                    $(row).appendTo(container);
                });
                //var subList = $(value).wrap('<div class="list-view" />');
                //alert(container.html());
                subSorter.list = container;
                var sortedContent = subSorter.orderBy(subKeys, subSortOrders);
                //alert($(sortedContent).html());	
                value = new Array();
                $('.list-view-row', sortedContent).each(function (e) {
                    //alert($(this).html());
                    value.push(this);
                });
            }
            //alert(value.length);
            for (var j = 0; j < value.length; j++) {
                var content = value[j];
                var row = $(content).wrap('<div class="list-view-row" />');
                //alert($(this.list).html());
                $(this.list).append(row);
            }
        }
        if (sortKeys.length == 1) {
            //alert($(this.list).html());	
        }
        
        return this.list;
    }
};



(function ($) {
    $.fn.listView = function (options) {
		var sortInProgress = false;
        var disColExp = options['groupOptions'] != null ? options['groupOptions']['disableColapseExpand'] : true;
        var utils = new ListUtils();
        utils.disableColapseExpand = disColExp;
        utils.list = $(this);
        //alert(disColExp);
        if (options['enableGrouping']) {
			if(!disColExp){
					if( $(utils.list).attr('data-expandedGroups') == null){
		            
					$('.group-list-header', this).live('click', function (e) {
						$($(this).parent()).attr('class', $($(this).parent()).attr('class') == 'group-colapsed' ? 'group-expanded' : 'group-colapsed');
						var toggledGroup = this;
						var curGroupStr = $(utils.list).attr('data-expandedGroups');//group-list-header
					   // alert(jQuery.data(utils.list, 'expanded-groups'));
		                
						if(curGroupStr == null){
							curGroupStr = $(this).html();
						}
						else
						{
							var curGroups = curGroupStr.split(',');
							if($.inArray($(this).html(), curGroups) == -1
							&& $($(this).parent()).attr('class') != 'group-colapsed'){
								curGroups.push($(this).html());
							}
							 if($.inArray($(this).html(), curGroups) != -1
							 && $($(this).parent()).attr('class') == 'group-colapsed')
							 {
								//alert(curGroups.length);
								var newGroups = new Array();
								$(curGroups).each(function(e){
									//alert(this + ':' + $('.group-list-header:first', utils.list).html());
									if(this != $(toggledGroup).html()){
										newGroups.push(this);
									}
								});
								//alert(newGroups.length);
								curGroups = newGroups;
							 }
							//alert(curGroups.join(','));
							curGroupStr = curGroups.join(',');
						}
		                
						$(utils.list).attr('data-expandedGroups', curGroupStr);
						//alert('data after click: ' + $(utils.list).attr('data-expandedGroups'));
		                
						$('.list-view:first', $($(this).parent()).parent()).slideToggle('fast');
					});
				}
				utils.removeGrouping();
				utils.groupBy(options['groupOptions']['groupBy'], options['groupOptions']['order'], options['groupOptions']['groupSortOptions']);
			}
			else
			{
				//alert('!');
				utils.removeGrouping();
				utils.groupBy(options['groupOptions']['groupBy'], options['groupOptions']['order'], options['groupOptions']['groupSortOptions']);
				$('.list-view', utils.list).slideToggle('fast');
			}
        }
        if (options['defaultSorting'] != null && !options['enableGrouping']) {
            utils.orderBy(options['defaultSorting']['orderBy'], options['defaultSorting']['sortDirections']);
        }
        if (options['enableSorting']) {
            var sortHandle = 'list-header';
            var context = $(this);
            var sortDirections = options['sortOptions']['sortDirections'];
            var reverseDirections = new Array();
            for (var i = 0; i < sortDirections.length; i++) {
                reverseDirections.push(sortDirections[i] == 0 ? 1 : 0);
            }
            if (options['enableGrouping']) {
                sortHandle = 'group-list-header';
                context = null;
            }
            var listSorter = new ListUtils();
            listSorter.list = context;
            //

            jQuery.data(context, 'current-sort-order', 'direct');
            $('.' + sortHandle).unbind('click');
            $('.' + sortHandle).click(function (e) {
               
               if(sortInProgress == true){
                    return false;
               }
               sortInProgress = true;
                if (context == null) {
                    context = $('.list:first', this);
                    listSorter.list = context;
                }
                setTimeout(function () {
                    listSorter.orderBy(options['sortOptions']['orderBy'], jQuery.data(context, 'current-sort-order') == 'direct' ?
				reverseDirections : sortDirections);
                     sortInProgress = false;
                }, 150);
				
                if (jQuery.data(context, 'current-sort-order') == 'direct') {
                    jQuery.data(context, 'current-sort-order', 'reverse');
                }
                else {
                    jQuery.data(context, 'current-sort-order', 'direct');
                }
               
            });
        }
        if (options['enableFilter']) {
            var context = $(this);
            if (options['filterOptions']['type'] == 'quick') {
                var minChars = options['filterOptions']['quickFilterMinChars'];
                var filterAttr = options['filterOptions']['quickFilterAttr'];
                $('.list-view-filter:first', $(this)).show();
                if($('.list-view-filter input:first', $(this)).val() == ''){
                    $('.list-view-filter input:first', $(this)).val(options['filterOptions']['quickFilterTitle']);
                    $('.list-view-filter input:first', $(this)).css('color', 'silver');
                }
                
                $('.list-view-filter input:first', $(this)).focus(function(e){
                    
                    if($('.list-view-filter input:first', $(context)).val() == options['filterOptions']['quickFilterTitle']){
                        $('.list-view-filter input:first', $(context)).val('');
                        //alert($('.list-view-filter input:first', $(context)).val());
                        $('.list-view-filter input:first', $(context)).css('color', 'black');
                    }
                });
                 $('.list-view-filter input:first', $(this)).keydown(function(e){
                    
                    if($('.list-view-filter input:first', $(context)).val() == options['filterOptions']['quickFilterTitle']){
                        $('.list-view-filter input:first', $(context)).val('');
                        //alert($('.list-view-filter input:first', $(context)).val());
                        $('.list-view-filter input:first', $(context)).css('color', 'black');
                    }
                });
                $('.list-view-filter input:first', $(this)).keyup(function (e) {
                    if ($(this).val().length >= minChars) {
                        var filter = new ListUtils();
                        filter.list = $(context);
                        filter.quickFilter(filterAttr, $(this).val());
                    }
                    if ($(this).val().length == 0) {

                        var filter = new ListUtils();
                        filter.list = $(context);
                        filter.clearFilter();
                    }
                });
            }
        }
    };
})(jQuery);

