001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.ui.graphicGraph.stylesheet;
033
034import java.util.ArrayList;
035import java.util.Iterator;
036
037/**
038 * Several values and the units of these values.
039 * 
040 * <p>
041 * As a style sheet may express values in several different units. This class
042 * purpose is to pack the value and the units it is expressed in into a single
043 * object.
044 * </p>
045 */
046public class Values implements Iterable<Double> {
047        // Attributes
048
049        /**
050         * The value.
051         */
052        public ArrayList<Double> values = new ArrayList<Double>();
053
054        /**
055         * The values units.
056         */
057        public Style.Units units;
058
059        // Constructor
060
061        /**
062         * New value set with one initial value.
063         * 
064         * @param units
065         *            The values units.
066         * @param values
067         *            A variable count of values.
068         */
069        public Values(Style.Units units, double... values) {
070                this.units = units;
071
072                for (double value : values)
073                        this.values.add(value);
074        }
075
076        /**
077         * New copy of another value set.
078         * 
079         * @param other
080         *            The other values to copy.
081         */
082        public Values(Values other) {
083                this.values = new ArrayList<Double>(other.values);
084                this.units = other.units;
085        }
086
087        /**
088         * New set of one value.
089         * 
090         * @param value
091         *            The value to copy with its units.
092         */
093        public Values(Value value) {
094                this.values = new ArrayList<Double>();
095                this.units = value.units;
096
097                values.add(value.value);
098        }
099
100        /**
101         * Number of values in this set.
102         * 
103         * @return The number of values.
104         */
105        public int size() {
106                return values.size();
107        }
108
109        /**
110         * Number of values in this set.
111         * 
112         * @return The number of values.
113         */
114        public int getValueCount() {
115                return values.size();
116        }
117
118        /**
119         * The i-th value of this set. If the index is less than zero, the first
120         * value is given, if the index if greater or equal to the number of values,
121         * the last value is given.
122         * 
123         * @param i
124         *            The value index.
125         * @return The corresponding value.
126         */
127        public double get(int i) {
128                if (i < 0)
129                        return values.get(0);
130                else if (i >= values.size())
131                        return values.get(values.size() - 1);
132                else
133                        return values.get(i);
134        }
135
136        /**
137         * Values units.
138         * 
139         * @return The units used for each value.
140         */
141        public Style.Units getUnits() {
142                return units;
143        }
144
145        @Override
146        public boolean equals(Object o) {
147                if (o != this) {
148                        if (!(o instanceof Values))
149                                return false;
150
151                        Values other = (Values) o;
152
153                        if (other.units != units)
154                                return false;
155
156                        int n = values.size();
157
158                        if (other.values.size() != n)
159                                return false;
160
161                        for (int i = 0; i < n; i++) {
162                                if (!other.values.get(i).equals(values.get(i)))
163                                        return false;
164                        }
165                }
166
167                return true;
168        }
169
170        public Iterator<Double> iterator() {
171                return values.iterator();
172        }
173
174        @Override
175        public String toString() {
176                StringBuilder builder = new StringBuilder();
177
178                builder.append('(');
179                for (double value : values) {
180                        builder.append(' ');
181                        builder.append(value);
182                }
183                builder.append(" )");
184
185                switch (units) {
186                case GU:
187                        builder.append("gu");
188                        break;
189                case PX:
190                        builder.append("px");
191                        break;
192                case PERCENTS:
193                        builder.append("%");
194                        break;
195                default:
196                        builder.append("wtf (what's the fuck?)");
197                        break;
198                }
199
200                return builder.toString();
201        }
202
203        /**
204         * Copy the given values to this set. The units are also copied.
205         * 
206         * @param values
207         *            The values to copy.
208         */
209        public void copy(Values values) {
210                units = values.units;
211                this.values.clear();
212                this.values.addAll(values.values);
213        }
214
215        /**
216         * Append the given set of values at the end of this set.
217         * 
218         * @param values
219         *            The value set to append.
220         */
221        public void addValues(double... values) {
222                for (double value : values)
223                        this.values.add(value);
224        }
225
226        /**
227         * Insert the given value at the given index.
228         * 
229         * @param i
230         *            Where to insert the value.
231         * @param value
232         *            The value to insert.
233         */
234        public void insertValue(int i, double value) {
235                values.add(i, value);
236        }
237
238        /**
239         * Change the i-th value.
240         * 
241         * @param i
242         *            The value index.
243         * @param value
244         *            The value to put.
245         */
246        public void setValue(int i, double value) {
247                values.set(i, value);
248        }
249
250        /**
251         * Remove the i-th value.
252         * 
253         * @param i
254         *            The index at which the value is to be removed.
255         */
256        public void removeValue(int i) {
257                values.remove(i);
258        }
259
260        /**
261         * Change the values units.
262         * 
263         * @param units
264         *            The units.
265         */
266        public void setUnits(Style.Units units) {
267                this.units = units;
268        }
269}