package org.ninjadev.multivim.client; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.HashMap; import java.util.LinkedList; import org.ninjadev.multivim.Buffer; import org.ninjadev.multivim.Cursor; import org.ninjadev.multivim.Message; import org.ninjadev.multivim.Mode; import org.ninjadev.multivim.User; import org.ninjadev.multivim.UserData; import org.ninjadev.multivim.ViewPort; import org.ninjadev.multivim.client.net.MessageHandler; import com.googlecode.lanterna.TerminalFacade; import com.googlecode.lanterna.input.Key; import com.googlecode.lanterna.screen.Screen; import com.googlecode.lanterna.terminal.Terminal; import com.googlecode.lanterna.terminal.Terminal.ResizeListener; import com.googlecode.lanterna.terminal.TerminalSize; import com.googlecode.lanterna.terminal.Terminal.Color; import com.googlecode.lanterna.terminal.swing.SwingTerminal; public class Client { public HashMap<Integer,User> users; public LinkedList<Buffer> buffers; private ObjectInputStream is; private ObjectOutputStream os; public User selfUser; private SwingTerminal terminal; private Screen screen; public OSD osd; public MessageHandler messageHandler; private int screenWidth; public void startKeyboardHandlerThread(){ new Thread(new Runnable(){ ObjectOutputStream os; Terminal terminal; public Runnable args(Terminal terminal, ObjectOutputStream os){ this.terminal = terminal; this.os = os; return this; } public void run() { while(true){ Key key; while((key = terminal.readInput()) != null){ try { os.writeObject(new Message("sendCommand", key)); os.flush(); } catch (IOException e) { e.printStackTrace(); } } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.args(terminal, os)).start(); } public void startMessageHandlerThread(){ new Thread(new Runnable(){ ObjectInputStream is; public Runnable args(ObjectInputStream is){ this.is = is; return this; } public void run() { while(true){ try { Message m = (Message)is.readObject(); System.out.println(m); messageHandler.processMessage(m); } catch (Exception e) { e.printStackTrace(); } } } }.args(is)).start(); } public Buffer createBuffer(int bufferId) throws IOException{ Buffer buffer = new Buffer(); buffer.bufferId = bufferId; for(Integer i: users.keySet()){ User u = users.get(i); u.cursors.put(buffer.bufferId, new Cursor(buffer, u)); } return buffer; } public User createUser(ViewPort viewPort) { User user = new User(); for(Buffer b: buffers){ user.cursors.put(b.bufferId, new Cursor(b, user)); } return user; } public void render(){ osd.render(screen); for(ViewPort viewPort : selfUser.viewPorts){ viewPort.scroll(selfUser.cursors.get(viewPort.buffer.bufferId).data.position); viewPort.render(users, screen); } /* render status line at bottom */ screen.putString(0, screen.getTerminalSize().getColumns(), "-- "+selfUser.getMode()+" -- ", Color.WHITE, Color.BLACK); screen.refresh(); } public Client(Socket socket) throws IOException{ terminal = TerminalFacade.createSwingTerminal(); terminal.addResizeListener(new ResizeListener() { public void onResized(TerminalSize newSize) { for(ViewPort viewPort : selfUser.viewPorts){ viewPort.setWidth(newSize.getColumns()); viewPort.setHeight(newSize.getRows()); } render(); } }); screen = TerminalFacade.createScreen(terminal); screen.startScreen(); terminal.setCursorVisible(false); messageHandler = new MessageHandler(this); users = new HashMap<Integer, User>(); osd = new OSD(); buffers = new LinkedList<Buffer>(); is = new ObjectInputStream(socket.getInputStream()); os = new ObjectOutputStream(socket.getOutputStream()); startMessageHandlerThread(); startKeyboardHandlerThread(); } public static void main(String[]args) throws Exception{ Socket socket = new Socket("localhost", 9999); new Client(socket); } public User createUser(UserData ud) { User user = new User(ud); for(Buffer b: buffers){ user.cursors.put(b.bufferId, new Cursor(b, user)); } return user; } }