/* * Copyright (c) 2008, 2009, 2010, 2011 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.plugins.discogs.model; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.discogs.model.Release; import org.discogs.model.Track; import com.tulskiy.musique.util.Util; /** * @author mliauchuk */ public class ReleaseTracklistingModel { public static final Pattern[] trackPositionPatterns = { Pattern.compile("(\\d+)\\.(\\d+)"), Pattern.compile("(\\d+)-(\\d+)"), Pattern.compile("CD(\\d+)\\.(\\d+)"), Pattern.compile("CD(\\d+)-(\\d+)") }; private final Map<Track, TracklistingItem> items = new LinkedHashMap<Track, TracklistingItem>(); public ReleaseTracklistingModel(Release release) { List<Track> tracks = new LinkedList<Track>(release.getTracks()); processIndexTracks(tracks); processDiscTotal(tracks); processDiscAndTrack(tracks); processTrackTotal(); } public String getTrackTrack(Track track) { TracklistingItem item = items.get(track); return item == null ? null : item.track.toString(); } public String getTrackTrackTotal(Track track) { TracklistingItem item = items.get(track); return item == null ? null : item.trackTotal.toString(); } public String getTrackDisc(Track track) { TracklistingItem item = items.get(track); return item == null ? null : item.disc.toString(); } public String getTrackDiscTotal(Track track) { TracklistingItem item = items.get(track); return item == null ? null : item.discTotal.toString(); } private class TracklistingItem { public Integer track; public Integer trackTotal; public Integer disc; public Integer discTotal; TracklistingItem(Integer track, Integer trackTotal, Integer disc, Integer discTotal) { this.track = track; this.trackTotal = trackTotal; this.disc = disc; this.discTotal = discTotal; } } private void processIndexTracks(List<Track> tracks) { int i = 0; while (i < tracks.size()) { if (Util.isEmpty(tracks.get(i).getPositionRaw())) { // items.put(tracks.get(i), new TracklistingItem(null, null, null, null)); tracks.remove(i); } else { i++; } } } private void processDiscTotal(List<Track> tracks) { String s; int discTotal = 0; for (Track track : tracks) { s = extractDisc(track.getPositionRaw()); if (s != null) { int disc = Integer.parseInt(s); if (disc > discTotal) { discTotal = disc; } } } if (discTotal == 0) { discTotal = 1; } for (Track track : tracks) { items.put(track, new TracklistingItem(null, null, null, discTotal)); } } private void processDiscAndTrack(List<Track> tracks) { Entry<Track, TracklistingItem> entry_prev = null; Entry<Track, TracklistingItem> entry_curr = null; TracklistingItem item_prev = null; TracklistingItem item_curr = null; Iterator<Entry<Track, TracklistingItem>> entries = items.entrySet().iterator(); while (entries.hasNext()) { entry_curr = entries.next(); item_curr = entry_curr.getValue(); if (entry_prev == null) { item_curr.disc = 1; item_curr.track = 1; } else { String pos = entry_curr.getKey().getPositionRaw(); String sDisc = extractDisc(pos); String sTrack = extractTrack(pos); if (sDisc == null && sTrack == null) { item_prev = entry_prev.getValue(); item_curr.disc = item_prev.disc; item_curr.track = item_prev.track + 1; } else { item_curr.disc = Integer.parseInt(sDisc); item_curr.track = Integer.parseInt(sTrack); } } entry_prev = entry_curr; } } private void processTrackTotal() { int disc = 0; List<TracklistingItem> discItems = new LinkedList<TracklistingItem>(); Iterator<Entry<Track, TracklistingItem>> entries = items.entrySet().iterator(); if (entries.hasNext()) { TracklistingItem item = entries.next().getValue(); disc = item.disc; discItems.add(item); } while (entries.hasNext()) { TracklistingItem item = entries.next().getValue(); if (disc != item.disc) { disc = item.disc; for (TracklistingItem discItem : discItems) { discItem.trackTotal = discItems.size(); } discItems.clear(); } discItems.add(item); } for (TracklistingItem discItem : discItems) { discItem.trackTotal = discItems.size(); } } private String extractDisc(String pos) { if (pos != null) { for (Pattern tpp : trackPositionPatterns) { Matcher matcher = tpp.matcher(pos); if (matcher.find()) { return matcher.group(1); } } } return null; } private String extractTrack(String pos) { if (pos != null) { for (Pattern tpp : trackPositionPatterns) { Matcher matcher = tpp.matcher(pos); if (matcher.find()) { return matcher.group(2); } } } return null; } }