package com.yonge.netty.dto;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 一个音符的频率范围，包含最大值和最小值
 */
public class NoteFrequencyRange {

	private double minFrequency;

	private double maxFrequency;

	public NoteFrequencyRange(double standardPitch, double frequency) {
		int midiNoteSize = 128;
		double[] midiNoteFrequencies = new double[midiNoteSize];

		for (int x = 0; x < midiNoteSize; ++x) {
			midiNoteFrequencies[x] = new BigDecimal(standardPitch).multiply(
					new BigDecimal(Math.pow(2, new BigDecimal(x - 69).divide(new BigDecimal(12), 6, BigDecimal.ROUND_HALF_UP).doubleValue()))).doubleValue();

			if(frequency <= 0){
				continue;
			}
			
			if (midiNoteFrequencies[x] >= frequency) {
				if (midiNoteFrequencies[x] - frequency > frequency - midiNoteFrequencies[x - 1]) {
					// frequency演奏的是上一个音符
					maxFrequency = midiNoteFrequencies[x - 1] + (midiNoteFrequencies[x] - midiNoteFrequencies[x - 1]) / 2;
					minFrequency = midiNoteFrequencies[x - 1] - (midiNoteFrequencies[x - 1] - midiNoteFrequencies[x - 2]) / 2;
				} else {
					// frequency演奏的是当前音符
					midiNoteFrequencies[x + 1] = new BigDecimal(standardPitch).multiply(
							new BigDecimal(Math.pow(2, new BigDecimal((x + 1) - 69).divide(new BigDecimal(12), 6, BigDecimal.ROUND_HALF_UP).doubleValue())))
							.doubleValue();
					maxFrequency = midiNoteFrequencies[x] + (midiNoteFrequencies[x + 1] - midiNoteFrequencies[x]) / 2;
					minFrequency = midiNoteFrequencies[x] - (midiNoteFrequencies[x] - midiNoteFrequencies[x - 1]) / 2;
				}
				break;
			}
		}
	}

	public NoteFrequencyRange(double frequency) {
		new NoteFrequencyRange(442, frequency);
	}

	public double getMinFrequency() {
		return minFrequency;
	}

	public void setMinFrequency(double minFrequency) {
		this.minFrequency = minFrequency;
	}

	public double getMaxFrequency() {
		return maxFrequency;
	}

	public void setMaxFrequency(double maxFrequency) {
		this.maxFrequency = maxFrequency;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof NoteFrequencyRange) {
			NoteFrequencyRange nfr = (NoteFrequencyRange) obj;
			return this.minFrequency == nfr.minFrequency && this.maxFrequency == nfr.maxFrequency;
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		int result = 17;
		result = 31 * result + Double.hashCode(minFrequency);
		result = 31 * result + Double.hashCode(maxFrequency);
		return result;
	}

	public static void main(String[] args) {
		
		Map<NoteFrequencyRange,Integer> map = new HashMap<NoteFrequencyRange, Integer>();
		
		NoteFrequencyRange nfr = new NoteFrequencyRange(442,442);
		System.out.println(nfr.getMinFrequency() + "-"+ nfr.getMaxFrequency());
		
		if(map.containsKey(nfr) == false){
			map.put(nfr, 1);
		}

		NoteFrequencyRange nfr1 = new NoteFrequencyRange(442,430);
		System.out.println(nfr1.getMinFrequency() + "-"+ nfr1.getMaxFrequency());
		
		if(map.containsKey(nfr1) == false){
			map.put(nfr1, 1);
		}else{
			map.put(nfr, 2);
		}
		
		System.out.println(nfr.equals(nfr1));
		System.out.println(map.size());
		
	}

}
