package gui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import common.Config;

/**
 * 
 * FOX 1 Telemetry Decoder
 * @author chris.e.thompson g0kla/ac2cz
 *
 * Copyright (C) 2015 amsat.org
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
@SuppressWarnings("serial")
public class FilterPanel extends JPanel  implements ChangeListener, ActionListener {
	
	public static final int MATCHED = 2;
	public static final int RAISED_COSINE = 0;
	public static final int WINDOWED_SINC = 1;
	public static final int MAX_FILTERS = 3;
	
	String[] filterName = { 
			"Raised Cosine", 
			"Windowed Sinc",
			"Matched"
			};
	/*
	Filter filters[] = {
			new RaisedCosineFilter(),
			new WindowedSincFilter()
	};
	*/
	
	public static final int WS_LEN_MIN = 480;
	public static final int WS_LEN_MAX = 4800;
	public static final int RC_LEN_MIN = 64;
	public static final int RC_LEN_MAX = 512;
	
	public static final int FREQ_MIN = 0;
	public static final int FREQ_MAX = 400;
	public static final int FREQ_STEP = 25;
	
	JRadioButton[] filterRadioButtons;
	JSlider rcSlider;
	JSlider wsSlider;
	JSlider freqSlider;
	JLabel lFreq;
	JLabel lLength;
	
	private String L_FREQ = "Cutoff frequency (Hz)";
	private String L_LENGTH = "Filter Length (samples)";
	
	FilterPanel() {
		//filter
		this.setBorder(new TitledBorder(null, "Data Under Voice (DUV) Filter", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		initializeGui();
	}
	
	/*
	public Filter getFilter(double sampleRate, double freq, int len) {
		filters[Config.useFilterNumber].init(sampleRate, freq, len);
		return filters[Config.useFilterNumber];
	}
	*/
	
	public void initializeGui() {

		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		ButtonGroup group = new ButtonGroup();
		filterRadioButtons = new JRadioButton[MAX_FILTERS];

		for (int i=0; i< MAX_FILTERS; i++) {
			filterRadioButtons[i] = addRadioButton(filterName[i]);
			group.add(filterRadioButtons[i]);
		}
	
		JLabel filler0 = new JLabel("");
		filler0.setMinimumSize(new Dimension(14,14));
		filler0.setMaximumSize(new Dimension(14,14));
		add(filler0);
		lFreq = new JLabel(L_FREQ);
		lFreq.setAlignmentX(Component.LEFT_ALIGNMENT);
		add(lFreq);
		
		freqSlider = createSlider(FREQ_MIN, FREQ_MAX, (int)Config.filterFrequency);
		freqSlider.setMinorTickSpacing(FREQ_STEP);
		
		add(freqSlider);
		
		//JPanel panel1 = new JPanel();
		//add(panel1);
		JLabel filler1 = new JLabel("");
		filler1.setMinimumSize(new Dimension(14,14));
		filler1.setMaximumSize(new Dimension(14,14));
		add(filler1);
		lLength = new JLabel(L_LENGTH);
		lLength.setAlignmentX(Component.LEFT_ALIGNMENT);
		add(lLength);
		
		rcSlider = createSlider(RC_LEN_MIN, RC_LEN_MAX, RC_LEN_MIN);
		wsSlider = createSlider(WS_LEN_MIN, WS_LEN_MAX, WS_LEN_MIN*2);
		//updateSlider();
		add(rcSlider);
		add(wsSlider);
		
		JLabel filler2 = new JLabel("");
		filler2.setMinimumSize(new Dimension(14,44));
		filler2.setMaximumSize(new Dimension(14,44));
		add(filler2);
		/*
		JPanel panel1 = new JPanel();
		add(panel1);
//		panel1.setLayout(new BoxLayout(panel1, BoxLayout.X_AXIS));
		panel1.setLayout(new FlowLayout());
		JLabel lfreq = new JLabel("Cuttoff Freq");
		panel1.add(lfreq);
		JTextField txtFreq = new JTextField();
		panel1.add(txtFreq);
		JPanel panel2 = new JPanel();
		add(panel2);
		//panel2.setLayout(new BoxLayout(panel2, BoxLayout.X_AXIS));
		panel2.setLayout(new FlowLayout());
		JLabel lLength = new JLabel("Length (bits)");
		panel2.add(lLength);
		JTextField txtLength = new JTextField();
		panel2.add(txtLength);
		*/
		
		setFilter();
	}
	
	private JSlider createSlider(int min, int max, int tick) {
		JSlider slideFilterLength = new JSlider(JSlider.HORIZONTAL, min, max, tick); 
		slideFilterLength.addChangeListener(this);
		//Turn on labels at major tick marks.
		slideFilterLength.setMajorTickSpacing(tick);
		//slideFilterLength.setMinorTickSpacing(64);
		slideFilterLength.setPaintTicks(true);
		slideFilterLength.setPaintLabels(true);
		//slideFilterLength.createStandardLabels(tick);
		slideFilterLength.setSnapToTicks(true);
		
		return slideFilterLength;
	}
	
	public static void checkFilterParams() {
		if (Config.useFilterNumber == RAISED_COSINE) {
			if (Config.filterLength > RC_LEN_MAX) {
				Config.filterLength = RC_LEN_MAX;
			}
		
		} else if (Config.useFilterNumber == WINDOWED_SINC){
			if (Config.filterLength < WS_LEN_MIN) {
				Config.filterLength = WS_LEN_MIN;
			}
		
		} 
		
	}
	
	private void updateSlider() {
		checkFilterParams();
		if (Config.useFilterNumber == RAISED_COSINE) {
			rcSlider.setVisible(true);
			wsSlider.setVisible(false);
			rcSlider.setValue(Config.filterLength);
			freqSlider.setVisible(true);
		
		} else if (Config.useFilterNumber == WINDOWED_SINC){
			rcSlider.setVisible(false);
			wsSlider.setVisible(true);
			wsSlider.setValue(Config.filterLength);
			freqSlider.setVisible(true);
		
		} else {
			rcSlider.setVisible(false);
			wsSlider.setVisible(false);
			freqSlider.setVisible(false);
			
		}
		lFreq.setText(L_FREQ+" " + Config.filterFrequency);
		lLength.setText(L_LENGTH+" "+Config.filterLength);
		//Log.println("Filter Len Set to: " + Config.filterLength);
		//Config.save();

	}
	
	
	private void setFilter() {
		updateSlider();
		filterRadioButtons[Config.useFilterNumber].setSelected(true);
		//Config.filter = filters[Config.useFilterNumber];
		//Config.save();
	}
	
	private JRadioButton addRadioButton(String name) {
		JRadioButton radioButton = new JRadioButton(name);
		radioButton.setEnabled(true);
		radioButton.addActionListener(this);
		add(radioButton);
		return radioButton;
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		for (int i=0; i< MAX_FILTERS; i++) {
			if (e.getSource() == filterRadioButtons[i]) {
				Config.useFilterNumber = i;

				setFilter();
				Config.save();
			}
		}
	
	}

	/**
	 * Listen for changes from the slider
	 */
	@Override
	public void stateChanged(ChangeEvent e) {
		JSlider source = (JSlider)e.getSource();
	    if (!source.getValueIsAdjusting()) {
	    	
	    	if (source == freqSlider) {
	    		int freq = (int)source.getValue();
	    		Config.filterFrequency = freq;
	    		Config.save();
	    	} else {
	    		int len = (int)source.getValue();
	    		Config.filterLength = len;
	    		Config.save();
	    	}
	    }
	}

	
}