function Transpack() {

    this.setFromSelector = function (selector, source) {
        if (source === undefined) {
            source = storage.transactions;
        }

        var transactions = [];
        
        var incomes = [];
        $.each(storage.incomes, function () {
            var reject = false;

            if (selector.startDate !== null) {

                if (this.getRealDate() < selector.startDate) {
                    reject = true;
                }
            }

            if (selector.endDate !== null) {
                if (this.getRealDate() > selector.endDate) {
                    reject = true;
                }
            }
            
            if (selector.bankAccount !== null) {
                if (this.getBankAccount() !== selector.bankAccount) {
                    reject = true;
                }
            }

            if (!reject) {
                incomes.push(this);
            }
            
        });
       
        $.each(source, function () {
            // push all transaction that matches filter
            var reject = false;

            if (selector.startDate !== null) {

                if (this.getRealDate() < selector.startDate) {
                    reject = true;
                }
            }

            if (selector.endDate !== null) {
                if (this.getRealDate() > selector.endDate) {
                    reject = true;
                }
            }

            if (selector.cat !== null) {
                if (this.getCategory() !== selector.cat) {
                    reject = true;
                }
            }

            if (selector.bankAccount !== null) {
                if (this.getBankAccount() !== selector.bankAccount) {
                    reject = true;
                }
            }

            if (!reject) {
                transactions.push(this);
            }
        });
       
        
        this.selector = selector;
            
        this.setTransactions(transactions);
        this.incomes = incomes;
    };


    this.setTransactions = function (transactions) {
        
        this.transactions = $(transactions);
        
        
        var maxAmount = 0;
        var total = 0;

        $.each(this.transactions, function () {
            total += parseFloat(this.getAmount());

            if (parseFloat(this.getAmount()) > maxAmount) {
                maxAmount = parseFloat(this.getAmount());
            }
        });

        this.totalAmount = total;
        this.maxAmount = maxAmount;
    };

    this.getNumberOfTransactions = function () {
        if (this.transactions === undefined) {
            return 0;
        }

        return this.transactions.length;
    };

    this.getAverageAmount = function () {
        var average = this.getTotalAmount() / this.getNumberOfTransactions();

        if (average > 0) {
            return parseInt(average, 10);
        } else {
            return 0;
        }
    };

    this.getTotalAmount = function () {
        return parseInt(this.totalAmount, 10);
    };

    this.getMaxAmount = function () {
        return this.maxAmount;
    };

    this.getFirstDate = function () {

        if (this.selector.getStart() !== null) {
            return this.selector.getStart();
        } else {
            
            if (this.transactions.length > 0) {
                return $(this.transactions).first()[0].getRealDate();
            } else {
                return "-1";
            }
        }
    };

    this.getLastDate = function () {

        if (this.selector.getEnd() !== null) {
            return this.selector.getEnd();
        } else {
            if (this.transactions.length > 0) {
                //return $(this.transactions).last()[0].getRealDate();
                return new Date();
            } else {
                return "-1";
            }
        }
    };

    this.getAmountPerDay = function () {
        var amount = this.getTotalAmount() / this.getTotalDaysByTransactions();
        return parseInt(amount, 10);
    };

    this.getTotalDaysByTransactions = function () {
     
        var diff = $(this.transactions).last()[0].getRealDate().getTime() - $(this.transactions).first()[0].getRealDate().getTime();
        var days = Math.round(diff / (1000 * 3600 * 24));

        if (days === 0) {
            return 1;
        }
        else {
            return days;
        }

        return 1;
    };
    
    this.getTotalDaysByDate = function () {
        var diff = this.getLastDate().getTime() - $(this.transactions).first()[0].getRealDate().getTime();
        var days = Math.round(diff / (1000 * 3600 * 24));

        if (days === 0) {
            return 1;
        }
        else {
            return days;
        }

        return 1;
           
    };
    
    

    this.getMonthTranspacks = function () {
        // selectors with from startDate to now

        var selectors = getMonthTranspackSelectors(this.getFirstDate(), {bankAccount: this.selector.bankAccount});

        var monthTranspacks = Array();
        
        // build transpacks for each month
        var that = this;
        $(selectors).each(function () {
            var temp = new Transpack();
            temp.setFromSelector(this, that.transactions);
            monthTranspacks.push(temp);
        });

        return monthTranspacks;
    };

    this.getPeriod = function () {

        return {
            start: this.getFirstDate(),
            end: this.getLastDate()
        };
    };

    this.getReportData = function () {
        var r = new Report(this);
        return r.getReportData();
    };
    
    
    this.getCombinedStartDate = function () {
            var incomeStartDate;
        
              var startDate =this.transactions[0].getRealDate();
              
              if(this.incomes.length >0)
                    incomeStartDate = this.incomes[0].getRealDate();
              
              if(startDate >incomeStartDate) {
                  startDate = incomeStartDate;
              }
              
              return startDate;
    };
    
    this.getTotalIncomes = function () {
           sum = 0;
           
           $(this.incomes).each(function () {
               sum += parseFloat(this.getAmount());
           });
           
           return parseInt(-sum, 10);
    };
    
    
    this.getTotalDiff = function () {
           return this.getTotalIncomes()-this.getTotalAmount();
    };
    
    
    this.getBarGraphDataByMonth = function () {
           var data = [];
           
           var monthTranspacks = this.getMonthTranspacks();
           
           $(monthTranspacks).each(function () {
               var temp = {
                   label: this.getFirstDate().getMonthName()+' '+this.getFirstDate().getFullYear(),
                   value: this.getTotalAmount()
               }
               
               data.push(temp);
               
           });
           
           return data;
    };
    
    this.getLineGraphDataExpenses = function () {
            //kind of a mess, but works...

            var allDates = [];

            var startDate =this.transactions[0].getRealDate();  
            var endDate =this.transactions[this.transactions.length -1].getRealDate();

            var num = 0;
            var data = [];

            while(startDate < endDate){
                data[new Date(startDate).toString('yyyy-MM-dd')] = 0;
                startDate.addDays(1);
                num++;
            }

            var total = 0;
            $(this.transactions).each(function () {
                var temp = this.getDate();
                total += parseInt(this.getAmount(),10);
                data[temp] = total;
            });

            var last = -1;
            for(var i in data) {
                if(data[i] !==0){
                 last = data[i]    
                }
                allDates.push(last);        	
            }

            allDates.pop();

            return allDates;
        };
    
    
    this.getLineGraphData = function () {
        //kind of a mess, but works...
        
        
        var allDates = [];
      
        var startDate = this.getCombinedStartDate();  
        
        var endDate = this.transactions[this.transactions.length -1].getRealDate();
        
        var incomeEndDate;
        if(this.incomes.length >0)
            incomeEndDate = this.incomes[this.incomes.length -1].getRealDate();
    
        
        if(endDate >incomeEndDate) {
            endDate = incomeEndDate;
        }
        
        var combined = [];
        
        
        $(this.transactions).each(function () {
            combined.push(this);
        });
        
        $(this.incomes).each(function () {
            combined.push(this);
        });
        
        
        
        
        combined = $(combined).sort("date", "asc");
        
        
        var num = 0;
        var data = [];
        
        while(startDate < endDate){
            data[new Date(startDate).toString('yyyy-MM-dd')] = 0;
            startDate.addDays(1);
            num++;
        }
        
        
        var total = 0;
        $(combined).each(function () {
            var temp = this.getDate();
            total += parseInt(this.getAmount(),10);
            data[temp] = total;
        });
        
        var last = -1;
        for(var i in data) {
            if(data[i] !==0){
             last = data[i]    
            }
            allDates.push(last);        	
        }
        
        allDates.pop();
        return allDates;
    };
    
}
