001/*
002 *    $RCSfile$
003 *
004 *     $Author: crawl $
005 *       $Date: 2014-08-26 00:46:48 +0000 (Tue, 26 Aug 2014) $
006 *   $Revision: 32920 $
007 *
008 *  For Details: http://kepler-project.org
009 *
010 * Copyright (c) 2007 The Regents of the University of California.
011 * All rights reserved.
012 *
013 * Permission is hereby granted, without written agreement and without
014 * license or royalty fees, to use, copy, modify, and distribute this
015 * software and its documentation for any purpose, provided that the
016 * above copyright notice and the following two paragraphs appear in
017 * all copies of this software.
018 *
019 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
020 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
021 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
022 * IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
023 * OF SUCH DAMAGE.
024 *
025 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
026 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
027 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
028 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
029 * OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
030 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
031 */
032package org.kepler.monitor.figure;
033
034import java.awt.Color;
035import java.awt.geom.Ellipse2D;
036import java.awt.geom.RectangularShape;
037
038import org.kepler.monitor.MonitoredStatus.State;
039
040import diva.canvas.toolbox.BasicFigure;
041
042public class TrafficLightFigure extends StateFigure {
043
044        public TrafficLightFigure(int numberOfLights, RectangularShape shape) {
045                super(shape);
046                if (numberOfLights <= 0) {
047                        throw new IllegalArgumentException(
048                                        "numberOfLights must be positive");
049                }
050
051                this._shape = (RectangularShape) shape.clone();
052
053                _orientation = Orientation.VERTICAL;
054
055                figs = new BasicFigure[numberOfLights];
056                _setLights(figs, _orientation, _shape);
057                for (BasicFigure fig : figs) {
058                        this.add(fig);
059                }
060
061                // set the color schemes for my possible states:
062                Color[] idleColors = new Color[numberOfLights];
063                Color[] waitingColors = new Color[numberOfLights];
064                Color[] runningColors = new Color[numberOfLights];
065                Color[] errorColors = new Color[numberOfLights];
066                for (int i = 0; i < numberOfLights; i++) {
067                        idleColors[i] = Color.GRAY;
068                        waitingColors[i] = Color.GRAY;
069                        runningColors[i] = Color.GRAY;
070                        errorColors[i] = Color.RED;
071                }
072                runningColors[numberOfLights - 1] = Color.GREEN;
073
074                int wait_from = 1;
075                int wait_lim = numberOfLights - 1;
076                if (numberOfLights == 2) {
077                        wait_from = 0;
078                } else if (numberOfLights == 1) {
079                        wait_from = 0;
080                        wait_lim = numberOfLights;
081                }
082                for (int i = wait_from; i < wait_lim; i++) {
083                        waitingColors[i] = Color.YELLOW;
084                }
085
086                // Add my possible states:
087                addColorScheme(State.IDLE, idleColors);
088                addColorScheme(State.WAITING, waitingColors);
089                addColorScheme(State.RUNNING, runningColors);
090                addColorScheme(State.ERROR, errorColors);
091
092                // set current state, and the state for the timer:
093                setState(State.IDLE);
094        }
095
096        /**
097         * Sets the orientation and calls {@link #update()} if the orientation
098         * changes.
099         * 
100         * @param orientation
101         *            the orientation.
102         */
103        @Override
104    public void setOrientation(Orientation orientation) {
105                Orientation old = this._orientation;
106                this._orientation = orientation;
107                if (old != orientation) {
108                        _setLights(figs, _orientation, _shape);
109                        update();
110                }
111        }
112
113        // /////////////////////////////////////////////////////////////////
114        // // protected members ////
115
116        /**
117         * Sets the color for each light according to current state.
118         */
119        @Override
120    protected void _update() {
121                Color[] colors = getColorScheme(_currentState);
122                for (int i = 0; i < figs.length; i++) {
123                        figs[i].setFillPaint(colors[i]);
124                }
125        }
126
127        // /////////////////////////////////////////////////////////////////
128        // // private members ////
129
130        /**
131         * Creates or sets the shape for the lights.
132         */
133        private static void _setLights(BasicFigure[] figs, Orientation orientation,
134                        RectangularShape shape) {
135                int numberOfLights = figs.length;
136                double x = shape.getX();
137                double y = shape.getY();
138                double h = shape.getHeight();
139                double w = shape.getWidth();
140
141                double figW = w;
142                double figH = h / numberOfLights;
143                double incX = 0;
144                double incY = figH;
145
146                if (orientation == Orientation.VERTICAL) {
147                        figW = w;
148                        figH = h / numberOfLights;
149                        incX = 0;
150                        incY = figH;
151                } else {
152                        figW = w / numberOfLights;
153                        figH = h;
154                        incX = figW;
155                        incY = 0;
156                }
157
158                // create or set the lights:
159                for (int i = 0; i < figs.length; i++) {
160                        if (figs[i] == null) {
161                                figs[i] = new BasicFigure(new Ellipse2D.Double(x + i * incX, y
162                                                + i * incY, figW, figH));
163                        } else {
164                                figs[i].setShape(new Ellipse2D.Double(x + i * incX, y + i
165                                                * incY, figW, figH));
166                        }
167                }
168        }
169
170        /** The lights */
171        private BasicFigure[] figs;
172
173}