package org.navalplanner.web.montecarlo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.joda.time.LocalDate;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.CategoryModel;
import org.zkoss.zul.Chart;
import org.zkoss.zul.SimpleCategoryModel;


/**
 * @author Diego Pino Garcia <dpino@igalia.com>
 *
 */
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class MonteCarloGraphController extends GenericForwardComposer {

    private Chart monteCarloChart;

    public MonteCarloGraphController() {

    }

    public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
        super.doAfterCompose(comp);
        self.setVariable("monteCarloGraphController", this, true);
    }

    public void onCancel(Event event) {
        cancel();
    }

    public void cancel() {
        self.setVisible(false);
    }

    public void generateMonteCarloGraph(String orderName, Map<LocalDate, BigDecimal> data, boolean byWeek) {
        CategoryModel xymodel;
        if (byWeek) {
            xymodel = generateMonteCarloGraphByWeek(orderName, groupByWeek(data));
        } else {
            xymodel = generateMonteCarloGraphByDay(orderName, data);
        }
        monteCarloChart.setModel(xymodel);
    }

    private CategoryModel generateMonteCarloGraphByDay(String orderName, Map<LocalDate, BigDecimal> data) {
        CategoryModel result = new SimpleCategoryModel();

        List<LocalDate> dates = new ArrayList(data.keySet());
        Collections.sort(dates);
        for (LocalDate date: dates) {
            String labelDate = date.toString();
            result.setValue(orderName, labelDate, data.get(date));
        }
        return result;
    }

    private CategoryModel generateMonteCarloGraphByWeek(String orderName, Map<Integer, BigDecimal> data) {
        CategoryModel result = new SimpleCategoryModel();

        List<Integer> weeks = new ArrayList(data.keySet());
        Collections.sort(weeks);
        Integer first = weeks.get(0);
        Integer last = weeks.get(weeks.size() - 1);
        for (Integer i = first; i <= last; i = i + 1) {
            String labelDate = "W" + i;
            BigDecimal probability = data.get(i);
            if (probability == null) {
                probability = BigDecimal.ZERO;
            }
            result.setValue(orderName, labelDate, probability);
        }

        return result;
    }

    private Map<Integer, BigDecimal> groupByWeek(Map<LocalDate, BigDecimal> data) {
        Map<Integer, BigDecimal> result = new HashMap<Integer, BigDecimal>();

        // Group values of each date by week
        for (LocalDate date: data.keySet()) {
            Integer week = Integer.valueOf(date.getWeekOfWeekyear());
            BigDecimal value = result.get(week);
            value = (value != null) ? value.add(data.get(date)) : data.get(date);
            result.put(week, value);
        }
        return result;
    }

}

@@ -1843,34 +1843,199 @@
     
-for (LocalDate date: dates
+LocalDate first = dates.get(0);%0A        LocalDate last = dates.get(dates.size() - 1);%0A        for (LocalDate i = first; i.isBefore(last) %7C%7C i.isEqual(last); i = i%0A                .plusDays(1)
 ) %7B%0A
@@ -2065,20 +2065,17 @@
 lDate = 
-date
+i
 .toStrin
@@ -2138,20 +2138,17 @@
 ata.get(
-date
+i
 ));%0A    
@@ -2604,34 +2604,62 @@
     
-String labelDate = %22W%22 + i
+plotWeekValue(result, orderName, %22W%22 + i, data.get(i))
 ;%0A  
@@ -2656,35 +2656,146 @@
 et(i));%0A        
+%7D%0A
    
+     return result;%0A    %7D%0A%0A    private void plotWeekValue(CategoryModel model, String orderName, String date,
  BigDecimal prob
@@ -2805,28 +2805,12 @@
 lity
- = data.get(i);%0A    
+) %7B%0A
     
@@ -2852,20 +2852,16 @@
         
-    
 probabil
@@ -2887,28 +2887,24 @@
 RO;%0A        
-    
 %7D%0A          
@@ -2897,34 +2897,29 @@
   %7D%0A        
-    result
+model
 .setValue(or
@@ -2923,30 +2923,25 @@
 (orderName, 
-labelD
+d
 ate, probabi
@@ -2951,42 +2951,8 @@
 y);%0A
-        %7D%0A%0A        return result;%0A
     

Fix bug show all days in MonteCarlo, from beginning to end, even if probability is 0