001/*
002 * $RCSfile$
003 * 
004 * $Author: crawl $ $Date: 2015-08-24 22:44:14 +0000 (Mon, 24 Aug 2015) $ $Revision: 33630 $
005 * 
006 * For Details: http://kepler-project.org
007 * 
008 * Copyright (c) 2007 The Regents of the University of California. All rights
009 * reserved.
010 * 
011 * Permission is hereby granted, without written agreement and without license
012 * or royalty fees, to use, copy, modify, and distribute this software and its
013 * documentation for any purpose, provided that the above copyright notice and
014 * the following two paragraphs appear in all copies of this software.
015 * 
016 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
017 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
018 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
019 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
020 * 
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
023 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
024 * "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
025 * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
026 */
027package org.kepler.monitor;
028
029import java.awt.Font;
030import java.awt.geom.Rectangle2D;
031import java.awt.geom.RoundRectangle2D;
032
033import org.kepler.monitor.figure.BaseFigure;
034import org.kepler.monitor.figure.ProgressBarFigure;
035import org.kepler.monitor.figure.QualityFigure;
036import org.kepler.monitor.figure.TrafficLightFigure;
037
038import diva.canvas.Figure;
039import diva.canvas.toolbox.LabelFigure;
040import ptolemy.actor.IOPort;
041import ptolemy.data.expr.StringParameter;
042import ptolemy.kernel.util.Attribute;
043import ptolemy.kernel.util.IllegalActionException;
044import ptolemy.kernel.util.NameDuplicationException;
045import ptolemy.kernel.util.NamedObj;
046import ptolemy.kernel.util.SingletonAttribute;
047
048/**
049 * An instance of this class is automatically added by the monitor manager for
050 * each entity to be monitored.
051 * 
052 * <p>
053 * This attribute contains a MonitorIcon.
054 * 
055 * @author Carlos Rueda
056 * @version $Id: MonitorAttribute.java 33630 2015-08-24 22:44:14Z crawl $
057 */
058public class MonitorAttribute extends SingletonAttribute {
059        public StringParameter iconType;
060
061        public StringParameter timerDelay;
062
063        /**
064         * Creates a monitor attribute.
065         */
066        public MonitorAttribute(NamedObj container, String name)
067                        throws IllegalActionException, NameDuplicationException {
068                super(container, name);
069
070                iconType = new StringParameter(this, "iconType");
071                String[] iconTypes = MonitorAttribute.iconTypes();
072                iconType.setExpression(iconTypes[0]);
073                for (int i = 0; i < iconTypes.length; i++) {
074                        // don't show the COUNTER style:
075                        if (!iconTypes[i].equals(MonitorAttribute.COUNTER)) {
076                                iconType.addChoice(iconTypes[i]);
077                        }
078                }
079                iconType.setDisplayName("Icon type");
080
081                timerDelay = new StringParameter(this, "timerDelay");
082                timerDelay.setExpression("1000");
083                timerDelay.setDisplayName("Timer delay (ms)");
084
085                _icon = new MonitorIcon(this, "_icon");
086                
087                setPersistent(false);
088        }
089
090        public void setMonitoredStatus(MonitoredStatus status) {
091                _status = status;
092        }
093
094        /**
095         * @param updater
096         *            the FigureUpdater to set
097         */
098        public void setFigureUpdater(FigureUpdater updater) {
099                _figureUpdater = updater;
100        }
101
102        public FigureUpdater getFigureUpdater() {
103                return _figureUpdater;
104        }
105
106        /**
107         * @return the IOPort. null by default.
108         */
109        public IOPort getPort() {
110                return port;
111        }
112
113        /**
114         * @param port
115         *            the IOPort to set
116         */
117        public void setPort(IOPort port) {
118                this.port = port;
119        }
120
121        /**
122         * Do updates according to the changed attribute.
123         */
124        @Override
125    public void attributeChanged(Attribute attribute)
126                        throws IllegalActionException {
127
128                if (attribute == iconType) {
129
130                        // Note: for simplicity, just recreate the figure.
131
132                        Figure fig;
133
134                        String iconTypeValue = iconType.stringValue();
135                        if (iconTypeValue.equals(TRAFFIC_LIGHT3_VRT)) {
136                                fig = new TrafficLightFigure(3, new Rectangle2D.Double(3, 3,
137                                                _radius, 3 * _radius));
138                        } else if (iconTypeValue.equals(TRAFFIC_LIGHT3_HRZ)) {
139                                fig = new TrafficLightFigure(3, new Rectangle2D.Double(3, 3,
140                                                3 * _radius, _radius));
141                                ((TrafficLightFigure) fig)
142                                                .setOrientation(BaseFigure.Orientation.HORIZONTAL);
143                        } else if (iconTypeValue.equals(TRAFFIC_LIGHT2_VRT)) {
144                                fig = new TrafficLightFigure(2, new Rectangle2D.Double(3, 3,
145                                                _radius, 2 * _radius));
146                        } else if (iconTypeValue.equals(TRAFFIC_LIGHT2_HRZ)) {
147                                fig = new TrafficLightFigure(2, new Rectangle2D.Double(3, 3,
148                                                2 * _radius, _radius));
149                                ((TrafficLightFigure) fig)
150                                                .setOrientation(BaseFigure.Orientation.HORIZONTAL);
151                        } else if (iconTypeValue.equals(TRAFFIC_LIGHT1)) {
152                                fig = new TrafficLightFigure(1, new Rectangle2D.Double(3, 3,
153                                                _radius, _radius));
154                        } else if (iconTypeValue.equals(PROGRESS_BAR_HRZ)) {
155                                ProgressBarFigure pb = new ProgressBarFigure(
156                                                new RoundRectangle2D.Double(3, 3, 6 * _radius, _radius,
157                                                                _radius, _radius));
158                                pb.setOrientation(BaseFigure.Orientation.HORIZONTAL);
159                                pb.setIndeterminate(true);
160                                fig = pb;
161                        } else if (iconTypeValue.equals(PROGRESS_BAR_VRT)) {
162                                ProgressBarFigure pb = new ProgressBarFigure(
163                                                new RoundRectangle2D.Double(3, 3, _radius, 3 * _radius,
164                                                                _radius, _radius));
165                                pb.setOrientation(BaseFigure.Orientation.VERTICAL);
166                                pb.setIndeterminate(true);
167                                fig = pb;
168                        } else if (iconTypeValue.equals(COUNTER)) {
169                                fig = new LabelFigure("0",
170                                                new Font("monospaced", Font.PLAIN, 8));
171
172                                // FIXME if the figure is set to a different style later,
173                                // the background color is lost.
174                                _icon.setBackgroundColor(null);
175                        } else if (iconTypeValue.equals(QUALITY_FIGURE)) { 
176                                fig = new QualityFigure(new Rectangle2D.Double(3, 3,
177                                                _radius, 3 * _radius));
178                        } else {
179                                throw new IllegalActionException("Unexpected iconType: "
180                                                + iconTypeValue);
181                        }
182
183                        _icon.setFigure(fig);
184
185                        if (_figureUpdater != null) {
186                                _figureUpdater.setFigure(fig);
187                        }
188                } else if (attribute == timerDelay) {
189                        int delay;
190                        try {
191                                delay = Integer.parseInt(timerDelay.stringValue());
192                        } catch (NumberFormatException e) {
193                                throw new IllegalActionException("NumberFormatException: " + e);
194                        }
195
196                        if (_status != null) {
197                                _status.getPropertyTimer().setDelay(delay);
198                        }
199                } else {
200                        super.attributeChanged(attribute);
201                }
202        }
203
204        /** If this component is removed from its container, finish monitoring */
205        @Override
206    public void setContainer(NamedObj container) throws IllegalActionException,
207                        NameDuplicationException {
208                super.setContainer(container);
209                if (container == null && _figureUpdater != null) {
210                        _figureUpdater.stop();
211                }
212                // else: what TODO if container != getContainer() ?
213        }
214
215        public MonitorIcon getIcon() {
216                return _icon;
217        }
218
219        // ///////////////////////////////////////////////////////////////
220        // package private members ////
221
222        /**
223         * Returns the types of the supported styles.
224         */
225        static String[] iconTypes() {
226                return ICON_TYPES;
227        }
228
229        static final String COUNTER = "counter";
230
231        // ///////////////////////////////////////////////////////////////
232        // private members ////
233
234        private static final String TRAFFIC_LIGHT3_HRZ = "horizontal trafficLight3";
235
236        private static final String TRAFFIC_LIGHT3_VRT = "vertical trafficLight3";
237
238        private static final String TRAFFIC_LIGHT2_HRZ = "horizontal trafficLight2";
239
240        private static final String TRAFFIC_LIGHT2_VRT = "vertical trafficLight2";
241
242        private static final String TRAFFIC_LIGHT1 = "trafficLight1";
243
244        private static final String PROGRESS_BAR_HRZ = "horizontal progress bar";
245
246        private static final String PROGRESS_BAR_VRT = "vertical progress bar";
247                
248        private static final String  QUALITY_FIGURE = "quality figure"; 
249
250        private static final String[] ICON_TYPES = { TRAFFIC_LIGHT3_HRZ,
251                        TRAFFIC_LIGHT3_VRT, TRAFFIC_LIGHT2_HRZ, TRAFFIC_LIGHT2_VRT,
252                        TRAFFIC_LIGHT1, PROGRESS_BAR_HRZ, PROGRESS_BAR_VRT, COUNTER, QUALITY_FIGURE };
253
254        // TODO parameterize
255        private static final double _radius = 8;
256
257        private MonitoredStatus _status;
258
259        private FigureUpdater _figureUpdater;
260
261        private MonitorIcon _icon;
262
263        private IOPort port;
264
265        private static final long serialVersionUID = 1L;
266}