import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;

import javax.swing.JFrame;

import com.videonext.mplayer.Capturer;
import com.videonext.mplayer.Exporter;
import com.videonext.mplayer.api.ICapturerURLProvider;
import com.videonext.mplayer.Player;

import java.awt.BorderLayout;

import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.border.EmptyBorder;

import com.videonext.mplayer.api.ControllerEvent;
import com.videonext.mplayer.api.ICapturer;
import com.videonext.mplayer.api.IControllerListener;
import com.videonext.mplayer.api.IExporter;
import com.videonext.mplayer.api.IPlayerController;
import com.videonext.mplayer.api.events.ChangeStateEvent;
import com.videonext.mplayer.api.events.NewFrameEvent;
import com.videonext.mplayer.internal.MediaPlayerListener;
import com.videonext.mplayer.internal.SwingMediaPlayer;

import javax.swing.JLabel;
import java.awt.GridLayout;
import java.awt.CardLayout;
import javax.swing.BoxLayout;


public class App {

	private JFrame frame;
	
	private JFrame capturePreviewFrame;
	
	// fullscreen support
	JFrame fullscreenFrame; 
	Rectangle restoredBounds;
	JLabel lblTime;
	
	Player player;
	private JButton btnCapturing;
	private JButton btnNewButton_2;
	
	ICapturer capturer = new Capturer();
	private JButton btnStop;
	private JButton btnPlay;
	private JButton btnPause;
	private boolean doResume = false;
	private JButton btnJmpMinus10;
	private JButton btnExport;
	
	private long lastFramePTSMillis = 0;
	private JTextField textFieldRTSPURL;
	private JTextField textFieldJitBuf;
	private JPanel panel_left;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					App window = new App();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 * @throws Exception 
	 */
	public App() throws Exception {
		initialize();
	}
	
	/**
	 * Initialize the contents of the frame.
	 * @throws Exception 
	 */
	private void initialize() throws Exception {
		frame = new JFrame();
		frame.setBounds(100, 100, 860, 600);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Map<String, Object> config = new HashMap<String, Object>();
		config.put("jitterBuffer", 2000);
		config.put("streamOverTCP", "1");
		
		player = new Player(1, config);

		player.addControllerListener(new IControllerListener() {
			JLabel lbl;
			@Override
			public void controllerUpdate(ControllerEvent event) {
				// TODO Auto-generated method stub
				if (event instanceof ChangeStateEvent)
				{
					ChangeStateEvent e = (ChangeStateEvent)event;
					
					System.out.println("state changed: " + e);
					
					if (e.getCurrentState() == IPlayerController.Opened) {
						
				          player.play(1);
				      
					}
				}
				else if (event instanceof NewFrameEvent) {
					NewFrameEvent e = (NewFrameEvent)event;
					final Date d = new Date(e.getFramePTSMillis());
					lblTime.setText(d.toString());
					lastFramePTSMillis = e.getFramePTSMillis();
					
					/// Transparent label
					if (lbl == null)
					{
						player.getOverlay().setLayout(new BorderLayout());
				       						
						lbl = new JLabel(d.toString());
				        lbl.setBackground(new Color(255,255,255,130));
				        lbl.setBounds(0, 0, 190, 30);
				        lbl.setOpaque(true);
				        player.getOverlay().add(lbl, BorderLayout.SOUTH);
				        player.updateUI();
				        
					}
					
					lbl.setText(d.toString());
					
				}
			}
			@Override
			public boolean canDisplayFrame(Date date) {
				// TODO Auto-generated method stub
				return true;
			}
		});
		
		player.setMute(false);
		
		
		frame.getContentPane().add(player, BorderLayout.CENTER);
		
		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEADING);
		frame.getContentPane().add(panel, BorderLayout.SOUTH);
		
		textFieldRTSPURL = new JTextField();
		textFieldRTSPURL.setText("rtsp://...");
		panel.add(textFieldRTSPURL);
		textFieldRTSPURL.setColumns(30);
		
