// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class Star implements Serializable {
// 	private static final long serialVersionUID = 1851275921474044916L;
// 		
// 
// 	private final double time;
// 	private final double frequency;
// 	private final double intensity;
// 	private final int x;
// 	private final int y;
// 		
// 	public Star(final double time, final double frequency, final double intensity, final int x, final int y) {
// 		this.time = time;
// 		this.frequency = frequency;
// 		this.intensity = intensity;
// 		this.x = x;
// 		this.y = y;
// 	}
// 
// 	public double getTime() {
// 		return time;
// 	}
// 
// 	public double getFrequency() {
// 		return frequency;
// 	}
// 
// 	public double getIntensity() {
// 		return intensity;
// 	}
// 		
// 	public int getTick() {
// 		return x;
// 	}
// 		
// 	public int getBin() {
// 		return y;
// 	}
// 		
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + x;
// 		result = prime * result + y;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Star other = (Star) obj;
// 		if (x != other.x)
// 			return false;
// 		if (y != other.y)
// 			return false;
// 		return true;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "Star [x=" + x + ", y=" + y + ", intensity=" + intensity + "]";
// 	}
// }
// 
// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class StarEnergyComparator implements Comparator<Star> {
// 		
// 	private final boolean reverse;
// 
// 	public StarEnergyComparator(boolean reverse) {
// 		this.reverse = reverse;
// 	}
// 
// 	@Override
// 	public int compare(Star o1, Star o2) {
// 		if (o1 == null || o2 == null) {
// 			throw new IllegalArgumentException("Can't compare null - " + o1 + " // " + o2 + "!");
// 		}
// 			
// 		if (reverse) {
// 			return Double.compare(o2.getIntensity(), o1.getIntensity());
// 		}
// 		else {
// 			return Double.compare(o1.getIntensity(), o2.getIntensity());
// 		}
// 	}
// 		
// }


import java.util.Collection;
import java.util.Collections;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.signature.ConstellationMap.StarEnergyComparator;
import org.sidoh.song_recognition.spectrogram.Spectrogram;
import com.google.common.collect.MinMaxPriorityQueue;
package org.sidoh.song_recognition.signature;




/**
 * This {@link StarBuffer} doesn't care where stars come from. It just keeps
 * track of the ones with the highest intensity using a {@link MinMaxPriorityQueue}.
 * 
 * @author chris
 *
 */
public class CoordinateAgnosticStarBuffer extends StarBuffer {
	
	public static class Builder extends StarBuffer.Builder {
		public Builder(double starDensityFactor) {
			super(starDensityFactor);
		}
		
		@Override
		public StarBuffer create(Spectrogram spec) {
			return new CoordinateAgnosticStarBuffer(spec, starDensityFactor);
		}
	}
	
	private final double starDensityFactor;
	private final Collection<Star> pq;

	public CoordinateAgnosticStarBuffer(Spectrogram spec, double starDensityFactor) {
		super(spec);
		this.starDensityFactor = starDensityFactor;
		this.pq = Collections.synchronizedCollection(MinMaxPriorityQueue
// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class Star implements Serializable {
// 	private static final long serialVersionUID = 1851275921474044916L;
// 		
// 
// 	private final double time;
// 	private final double frequency;
// 	private final double intensity;
// 	private final int x;
// 	private final int y;
// 		
// 	public Star(final double time, final double frequency, final double intensity, final int x, final int y) {
// 		this.time = time;
// 		this.frequency = frequency;
// 		this.intensity = intensity;
// 		this.x = x;
// 		this.y = y;
// 	}
// 
// 	public double getTime() {
// 		return time;
// 	}
// 
// 	public double getFrequency() {
// 		return frequency;
// 	}
// 
// 	public double getIntensity() {
// 		return intensity;
// 	}
// 		
// 	public int getTick() {
// 		return x;
// 	}
// 		
// 	public int getBin() {
// 		return y;
// 	}
// 		
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + x;
// 		result = prime * result + y;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Star other = (Star) obj;
// 		if (x != other.x)
// 			return false;
// 		if (y != other.y)
// 			return false;
// 		return true;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "Star [x=" + x + ", y=" + y + ", intensity=" + intensity + "]";
// 	}
// }
// 
// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class StarEnergyComparator implements Comparator<Star> {
// 		
// 	private final boolean reverse;
// 
// 	public StarEnergyComparator(boolean reverse) {
// 		this.reverse = reverse;
// 	}
// 
// 	@Override
// 	public int compare(Star o1, Star o2) {
// 		if (o1 == null || o2 == null) {
// 			throw new IllegalArgumentException("Can't compare null - " + o1 + " // " + o2 + "!");
// 		}
// 			
// 		if (reverse) {
// 			return Double.compare(o2.getIntensity(), o1.getIntensity());
// 		}
// 		else {
// 			return Double.compare(o1.getIntensity(), o2.getIntensity());
// 		}
// 	}
// 		
// }


// Path: src/java/org/sidoh/song_recognition/signature/CoordinateAgnosticStarBuffer.java
import java.util.Collection;
import java.util.Collections;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.signature.ConstellationMap.StarEnergyComparator;
import org.sidoh.song_recognition.spectrogram.Spectrogram;
import com.google.common.collect.MinMaxPriorityQueue;

package org.sidoh.song_recognition.signature;




/**
 * This {@link StarBuffer} doesn't care where stars come from. It just keeps
 * track of the ones with the highest intensity using a {@link MinMaxPriorityQueue}.
 * 
 * @author chris
 *
 */
public class CoordinateAgnosticStarBuffer extends StarBuffer {
	
	public static class Builder extends StarBuffer.Builder {
		public Builder(double starDensityFactor) {
			super(starDensityFactor);
		}
		
		@Override
		public StarBuffer create(Spectrogram spec) {
			return new CoordinateAgnosticStarBuffer(spec, starDensityFactor);
		}
	}
	
	private final double starDensityFactor;
	private final Collection<Star> pq;

	public CoordinateAgnosticStarBuffer(Spectrogram spec, double starDensityFactor) {
		super(spec);
		this.starDensityFactor = starDensityFactor;
		this.pq = Collections.synchronizedCollection(MinMaxPriorityQueue
			.orderedBy(new StarEnergyComparator(true))