001    /**
002     * planningtool - A Planning Tool with Critiquing Support.
003     * 
004     * Copyright (C) 2006 olale
005    
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU General Public License
008     * as published by the Free Software Foundation; either version 2
009     * of the License, or (at your option) any later version.
010    
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015    
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019    
020     * Contact information: 
021     * E-mail: olale@ida.liu.se
022     *         olale@lysator.liu.se
023     */
024    package se.liu.ida.critiquer.constraints;
025    
026    import java.awt.BasicStroke;
027    import java.awt.Color;
028    import java.awt.Graphics2D;
029    import java.awt.Shape;
030    import java.awt.Stroke;
031    import java.util.HashMap;
032    import java.util.Set;
033    import java.util.Map.Entry;
034    
035    import se.liu.ida.critiquer.activities.Activity;
036    import se.liu.ida.critiquer.activities.ActivityUtils;
037    import se.liu.ida.critiquer.activities.parameters.NumberSelectionParameter;
038    import se.liu.ida.critiquer.activities.parameters.Parameter;
039    import se.liu.ida.critiquer.activities.parameters.TimeParameter;
040    import se.liu.ida.critiquer.gui.View;
041    
042    /**
043     * This class represents the constraint that activities must be completed within a certain time frame from the time they are started 
044     * 
045     */
046    public class TooLongTime extends StandardConstraint {
047    
048            
049            /**
050             * 
051             */
052            private static final long serialVersionUID = 1L;
053            private HashMap<Activity, Boolean> violationActivities = new HashMap<Activity, Boolean>();
054            
055            /* (non-Javadoc)
056             * @see se.liu.ida.critiquer.activities.AbstractParamChangedListener#activityCreated(se.liu.ida.critiquer.activities.Activity)
057             */
058            @Override
059            public void activityCreated(Activity activity) {
060                    checkViolation(activity, ActivityUtils.getStartTimeParameter(activity), ActivityUtils.getEndTimeParameter(activity));
061            }
062    
063            /* (non-Javadoc)
064             * @see se.liu.ida.critiquer.activities.AbstractParamChangedListener#activityUpdated(se.liu.ida.critiquer.activities.Activity)
065             */
066            @Override
067            public void activityUpdated(Activity activity) {
068                    checkViolation(activity, ActivityUtils.getStartTimeParameter(activity), ActivityUtils.getEndTimeParameter(activity));
069            }
070    
071            public <T> void paramChanged(Activity activity, Parameter<T> p) {
072                    TimeParameter startParam = ActivityUtils.getStartTimeParameter(activity);
073                    TimeParameter endParam = ActivityUtils.getEndTimeParameter(activity);
074                    NumberSelectionParameter maxTimeParam = ActivityUtils.getMaxTimeParameter(activity);
075                    if (p == startParam || p == endParam || p == maxTimeParam) {
076                            checkViolation(activity, startParam, endParam);
077                            
078                    }
079            
080            }
081    
082            private void checkViolation(Activity activity, TimeParameter startParam, TimeParameter endParam) {
083                    // Time currently scheduled for activity, in minutes
084                    long activityTime = ((endParam.getValue().getTimeInMillis() - 
085                                    startParam.getValue().getTimeInMillis()) / 60000);
086                    if (activityTime > activity.getMaxTime()) {
087                            violationActivities.put(activity, true);
088                    } else {
089                            violationActivities.put(activity, false);
090                    }
091                    setConsistent(!violationActivities.containsValue(Boolean.TRUE));
092            }
093    
094            public void viewUpdated(View v, Graphics2D g2) {
095                    Set<Entry<Activity, Boolean>> set = violationActivities.entrySet();
096                    Activity activity;
097                    Boolean violation;
098                    for (Entry<Activity, Boolean> entry : set) {
099                            activity = entry.getKey();
100                            violation = entry.getValue();
101                            Shape activityArea = v.getActivityArea(activity);
102                            /*
103                             * only visualize activities that the view shows.
104                             * 
105                             */
106                            if (violation && (activityArea != null)) {
107                                    
108                                    Color oldColor = g2.getColor();
109                                    g2.setColor(getColor());
110                                    Stroke s = new BasicStroke(3,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,0,new float[] {3},0);
111                                    Stroke oldStroke = g2.getStroke();
112                                    g2.setStroke(s);
113                                    g2.draw(activityArea);
114                                    g2.setStroke(oldStroke);
115                                    g2.setColor(oldColor);
116                            }
117                    }
118            }
119    
120    
121    
122            public String getDescription() {
123                    String nl = System.getProperty("line.separator");
124                    return "Draws a red line around missions that take"+nl+
125                    "too long time to complete according to a"+nl+
126                    "specified max time."+nl+nl+"The maximum allowed time depends on the type of activity";
127            }
128    
129    }