		final JCheckBox cbJitterBuffer = new JCheckBox("JitBuff", true);
		cbJitterBuffer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (cbJitterBuffer.isSelected())
					player.changeJitterBufferLen(3000);
				else
					player.changeJitterBufferLen(0);
			}
		});
		
		textFieldJitBuf = new JTextField();
		textFieldJitBuf.setText("1000");
		panel.add(textFieldJitBuf);
		textFieldJitBuf.setColumns(4);
		panel.add(cbJitterBuffer);
		
		btnCapturing = new JButton("CapStart");
		btnCapturing.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				List<String> audioDevices = null;
				List<String> videoDevices = null;
				try {
					capturer.init();
					audioDevices = capturer.getAudioDevices();
					videoDevices = capturer.getVideoDevices();
					
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				System.out.println("Audio devices:");
				for (String device : audioDevices) {
					System.out.println(device);
				}
				System.out.println("Video devices:");
				for (String device : videoDevices) {
					System.out.println(device);
					
					List<String> videoSizes = null;
					try {
						videoSizes = capturer.getVideoParams(device);
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
						return;
					}
					for (String size : videoSizes) {
						System.out.println("   " + size);
					}	
				}
				
				capturer.setURLProvider(new ICapturerURLProvider() {
					public String getURL() {
						return "rtsp://10.168.0.105:8554/xmedia?dev=102&authorizationid=1";
					}
				});
				
				try {
					capturer.start("Микрофон (HD Pro Webcam C920)", "Logitech HD Pro Webcam C920", "1280x720/I420/30", 1000000);
					//capturer.start("Микрофон (Устройство с поддержк", "HP Webcam [2 MP Fixed]", "640x480/YUY2/30", 1000000);
										
					capturePreviewFrame = new JFrame("Camera Preview");
					capturePreviewFrame.getContentPane().add(new CapturePreviewPanel((Capturer)capturer), BorderLayout.CENTER);
					capturePreviewFrame.pack();
					capturePreviewFrame.setBounds(800, 100, 694, 437);
					capturePreviewFrame.setVisible(true);
					
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
			}
		});
		panel.add(btnCapturing);
		
		btnNewButton_2 = new JButton("CapStop");
		btnNewButton_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					capturePreviewFrame.dispose();
					capturePreviewFrame = null;

					capturer.stop();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		panel.add(btnNewButton_2);
		
		
		btnExport = new JButton("Export");
		btnExport.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					IExporter exporter = new Exporter();
					exporter.start("rtsp://10.168.0.105:8554/xmedia?dev=113&audio=a114&start=1412083320&end=1412083420&authorizationid=1", "c:\\aaa\\file.mov");
					
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		panel.add(btnExport);
		
		
		lblTime = new JLabel("New label");
		panel.add(lblTime);
		
		panel_left = new JPanel();
		frame.getContentPane().add(panel_left, BorderLayout.WEST);
		panel_left.setLayout(new BoxLayout(panel_left, BoxLayout.Y_AXIS));
		
		btnPlay = new JButton("  >  ");
		panel_left.add(btnPlay);
		btnPlay.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				if (doResume)
				{
					player.play(1);
					return;
				}
				
				
				// integration test хлопки
				//player.open("rtsp://10.168.0.104:8554/xmedia?dev=103&start=1405594740&end=1405598740&audio=a104&streamnum=1&authorizationid=1");
				
				// integration test cinema
				//player.open("rtsp://10.168.0.104:8554/xmedia?dev=103&start=1405674240&end=1405679000&audio=a104&streamnum=1&authorizationid=1");
				
				
				// live
				player.open("rtsp://10.168.0.104:8554/xmedia?dev=106&authorizationid=1");
				
				//player.open("rtsp://10.168.0.104:8554/xmedia?dev=103&streamnum=1&authorizationid=1");
			}
		});
		

		btnPause = new JButton("  ||  ");
		panel_left.add(btnPause);
		
		btnStop = new JButton(" S   ");
		panel_left.add(btnStop);
		btnStop.setBackground(Color.RED);
		
		btnJmpMinus10 = new JButton("<30");
		panel_left.add(btnJmpMinus10);
		
		JButton btnJmpPlus10 = new JButton("30>");
		panel_left.add(btnJmpPlus10);
		btnJmpPlus10.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				player.jumpTo(new Date(lastFramePTSMillis + 30000));
			}
		});
		btnJmpMinus10.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				player.jumpTo(new Date(lastFramePTSMillis - 30000));
			}
		});
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				player.stop();
				doResume = false;
				btnPlay.setText("Play");
			}
		});
		btnPause.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				player.pause();
				doResume = true;
				btnPlay.setText("Resume");
			}
		});
		
		
	}

	class CapturePreviewPanel extends JPanel implements ActionListener
	{
		private static final long serialVersionUID = 1L;
		private Capturer capturer;
		private Timer timer;
		
		public CapturePreviewPanel(Capturer capturer) {
			this.capturer = capturer;
			timer = new Timer(30, this);
			timer.start(); 
		}
		
		@Override
		public void paintComponent(Graphics g) 
		{
			int width = this.getWidth();
			int height = this.getHeight();
			
			if (capturer.getPreviewImage() != null)
			{
				g.drawImage(capturer.getPreviewImage(), 0, 0, width, height, null);	
			}
			
			this.revalidate();
			
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == timer)
			 {
			      repaint();
			 }
			
		}

	}
}
