package io.antielectron.framework.js;

import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSObject;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BooleanSupplier;

/**
 * TODO Document
 * @author Evan Geng
 */
public class JSGlobals {

    private final Map<String, Object> globals = new HashMap<>();
    private final Map<Browser, BooleanSupplier> boundBrowsers = new HashMap<>();

    public void put(String name, Object value) {
        globals.put(name, value);
        boundBrowsers.entrySet().removeIf(e -> {
            if (!e.getValue().getAsBoolean())
                return true;
            globalsOf(e.getKey()).setProperty(name, value);
            return false;
        });
    }

    public void clear() {
        globals.clear();
    }

    public void clearBindings() {
        boundBrowsers.clear();
    }

    public void bind(BooleanSupplier activeCheck, Browser browser) {
        if (activeCheck.getAsBoolean()) {
            boundBrowsers.put(browser, activeCheck);
            injectTo(globalsOf(browser));
        }
    }

    public void injectTo(JSObject object) {
        globals.forEach(object::setProperty);
    }

    private static JSObject globalsOf(Browser browser) {
        return browser.executeJavaScriptAndReturnValue("window").asObject();
    }

}

@@ -658,25 +658,22 @@
         
-globalsOf
+inject
 (e.getKe
@@ -679,22 +679,10 @@
 ey()
-).setProperty(
+, 
 name
@@ -728,32 +728,158 @@
      %7D);%0A    %7D%0A%0A
+    public void putExecution(String code) %7B%0A        put(Integer.toString(code.hashCode()), new ScriptExecution(code));%0A    %7D%0A%0A
     public void 
@@ -1181,26 +1181,16 @@
 tTo(
-globalsOf(
 browser)
 );%0A 
@@ -1185,17 +1185,16 @@
 browser)
-)
 ;%0A      
@@ -1233,23 +1233,23 @@
 tTo(
-JSObject object
+Browser browser
 ) %7B%0A
@@ -1276,170 +1276,612 @@
 ach(
-object::setProperty);%0A    %7D%0A%0A    private static JSObject globalsOf(Browser browser) %7B%0A        return browser.executeJavaScriptAndReturnValue(%22window%22).asObject();
+(k, v) -%3E inject(browser, k, v));%0A    %7D%0A%0A    private void inject(Browser browser, String key, Object value) %7B%0A        if (value instanceof ScriptExecution)%0A            browser.executeJavaScript(((ScriptExecution)value).script);%0A        else%0A            globalsOf(browser).setProperty(key, value);%0A    %7D%0A%0A    private static JSObject globalsOf(Browser browser) %7B%0A        return browser.executeJavaScriptAndReturnValue(%22window%22).asObject();%0A    %7D%0A%0A    private static class ScriptExecution %7B%0A%0A        final String script;%0A%0A        ScriptExecution(String script) %7B%0A            this.script = script;%0A        %7D%0A
 %0A   

Support for script-execution based deps