package jp.ac.naka.ec.entity.test;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.sdp.SessionDescription;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;

import jp.ac.naka.ec.dht.Chord;
import jp.ac.naka.ec.entity.AbstractEntity;
import jp.ac.naka.ec.entity.Entity;
import jp.ac.naka.ec.entity.EntityContainer;
import jp.ac.naka.ec.entity.EntityEvent;
import jp.ac.naka.ec.media.MediaListener;
import jp.ac.naka.ec.media.MediaReceiveEvent;
import jp.ac.naka.ec.media.MediaReceiver;
import jp.ac.naka.ec.sensor.SensorData;

/**
 * すべての機能を網羅したEntity．テスト用
 * @author kasuya
 *
 */
public class SampleEntity extends AbstractEntity implements ActionListener,
		MediaListener {

	JFrame frame;
	JTextField keyword;
	JTextField msgField;
	JList list;
	JButton search, subscribe, message, invite, bye, add, remove;
	DefaultListModel model;
	JTextArea console;

	MediaReceiver receiver;

	public SampleEntity() {
		frame = new JFrame("Sample");
		keyword = new JTextField(30);
		msgField = new JTextField(30);

		JPanel p1 = new JPanel();
		p1.setLayout(new GridLayout(2, 0));
		JLabel l1 = new JLabel("keyword :");
		JPanel keywordPanel = new JPanel();
		keywordPanel.add(l1);
		keywordPanel.add(keyword);
		JLabel msgLable = new JLabel("message :");
		JPanel msgPanel = new JPanel();
		msgPanel.add(msgLable);
		msgPanel.add(msgField);
		p1.add(keywordPanel);
		p1.add(msgPanel);
		// frame.setLayout(new GridLayout(4,0));
		frame.add(p1, BorderLayout.NORTH);

		model = new DefaultListModel();
		list = new JList(model);

		JPanel p2 = new JPanel();
		p2.setLayout(new BorderLayout());
		p2.add(new JScrollPane(list), BorderLayout.CENTER);

		JButton buttons[] = new JButton[7];
		add = buttons[0] = new JButton("add");
		remove = buttons[1] = new JButton("remove");
		search = buttons[2] = new JButton("search");
		subscribe = buttons[3] = new JButton("subscribe");
		message = buttons[4] = new JButton("message");
		invite = buttons[5] = new JButton("invite");
		bye = buttons[6] = new JButton("bye");

		JPanel p3 = new JPanel();
		JPanel p4 = new JPanel();
		JPanel p5 = new JPanel();
		p3.setLayout(new GridLayout(2, 0));
		p3.setBorder(new EtchedBorder(EtchedBorder.RAISED));
		int i = 0;
		for (JButton button : buttons) {
			if (i++ < 3)
				p4.add(button);
			else
				p5.add(button);
			button.addActionListener(this);
		}
		p3.add(p4);
		p3.add(p5);
		p2.add(p3, BorderLayout.SOUTH);
		buttons = null;
		frame.add(p2, BorderLayout.CENTER);
		console = new JTextArea(6, 30);
		frame.add(new JScrollPane(console), BorderLayout.SOUTH);

		frame.setVisible(true);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		receiver = new MediaReceiver();
		receiver.addMediaListener(this);

	}

	@Override
	public void receiveMessage(EntityEvent e) {
		String msg = e.getMessage();
		String temp = console.getText();
		temp += msg + "\r\n";
		console.setText(temp);
	}

	@Override
	public void receiveAnswer(EntityEvent evt) {
		SessionDescription sdp = evt.getSessionDescription();
		try {
			System.out.println(sdp.toString());
			receiver.receiveMedia(sdp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void receiveNotify(EntityEvent evt) {
		Entity source = (Entity) evt.getSource();
		StringBuilder sb = new StringBuilder();
		sb.append("Notify : " + source.toString() + "\r\n");
		sb.append("Location :" + source.getLocation() + "\r\n");
		SensorData[] sensors = source.getSensors();
		for (SensorData sensor : sensors) {
			sb.append("\tSensor value : " + sensor.getData().toString() + " "
					+ sensor.getMeasure() + "\r\n");
		}
		console.setText(sb.toString());
	}

	@Override
	public void receiveErrorResponse(EntityEvent evt) {
		String msg = evt.getMessage();
		String temp = console.getText();
		temp += msg + "\r\n";
		console.setText(temp);
	}

	Entity callee = null;

	public void actionPerformed(ActionEvent evt) {
		JButton source = (JButton) evt.getSource();
		String msg = keyword.getText();
		if (source == add) {
			Chord chord = Chord.getInstance();
			if (chord != null) {
				this.addKeyword(msg);
				try {
					chord.insertEntity(msg, this);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} else if (source == remove) {
			Chord chord = Chord.getInstance();
			if (chord != null) {
				this.removeKeyword(msg);
				try {
					chord.removeEntity(msg, this);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} else if (source == subscribe) {
			Entity target = getTarget();
			if (target != null)
				subscribe(target);
		} else if (source == message) {
			msg = msgField.getText();
			Entity target = getTarget();
			if (target != null)
				sendMessage(msg, target);
			else
				sendMessage(msg);
		} else if (source == invite) {
			Entity target = getTarget();
			if (target != null) {
				try {
					sendOffer(receiver.getRequestSessionDescription(),
							target);
				} catch (Exception e) {
					e.printStackTrace();
				}
				callee = target;
			}
		} else if (source == bye) {
			if (callee != null) {
				sendBye(callee);
				callee = null;
			}
		} else if (source == search) {
			EntityContainer con = getContainer();
			if (con != null) {
				Entity[] entities = con.searchEntities(msg);
				int i = 0;
				model.clear();
				for (Entity entity : entities) {
					model.add(i++, entity);
				}

			}
		}
	}

	private Entity getTarget() {
		int index = list.getSelectedIndex();
		if (index == -1)
			return null;
		Entity target = (Entity) model.get(index);
		return target;
	}

	public static void main(String[] args) {
		new SampleEntity().init();
	}

	JFrame prev;

	public void receiveMedia(MediaReceiveEvent e) {
		System.out.println("start");
		prev = new JFrame("movie");
		JPanel panel = new JPanel();
		Component comp = receiver.getVisualComponent();
		panel.setPreferredSize(comp.getPreferredSize());
		panel.add(comp);
		prev.add(panel);
		prev.pack();
		prev.setVisible(true);
	}

	public void terminateMedia(MediaReceiveEvent e) {
		System.out.println("end");
		prev.remove(0);
		prev.setVisible(false);
	}
}
