/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ht.data.script;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import com.ht.ui.MainApplication;

/**
 *
 * @author Administrator
 */
public class ScriptHandler {

    private static final Logger log = LoggerFactory.getLogger(ScriptHandler.class);
    private static final String loopFileName = "loop.js";
    private static final String startFileName = "start.js";
    private static final String endFileName = "end.js";
    private static final String utilFileName = "util.js";
    /**
     * the main display
     */
    private int interval = 2000;// ms
    private String loopScript;
    private String startScript;
    private String endScript;
    private String utilScript;// 内部实现的工具函数库, 程序启动时运行
    private Thread runningThread;
    private Runnable scriptloopRun;
    private boolean running = false;

    public ScriptHandler(ConcurrentHashMap<String, Object> dataMap) {
    	
        ScriptUtil.INSTANCE.getEngine().setBindings(new RealtimeDataBinding(dataMap), ScriptContext.ENGINE_SCOPE);

        scriptloopRun = new Runnable() {

            @Override
            public void run() {
                runStart();

                CompiledScript compiledScript = null;
                if (ScriptUtil.INSTANCE.getEngine() instanceof Compilable) {
                    if (loopScript != null && !loopScript.isEmpty()) {

                        Compilable compilable = (Compilable) ScriptUtil.INSTANCE.getEngine();
                        try {
                            compiledScript = compilable.compile(loopScript);
                        } catch (ScriptException ex) {
                            //java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
                            ex.printStackTrace();
                        }
                    }
                }

                while (running) {

                    if (compiledScript != null) {
                        try {
                            compiledScript.eval();
                        } catch (ScriptException ex) {
                            ex.printStackTrace();
                        }
                    }
                    try {
                        Thread.sleep(interval);
                    } catch (InterruptedException ex) {
                    }
                }
                runEnd();
                log.info("循环脚本终止");

            }

            // 执行停止脚本
            private void runEnd() {
                if (endScript != null && !endScript.isEmpty()) {
                    try {
                        ScriptUtil.INSTANCE.getEngine().eval(endScript);
                    } catch (ScriptException ex) {
                        java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }

            // 执行启动脚本和工具类库脚本
            private void runStart() {
                if (utilScript != null && !utilScript.isEmpty()) {
					System.out.println(utilScript);
                    try {
                        ScriptUtil.INSTANCE.getEngine().eval(utilScript);
                    } catch (ScriptException ex) {
                        ex.printStackTrace();
                    }
                }

                if (startScript != null && !startScript.isEmpty()) {
                    try {
                        ScriptUtil.INSTANCE.getEngine().eval(startScript);
                    } catch (ScriptException ex) {
                    	log.error("执行启动脚本时出错", ex);
                    }
                }
            }// END Runnable
        };
    }

    private void initScript() {
        startScript = getScriptText(startFileName);
        loopScript = getScriptText(loopFileName);
        endScript = getScriptText(endFileName);

        // 获取工具类库脚本
        try {
            InputStream is = getClass().getResourceAsStream(utilFileName);
            if (is != null) {

                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuilder sb = new StringBuilder();
                while (reader.ready()) {
                    sb.append(reader.readLine());
                    sb.append("\n");
                }
                utilScript = sb.toString();
            }
        } catch (Exception ex) {
            java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private String getScriptText(String fileName) {
        BufferedReader reader = null;
            try {
                URL url = new URL("http://" + MainApplication.getMainApp().hostProperty() + "/" + fileName);
                InputStream is = url.openStream();
                reader = new BufferedReader(new InputStreamReader(is));
            } catch (Exception ex) {
            	log.warn("文件未找到: {}", fileName);
                //java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
//        if (MainApplication.getMainApp().isApplet()) {
//        } else {
//            try {
//                File loopFile = new File(new URI(MainApplication.getMainApp().getHostServices().resolveURI(MainApplication.getMainApp().getHostServices().getDocumentBase(), fileName)));
//                if (loopFile.exists()) {
//                    try {
//                        reader = new BufferedReader(new InputStreamReader(new FileInputStream(loopFile), "UTF-8"));
//                    } catch (FileNotFoundException ex) {
//                    } catch (UnsupportedEncodingException ex) {
//                        java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
//                    }
//                }
//            } catch (URISyntaxException ex) {
//                java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
//            }
//        }

        if (reader != null) {

            try {
                StringBuilder sb = new StringBuilder();
                while (reader.ready()) {
                    sb.append(reader.readLine());
                    sb.append("\n");
                }
                return sb.toString();
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException ex) {
                    }
                }
            }
        }

        return null;
    }

    public void start() {
        if (this.running) {
            log.info("线程已经启动");
            return;
        }
        log.info("启动循环脚本.");
        this.running = true;

//        Document doc = MainApplication.getMainApp().getSvgViewer().getWebEngine().getDocument();
//        if (doc != null) {
//            String str = doc.getDocumentElement().getAttribute("interval");
//            if (str != null) {
//                try {
//                    interval = Integer.parseInt(str);
//                } catch (NumberFormatException numberFormatException) {
//                }
//            }
//        }

        initScript();
        runningThread = new Thread(scriptloopRun);
        runningThread.start();
    }

    public void stop() {
        this.running = false;
        if (this.runningThread != null) {
            try {
                runningThread.join();
            } catch (InterruptedException ex) {
                java.util.logging.Logger.getLogger(ScriptHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
