package cz.vutbr.feec.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.Random;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import cz.vutbr.feec.math.GNPConfig;

/**
 * Konfiguracni panel zobrazovany ve spodni casti okna. Je v nem
 * zobrazen pocet landmarku.
 * 
 * @author Radim Burget
 */
public class ConfigPanel extends JPanel {
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -6940809677441553444L;

	/** The slider. */
	private static JSlider lmsCountSlider;
	
	/** The slider. */
	private static JSlider noiseRatioSlider;

	/** The number of landmarks. */
	private JLabel numberOfLm;
	
	/** The number of landmarks. */
	private JLabel noiseRatioLabel;

	private GNPConfig config;
	
	private static boolean configPanelChanged = false;

	/**
	 * The Constructor.
	 * 
	 * @param landmarks Landmarky
	 */
	public ConfigPanel(GNPConfig conf) {
		this.config = conf;
		init();
	}
	
	/**
	 * Init. Inicializace vychozich hodnot objektu.
	 */
	public void init() {
		setLayout(new GridLayout(3,1));
		
		JPanel lmsCountPanel = createLandmarksCountPanel();
		JPanel noisePanel = createNoisePanel();
		
		add(lmsCountPanel);
		add(noisePanel);
	}

	private JPanel createLandmarksCountPanel() {
		JPanel p = new JPanel();
		p.setLayout(new BorderLayout());

		lmsCountSlider = new JSlider(3, 100);
		lmsCountSlider.setValue(config.getLandmarks().size());
		numberOfLm = new JLabel("" + lmsCountSlider.getValue());
		numberOfLm.setPreferredSize(new Dimension(60, 10));
		lmsCountSlider.addChangeListener(listener);
		
		p.add(new JLabel("Number of landmarks: "), BorderLayout.WEST);
		p.add(lmsCountSlider, BorderLayout.CENTER);
		p.add(numberOfLm, BorderLayout.EAST);
		
		return p;
	}
	
	private JPanel createNoisePanel() {
		JPanel p = new JPanel();
		p.setLayout(new BorderLayout());
		
		noiseRatioSlider = new JSlider(0, 100);
		noiseRatioSlider.setValue((int)(config.getNoiseRatio()*100));
		noiseRatioLabel = new JLabel( "" + noiseRatioSlider.getValue()+" %");
		noiseRatioLabel.setPreferredSize(new Dimension(40, 10));
		noiseRatioSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				noiseRatioSlider.getValue();
				noiseRatioLabel.setText( "" + noiseRatioSlider.getValue()+" %");
				config.setNoiseRatio(noiseRatioSlider.getValue()/100f);
				configPanelChanged = true;
			}
		});
		p.add(new JLabel("Noise ratio: "), BorderLayout.WEST);
		p.add(noiseRatioSlider, BorderLayout.CENTER);
		p.add(noiseRatioLabel, BorderLayout.EAST);
		return p;
	}

	public static int getSliderValue() {
		return lmsCountSlider.getValue();
	}
	
	@Override
	public void setEnabled(boolean enabled) {
		lmsCountSlider.setEnabled(enabled);
	}

	/**
	 * Sets the map height.
	 * 
	 * @param mapHeight the map height
	 */
	public void setMapHeight(int mapHeight) {
		listener.setMapHeight(mapHeight);
	}
	
	/**
	 * Sets the map width.
	 * 
	 * @param mapWidth the map width
	 */
	public void setMapWidth(int mapWidth) {
		listener.setMapWidth(mapWidth);
	}

	/** The listener. */
	private LandmarksSliderListener listener = new LandmarksSliderListener();
	
	/**
	 * The Class SliderListener. Reaguje na udalosti, ktere nastanou 
	 * pri zmene slideru.
	 */
	public class LandmarksSliderListener implements ChangeListener {
		
		/** The map width. */
		private int mapWidth = -1;

		/** The map height. */
		private int mapHeight = -1;

		/**
		 * The Constructor.
		 */
		public LandmarksSliderListener() {
		}
		
		/**
		 * The Constructor.
		 * 
		 * @param mapWidth the map width
		 * @param mapHeight the map height
		 */
		public LandmarksSliderListener(int mapWidth, int mapHeight) {
			this.mapWidth = mapWidth;
			this.mapHeight = mapHeight;
		}
		
		/**
		 * State changed.
		 * 
		 * @param e the e
		 */
		public void stateChanged(ChangeEvent e) {
			if(("" + lmsCountSlider.getValue()) != numberOfLm.getText()) {
				numberOfLm.setText("" + lmsCountSlider.getValue());
				Vector<LandmarkGui> landmarkList = config.getLandmarks();
				synchronized (landmarkList ) {
					Random rnd = new Random();
					if (landmarkList.size() < lmsCountSlider.getValue()) {
						while (landmarkList.size() != lmsCountSlider.getValue()) {
							LandmarkGui o = new LandmarkGui();
							o.setPosition(rnd.nextInt(mapWidth), rnd.nextInt(mapHeight));
							landmarkList.add(o);
							//o.setId(landmarkList.size() - 1);	//pro zajištění správného číslování
						}
						configPanelChanged = true;
					}
					else if (landmarkList.size() > lmsCountSlider.getValue()) {
						while (landmarkList.size() != lmsCountSlider.getValue()) {
							landmarkList.remove(landmarkList.size() - 1);
						}	
						configPanelChanged = true;
					}
					System.out.println("SIZE>" + landmarkList.size());
				}
			}
			else configPanelChanged = false;
		}
		
		/**
		 * Sets the map height.
		 * 
		 * @param mapHeight the map height
		 */
		public void setMapHeight(int mapHeight) {
			this.mapHeight = mapHeight;
		}
		
		/**
		 * Sets the map width.
		 * 
		 * @param mapWidth the map width
		 */
		public void setMapWidth(int mapWidth) {
			this.mapWidth = mapWidth;
		}
	}
	
	public boolean isConfigPanelChanged() {
		return configPanelChanged;
	}
	
	public void setConfigPanelChanged(boolean changed) {
		configPanelChanged = false;
	}
}
