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.gui.sequence.tools;
020
021import icy.gui.dialog.ActionDialog;
022import icy.gui.frame.progress.ProgressFrame;
023import icy.gui.util.ComponentUtil;
024import icy.image.IcyBufferedImage;
025import icy.main.Icy;
026import icy.sequence.AbstractSequenceModel;
027import icy.sequence.DimensionId;
028import icy.sequence.Sequence;
029import icy.sequence.SequenceUtil;
030import icy.sequence.SequenceUtil.MergeCHelper;
031import icy.sequence.SequenceUtil.MergeTHelper;
032import icy.sequence.SequenceUtil.MergeZHelper;
033import icy.system.thread.ThreadUtil;
034
035import java.awt.BorderLayout;
036import java.awt.event.ActionEvent;
037import java.awt.event.ActionListener;
038import java.awt.image.BufferedImage;
039
040import javax.swing.BorderFactory;
041
042/**
043 * @author Stephane
044 */
045public class SequenceDimensionMergeFrame extends ActionDialog
046{
047    /**
048     * 
049     */
050    private static final long serialVersionUID = 840989682349623342L;
051
052    private class SequenceDimensionMergeFrameModel extends AbstractSequenceModel
053    {
054        public SequenceDimensionMergeFrameModel()
055        {
056            super();
057        }
058
059        @Override
060        public int getSizeX()
061        {
062            return SequenceUtil.getMaxDim(mergePanel.getSequences(), DimensionId.X);
063        }
064
065        @Override
066        public int getSizeY()
067        {
068            return SequenceUtil.getMaxDim(mergePanel.getSequences(), DimensionId.Y);
069        }
070
071        @Override
072        public int getSizeZ()
073        {
074            if (getDimensionId() != DimensionId.Z)
075                return SequenceUtil.getMaxDim(mergePanel.getSequences(), DimensionId.Z);
076
077            int size = 0;
078            for (Sequence seq : mergePanel.getSequences())
079                size += seq.getSizeZ();
080
081            return size;
082        }
083
084        @Override
085        public int getSizeT()
086        {
087            if (getDimensionId() != DimensionId.T)
088                return SequenceUtil.getMaxDim(mergePanel.getSequences(), DimensionId.T);
089
090            int size = 0;
091            for (Sequence seq : mergePanel.getSequences())
092                size += seq.getSizeT();
093
094            return size;
095        }
096
097        @Override
098        public int getSizeC()
099        {
100            int size = 0;
101
102            if (getDimensionId() != DimensionId.C)
103            {
104                for (Sequence seq : mergePanel.getSequences())
105                    size = Math.max(size, seq.getSizeC());
106
107                return size;
108            }
109
110            // in this case we have only single channel sequence
111            return mergePanel.getSelectedChannels().length;
112        }
113
114        @Override
115        public BufferedImage getImage(int t, int z)
116        {
117            final Sequence[] sequences = mergePanel.getSequences();
118
119            final int sizeX = SequenceUtil.getMaxDim(sequences, DimensionId.X);
120            final int sizeY = SequenceUtil.getMaxDim(sequences, DimensionId.Y);
121            final int sizeC = getSizeC();
122
123            final IcyBufferedImage image;
124
125            switch (getDimensionId())
126            {
127                default:
128                case C:
129
130                    image = MergeCHelper.getImage(sequences, mergePanel.getSelectedChannels(), sizeX, sizeY, t, z,
131                            mergePanel.isFillEmptyImageEnabled(), mergePanel.isFitImagesEnabled());
132                    break;
133
134                case Z:
135                    image = MergeZHelper.getImage(sequences, sizeX, sizeY, sizeC, t, z, mergePanel.isInterlaceEnabled(),
136                            mergePanel.isFillEmptyImageEnabled(), mergePanel.isFitImagesEnabled());
137                    break;
138
139                case T:
140                    image = MergeTHelper.getImage(sequences, sizeX, sizeY, sizeC, t, z, mergePanel.isInterlaceEnabled(),
141                            mergePanel.isFillEmptyImageEnabled(), mergePanel.isFitImagesEnabled());
142                    break;
143            }
144
145            return image;
146        }
147
148        @Override
149        public BufferedImage getImage(int t, int z, int c)
150        {
151            final IcyBufferedImage img = (IcyBufferedImage) getImage(t, z);
152
153            if (img != null)
154                return img.getImage(c);
155
156            return null;
157        }
158
159    }
160
161    final SequenceDimensionMergePanel mergePanel;
162
163    public SequenceDimensionMergeFrame(DimensionId dim)
164    {
165        super(dim.toString() + " Dimension merge");
166
167        mergePanel = new SequenceDimensionMergePanel(dim);
168        mergePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 0, 4));
169
170        mainPanel.add(mergePanel, BorderLayout.CENTER);
171        validate();
172
173        mergePanel.setModel(new SequenceDimensionMergeFrameModel());
174
175        setOkAction(new ActionListener()
176        {
177            @Override
178            public void actionPerformed(ActionEvent e)
179            {
180                ThreadUtil.bgRun(new Runnable()
181                {
182                    @Override
183                    public void run()
184                    {
185                        final ProgressFrame pf = new ProgressFrame("Merging sequences...");
186
187                        try
188                        {
189                            final Sequence out;
190
191                            switch (getDimensionId())
192                            {
193                                default:
194                                case C:
195                                    out = SequenceUtil.concatC(mergePanel.getSequences(),
196                                            mergePanel.getSelectedChannels(), mergePanel.isFillEmptyImageEnabled(),
197                                            mergePanel.isFitImagesEnabled(), pf);
198                                    break;
199
200                                case Z:
201                                    out = SequenceUtil.concatZ(mergePanel.getSequences(),
202                                            mergePanel.isInterlaceEnabled(), mergePanel.isFillEmptyImageEnabled(),
203                                            mergePanel.isFitImagesEnabled(), pf);
204                                    break;
205
206                                case T:
207                                    out = SequenceUtil.concatT(mergePanel.getSequences(),
208                                            mergePanel.isInterlaceEnabled(), mergePanel.isFillEmptyImageEnabled(),
209                                            mergePanel.isFitImagesEnabled(), pf);
210                                    break;
211                            }
212
213                            Icy.getMainInterface().addSequence(out);
214                        }
215                        finally
216                        {
217                            pf.close();
218                        }
219                    }
220                });
221            }
222        });
223
224        setSize(420, 520);
225        ComponentUtil.center(this);
226
227        setVisible(true);
228    }
229
230    DimensionId getDimensionId()
231    {
232        return mergePanel.getDimensionId();
233    }
234
235}