// 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 + "]";
// 	}
// }


import java.util.Iterator;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.spectrogram.Spectrogram;
package org.sidoh.song_recognition.signature;



/**
 * This is used in conjunction with {@link ConstellationMapExtractor} to extract
 * {@link Star}s (Spectrogram peaks). It is fed potential peaks and the coordinates
 * that they reside at, and it keeps track of which ones it likes to keep (in
 * memory). 
 * 
 * It should support an operation called flush(), which should return an 
 * {@link Iterator} of {@link Star}s that it'd like to keep.
 * 
 * {@link StarBuffer}s are required to be thread safe.
 * 
 * @author chris
 */
public abstract class StarBuffer {
	
	public static abstract class Builder {
		protected static final double[] fairSizes   = {0.05d, 0.15, 0.40d};
		protected static final double[] fairWeights = {0.1d, 0.7d, 0.2d};
		
		protected double starDensityFactor;
		
		public Builder(double starDensityFactor) {
			this.starDensityFactor = starDensityFactor;
		}
		
		public Builder starDensityFactor(double starDensityFactor) {
			this.starDensityFactor = starDensityFactor;
			return this;
		}
		
		public EvenFrequencyBandsStarBuffer.Builder evenlyBanded(int numBands) {
			return new EvenFrequencyBandsStarBuffer.Builder(numBands, this);
		}
		
		public ManuallyBucketizedFrequencyBandsStarBuffer.Builder manuallyBanded(double[] bandSizes, double[] bandWeights) {
			return new ManuallyBucketizedFrequencyBandsStarBuffer.Builder(starDensityFactor, bandSizes, bandWeights, this);
		}
		
		public ManuallyBucketizedFrequencyBandsStarBuffer.Builder fairlyBanded() {
			return manuallyBanded(fairSizes, fairWeights);
		}
		
		public abstract StarBuffer create(Spectrogram spec);
	}
	
	protected final Spectrogram spec;

	public StarBuffer(Spectrogram spec) {
		this.spec = spec;
	}

	/**
	 * Offer a {@link Star} to this buffer. It may or may not accept it, and this 
	 * {@link Star} may or may not be returned by {@link #flush()} depending on
	 * how the internal logic works.
	 * 
	 * @param s
	 */
// 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/StarBuffer.java
import java.util.Iterator;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.spectrogram.Spectrogram;

package org.sidoh.song_recognition.signature;



/**
 * This is used in conjunction with {@link ConstellationMapExtractor} to extract
 * {@link Star}s (Spectrogram peaks). It is fed potential peaks and the coordinates
 * that they reside at, and it keeps track of which ones it likes to keep (in
 * memory). 
 * 
 * It should support an operation called flush(), which should return an 
 * {@link Iterator} of {@link Star}s that it'd like to keep.
 * 
 * {@link StarBuffer}s are required to be thread safe.
 * 
 * @author chris
 */
public abstract class StarBuffer {
	
	public static abstract class Builder {
		protected static final double[] fairSizes   = {0.05d, 0.15, 0.40d};
		protected static final double[] fairWeights = {0.1d, 0.7d, 0.2d};
		
		protected double starDensityFactor;
		
		public Builder(double starDensityFactor) {
			this.starDensityFactor = starDensityFactor;
		}
		
		public Builder starDensityFactor(double starDensityFactor) {
			this.starDensityFactor = starDensityFactor;
			return this;
		}
		
		public EvenFrequencyBandsStarBuffer.Builder evenlyBanded(int numBands) {
			return new EvenFrequencyBandsStarBuffer.Builder(numBands, this);
		}
		
		public ManuallyBucketizedFrequencyBandsStarBuffer.Builder manuallyBanded(double[] bandSizes, double[] bandWeights) {
			return new ManuallyBucketizedFrequencyBandsStarBuffer.Builder(starDensityFactor, bandSizes, bandWeights, this);
		}
		
		public ManuallyBucketizedFrequencyBandsStarBuffer.Builder fairlyBanded() {
			return manuallyBanded(fairSizes, fairWeights);
		}
		
		public abstract StarBuffer create(Spectrogram spec);
	}
	
	protected final Spectrogram spec;

	public StarBuffer(Spectrogram spec) {
		this.spec = spec;
	}

	/**
	 * Offer a {@link Star} to this buffer. It may or may not accept it, and this 
	 * {@link Star} may or may not be returned by {@link #flush()} depending on
	 * how the internal logic works.
	 * 
	 * @param s
	 */
	public abstract void offerStar(Star s);