001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2023
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see http://www.gnu.org/licenses.
027 */
028
029package edu.wisc.ssec.mcidasv.ui;
030
031import java.io.IOException;
032
033import java.util.List;
034import java.util.ArrayList;
035
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038import ucar.unidata.ui.colortable.ColorTableManager;
039import ucar.unidata.ui.colortable.ColorTableDefaults;
040
041import ucar.unidata.util.ColorTable;
042import ucar.unidata.util.FileManager;
043import ucar.unidata.util.IOUtil;
044import ucar.unidata.util.NamedObject;
045import ucar.unidata.util.ObjectListener;
046import ucar.unidata.util.PatternFileFilter;
047import ucar.unidata.util.ResourceManager;
048
049import ucar.unidata.xml.XmlEncoder;
050
051/**
052 * A class to manage Hydra color tables
053 */
054public class McIdasColorTableManager extends ColorTableManager {
055
056    /** The color table category */
057    public static final String CATEGORY_HYDRA = "HYDRA";
058
059    /** File filter used for {@literal "HYDRA"} color tables */
060    public static final PatternFileFilter FILTER_HYDRA =
061        new PatternFileFilter(".+\\.ascii", "3-column RGB color table (*.ascii)", ".ascii");
062
063    /** File filter used for McIDAS-X {@literal "enhancement files"} */
064    public static final PatternFileFilter FILTER_ET =
065        new PatternFileFilter(".+\\.et", "McIDAS-X color table (*.et)", ".et");
066
067    /** File filter used for AWIPS II {@literal ".cmap"} color tables.*/
068    public static final PatternFileFilter FILTER_AWIPS2 = 
069        new PatternFileFilter(".+\\.cmap", "AWIPS II color table (*.cmap)", ".cmap");
070    
071    /**
072     * Create the color table manager.
073     */
074    public McIdasColorTableManager() {
075        super();
076    }
077
078    /**
079     * Fills the given list with menu items that represent that available
080     * color tables.
081     * 
082     * Overridden in McIDAS-V to force presence of the {@literal "local"} tag.
083     */
084    @Override public void makeColorTableMenu(final ObjectListener listener, List l) {
085        makeColorTableMenu(listener, l, true);
086    }
087
088    /**
089     * Return the file filters used for writing a file on an import.
090     *
091     * @return Read file filters.
092     */
093    @Override public List getReadFileFilters() {
094        ColorTableManager ctm = new ColorTableManager();
095        List filters = ctm.getWriteFileFilters();
096        filters.add(FILTER_HYDRA);
097        filters.add(FILTER_ET);
098        filters.add(FILTER_AWIPS2);
099        return filters;
100    }
101
102    /**
103     * Import a color table.
104     *
105     * @param makeUnique If true then we change the name of the color table so it is unique
106     * @return The imported color table
107     */
108    @Override public NamedObject doImport(boolean makeUnique) {
109        String file = FileManager.getReadFile(getTitle() + " import",
110                          getReadFileFilters());
111        if (file == null) {
112            return null;
113        }
114
115        try {
116            List cts = processSpecial(file, null, null);
117            if (cts != null) {
118                return doImport(cts, makeUnique);
119            }
120        } catch (IOException ioe) {
121            LU.printException(log_, "Error reading file: " + file, ioe);
122            return null;
123        }
124        try {
125            String xml = IOUtil.readContents(file, ResourceManager.class);
126            if (xml == null) {
127                return null;
128            }
129            Object o = (new XmlEncoder()).toObject(xml);
130            return doImport(o, makeUnique);
131        } catch (Exception exc) {
132            LU.printException(log_, "Error reading file: " + file, exc);
133        }
134        return null;
135    }
136
137    private static final Logger logger = LoggerFactory.getLogger(McIdasColorTableManager.class);
138
139    /**
140     * Try to load in one of the {@literal "special"} color table formats..
141     *
142     * <p>Special types include: </p>
143     *
144     * @param file file
145     * @param name _more_
146     * @param category category
147     *
148     * @return the ct
149     *
150     * @throws IOException _more_
151     */
152    public List<ColorTable> handleColorTable(String file,
153                                             String name,
154                                             String category)
155        throws IOException
156    {
157        String cat = category;
158        if (name == null) {
159            name = IOUtil.stripExtension(IOUtil.getFileTail(file));
160        }
161        if (cat == null) {
162            cat = ColorTable.CATEGORY_BASIC;
163        }
164
165        String suffix = file.toLowerCase();
166        List<ColorTable> cts = new ArrayList<>();
167        if (suffix.endsWith(".et")) {
168            if (category == null) {
169                cat = ColorTable.CATEGORY_SATELLITE;
170            }
171            cts.add(ColorTableDefaults.createColorTable(name, cat,
172                    ColorTableDefaults.makeTableFromET(file, false)));
173        } else if (suffix.endsWith(".pa1")) {
174            cts.add(ColorTableDefaults.createColorTable(name, cat,
175                    ColorTableDefaults.makeTableFromPal1(file)));
176        } else if (suffix.endsWith(".pa2")) {
177            cts.add(ColorTableDefaults.createColorTable(name, cat,
178                    ColorTableDefaults.makeTableFromPal2(file)));
179        } else if (suffix.endsWith(".pal")) {
180            cts.add(ColorTableDefaults.createColorTable(name, cat,
181                    ColorTableDefaults.makeTableFromPal(file)));
182        } else if (suffix.endsWith(".act")) {
183            cts.add(ColorTableDefaults.createColorTable(name, cat,
184                    ColorTableDefaults.makeTableFromAct(file)));
185        } else if (suffix.endsWith(".ncmap")) {
186            //Treat these like gempak
187            cts.addAll(ColorTableDefaults.makeGempakColorTables(name, cat, file));
188        } else if (suffix.endsWith(".gp")) {
189            cts.addAll(ColorTableDefaults.makeNclRgbColorTables(name, cat, file, null));
190        } else if (isGempakFile(file)) {
191            cts.addAll(ColorTableDefaults.makeGempakColorTables(name, cat, file));
192        } else if (suffix.endsWith(".rgb")) {
193            cts.addAll(ColorTableDefaults.makeRgbColorTables(name, cat, file));
194        } else if (suffix.endsWith(".cmap")) {
195            cts.addAll(McIdasColorTableDefaults.makeAwips2ColorTables(name, cat, file));
196        } else if (suffix.endsWith(".ascii")) {
197            if (category == null) {
198                cat = CATEGORY_HYDRA;
199            }
200            cts.add(McIdasColorTableDefaults.createColorTable(name, cat,
201                    McIdasColorTableDefaults.makeTableFromASCII(file)));
202        } else {
203            return null;
204        }
205        if (cts.isEmpty()) {
206            logger.trace("nothing to return!?");
207            return null;
208        }
209        return cts;
210    }
211
212    /**
213     * Try to load in one of the special colortables
214     *
215     * @param file file
216     * @param name _more_
217     * @param category category
218     *
219     * @return the ct
220     *
221     * @throws IOException _more_
222     */
223    private List processSpecial(String file, String name, String category)
224            throws IOException
225    {
226        return handleColorTable(file, name, category);
227    }
228    
229    /**
230     * Is the given file a Gempak file
231     *          
232     * @param file The file name to check
233     * @return Is it a Gempak file
234     */
235    private boolean isGempakFile(String file) {
236        return file.toLowerCase().endsWith(".tbl");
237    }
238}
239