001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.image;
020
021/**
022 * @author Stephane
023 */
024public class PixelPosition extends ChannelPosition
025{
026    public static final char X_ID = 'X';
027    public static final char Y_ID = 'Y';
028
029    private int x;
030    private int y;
031
032    /**
033     * @param t
034     * @param z
035     * @param c
036     */
037    public PixelPosition(int t, int z, int c, int x, int y)
038    {
039        super(t, z, c);
040
041        this.x = x;
042        this.y = y;
043    }
044
045    public PixelPosition()
046    {
047        this(-1, -1, -1, -1, -1);
048    }
049
050    public void copyFrom(PixelPosition pp)
051    {
052        t = pp.t;
053        z = pp.z;
054        c = pp.c;
055        y = pp.y;
056        x = pp.x;
057    }
058
059    @Override
060    public void switchLeft()
061    {
062        t = z;
063        z = c;
064        c = y;
065        y = x;
066        x = 0;
067    }
068
069    @Override
070    public void switchRight()
071    {
072        x = y;
073        y = c;
074        c = z;
075        z = t;
076        t = 0;
077    }
078
079    /**
080     * @return the x
081     */
082    public int getX()
083    {
084        return x;
085    }
086
087    /**
088     * @param x
089     *        the x to set
090     */
091    public void setX(int x)
092    {
093        this.x = x;
094    }
095
096    /**
097     * @return the y
098     */
099    public int getY()
100    {
101        return y;
102    }
103
104    /**
105     * @param y
106     *        the y to set
107     */
108    public void setY(int y)
109    {
110        this.y = y;
111    }
112
113    public void set(int t, int z, int c, int x, int y)
114    {
115        super.set(t, z, c);
116        this.x = x;
117        this.y = y;
118    }
119
120    @Override
121    public int get(char ident)
122    {
123        final char id = Character.toUpperCase(ident);
124
125        switch (id)
126        {
127            case X_ID:
128                return x;
129
130            case Y_ID:
131                return y;
132        }
133
134        return super.get(ident);
135    }
136
137    public static boolean isValidIdentStatic(char ident)
138    {
139        final char id = Character.toUpperCase(ident);
140
141        return ChannelPosition.isValidIdentStatic(ident) || (id == X_ID) || (id == Y_ID);
142    }
143
144    @Override
145    public boolean isValidIdent(char ident)
146    {
147        return super.isValidIdentStatic(ident);
148    }
149
150    public boolean isXUndefined()
151    {
152        return (x == -1);
153    }
154
155    public boolean isYUndefined()
156    {
157        return (y == -1);
158    }
159
160    @Override
161    public boolean isUndefined()
162    {
163        return isXUndefined() || isYUndefined() || super.isUndefined();
164    }
165
166    /**
167     * Return first undefined position (T -> Z -> C -> Y -> X)
168     */
169    @Override
170    public char getFirstEmptyPos()
171    {
172        final char result = super.getFirstEmptyPos();
173
174        // parent doesn't have any spare position
175        if (result == ' ')
176        {
177            // check in own position
178            if (isYUndefined())
179                return Y_ID;
180            if (isXUndefined())
181                return X_ID;
182        }
183
184        return result;
185    }
186
187    /**
188     * Return last undefined position (X -> Y -> C -> Z -> T)
189     */
190    @Override
191    public char getLastEmptyPos()
192    {
193        // check in own position
194        if (isXUndefined())
195            return X_ID;
196        if (isYUndefined())
197            return Y_ID;
198
199        return super.getFirstEmptyPos();
200    }
201
202    public boolean isSamePos(PixelPosition pp, char posIdent)
203    {
204        final char id = Character.toUpperCase(posIdent);
205
206        switch (id)
207        {
208            case X_ID:
209                if ((t == -1) || (z == -1) || (c == -1) || (x == -1))
210                    return false;
211                return (pp.t == t) && (pp.z == z) && (pp.c == c) && (pp.x == x);
212
213            case Y_ID:
214                if ((t == -1) || (z == -1) || (c == -1) || (x == -1) || (y == -1))
215                    return false;
216                return (pp.t == t) && (pp.z == z) && (pp.c == c) && (pp.x == x) && (pp.y == y);
217        }
218
219        return super.isSamePos(pp, posIdent);
220    }
221
222    @Override
223    public int compareTo(ImagePosition o)
224    {
225        final int result = super.compareTo(o);
226
227        if ((result == 0) && (o instanceof PixelPosition))
228        {
229            final PixelPosition pp = (PixelPosition) o;
230
231            final int ox = pp.x;
232            final int oy = pp.y;
233
234            if (x > ox)
235                return 1;
236            if (x < ox)
237                return -1;
238            if (y > oy)
239                return 1;
240            if (y < oy)
241                return -1;
242        }
243
244        return result;
245    }
246}