package kr.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JSlider;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import kr.util.Listener;
import kr.util.ListenerManager;

public class TimeController extends TimeSyncedController implements ChangeListener, ActionListener, Listener
{
	private TimePanel timePanel;
	private GuiModel guiModel;
	private Model model;
	private boolean selfSliderUpdate = false;
	
	public TimeController()
	{
		super();
	}

	public void stateChanged(ChangeEvent e) {
		if(e.getSource() == timePanel.timeSlider && !selfSliderUpdate)
		{
			guiModel.updateNowMicros(timePanel.timeSlider.getValue() * 1000);
		}
		
	}

	public void init(final Model model, final GuiModel guiModel, TimePanel timePanel) {
		this.model = model;
		this.guiModel = guiModel;
		this.timePanel = timePanel;
        timePanel.timeSlider.addChangeListener(this);
        timePanel.play.addActionListener(this);
        timePanel.playLoop.addActionListener(this);
        timePanel.stop.addActionListener(this);
        timePanel.threeQuartersSpeed.addActionListener(this);
        timePanel.halfSpeed.addActionListener(this);
        timePanel.fullSpeed.addActionListener(this);
        
        ListenerManager.inst().registerListener(model, this);    
        ListenerManager.inst().registerListener(guiModel, this);    
        super.init(guiModel);

		timePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(
                KeyEvent.VK_LEFT, 0),"left");
		timePanel.getActionMap().put("left", new AbstractAction()
				{
			public void actionPerformed(java.awt.event.ActionEvent e) 
			{
				guiModel.updateNowMicros(Math.max(guiModel.getCurrMicros() - 500000, 0));
			}
				});
		
		timePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(
                KeyEvent.VK_RIGHT, 0),"right");
		timePanel.getActionMap().put("right", new AbstractAction()
				{
			public void actionPerformed(java.awt.event.ActionEvent e) 
			{
				guiModel.updateNowMicros(Math.min(guiModel.getCurrMicros() + 500000, model.getMaxMilliSeconds()* 1000));
			}
				});

	}
	
	public void notify(Object source, Object type, Object... values) {
		if(source == model && type == Model.MessageType.MAX_MILLIS_UPDATED)
		{
			timePanel.updateSliderMax();
		}
		else if (source == guiModel && type == GuiModel.MessageType.IS_PLAYING_UPDATED) {
			boolean enabled = !guiModel.isPlaying();
			timePanel.timeSlider.setEnabled(enabled);
			timePanel.threeQuartersSpeed.setEnabled(enabled);
			timePanel.halfSpeed.setEnabled(enabled);
			timePanel.fullSpeed.setEnabled(enabled);
			timePanel.play.setEnabled(enabled);
			timePanel.playLoop.setEnabled(enabled);
			timePanel.stop.setEnabled(!enabled);
		}
	}

	
	protected void performTimedAction()
	{
		selfSliderUpdate = true;
		timePanel.updateSliderValue();
		selfSliderUpdate = false;
	}

	public void actionPerformed(ActionEvent e) 
	{
		if(e.getSource() == timePanel.play)
		{
			guiModel.startPlaying();
		}
		else if(e.getSource() == timePanel.stop)
		{
			guiModel.stopPlaying();
		}
		else if(e.getSource() == timePanel.playLoop)
		{
			guiModel.startPlayingLoop();
		}
		else if(e.getSource() == timePanel.threeQuartersSpeed)
		{
			guiModel.setPlaybackRate(.75);
		}
		else if(e.getSource() == timePanel.halfSpeed)
		{
			guiModel.setPlaybackRate(.5);
		}
		else if(e.getSource() == timePanel.fullSpeed)
		{
			guiModel.setPlaybackRate(1.);
		}
		
	}

}
