package DFT;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.text.NumberFormat;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;

import signals.Signals;

public class Tools extends JPanel implements ActionListener,MouseListener,MouseMotionListener{
	
	private static final long serialVersionUID = 1L;
	private float[] samples;
	private float[] dft;
	private int Nsample=150;
	private Signals signal;
	private Graph graph;
	private int width;
	private float offset = 0f;
	
	private boolean onSig = false;
	private int widthTmp;
	private boolean removeContinous = false;
	
	// Interaction
	private JLabel samplingLabel = new JLabel("Sampling Rate: ");
	private JFormattedTextField samplingField = new JFormattedTextField(NumberFormat.getIntegerInstance());
	private JButton okSampleButton = new JButton("Ok");
	private JCheckBox continousPart = new JCheckBox("Remove continous part");

	public Tools(Signals s, int width, Graph graph){
		this.signal=s;
		this.graph=graph;
		this.width=width;
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		
		samplingField.setPreferredSize(new Dimension(60, 20));
		samplingField.setValue(Nsample);
		okSampleButton.setPreferredSize(new Dimension(50, 20));
		okSampleButton.addActionListener(this);
		okSampleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	String tmp = samplingField.getText();
            	tmp=tmp.replaceAll(",", "");
            	Nsample=Integer.parseInt(tmp);
        		genDFT();
        		repaint();
            }
        });
		
		continousPart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	removeContinous=continousPart.getModel().isSelected();
        		genDFT();
        		repaint();
            }
        });
		
		JSeparator sep = new JSeparator(SwingConstants.VERTICAL);
		sep.setPreferredSize(new Dimension(5, 20));
		
		this.add(samplingLabel);
		this.add(samplingField);
		this.add(okSampleButton);
		
		this.add(sep);
		
		this.add(continousPart);

		genDFT();
	}
	
	public void paintComponent(Graphics g){
		/******* Background *******/
		g.setColor(new Color(220,220,220));
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		
		/******* Signal Part *******/
		g.translate(0, 30);
		int sigHeight = Signals.heightUnit+Signals.Yspace+10;
		// Draw background
		g.setColor(Color.WHITE);
		g.fillRect(3, 5, this.getWidth()-6, sigHeight-5);
		g.setColor(Color.BLACK);
		g.drawRect(3, 5, this.getWidth()-6, sigHeight-5);
		// Draw range
		if (onSig){
			g.setColor(new Color(210,210,230));
			g.fillRect(Signals.leftSpace, Signals.Yspace-8, widthTmp-Signals.leftSpace, Signals.heightUnit+16);
		}
		// Draw signal
		signal.draw(g, null, 0, this.getWidth());
		// Draw sample rate
		g.setColor(Color.RED);
		for (int i=0; i<Nsample; i++){
			int x = Signals.leftSpace+i*(width-Signals.leftSpace)/Nsample;
			g.fillRect(x-1, (int)(1-samples[i])*Signals.heightUnit+Signals.Yspace-1, 3, 3);
		}
		g.translate(0, -30);
		
		graph.update(dft);
	}
	
	public void genDFT(){
		// DFT Input
		samples = new float[Nsample];
		// DFT Output
		float[] dftTmp = new float[Nsample];
		dft = new float[Nsample/2];
		
		
		// Sampling
		for (int i=0; i<Nsample; i++){
			int x = Signals.leftSpace+i*(width-Signals.leftSpace)/Nsample;
			samples[i]=signal.wave[signal.getIndex(x)]+offset;
		}
		// DFT processing
		dftTmp = DftGen.from(samples);
		// Take positive part
		for (int i=0; i<Nsample/2; i++) dft[i]=dftTmp[i];
		
		// Remove offset for signal drawing
		if (removeContinous) dft[0]=0;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		if (onSig=true && widthTmp>Signals.leftSpace){
			width=widthTmp;
			genDFT();
			repaint();
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		onSig=false;
		repaint();
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		if (e.getY()>30) onSig=true;
		else onSig=false;
		widthTmp=((e.getX()-Signals.leftSpace+signal.widthUnit/2)/signal.widthUnit)*signal.widthUnit+Signals.leftSpace;
		repaint();
	}

}
