package at.irian.ankorsamples.todosample.fxclient;

import at.irian.ankor.messaging.json.viewmodel.ViewModelJsonMessageMapper;
import at.irian.ankor.ref.RefContext;
import at.irian.ankor.ref.RefFactory;
import at.irian.ankor.servlet.websocket.messaging.WebSocketMessageBus;
import at.irian.ankor.servlet.websocket.session.WebSocketRemoteSystem;
import at.irian.ankor.session.SingletonSessionManager;
import at.irian.ankor.system.AnkorSystem;
import at.irian.ankor.system.AnkorSystemBuilder;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class App extends Application {
    private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(App.class);

    private static RefFactory refFactory;
    private static HostServices services;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        services = getHostServices();
        AnkorSystem clientSystem = createWebSocketClientSystem();

        RefContext clientRefContext = ((SingletonSessionManager) clientSystem.getSessionManager()).getSession().getRefContext();
        refFactory = clientRefContext.refFactory();

        startFXClient(primaryStage);
    }

    private void startFXClient(Stage primaryStage) throws IOException {
        primaryStage.setTitle("Ankor FX Sample");
        Pane myPane = FXMLLoader.load(getClass().getClassLoader().getResource("tasks.fxml"));

        Scene myScene = new Scene(myPane);
        myScene.getStylesheets().add("style.css");
        primaryStage.setScene(myScene);
        primaryStage.show();
    }

    private AnkorSystem createWebSocketClientSystem() throws IOException, DeploymentException, InterruptedException {
        final String clientId = UUID.randomUUID().toString();

        final AnkorSystem[] clientSystem = new AnkorSystem[1];
        final WebSocketMessageBus messageBus = new WebSocketMessageBus(new ViewModelJsonMessageMapper());
        final AnkorSystemBuilder systemBuilder = new AnkorSystemBuilder()
                .withName(clientId)
                // .withGlobalEventListener(new FXControllerChangeListener())
                .withMessageBus(messageBus)
                .withModelContextId("collabTest");

        final CountDownLatch latch = new CountDownLatch(1);

        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        String uri = "ws://localhost:8080" + "/websocket/ankor/" + clientId;

        container.connectToServer(new Endpoint() {

            @Override
            public void onOpen(Session session, EndpointConfig config) {
                session.addMessageHandler(new MessageHandler.Whole<String>() {

                    @Override
                    public void onMessage(String message) {
                        messageBus.receiveSerializedMessage(message);
                    }
                });

                messageBus.addRemoteSystem(new WebSocketRemoteSystem(clientId, session));
                clientSystem[0] = systemBuilder.createClient();
                clientSystem[0].start();
                latch.countDown();
            }
        }, URI.create(uri));

        if (latch.await(5, TimeUnit.SECONDS)) {
            return clientSystem[0];
        } else {
            throw new IOException("WebSocket could not connect to " + uri);
        }
    }

    public static HostServices getServices() {
        return services;
    }

    public static RefFactory refFactory() {
        return refFactory;
    }
}
@@ -757,16 +757,38 @@
 et.URI;%0A
+import java.util.Map;%0A
 import j
@@ -802,16 +802,16 @@
 l.UUID;%0A
-
 import j
@@ -1015,24 +1015,181 @@
 pp.class);%0A%0A
+    private static final String DEFAULT_SERVER = %22wss://ankor-todo-sample.irian.at%22;%0A    private static final String DEFAULT_ENDPOINT = %22/websocket/ankor%22;%0A%0A
     private 
@@ -1261,16 +1261,17 @@
 vices;%0A%0A
+%0A
     publ
@@ -1423,37 +1423,322 @@
     
-services = getHostServices();
+Map%3CString,String%3E params = getParameters().getNamed();%0A%0A        String server = params.get(%22server%22);%0A        if (server == null) %7B%0A            server = DEFAULT_SERVER;%0A        %7D%0A%0A        String endpoint = params.get(%22endpoint%22);%0A        if (endpoint == null) %7B%0A            endpoint = DEFAULT_ENDPOINT;%0A        %7D%0A
 %0A   
@@ -1797,16 +1797,32 @@
 tSystem(
+server, endpoint
 );%0A%0A    
@@ -1997,16 +1997,54 @@
 ctory();
+%0A        services = getHostServices();
 %0A%0A      
@@ -2460,32 +2460,67 @@
 .show();%0A    %7D%0A%0A
+    // TODO: This should be easier%0A
     private Anko
@@ -2555,16 +2555,46 @@
 tSystem(
+String server, String endpoint
 ) throws
@@ -2997,86 +2997,8 @@
 Id)%0A
-                // .withGlobalEventListener(new FXControllerChangeListener())%0A
     
@@ -3257,49 +3257,29 @@
 i = 
-%22ws://localhost:8080%22 + %22/websocket/ankor
+server + endpoint + %22
 /%22 +

connect todo fx client to irian server by default