package com.dlsc.flexgantt.showcase.demo.paging;

import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import com.dlsc.flexgantt.command.IProgressMonitor;
import com.dlsc.flexgantt.model.TimeSpan;
import com.dlsc.flexgantt.model.gantt.DefaultActivityObject;
import com.dlsc.flexgantt.model.gantt.DefaultGanttChartModel;
import com.dlsc.flexgantt.model.gantt.DefaultGanttChartNode;
import com.dlsc.flexgantt.model.gantt.ILayer.Feature;
import com.dlsc.flexgantt.model.gantt.ITimelineObject;
import com.dlsc.flexgantt.model.gantt.Layer;
import com.dlsc.flexgantt.model.paging.Page;
import com.dlsc.flexgantt.util.LabelType;

public class PagingDemoGanttChartModel
        extends
        DefaultGanttChartModel<DefaultGanttChartNode<String, ITimelineObject>, ITimelineObject> {

    private List<Page> loadedPages = new LinkedList<Page>();
    private Layer layer;
    private final int ROW_COUNT = 10;
    private DefaultGanttChartNode[] node;

    public PagingDemoGanttChartModel() {
        super(new DefaultGanttChartNode<String, ITimelineObject>());
        
        layer = new Layer("Layer");
        layer.removeFeature(Feature.TIMELINE_OBJECT_DESCRIPTIONS);
        addLayer(layer);
 
        DefaultGanttChartNode<String, ITimelineObject> rootNode = getRoot();
        node = new DefaultGanttChartNode[ROW_COUNT];
        for (int i = 0; i < ROW_COUNT; i++) {
            node[i] = new DefaultGanttChartNode<String, ITimelineObject>(true);
            node[i].setRowLineVisible(false, true);
            node[i].setKey("Node " + i);
            rootNode.add(node[i]);
            for (int j = 0; j < 3; j++) {
                DefaultGanttChartNode subNode = new DefaultGanttChartNode<String, ITimelineObject>(
                        false);
                subNode.setKey("Sub Node " + j);
                if (j < 2) {
                    subNode.setRowLineVisible(false, false);
                }
                subNode.setColumnValue(Calendar.getInstance().getTime(), 0);
                subNode.setValueEditable(0, true);
                node[i].add(subNode);
            }
        }
    }

    public void loadPage(Page page, IProgressMonitor monitor) {
        if (!loadedPages.contains(page)) {
            doLoadPage(page, monitor);
            loadedPages.add(page);
        }
    }

    @SuppressWarnings("unchecked")
    private void doLoadPage(Page page, IProgressMonitor monitor) {
        if (monitor != null) {
            monitor.beginTask("Loading timeline objects...", ROW_COUNT);
        }
        for (int i = 0; i < ROW_COUNT; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < Math.random() * 500; k++) {
                    DefaultActivityObject tlo = new DefaultActivityObject();
                    int offset = (int) (Math.random() * 334);
                    Calendar c = Calendar.getInstance();
                    c.setTimeInMillis(page.getTimeSpan().getStartTime());
                    c.add(Calendar.DAY_OF_YEAR, offset);
                    Calendar c2 = Calendar.getInstance();
                    c2.setTimeInMillis(page.getTimeSpan().getStartTime());
                    c2.add(Calendar.DAY_OF_YEAR, offset);
                    c2.add(Calendar.DAY_OF_YEAR, Math.max(3, (int) (Math
                            .random() * 10)));
                    if (Math.random() < 0.66) {
                        tlo.setTimeSpan(new TimeSpan(c, c2));
                    } else {
                        tlo.setTimeSpan(new TimeSpan(c));
                    }
                    ((DefaultGanttChartNode) node[i].getChildAt(j))
                            .addTimelineObject(layer, tlo);
                    String label = "Timeline Object " + k;
                    tlo.setLabel(label, LabelType.DESCRIPTION);
                    if (monitor != null) {
                        monitor.subTask(label);
                    }
                }
            }
            if (monitor != null) {
                monitor.worked(1);
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        if (monitor != null) {
            monitor.done();
        }
    }
}
