/* * Copyright (c) 2008, 2009, 2010 Denis Tulskiy * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>. */ package com.tulskiy.musique.gui.model; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import com.tulskiy.musique.playlist.Track; import com.tulskiy.musique.playlist.TrackData; import com.tulskiy.musique.util.Util; /** * @author mliauchuk */ public class FileInfoModel extends MultiTagFieldModel { class Entry { String key; Object value; Entry(String key, Object value) { this.key = key; this.value = value; } } private ArrayList<Entry> list; public FileInfoModel(List<Track> tracks) { super(tracks); } @Override protected void loadTracks(List<Track> tracks) { list = new ArrayList<Entry>(); if (tracks.size() == 1) { fillSingleTrack(tracks.get(0)); } else { fillMultipleTracks(tracks); } } private void fillMultipleTracks(List<Track> tracks) { list.add(new Entry("Tracks selected", tracks.size())); long fileSize = 0; double length = 0; HashMap<String, Integer> formats = new HashMap<String, Integer>(); HashMap<String, Integer> channels = new HashMap<String, Integer>(); HashMap<String, Integer> sampleRate = new HashMap<String, Integer>(); HashSet<String> files = new HashSet<String>(); for (Track track : tracks) { TrackData trackData = track.getTrackData(); if (trackData.isFile()) { fileSize += trackData.getFile().length(); length += trackData.getTotalSamples() / (double) trackData.getSampleRate(); files.add(trackData.getFile().getAbsolutePath()); increment(formats, trackData.getCodec()); increment(channels, trackData.getChannelsAsString()); increment(sampleRate, trackData.getSampleRate() + " Hz"); } } list.add(new Entry("Files", files.toString())); list.add(new Entry("Total size", fileSize + " bytes")); list.add(new Entry("Total Length", Util.formatSeconds(length, 3))); list.add(new Entry("Format", calcPercentage(formats))); list.add(new Entry("Channels", calcPercentage(channels))); list.add(new Entry("Sample Rate", calcPercentage(sampleRate))); } private Object calcPercentage(Map<String, Integer> map) { double total = 0; for (Integer val : map.values()) { total += val; } ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); boolean single = map.size() == 1; StringBuilder sb = new StringBuilder(); for (Map.Entry<String, Integer> entry : list) { sb.append(entry.getKey()); if (!single) { sb.append(" (").append(String.format("%.2f", entry.getValue() / total * 100)).append("%), "); } } return sb.toString().replaceAll(", $", ""); } private void increment(Map<String, Integer> map, String key) { Integer val = map.get(key); if (val == null) { map.put(key, 1); } else { map.put(key, val + 1); } } private void fillSingleTrack(Track track) { TrackData trackData = track.getTrackData(); list.add(new Entry("Location", trackData.getLocation().toString().replaceAll("%\\d\\d", " "))); if (trackData.isFile()) list.add(new Entry("File Size (bytes)", trackData.getFile().length())); if (trackData.getTotalSamples() >= 0) list.add(new Entry("Length", Util.samplesToTime(trackData.getTotalSamples(), trackData.getSampleRate(), 3) + " (" + trackData.getTotalSamples() + " samples)")); list.add(new Entry("Subsong Index", trackData.getSubsongIndex())); if (trackData.isCue()) { list.add(new Entry("Cue Embedded", trackData.isCueEmbedded())); if (!trackData.isCueEmbedded()) { list.add(new Entry("Cue Path", trackData.getCueLocation())); } } list.add(new Entry("Format", trackData.getCodec())); if (!Util.isEmpty(trackData.getEncoder())) { list.add(new Entry("Encoder", trackData.getEncoder())); } list.add(new Entry("Channels", trackData.getChannels())); if (trackData.getSampleRate() > 0) list.add(new Entry("Sample Rate", trackData.getSampleRate() + " Hz")); } @Override public int getRowCount() { return list.size(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { Entry entry = list.get(rowIndex); if (columnIndex == 0) return entry.key; else return String.valueOf(entry.value); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } }