package kr.gui.midigraph;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;

import kr.gui.GuiModel;
import kr.util.audio.MidiAudioClip;
import kr.util.ft.SpectrumAnalyzer;

public class SpectrumScaleUI extends UI
{
	private int minNote;
	private int maxNote;
	private MidiTuneGraph comp;
	private GuiModel gm;

	public SpectrumScaleUI(GuiModel gm, MidiTuneGraph comp, int minNote, int maxNote)
	{
		this.gm = gm;
		this.comp = comp;
		this.minNote = minNote;
		this.maxNote = maxNote;
	}
	
	
	public void drawScale(Graphics2D g, int startX, int endX, SpectrumAnalyzer spectrumAnalyzer, SpectrumAnalyzer spectrumAnalyzer2)
	{
		int w = comp.getWidth();
		int h = comp.getHeight();
		double step = h / (maxNote - minNote + 1);
		double start = step/2.;
		
		//if the step is so small we would end up painting the same note twice at the same pos,
		//skip some notes
		if(step < 1) step = step * Math.ceil(2 / step);
		
		
		double indexToPixelsRatio = 1 / (gm.getPixelsToMicrosRatio() * spectrumAnalyzer.getAudioClip().getMicrosToIndexRatio());
		double offset = (startX - gm.calcNowX(w)) * indexToPixelsRatio + 
			gm.getNowMicros() / spectrumAnalyzer.getAudioClip().getMicrosToIndexRatio(); 
		//indexToPixelsRatio = 1;
		//offset=0;

		
		for(int x = startX; x < endX; x++)
		{
			double [] vals1 = spectrumAnalyzer.getRawResults((int)Math.round(indexToPixelsRatio * (x-startX) + offset));
			double [] vals2 = spectrumAnalyzer2.getRawResults((int)Math.round(indexToPixelsRatio * (x-startX) + offset));
			
			int currMidiNote = minNote-1;
			double threshold = 0;

			double [] results = new double[maxNote - minNote + 1];
			
			for(int i = 0; i < vals1.length; i++)
			{
				//vals1[i] -= vals2[i];
				if(spectrumAnalyzer.getFreqs()[i] > threshold)
				{
					currMidiNote++;
					threshold = (MidiAudioClip.getFreqForMidi(currMidiNote)+ MidiAudioClip.getFreqForMidi(currMidiNote+1))*.5;
				}
				results[currMidiNote - minNote] += vals1[i] - vals2[i];
			}
			
			
			
			spectrumAnalyzer.normalize(results);
			
			for(double i = start; i < h-step/2.; i+= step)
			{
				//float v = (float)(1- vals[c]); 
				//g.setColor(new Color(v,v,v));

				float v = (float)(results[pixelsToNote((int)Math.round(i)) - minNote]); 
				g.setColor(Color.getHSBColor(0, v, 1));
				g.drawLine(x, (int)Math.round(i), x, (int)Math.round(i));
			}
		}
	}
	
	public int noteToPixels(int note) {
		return comp.getHeight()-(int)Math.round(comp.getHeight()/(maxNote - minNote + .5) * (note - minNote + .5));
	}

	public byte pixelsToNote(int y) {
		return (byte)(Math.round(((double)comp.getHeight()-y) / comp.getHeight() * (maxNote - minNote + .5) - .5) + minNote);
	}


}
