package kr.co.swh.lecture.opensource.project.drawing;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class LineDraw extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private List<List<Point>> point = new ArrayList<List<Point>>();
	private List<List<Point>> drawingPoint = new ArrayList<List<Point>>();
	private DataOutputStream drawingOutputStream;
	private DrawingInputThread drawingInputThread;
	private Gson gson = new Gson();;
	
	class DrawingInputThread extends Thread{
		private Socket socket;

		public DrawingInputThread(Socket socket) {
			this.socket = socket;
		}

		public void run() {
			DataInputStream dis = null;
			try {
				dis = new DataInputStream(socket.getInputStream());
				while(true) {
					String line = dis.readUTF();
					drawingPoint = gson.fromJson(line, new TypeToken<List<List<Point>>>(){}.getType());
					System.out.println(drawingPoint);
					repaint();
				}
			}catch(IOException e) {
				e.printStackTrace();
			}finally{
//				try{ dis.close(); }catch(Exception e) {}
			}
		}
	}
	
	public LineDraw(Socket socket) {
		drawingInputThread = new DrawingInputThread(socket);
		drawingInputThread.start();
		try {
			drawingOutputStream = new DataOutputStream(socket.getOutputStream());
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public void addListener() {
		
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent event) {
				List<Point> list = new ArrayList<Point>();
				point.add(list);
			}
			
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub

			}
			
		});

		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent event) {
				
				point.get(point.size()-1).add(event.getPoint());
//				repaint();
				System.out.println("mouseDragged " + point.size());
				try {
					drawingOutputStream.writeUTF(gson.toJson(point));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("mouseDragged " + point.size() + " write");
			}
			
		});
		
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		System.out.println("paintComponent " + drawingPoint.size());
		Graphics2D g2 = (Graphics2D) g;
		g2.setColor(new Color(0, 0, 128));
		g2.setStroke(new BasicStroke(15f,
				BasicStroke.CAP_ROUND,
				BasicStroke.JOIN_ROUND));
		for (int i = 0; i < drawingPoint.size(); i++) {
			List<Point> l = drawingPoint.get(i);
			for (int j = 1; j < l.size(); j++) {
				g2.draw(new Line2D.Float(l.get(j-1), l.get(j)));
			}
		}
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 9998);
		JFrame f = new JFrame();
		LineDraw panel = new LineDraw(socket);
		panel.addListener();
//		JTextField userText = new JTextField();
//		userText.setEditable(false);
//		userText.addActionListener(new ActionListener(){
//			public void actionPerformed(ActionEvent e){
//				userText.setText("");
//			}
//		});
//		f.add(userText, BorderLayout.NORTH);
//		JTextArea chatWindow=new JTextArea();
//		f.add(new JScrollPane(chatWindow),BorderLayout.CENTER);
		f.add(panel);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(800, 600);
		f.setVisible(true);
	}
}