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

import java.awt.dnd.DnDConstants;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

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.gantt.TimelineObjectPath;
import com.dlsc.flexgantt.model.treetable.ITreeTableNode;
import com.dlsc.flexgantt.swing.IMessage;
import com.dlsc.flexgantt.swing.MessageTypeId;
import com.dlsc.flexgantt.swing.TimelineObjectPathMessage;
import com.dlsc.flexgantt.util.LabelType;

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

    public static final String INFO = "info";
    public static final String WARNING = "warning";
    public static final String ERROR = "error";

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

    @SuppressWarnings("unchecked")
    public NavigationGanttChartModel() {
        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);
            }
        }

        for (int i = 0; i < ROW_COUNT; i++) {
            
            for (int j = 0; j < 3; j++) {
                /*
                 *  The chances that row contains timeline objects for the current layer is 2 to 1.
                 */

                for (int k = 0; k < Math.random() * 500; k++) {
                    
                    /*
                     *  Row can have up to 500 timeline objects on the current layer.
                     */

                    DefaultActivityObject tlo = new DefaultActivityObject();
                    int offset = (int) (Math.random() * 334);
                    Calendar c = Calendar.getInstance();
                    c.add(Calendar.DAY_OF_YEAR, offset);
                    Calendar c2 = Calendar.getInstance();
                    c2.add(Calendar.DAY_OF_YEAR, offset);
                    c2.add(Calendar.DAY_OF_YEAR,
                            Math.max(3, (int) (Math.random() * 10)));
                        tlo.setTimeSpan(new TimeSpan(c, c2));
                    ((DefaultGanttChartNode) node[i].getChildAt(j))
                            .addTimelineObject(layer, tlo);
                    String label = "tlo #" + k;
                    tlo.setLabel(label, LabelType.DESCRIPTION);
                    if (Math.random() > 0.8) {
                        TimelineObjectPath path = new TimelineObjectPath(
                                new Object[] { root, node[i],
                                        node[i].getChildAt(j) }, tlo, layer);
                        
                        MessageTypeId messageTypeId = MessageTypeId.INFORMATION;
                        if (Math.random() > .7) {
                            messageTypeId = MessageTypeId.WARNING;
                        } else if (Math.random() > .4){
                            messageTypeId = MessageTypeId.ERROR;
                        }
                        TimelineObjectPathMessage msg = new TimelineObjectPathMessage(
                                messageTypeId,
                                node[i].getKey()
                                        + " / "
                                        + ((ITreeTableNode) node[i]
                                                .getChildAt(j)).getKey()
                                        + " / "
                                        + tlo.getLabel(LabelType.DESCRIPTION),
                                path);
                        messages.add(msg);
                    }

                    String nl = System.getProperty("line.separator");
                    StringBuilder sb = new StringBuilder();
                    sb.append("Status: ");
                    
                    if (Math.random() > 0.97) {
                        tlo.setStatus(INFO);
                        sb.append("Info");
                    }
                    
                    if (Math.random() > 0.98) {
                        tlo.setStatus(WARNING);
                        sb.append("Warning");
                    }
                    
                    if (Math.random() > 0.98) {
                        tlo.setStatus(ERROR);
                        sb.append("Error");
                    }
                    
                    if (tlo.getStatus() == null) {
                        sb.append("None");
                    }
                    
                    sb.append(nl);
                    sb.append("Node Changeable: ");
                    if (Math.random() > 0.33) {
                        tlo.setDragActions(DnDConstants.ACTION_NONE);
                        sb.append("Yes");
                    } else {
                        sb.append("No");
                    }
                    sb.append(nl);
                    sb.append("Node Changeable: ");
                    if (Math.random() > 0.66) {
                        tlo.setStartTimeChangeable(false);
                        sb.append("Yes");
                    } else {
                        sb.append("No");
                    }
                    sb.append(nl);
                    sb.append("Duration Changeable: ");
                    if (Math.random() > 0.80) {
                        tlo.setDurationChangeable(false);
                        sb.append("Yes");
                    } else {
                        sb.append("No");
                    }
                    sb.append(nl);
                    tlo.setPopupObject(sb.toString(), false);
                }
            }
        }
    }

    public List<IMessage> getMessages() {
        return messages;
    }
}
